diff --git a/.ci/generate-buildkite-pipeline-premerge b/.ci/generate-buildkite-pipeline-premerge index 4ebf304e23d5875c23d626984d17fb1ed5004a0f..2e503c867403bcf6fc56f6eed024229b82a0cc1d 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 libc lldb openmp cross-project-tests; do + for p in clang-tools-extra compiler-rt flang lldb cross-project-tests; do echo $p done ;; @@ -224,7 +224,7 @@ fi # needs while letting them run on the infrastructure provided by LLVM. # Figure out which projects need to be built on each platform -all_projects="bolt clang-tools-extra compiler-rt cross-project-tests flang libc libclc lld lldb llvm mlir openmp polly pstl" +all_projects="bolt clang clang-tools-extra compiler-rt cross-project-tests flang libc libclc lld lldb llvm mlir openmp polly pstl" modified_projects="$(keep-modified-projects ${all_projects})" linux_projects_to_test=$(exclude-linux $(compute-projects-to-test ${modified_projects})) diff --git a/.ci/monolithic-linux.sh b/.ci/monolithic-linux.sh index 1e7b2d2a36c2453d8dce7bc08ee53a152b9f2cfc..9e670c447fbaddc82106905b60927fc2c5c883db 100755 --- a/.ci/monolithic-linux.sh +++ b/.ci/monolithic-linux.sh @@ -54,4 +54,4 @@ cmake -S ${MONOREPO_ROOT}/llvm -B ${BUILD_DIR} \ echo "--- ninja" # Targets are not escaped as they are passed as separate arguments. -ninja -C "${BUILD_DIR}" ${targets} +ninja -C "${BUILD_DIR}" -k 0 ${targets} diff --git a/.ci/monolithic-windows.sh b/.ci/monolithic-windows.sh index 9561bf668a90cb87e44b26195bb86c2c0400c212..52ba13036f915983e97ad1149ffc40ee51a4c24e 100755 --- a/.ci/monolithic-windows.sh +++ b/.ci/monolithic-windows.sh @@ -62,4 +62,4 @@ cmake -S ${MONOREPO_ROOT}/llvm -B ${BUILD_DIR} \ echo "--- ninja" # Targets are not escaped as they are passed as separate arguments. -ninja -C "${BUILD_DIR}" ${targets} +ninja -C "${BUILD_DIR}" -k 0 ${targets} diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 85850848b220c4e61b447dc022657065bb914ab1..561da6a588c016ae0ca7d5ee78d3da867f6a9b85 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -32,6 +32,9 @@ /clang/www/cxx_dr_status.html @Endilll /clang/www/make_cxx_dr_status @Endilll +clang/lib/AST/Interp/ @tbaederr +clang/test/AST/Interp/ @tbaederr + /lldb/ @JDevlieghere # MLIR Interfaces. @@ -105,3 +108,6 @@ # BOLT /bolt/ @aaupov @maksfb @rafaelauler @ayermolo @dcci + +# Bazel build system. +/utils/bazel/ @rupprecht diff --git a/.github/new-prs-labeler.yml b/.github/new-prs-labeler.yml index 9a580c6d6984e105fbc9b3516d99c72896fa888f..a0428336d300f9ac3d4eaff2f2daf4100e4ccdfc 100644 --- a/.github/new-prs-labeler.yml +++ b/.github/new-prs-labeler.yml @@ -629,6 +629,8 @@ backend:DirectX: - '**/*DirectX*/**' - '**/*DXIL*/**' - '**/*dxil*/**' + - '**/*DXContainer*' + - '**/*DXContainer*/**' backend:SPIR-V: - clang/lib/Driver/ToolChains/SPIRV.* @@ -933,3 +935,6 @@ openmp:libomp: openmp:libomptarget: - any: ['openmp/**', '!openmp/runtime/**'] + +bazel: + - utils/bazel/** diff --git a/.github/workflows/issue-release-workflow.yml b/.github/workflows/issue-release-workflow.yml index 448c1c56f897f5ef99aa9877fb30dd8c5603a3f9..eb88ec6e43c57409b6656c9b3e21bdc7cf76fede 100644 --- a/.github/workflows/issue-release-workflow.yml +++ b/.github/workflows/issue-release-workflow.yml @@ -65,5 +65,5 @@ jobs: release-workflow \ --branch-repo-token ${{ secrets.RELEASE_WORKFLOW_PUSH_SECRET }} \ --issue-number ${{ github.event.issue.number }} \ - --requested-by ${{ github.event.issue.user.login }} \ + --requested-by ${{ (github.event.action == 'opened' && github.event.issue.user.login) || github.event.comment.user.login }} \ auto diff --git a/.github/workflows/llvm-project-tests.yml b/.github/workflows/llvm-project-tests.yml index 43b90193406fc96983e9a73675fc322f1280c70e..a52dd2db8035ddce07a606268f6472f552841f5c 100644 --- a/.github/workflows/llvm-project-tests.yml +++ b/.github/workflows/llvm-project-tests.yml @@ -118,6 +118,11 @@ jobs: else builddir="$(pwd)"/build fi + if [ "${{ runner.os }}" == "macOS" ]; then + # Workaround test failure on some lld tests on MacOS + # https://github.com/llvm/llvm-project/issues/81967 + extra_cmake_args="-DLLVM_DISABLE_ASSEMBLY_FILES=ON" + fi echo "llvm-builddir=$builddir" >> "$GITHUB_OUTPUT" cmake -G Ninja \ -B "$builddir" \ diff --git a/.github/workflows/pr-code-format.yml b/.github/workflows/pr-code-format.yml index 3d0c23917bd403007ccd102787546793b8bfa36a..1d1fa2483b658f762b5d4a3a65ec4c99842d65ba 100644 --- a/.github/workflows/pr-code-format.yml +++ b/.github/workflows/pr-code-format.yml @@ -53,7 +53,7 @@ jobs: - name: Install clang-format uses: aminya/setup-cpp@v1 with: - clangformat: 17.0.1 + clangformat: 18.1.1 - name: Setup Python env uses: actions/setup-python@v4 diff --git a/.github/workflows/release-binaries.yml b/.github/workflows/release-binaries.yml index 1dba91746dae5a8a375a554feb41592578dba859..131ad3004f457743403fbc07a64193cf53262c6a 100644 --- a/.github/workflows/release-binaries.yml +++ b/.github/workflows/release-binaries.yml @@ -71,8 +71,8 @@ jobs: # | X.Y.Z | -final run: | tag="${{ github.ref_name }}" - trimmed=$(echo ${{ inputs.tag }} | xargs) - [[ "$trimmed" != "" ]] && tag="$trimmed" + trimmed=$(echo ${{ inputs.release-version }} | xargs) + [[ "$trimmed" != "" ]] && tag="llvmorg-$trimmed" if [ "$tag" = "main" ]; then # If tag is main, then we've been triggered by a scheduled so pass so # use the head commit as the tag. diff --git a/bolt/include/bolt/Core/DIEBuilder.h b/bolt/include/bolt/Core/DIEBuilder.h index 4debf9363354725d612d6fae03a0f2d0e0cce1e5..06084819ec0b3ab96daa83f071a5594e8d7efcd0 100644 --- a/bolt/include/bolt/Core/DIEBuilder.h +++ b/bolt/include/bolt/Core/DIEBuilder.h @@ -209,7 +209,13 @@ private: void updateReferences(); /// Update the Offset and Size of DIE, populate DebugNames table. - uint32_t finalizeDIEs(DWARFUnit &CU, DIE &Die, uint32_t &CurOffset); + /// Along with current CU, and DIE being processed and the new DIE offset to + /// be updated, it takes in Parents vector that can be empty if this DIE has + /// no parents. + uint32_t + finalizeDIEs(DWARFUnit &CU, DIE &Die, + std::vector> &Parents, + uint32_t &CurOffset); void registerUnit(DWARFUnit &DU, bool NeedSort); diff --git a/bolt/include/bolt/Core/DebugNames.h b/bolt/include/bolt/Core/DebugNames.h index 84c448aa1354cc866a8c484e11c808724ad4d550..1f17f1ae4d139badf57defc981f0557d78c35593 100644 --- a/bolt/include/bolt/Core/DebugNames.h +++ b/bolt/include/bolt/Core/DebugNames.h @@ -36,6 +36,9 @@ public: bool isTU() const { return DWARF5AccelTableData::isTU(); } std::optional getSecondUnitID() const { return SecondUnitID; } + void setPatchOffset(uint64_t PatchOffset) { OffsetVal = PatchOffset; } + uint64_t getPatchOffset() const { return std::get(OffsetVal); } + private: std::optional SecondUnitID; }; @@ -49,10 +52,12 @@ public: Abbrev->~DebugNamesAbbrev(); } /// Add DWARF5 Accelerator table entry. - /// Input is DWARFUnit being processed, DIE that belongs to it, and potential - /// SkeletonCU if the Unit comes from a DWO section. - void addAccelTableEntry(DWARFUnit &Unit, const DIE &Die, - const std::optional &DWOID); + /// Input is DWARFUnit being processed, DIE that belongs to it, potential + /// DWOID if the Unit comes from a DWO section, and potential parent entry. + std::optional + addAccelTableEntry(DWARFUnit &Unit, const DIE &Die, + const std::optional &DWOID, + std::optional &Parent); /// Set current unit being processed. void setCurrentUnit(DWARFUnit &Unit, const uint64_t UnitStartOffset); /// Emit Accelerator table. @@ -121,6 +126,8 @@ private: llvm::DenseMap StrCacheToOffsetMap; // Contains DWO ID to CUList Index. llvm::DenseMap CUOffsetsToPatch; + // Contains a map of Entry ID to Entry relative offset. + llvm::DenseMap EntryRelativeOffsets; /// Adds Unit to either CUList, LocalTUList or ForeignTUList. /// Input Unit being processed, and DWO ID if Unit is being processed comes /// from a DWO section. @@ -143,7 +150,7 @@ private: /// Write Entries. void writeEntries(); /// Write an Entry. - void writeEntry(const BOLTDWARF5AccelTableData &Entry); + void writeEntry(BOLTDWARF5AccelTableData &Entry); /// Write augmentation_string for BOLT. void writeAugmentationString(); /// Emit out Header for DWARF5 Accelerator table. diff --git a/bolt/include/bolt/Core/MCPlusBuilder.h b/bolt/include/bolt/Core/MCPlusBuilder.h index 6bb76d1b917db3159bfca8cbd3904110486a056b..96b58f541623447e507715cb2da5358986b70fc5 100644 --- a/bolt/include/bolt/Core/MCPlusBuilder.h +++ b/bolt/include/bolt/Core/MCPlusBuilder.h @@ -487,10 +487,9 @@ public: llvm_unreachable("not implemented"); } - virtual bool createDirectCall(MCInst &Inst, const MCSymbol *Target, + virtual void createDirectCall(MCInst &Inst, const MCSymbol *Target, MCContext *Ctx, bool IsTailCall) { llvm_unreachable("not implemented"); - return false; } virtual MCPhysReg getX86R11() const { llvm_unreachable("not implemented"); } @@ -1534,15 +1533,13 @@ public: } /// Create a no-op instruction. - virtual bool createNoop(MCInst &Inst) const { + virtual void createNoop(MCInst &Inst) const { llvm_unreachable("not implemented"); - return false; } /// Create a return instruction. - virtual bool createReturn(MCInst &Inst) const { + virtual void createReturn(MCInst &Inst) const { llvm_unreachable("not implemented"); - return false; } /// Store \p Target absolute address to \p RegName @@ -1556,32 +1553,30 @@ public: /// Creates a new unconditional branch instruction in Inst and set its operand /// to TBB. - /// - /// Returns true on success. - virtual bool createUncondBranch(MCInst &Inst, const MCSymbol *TBB, + virtual void createUncondBranch(MCInst &Inst, const MCSymbol *TBB, MCContext *Ctx) const { llvm_unreachable("not implemented"); - return false; + } + + /// Create a version of unconditional jump that has the largest span for a + /// single instruction with direct target. + virtual void createLongUncondBranch(MCInst &Inst, const MCSymbol *Target, + MCContext *Ctx) const { + llvm_unreachable("not implemented"); } /// Creates a new call instruction in Inst and sets its operand to /// Target. - /// - /// Returns true on success. - virtual bool createCall(MCInst &Inst, const MCSymbol *Target, + virtual void createCall(MCInst &Inst, const MCSymbol *Target, MCContext *Ctx) { llvm_unreachable("not implemented"); - return false; } /// Creates a new tail call instruction in Inst and sets its operand to /// Target. - /// - /// Returns true on success. - virtual bool createTailCall(MCInst &Inst, const MCSymbol *Target, + virtual void createTailCall(MCInst &Inst, const MCSymbol *Target, MCContext *Ctx) { llvm_unreachable("not implemented"); - return false; } virtual void createLongTailCall(InstructionListType &Seq, @@ -1590,43 +1585,36 @@ public: } /// Creates a trap instruction in Inst. - /// - /// Returns true on success. - virtual bool createTrap(MCInst &Inst) const { + virtual void createTrap(MCInst &Inst) const { llvm_unreachable("not implemented"); - return false; } /// Creates an instruction to bump the stack pointer just like a call. - virtual bool createStackPointerIncrement(MCInst &Inst, int Size = 8, + virtual void createStackPointerIncrement(MCInst &Inst, int Size = 8, bool NoFlagsClobber = false) const { llvm_unreachable("not implemented"); - return false; } /// Creates an instruction to move the stack pointer just like a ret. - virtual bool createStackPointerDecrement(MCInst &Inst, int Size = 8, + virtual void createStackPointerDecrement(MCInst &Inst, int Size = 8, bool NoFlagsClobber = false) const { llvm_unreachable("not implemented"); - return false; } /// Create a store instruction using \p StackReg as the base register /// and \p Offset as the displacement. - virtual bool createSaveToStack(MCInst &Inst, const MCPhysReg &StackReg, + virtual void createSaveToStack(MCInst &Inst, const MCPhysReg &StackReg, int Offset, const MCPhysReg &SrcReg, int Size) const { llvm_unreachable("not implemented"); - return false; } - virtual bool createLoad(MCInst &Inst, const MCPhysReg &BaseReg, int64_t Scale, + virtual void createLoad(MCInst &Inst, const MCPhysReg &BaseReg, int64_t Scale, const MCPhysReg &IndexReg, int64_t Offset, const MCExpr *OffsetExpr, const MCPhysReg &AddrSegmentReg, const MCPhysReg &DstReg, int Size) const { llvm_unreachable("not implemented"); - return false; } virtual InstructionListType createLoadImmediate(const MCPhysReg Dest, @@ -1636,32 +1624,27 @@ public: /// Create a fragment of code (sequence of instructions) that load a 32-bit /// address from memory, zero-extends it to 64 and jump to it (indirect jump). - virtual bool + virtual void createIJmp32Frag(SmallVectorImpl &Insts, const MCOperand &BaseReg, const MCOperand &Scale, const MCOperand &IndexReg, const MCOperand &Offset, const MCOperand &TmpReg) const { llvm_unreachable("not implemented"); - return false; } /// Create a load instruction using \p StackReg as the base register /// and \p Offset as the displacement. - virtual bool createRestoreFromStack(MCInst &Inst, const MCPhysReg &StackReg, + virtual void createRestoreFromStack(MCInst &Inst, const MCPhysReg &StackReg, int Offset, const MCPhysReg &DstReg, int Size) const { llvm_unreachable("not implemented"); - return false; } /// Creates a call frame pseudo instruction. A single operand identifies which /// MCCFIInstruction this MCInst is referring to. - /// - /// Returns true on success. - virtual bool createCFI(MCInst &Inst, int64_t Offset) const { + virtual void createCFI(MCInst &Inst, int64_t Offset) const { Inst.clear(); Inst.setOpcode(TargetOpcode::CFI_INSTRUCTION); Inst.addOperand(MCOperand::createImm(Offset)); - return true; } /// Create an inline version of memcpy(dest, src, 1). @@ -1699,6 +1682,12 @@ public: return Inst.getOpcode() == TargetOpcode::CFI_INSTRUCTION; } + /// Create a conditional branch with a target-specific conditional code \p CC. + virtual void createCondBranch(MCInst &Inst, const MCSymbol *Target, + unsigned CC, MCContext *Ctx) const { + llvm_unreachable("not implemented"); + } + /// Reverses the branch condition in Inst and update its taken target to TBB. /// /// Returns true on success. diff --git a/bolt/lib/Core/DIEBuilder.cpp b/bolt/lib/Core/DIEBuilder.cpp index 42287978a8576feb868f82cd38496adb41504658..0cf8a5e8c2c3db8a4892a62b78ee1f326887bb89 100644 --- a/bolt/lib/Core/DIEBuilder.cpp +++ b/bolt/lib/Core/DIEBuilder.cpp @@ -377,20 +377,32 @@ getUnitForOffset(DIEBuilder &Builder, DWARFContext &DWCtx, return nullptr; } -uint32_t DIEBuilder::finalizeDIEs(DWARFUnit &CU, DIE &Die, - uint32_t &CurOffset) { +uint32_t DIEBuilder::finalizeDIEs( + DWARFUnit &CU, DIE &Die, + std::vector> &Parents, + uint32_t &CurOffset) { getState().DWARFDieAddressesParsed.erase(Die.getOffset()); uint32_t CurSize = 0; Die.setOffset(CurOffset); - DebugNamesTable.addAccelTableEntry( - CU, Die, SkeletonCU ? SkeletonCU->getDWOId() : std::nullopt); + std::optional NameEntry = + DebugNamesTable.addAccelTableEntry( + CU, Die, SkeletonCU ? SkeletonCU->getDWOId() : std::nullopt, + Parents.back()); + // It is possible that an indexed debugging information entry has a parent + // that is not indexed (for example, if its parent does not have a name + // attribute). In such a case, a parent attribute may point to a nameless + // index entry (that is, one that cannot be reached from any entry in the name + // table), or it may point to the nearest ancestor that does have an index + // entry. + if (NameEntry) + Parents.push_back(std::move(NameEntry)); for (DIEValue &Val : Die.values()) CurSize += Val.sizeOf(CU.getFormParams()); CurSize += getULEB128Size(Die.getAbbrevNumber()); CurOffset += CurSize; for (DIE &Child : Die.children()) { - uint32_t ChildSize = finalizeDIEs(CU, Child, CurOffset); + uint32_t ChildSize = finalizeDIEs(CU, Child, Parents, CurOffset); CurSize += ChildSize; } // for children end mark. @@ -400,6 +412,8 @@ uint32_t DIEBuilder::finalizeDIEs(DWARFUnit &CU, DIE &Die, } Die.setSize(CurSize); + if (NameEntry) + Parents.pop_back(); return CurSize; } @@ -410,7 +424,9 @@ void DIEBuilder::finish() { uint32_t HeaderSize = CU.getHeaderSize(); uint32_t CurOffset = HeaderSize; DebugNamesTable.setCurrentUnit(CU, UnitStartOffset); - finalizeDIEs(CU, *UnitDIE, CurOffset); + std::vector> Parents; + Parents.push_back(std::nullopt); + finalizeDIEs(CU, *UnitDIE, Parents, CurOffset); DWARFUnitInfo &CurUnitInfo = getUnitInfoByDwarfUnit(CU); CurUnitInfo.UnitOffset = UnitStartOffset; diff --git a/bolt/lib/Core/DebugNames.cpp b/bolt/lib/Core/DebugNames.cpp index 1a7792afbbd941fa962b98f04205939b9f60806e..23a29f52513c04bb751e9932df923fa052419a95 100644 --- a/bolt/lib/Core/DebugNames.cpp +++ b/bolt/lib/Core/DebugNames.cpp @@ -13,6 +13,7 @@ #include "llvm/Support/EndianStream.h" #include "llvm/Support/LEB128.h" #include +#include namespace llvm { namespace bolt { @@ -163,10 +164,16 @@ static uint64_t getNameOffset(BinaryContext &BC, DWARFUnit &Unit, Index * DwarfOffsetByteSize); } -void DWARF5AcceleratorTable::addAccelTableEntry( - DWARFUnit &Unit, const DIE &Die, const std::optional &DWOID) { +static uint64_t getEntryID(const BOLTDWARF5AccelTableData &Entry) { + return reinterpret_cast(&Entry); +} + +std::optional +DWARF5AcceleratorTable::addAccelTableEntry( + DWARFUnit &Unit, const DIE &Die, const std::optional &DWOID, + std::optional &Parent) { if (Unit.getVersion() < 5 || !NeedToCreate) - return; + return std::nullopt; std::string NameToUse = ""; auto canProcess = [&](const DIE &Die) -> bool { switch (Die.getTag()) { @@ -217,7 +224,7 @@ void DWARF5AcceleratorTable::addAccelTableEntry( }; if (!canProcess(Die)) - return; + return std::nullopt; // Addes a Unit to either CU, LocalTU or ForeignTU list the first time we // encounter it. @@ -227,10 +234,10 @@ void DWARF5AcceleratorTable::addAccelTableEntry( addUnit(Unit, DWOID); } - auto addEntry = [&](DIEValue ValName) -> void { + auto getName = [&](DIEValue ValName) -> std::optional { if ((!ValName || ValName.getForm() == dwarf::DW_FORM_string) && NameToUse.empty()) - return; + return std::nullopt; std::string Name = ""; uint64_t NameIndexOffset = 0; if (NameToUse.empty()) { @@ -260,7 +267,16 @@ void DWARF5AcceleratorTable::addAccelTableEntry( // This the same hash function used in DWARF5AccelTableData. It.HashValue = caseFoldingDjbHash(Name); } + return Name; + }; + + auto addEntry = + [&](DIEValue ValName) -> std::optional { + std::optional Name = getName(ValName); + if (!Name) + return std::nullopt; + auto &It = Entries[*Name]; bool IsTU = false; uint32_t DieTag = 0; uint32_t UnitID = getUnitID(Unit, IsTU, DieTag); @@ -270,18 +286,53 @@ void DWARF5AcceleratorTable::addAccelTableEntry( if (Iter == CUOffsetsToPatch.end()) BC.errs() << "BOLT-WARNING: [internal-dwarf-warning]: Could not find " "DWO ID in CU offsets for second Unit Index " - << Name << ". For DIE at offset: " + << *Name << ". For DIE at offset: " << Twine::utohexstr(CurrentUnitOffset + Die.getOffset()) << ".\n"; SecondIndex = Iter->second; } + std::optional ParentOffset = + (Parent ? std::optional(getEntryID(**Parent)) : std::nullopt); + // This will be populated later in writeEntry. + // This way only parent entries get tracked. + // Keeping memory footprint down. + if (ParentOffset) + EntryRelativeOffsets.insert({*ParentOffset, 0}); It.Values.push_back(new (Allocator) BOLTDWARF5AccelTableData( - Die.getOffset(), std::nullopt, DieTag, UnitID, IsTU, SecondIndex)); + Die.getOffset(), ParentOffset, DieTag, UnitID, IsTU, SecondIndex)); + return It.Values.back(); }; - addEntry(Die.findAttribute(dwarf::Attribute::DW_AT_name)); - addEntry(Die.findAttribute(dwarf::Attribute::DW_AT_linkage_name)); - return; + // Minor optimization not to add entry twice for DW_TAG_namespace if it has no + // DW_AT_name. + if (!(Die.getTag() == dwarf::DW_TAG_namespace && + !Die.findAttribute(dwarf::Attribute::DW_AT_name))) + addEntry(Die.findAttribute(dwarf::Attribute::DW_AT_linkage_name)); + // For the purposes of determining whether a debugging information entry has a + // particular attribute (such as DW_AT_name), if debugging information entry A + // has a DW_AT_specification or DW_AT_abstract_origin attribute pointing to + // another debugging information entry B, any attributes of B are considered + // to be part of A. + auto processReferencedDie = [&](const dwarf::Attribute &Attr) + -> std::optional { + const DIEValue Value = Die.findAttribute(Attr); + if (!Value) + return std::nullopt; + const DIEEntry &DIEENtry = Value.getDIEEntry(); + DIE &EntryDie = DIEENtry.getEntry(); + addEntry(EntryDie.findAttribute(dwarf::Attribute::DW_AT_linkage_name)); + return addEntry(EntryDie.findAttribute(dwarf::Attribute::DW_AT_name)); + }; + + if (std::optional Entry = + processReferencedDie(dwarf::Attribute::DW_AT_abstract_origin)) + return *Entry; + if (std::optional Entry = + processReferencedDie(dwarf::Attribute::DW_AT_specification)) + return *Entry; + + return addEntry(Die.findAttribute(dwarf::Attribute::DW_AT_name)); + ; } /// Algorithm from llvm implementation. @@ -345,8 +396,13 @@ void DWARF5AcceleratorTable::finalize() { std::optional DWARF5AcceleratorTable::getIndexForEntry( const BOLTDWARF5AccelTableData &Value) const { + // The foreign TU list immediately follows the local TU list and they both + // use the same index, so that if there are N local TU entries, the index for + // the first foreign TU is N. if (Value.isTU()) - return {{Value.getUnitID(), {dwarf::DW_IDX_type_unit, TUIndexForm}}}; + return {{(Value.getSecondUnitID() ? (unsigned)LocalTUList.size() : 0) + + Value.getUnitID(), + {dwarf::DW_IDX_type_unit, TUIndexForm}}}; if (CUList.size() > 1) return {{Value.getUnitID(), {dwarf::DW_IDX_compile_unit, CUIndexForm}}}; return std::nullopt; @@ -377,6 +433,11 @@ void DWARF5AcceleratorTable::populateAbbrevsMap() { if (SecondEntryRet) Abbrev.addAttribute(SecondEntryRet->Encoding); Abbrev.addAttribute({dwarf::DW_IDX_die_offset, dwarf::DW_FORM_ref4}); + if (std::optional Offset = Value->getParentDieOffset()) + Abbrev.addAttribute({dwarf::DW_IDX_parent, dwarf::DW_FORM_ref4}); + else + Abbrev.addAttribute( + {dwarf::DW_IDX_parent, dwarf::DW_FORM_flag_present}); FoldingSetNodeID ID; Abbrev.Profile(ID); void *InsertPos; @@ -396,7 +457,11 @@ void DWARF5AcceleratorTable::populateAbbrevsMap() { } } -void DWARF5AcceleratorTable::writeEntry(const BOLTDWARF5AccelTableData &Entry) { +void DWARF5AcceleratorTable::writeEntry(BOLTDWARF5AccelTableData &Entry) { + const uint64_t EntryID = getEntryID(Entry); + if (EntryRelativeOffsets.find(EntryID) != EntryRelativeOffsets.end()) + EntryRelativeOffsets[EntryID] = EntriesBuffer->size(); + const std::optional EntryRet = getIndexForEntry(Entry); // For forgeign type (FTU) units that need to refer to the FTU and to the CU. @@ -451,6 +516,17 @@ void DWARF5AcceleratorTable::writeEntry(const BOLTDWARF5AccelTableData &Entry) { llvm::endianness::little); break; } + case dwarf::DW_IDX_parent: { + assert( + (AttrEnc.Form == dwarf::DW_FORM_ref4 && Entry.getParentDieOffset()) || + AttrEnc.Form == dwarf::DW_FORM_flag_present); + if (std::optional ParentOffset = Entry.getParentDieOffset()) { + Entry.setPatchOffset(EntriesBuffer->size()); + support::endian::write(*Entriestream, static_cast(UINT32_MAX), + llvm::endianness::little); + } + break; + } } } } @@ -459,13 +535,34 @@ void DWARF5AcceleratorTable::writeEntries() { for (auto &Bucket : getBuckets()) { for (DWARF5AcceleratorTable::HashData *Hash : Bucket) { Hash->EntryOffset = EntriesBuffer->size(); - for (const BOLTDWARF5AccelTableData *Value : Hash->Values) { + for (BOLTDWARF5AccelTableData *Value : Hash->Values) { writeEntry(*Value); } support::endian::write(*Entriestream, static_cast(0), llvm::endianness::little); } } + // Patching parent offsets. + for (auto &Bucket : getBuckets()) { + for (DWARF5AcceleratorTable::HashData *Hash : Bucket) { + for (BOLTDWARF5AccelTableData *Entry : Hash->Values) { + std::optional ParentOffset = Entry->getParentDieOffset(); + if (!ParentOffset) + continue; + if (const auto Iter = EntryRelativeOffsets.find(*ParentOffset); + Iter != EntryRelativeOffsets.end()) { + const uint64_t PatchOffset = Entry->getPatchOffset(); + uint32_t *Ptr = reinterpret_cast( + &EntriesBuffer.get()->data()[PatchOffset]); + *Ptr = Iter->second; + } else { + BC.errs() << "BOLT-WARNING: [internal-dwarf-warning]: Could not find " + "entry with offset " + << *ParentOffset << "\n"; + } + } + } + } } void DWARF5AcceleratorTable::writeAugmentationString() { diff --git a/bolt/lib/Passes/BinaryPasses.cpp b/bolt/lib/Passes/BinaryPasses.cpp index d2850b03e2e13f0aab563815743a412cc31cb18f..bf1c2ddd37dd241ab8ae6794f7f4a209713f4033 100644 --- a/bolt/lib/Passes/BinaryPasses.cpp +++ b/bolt/lib/Passes/BinaryPasses.cpp @@ -1056,10 +1056,9 @@ void Peepholes::addTailcallTraps(BinaryFunction &Function) { MCInst *Inst = BB.getLastNonPseudoInstr(); if (Inst && MIB->isTailCall(*Inst) && MIB->isIndirectBranch(*Inst)) { MCInst Trap; - if (MIB->createTrap(Trap)) { - BB.addInstruction(Trap); - ++TailCallTraps; - } + MIB->createTrap(Trap); + BB.addInstruction(Trap); + ++TailCallTraps; } } } diff --git a/bolt/lib/Passes/ShrinkWrapping.cpp b/bolt/lib/Passes/ShrinkWrapping.cpp index 9a1f9d72623a388a275f204a72a0a092cf962123..c9706500758d1f223f5d71de45e310755f021f78 100644 --- a/bolt/lib/Passes/ShrinkWrapping.cpp +++ b/bolt/lib/Passes/ShrinkWrapping.cpp @@ -680,16 +680,15 @@ void StackLayoutModifier::performChanges() { if (StackPtrReg != BC.MIB->getFramePointer()) Adjustment = -Adjustment; if (IsLoad) - Success = BC.MIB->createRestoreFromStack( - Inst, StackPtrReg, StackOffset + Adjustment, Reg, Size); + BC.MIB->createRestoreFromStack(Inst, StackPtrReg, + StackOffset + Adjustment, Reg, Size); else if (IsStore) - Success = BC.MIB->createSaveToStack( - Inst, StackPtrReg, StackOffset + Adjustment, Reg, Size); + BC.MIB->createSaveToStack(Inst, StackPtrReg, StackOffset + Adjustment, + Reg, Size); LLVM_DEBUG({ dbgs() << "Adjusted instruction: "; Inst.dump(); }); - assert(Success); } } } @@ -1653,19 +1652,13 @@ Expected ShrinkWrapping::createStackAccess(int SPVal, int FPVal, if (SPVal != StackPointerTracking::SUPERPOSITION && SPVal != StackPointerTracking::EMPTY) { if (FIE.IsLoad) { - if (!BC.MIB->createRestoreFromStack(NewInst, BC.MIB->getStackPointer(), - FIE.StackOffset - SPVal, FIE.RegOrImm, - FIE.Size)) { - return createFatalBOLTError( - "createRestoreFromStack: not supported on this platform\n"); - } - } else { - if (!BC.MIB->createSaveToStack(NewInst, BC.MIB->getStackPointer(), + BC.MIB->createRestoreFromStack(NewInst, BC.MIB->getStackPointer(), FIE.StackOffset - SPVal, FIE.RegOrImm, - FIE.Size)) { - return createFatalBOLTError( - "createSaveToStack: not supported on this platform\n"); - } + FIE.Size); + } else { + BC.MIB->createSaveToStack(NewInst, BC.MIB->getStackPointer(), + FIE.StackOffset - SPVal, FIE.RegOrImm, + FIE.Size); } if (CreatePushOrPop) BC.MIB->changeToPushOrPop(NewInst); @@ -1675,19 +1668,12 @@ Expected ShrinkWrapping::createStackAccess(int SPVal, int FPVal, FPVal != StackPointerTracking::EMPTY); if (FIE.IsLoad) { - if (!BC.MIB->createRestoreFromStack(NewInst, BC.MIB->getFramePointer(), - FIE.StackOffset - FPVal, FIE.RegOrImm, - FIE.Size)) { - return createFatalBOLTError( - "createRestoreFromStack: not supported on this platform\n"); - } - } else { - if (!BC.MIB->createSaveToStack(NewInst, BC.MIB->getFramePointer(), + BC.MIB->createRestoreFromStack(NewInst, BC.MIB->getFramePointer(), FIE.StackOffset - FPVal, FIE.RegOrImm, - FIE.Size)) { - return createFatalBOLTError( - "createSaveToStack: not supported on this platform\n"); - } + FIE.Size); + } else { + BC.MIB->createSaveToStack(NewInst, BC.MIB->getFramePointer(), + FIE.StackOffset - FPVal, FIE.RegOrImm, FIE.Size); } return NewInst; } diff --git a/bolt/lib/Profile/StaleProfileMatching.cpp b/bolt/lib/Profile/StaleProfileMatching.cpp index 631ccaec6ae61471edd81efcec353256c1d56d04..016962ff34d8dff0637ff6880f55f15aef6b0b19 100644 --- a/bolt/lib/Profile/StaleProfileMatching.cpp +++ b/bolt/lib/Profile/StaleProfileMatching.cpp @@ -705,6 +705,9 @@ void assignProfile(BinaryFunction &BF, bool YAMLProfileReader::inferStaleProfile( BinaryFunction &BF, const yaml::bolt::BinaryFunctionProfile &YamlBF) { + if (!BF.hasCFG()) + return false; + LLVM_DEBUG(dbgs() << "BOLT-INFO: applying profile inference for " << "\"" << BF.getPrintName() << "\"\n"); diff --git a/bolt/lib/Rewrite/LinuxKernelRewriter.cpp b/bolt/lib/Rewrite/LinuxKernelRewriter.cpp index 331a61e7c3c2cdc0f344adc12f10be5fed6cea29..a2bfd45a64e3040d5a8c9caf889ea24d0d780734 100644 --- a/bolt/lib/Rewrite/LinuxKernelRewriter.cpp +++ b/bolt/lib/Rewrite/LinuxKernelRewriter.cpp @@ -55,6 +55,11 @@ static cl::opt DumpParavirtualPatchSites( "dump-para-sites", cl::desc("dump Linux kernel paravitual patch sites"), cl::init(false), cl::Hidden, cl::cat(BoltCategory)); +static cl::opt + DumpPCIFixups("dump-pci-fixups", + cl::desc("dump Linux kernel PCI fixup table"), + cl::init(false), cl::Hidden, cl::cat(BoltCategory)); + static cl::opt DumpStaticCalls("dump-static-calls", cl::desc("dump Linux kernel static calls"), cl::init(false), cl::Hidden, @@ -181,6 +186,10 @@ class LinuxKernelRewriter final : public MetadataRewriter { /// Size of bug_entry struct. static constexpr size_t BUG_TABLE_ENTRY_SIZE = 12; + /// .pci_fixup section. + ErrorOr PCIFixupSection = std::errc::bad_address; + static constexpr size_t PCI_FIXUP_ENTRY_SIZE = 16; + /// Insert an LKMarker for a given code pointer \p PC from a non-code section /// \p SectionName. void insertLKMarker(uint64_t PC, uint64_t SectionOffset, @@ -190,9 +199,6 @@ class LinuxKernelRewriter final : public MetadataRewriter { /// Process linux kernel special sections and their relocations. void processLKSections(); - /// Process special linux kernel section, .pci_fixup. - void processLKPCIFixup(); - /// Process __ksymtab and __ksymtab_gpl. void processLKKSymtab(bool IsGPL = false); @@ -226,6 +232,9 @@ class LinuxKernelRewriter final : public MetadataRewriter { /// Read alternative instruction info from .altinstructions. Error readAltInstructions(); + /// Read .pci_fixup + Error readPCIFixupTable(); + /// Mark instructions referenced by kernel metadata. Error markInstructions(); @@ -256,6 +265,9 @@ public: if (Error E = readAltInstructions()) return E; + if (Error E = readPCIFixupTable()) + return E; + return Error::success(); } @@ -318,41 +330,11 @@ void LinuxKernelRewriter::insertLKMarker(uint64_t PC, uint64_t SectionOffset, } void LinuxKernelRewriter::processLKSections() { - processLKPCIFixup(); processLKKSymtab(); processLKKSymtab(true); processLKSMPLocks(); } -/// Process .pci_fixup section of Linux Kernel. -/// This section contains a list of entries for different PCI devices and their -/// corresponding hook handler (code pointer where the fixup -/// code resides, usually on x86_64 it is an entry PC relative 32 bit offset). -/// Documentation is in include/linux/pci.h. -void LinuxKernelRewriter::processLKPCIFixup() { - ErrorOr SectionOrError = - BC.getUniqueSectionByName(".pci_fixup"); - if (!SectionOrError) - return; - - const uint64_t SectionSize = SectionOrError->getSize(); - const uint64_t SectionAddress = SectionOrError->getAddress(); - assert((SectionSize % 16) == 0 && ".pci_fixup size is not a multiple of 16"); - - for (uint64_t I = 12; I + 4 <= SectionSize; I += 16) { - const uint64_t PC = SectionAddress + I; - ErrorOr Offset = BC.getSignedValueAtAddress(PC, 4); - assert(Offset && "cannot read value from .pci_fixup"); - const int32_t SignedOffset = *Offset; - const uint64_t HookupAddress = PC + SignedOffset; - BinaryFunction *HookupFunction = - BC.getBinaryFunctionAtAddress(HookupAddress); - assert(HookupFunction && "expected function for entry in .pci_fixup"); - BC.addRelocation(PC, HookupFunction->getSymbol(), Relocation::getPC32(), 0, - *Offset); - } -} - /// Process __ksymtab[_gpl] sections of Linux Kernel. /// This section lists all the vmlinux symbols that kernel modules can access. /// @@ -1283,6 +1265,84 @@ Error LinuxKernelRewriter::readAltInstructions() { return Error::success(); } +/// When the Linux kernel needs to handle an error associated with a given PCI +/// device, it uses a table stored in .pci_fixup section to locate a fixup code +/// specific to the vendor and the problematic device. The section contains a +/// list of the following structures defined in include/linux/pci.h: +/// +/// struct pci_fixup { +/// u16 vendor; /* Or PCI_ANY_ID */ +/// u16 device; /* Or PCI_ANY_ID */ +/// u32 class; /* Or PCI_ANY_ID */ +/// unsigned int class_shift; /* should be 0, 8, 16 */ +/// int hook_offset; +/// }; +/// +/// Normally, the hook will point to a function start and we don't have to +/// update the pointer if we are not relocating functions. Hence, while reading +/// the table we validate this assumption. If a function has a fixup code in the +/// middle of its body, we issue a warning and ignore it. +Error LinuxKernelRewriter::readPCIFixupTable() { + PCIFixupSection = BC.getUniqueSectionByName(".pci_fixup"); + if (!PCIFixupSection) + return Error::success(); + + if (PCIFixupSection->getSize() % PCI_FIXUP_ENTRY_SIZE) + return createStringError(errc::executable_format_error, + "PCI fixup table size error"); + + const uint64_t Address = PCIFixupSection->getAddress(); + DataExtractor DE = DataExtractor(PCIFixupSection->getContents(), + BC.AsmInfo->isLittleEndian(), + BC.AsmInfo->getCodePointerSize()); + uint64_t EntryID = 0; + DataExtractor::Cursor Cursor(0); + while (Cursor && !DE.eof(Cursor)) { + const uint16_t Vendor = DE.getU16(Cursor); + const uint16_t Device = DE.getU16(Cursor); + const uint32_t Class = DE.getU32(Cursor); + const uint32_t ClassShift = DE.getU32(Cursor); + const uint64_t HookAddress = + Address + Cursor.tell() + (int32_t)DE.getU32(Cursor); + + if (!Cursor) + return createStringError(errc::executable_format_error, + "out of bounds while reading .pci_fixup: %s", + toString(Cursor.takeError()).c_str()); + + ++EntryID; + + if (opts::DumpPCIFixups) { + BC.outs() << "PCI fixup entry: " << EntryID << "\n\tVendor 0x" + << Twine::utohexstr(Vendor) << "\n\tDevice: 0x" + << Twine::utohexstr(Device) << "\n\tClass: 0x" + << Twine::utohexstr(Class) << "\n\tClassShift: 0x" + << Twine::utohexstr(ClassShift) << "\n\tHookAddress: 0x" + << Twine::utohexstr(HookAddress) << '\n'; + } + + BinaryFunction *BF = BC.getBinaryFunctionContainingAddress(HookAddress); + if (!BF && opts::Verbosity) { + BC.outs() << "BOLT-INFO: no function matches address 0x" + << Twine::utohexstr(HookAddress) + << " of hook from .pci_fixup\n"; + } + + if (!BF || !BC.shouldEmit(*BF)) + continue; + + if (const uint64_t Offset = HookAddress - BF->getAddress()) { + BC.errs() << "BOLT-WARNING: PCI fixup detected in the middle of function " + << *BF << " at offset 0x" << Twine::utohexstr(Offset) << '\n'; + BF->setSimple(false); + } + } + + BC.outs() << "BOLT-INFO: parsed " << EntryID << " PCI fixup entries\n"; + + return Error::success(); +} + } // namespace std::unique_ptr diff --git a/bolt/lib/Target/AArch64/AArch64MCPlusBuilder.cpp b/bolt/lib/Target/AArch64/AArch64MCPlusBuilder.cpp index 9efb428a6e1baef1adb0e35bd210f9ae4640f7ed..0ae9d3668b93bb87290a54b763e775a5234cfd6d 100644 --- a/bolt/lib/Target/AArch64/AArch64MCPlusBuilder.cpp +++ b/bolt/lib/Target/AArch64/AArch64MCPlusBuilder.cpp @@ -1026,7 +1026,7 @@ public: return Code; } - bool createTailCall(MCInst &Inst, const MCSymbol *Target, + void createTailCall(MCInst &Inst, const MCSymbol *Target, MCContext *Ctx) override { return createDirectCall(Inst, Target, Ctx, /*IsTailCall*/ true); } @@ -1036,11 +1036,10 @@ public: createShortJmp(Seq, Target, Ctx, /*IsTailCall*/ true); } - bool createTrap(MCInst &Inst) const override { + void createTrap(MCInst &Inst) const override { Inst.clear(); Inst.setOpcode(AArch64::BRK); Inst.addOperand(MCOperand::createImm(1)); - return true; } bool convertJmpToTailCall(MCInst &Inst) override { @@ -1068,16 +1067,15 @@ public: Inst.getOperand(0).getImm() == 0; } - bool createNoop(MCInst &Inst) const override { + void createNoop(MCInst &Inst) const override { Inst.setOpcode(AArch64::HINT); Inst.clear(); Inst.addOperand(MCOperand::createImm(0)); - return true; } bool mayStore(const MCInst &Inst) const override { return false; } - bool createDirectCall(MCInst &Inst, const MCSymbol *Target, MCContext *Ctx, + void createDirectCall(MCInst &Inst, const MCSymbol *Target, MCContext *Ctx, bool IsTailCall) override { Inst.setOpcode(IsTailCall ? AArch64::B : AArch64::BL); Inst.clear(); @@ -1086,7 +1084,6 @@ public: *Ctx, 0))); if (IsTailCall) convertJmpToTailCall(Inst); - return true; } bool analyzeBranch(InstructionIterator Begin, InstructionIterator End, @@ -1293,14 +1290,13 @@ public: return true; } - bool createUncondBranch(MCInst &Inst, const MCSymbol *TBB, + void createUncondBranch(MCInst &Inst, const MCSymbol *TBB, MCContext *Ctx) const override { Inst.setOpcode(AArch64::B); Inst.clear(); Inst.addOperand(MCOperand::createExpr(getTargetExprFor( Inst, MCSymbolRefExpr::create(TBB, MCSymbolRefExpr::VK_None, *Ctx), *Ctx, 0))); - return true; } bool shouldRecordCodeRelocation(uint64_t RelType) const override { @@ -1353,14 +1349,13 @@ public: return StringRef("\0\0\0\0", 4); } - bool createReturn(MCInst &Inst) const override { + void createReturn(MCInst &Inst) const override { Inst.setOpcode(AArch64::RET); Inst.clear(); Inst.addOperand(MCOperand::createReg(AArch64::LR)); - return true; } - bool createStackPointerIncrement( + void createStackPointerIncrement( MCInst &Inst, int Size, bool NoFlagsClobber = false /*unused for AArch64*/) const override { Inst.setOpcode(AArch64::SUBXri); @@ -1369,10 +1364,9 @@ public: Inst.addOperand(MCOperand::createReg(AArch64::SP)); Inst.addOperand(MCOperand::createImm(Size)); Inst.addOperand(MCOperand::createImm(0)); - return true; } - bool createStackPointerDecrement( + void createStackPointerDecrement( MCInst &Inst, int Size, bool NoFlagsClobber = false /*unused for AArch64*/) const override { Inst.setOpcode(AArch64::ADDXri); @@ -1381,12 +1375,12 @@ public: Inst.addOperand(MCOperand::createReg(AArch64::SP)); Inst.addOperand(MCOperand::createImm(Size)); Inst.addOperand(MCOperand::createImm(0)); - return true; } void createIndirectBranch(MCInst &Inst, MCPhysReg MemBaseReg, int64_t Disp) const { Inst.setOpcode(AArch64::BR); + Inst.clear(); Inst.addOperand(MCOperand::createReg(MemBaseReg)); } diff --git a/bolt/lib/Target/RISCV/RISCVMCPlusBuilder.cpp b/bolt/lib/Target/RISCV/RISCVMCPlusBuilder.cpp index e19c070b081733c1faea19e509c6e3933fc05107..ab9623d5c51b287f4a1e6e58e1ff0784eb6508a7 100644 --- a/bolt/lib/Target/RISCV/RISCVMCPlusBuilder.cpp +++ b/bolt/lib/Target/RISCV/RISCVMCPlusBuilder.cpp @@ -219,46 +219,43 @@ public: return true; } - bool createReturn(MCInst &Inst) const override { + void createReturn(MCInst &Inst) const override { // TODO "c.jr ra" when RVC is enabled Inst.setOpcode(RISCV::JALR); Inst.clear(); Inst.addOperand(MCOperand::createReg(RISCV::X0)); Inst.addOperand(MCOperand::createReg(RISCV::X1)); Inst.addOperand(MCOperand::createImm(0)); - return true; } - bool createUncondBranch(MCInst &Inst, const MCSymbol *TBB, + void createUncondBranch(MCInst &Inst, const MCSymbol *TBB, MCContext *Ctx) const override { Inst.setOpcode(RISCV::JAL); Inst.clear(); Inst.addOperand(MCOperand::createReg(RISCV::X0)); Inst.addOperand(MCOperand::createExpr( MCSymbolRefExpr::create(TBB, MCSymbolRefExpr::VK_None, *Ctx))); - return true; } StringRef getTrapFillValue() const override { return StringRef("\0\0\0\0", 4); } - bool createCall(unsigned Opcode, MCInst &Inst, const MCSymbol *Target, + void createCall(unsigned Opcode, MCInst &Inst, const MCSymbol *Target, MCContext *Ctx) { Inst.setOpcode(Opcode); Inst.clear(); Inst.addOperand(MCOperand::createExpr(RISCVMCExpr::create( MCSymbolRefExpr::create(Target, MCSymbolRefExpr::VK_None, *Ctx), RISCVMCExpr::VK_RISCV_CALL, *Ctx))); - return true; } - bool createCall(MCInst &Inst, const MCSymbol *Target, + void createCall(MCInst &Inst, const MCSymbol *Target, MCContext *Ctx) override { return createCall(RISCV::PseudoCALL, Inst, Target, Ctx); } - bool createTailCall(MCInst &Inst, const MCSymbol *Target, + void createTailCall(MCInst &Inst, const MCSymbol *Target, MCContext *Ctx) override { return createCall(RISCV::PseudoTAIL, Inst, Target, Ctx); } diff --git a/bolt/lib/Target/X86/X86MCPlusBuilder.cpp b/bolt/lib/Target/X86/X86MCPlusBuilder.cpp index 387cf481ba304fa472e92ee7866c306cdf1cba28..de55fbe51764dd5fca69091d86ace09c63aba924 100644 --- a/bolt/lib/Target/X86/X86MCPlusBuilder.cpp +++ b/bolt/lib/Target/X86/X86MCPlusBuilder.cpp @@ -2230,7 +2230,7 @@ public: return true; } - bool createStackPointerIncrement(MCInst &Inst, int Size, + void createStackPointerIncrement(MCInst &Inst, int Size, bool NoFlagsClobber) const override { if (NoFlagsClobber) { Inst.setOpcode(X86::LEA64r); @@ -2241,17 +2241,16 @@ public: Inst.addOperand(MCOperand::createReg(X86::NoRegister)); // IndexReg Inst.addOperand(MCOperand::createImm(-Size)); // Displacement Inst.addOperand(MCOperand::createReg(X86::NoRegister)); // AddrSegmentReg - return true; + return; } Inst.setOpcode(X86::SUB64ri8); Inst.clear(); Inst.addOperand(MCOperand::createReg(X86::RSP)); Inst.addOperand(MCOperand::createReg(X86::RSP)); Inst.addOperand(MCOperand::createImm(Size)); - return true; } - bool createStackPointerDecrement(MCInst &Inst, int Size, + void createStackPointerDecrement(MCInst &Inst, int Size, bool NoFlagsClobber) const override { if (NoFlagsClobber) { Inst.setOpcode(X86::LEA64r); @@ -2262,22 +2261,22 @@ public: Inst.addOperand(MCOperand::createReg(X86::NoRegister)); // IndexReg Inst.addOperand(MCOperand::createImm(Size)); // Displacement Inst.addOperand(MCOperand::createReg(X86::NoRegister)); // AddrSegmentReg - return true; + return; } Inst.setOpcode(X86::ADD64ri8); Inst.clear(); Inst.addOperand(MCOperand::createReg(X86::RSP)); Inst.addOperand(MCOperand::createReg(X86::RSP)); Inst.addOperand(MCOperand::createImm(Size)); - return true; } - bool createSaveToStack(MCInst &Inst, const MCPhysReg &StackReg, int Offset, + void createSaveToStack(MCInst &Inst, const MCPhysReg &StackReg, int Offset, const MCPhysReg &SrcReg, int Size) const override { unsigned NewOpcode; switch (Size) { default: - return false; + llvm_unreachable("Invalid operand size"); + return; case 2: NewOpcode = X86::MOV16mr; break; case 4: NewOpcode = X86::MOV32mr; break; case 8: NewOpcode = X86::MOV64mr; break; @@ -2290,10 +2289,9 @@ public: Inst.addOperand(MCOperand::createImm(Offset)); // Displacement Inst.addOperand(MCOperand::createReg(X86::NoRegister)); // AddrSegmentReg Inst.addOperand(MCOperand::createReg(SrcReg)); - return true; } - bool createRestoreFromStack(MCInst &Inst, const MCPhysReg &StackReg, + void createRestoreFromStack(MCInst &Inst, const MCPhysReg &StackReg, int Offset, const MCPhysReg &DstReg, int Size) const override { return createLoad(Inst, StackReg, /*Scale=*/1, /*IndexReg=*/X86::NoRegister, @@ -2301,14 +2299,15 @@ public: DstReg, Size); } - bool createLoad(MCInst &Inst, const MCPhysReg &BaseReg, int64_t Scale, + void createLoad(MCInst &Inst, const MCPhysReg &BaseReg, int64_t Scale, const MCPhysReg &IndexReg, int64_t Offset, const MCExpr *OffsetExpr, const MCPhysReg &AddrSegmentReg, const MCPhysReg &DstReg, int Size) const override { unsigned NewOpcode; switch (Size) { default: - return false; + llvm_unreachable("Invalid operand size"); + return; case 2: NewOpcode = X86::MOV16rm; break; case 4: NewOpcode = X86::MOV32rm; break; case 8: NewOpcode = X86::MOV64rm; break; @@ -2324,7 +2323,6 @@ public: else Inst.addOperand(MCOperand::createImm(Offset)); // Displacement Inst.addOperand(MCOperand::createReg(AddrSegmentReg)); // AddrSegmentReg - return true; } InstructionListType createLoadImmediate(const MCPhysReg Dest, @@ -2338,7 +2336,7 @@ public: return Insts; } - bool createIJmp32Frag(SmallVectorImpl &Insts, + void createIJmp32Frag(SmallVectorImpl &Insts, const MCOperand &BaseReg, const MCOperand &Scale, const MCOperand &IndexReg, const MCOperand &Offset, const MCOperand &TmpReg) const override { @@ -2362,17 +2360,16 @@ public: Insts.push_back(Load); Insts.push_back(IJmp); - return true; } - bool createNoop(MCInst &Inst) const override { + void createNoop(MCInst &Inst) const override { Inst.setOpcode(X86::NOOP); - return true; + Inst.clear(); } - bool createReturn(MCInst &Inst) const override { + void createReturn(MCInst &Inst) const override { Inst.setOpcode(X86::RET64); - return true; + Inst.clear(); } InstructionListType createInlineMemcpy(bool ReturnEnd) const override { @@ -2729,23 +2726,31 @@ public: return FoundOne; } - bool createUncondBranch(MCInst &Inst, const MCSymbol *TBB, + void createUncondBranch(MCInst &Inst, const MCSymbol *TBB, MCContext *Ctx) const override { Inst.setOpcode(X86::JMP_1); + Inst.clear(); Inst.addOperand(MCOperand::createExpr( MCSymbolRefExpr::create(TBB, MCSymbolRefExpr::VK_None, *Ctx))); - return true; } - bool createCall(MCInst &Inst, const MCSymbol *Target, + void createLongUncondBranch(MCInst &Inst, const MCSymbol *Target, + MCContext *Ctx) const override { + Inst.setOpcode(X86::JMP_4); + Inst.clear(); + Inst.addOperand(MCOperand::createExpr( + MCSymbolRefExpr::create(Target, MCSymbolRefExpr::VK_None, *Ctx))); + } + + void createCall(MCInst &Inst, const MCSymbol *Target, MCContext *Ctx) override { Inst.setOpcode(X86::CALL64pcrel32); + Inst.clear(); Inst.addOperand(MCOperand::createExpr( MCSymbolRefExpr::create(Target, MCSymbolRefExpr::VK_None, *Ctx))); - return true; } - bool createTailCall(MCInst &Inst, const MCSymbol *Target, + void createTailCall(MCInst &Inst, const MCSymbol *Target, MCContext *Ctx) override { return createDirectCall(Inst, Target, Ctx, /*IsTailCall*/ true); } @@ -2757,10 +2762,18 @@ public: createDirectCall(Seq.back(), Target, Ctx, /*IsTailCall*/ true); } - bool createTrap(MCInst &Inst) const override { + void createTrap(MCInst &Inst) const override { Inst.clear(); Inst.setOpcode(X86::TRAP); - return true; + } + + void createCondBranch(MCInst &Inst, const MCSymbol *Target, unsigned CC, + MCContext *Ctx) const override { + Inst.setOpcode(X86::JCC_1); + Inst.clear(); + Inst.addOperand(MCOperand::createExpr( + MCSymbolRefExpr::create(Target, MCSymbolRefExpr::VK_None, *Ctx))); + Inst.addOperand(MCOperand::createImm(CC)); } bool reverseBranchCondition(MCInst &Inst, const MCSymbol *TBB, @@ -2862,7 +2875,7 @@ public: Inst.setOpcode(X86::LFENCE); } - bool createDirectCall(MCInst &Inst, const MCSymbol *Target, MCContext *Ctx, + void createDirectCall(MCInst &Inst, const MCSymbol *Target, MCContext *Ctx, bool IsTailCall) override { Inst.clear(); Inst.setOpcode(IsTailCall ? X86::JMP_4 : X86::CALL64pcrel32); @@ -2870,7 +2883,6 @@ public: MCSymbolRefExpr::create(Target, MCSymbolRefExpr::VK_None, *Ctx))); if (IsTailCall) setTailCall(Inst); - return true; } void createShortJmp(InstructionListType &Seq, const MCSymbol *Target, @@ -3066,6 +3078,7 @@ public: void createSwap(MCInst &Inst, MCPhysReg Source, MCPhysReg MemBaseReg, int64_t Disp) const { Inst.setOpcode(X86::XCHG64rm); + Inst.clear(); Inst.addOperand(MCOperand::createReg(Source)); Inst.addOperand(MCOperand::createReg(Source)); Inst.addOperand(MCOperand::createReg(MemBaseReg)); // BaseReg @@ -3078,6 +3091,7 @@ public: void createIndirectBranch(MCInst &Inst, MCPhysReg MemBaseReg, int64_t Disp) const { Inst.setOpcode(X86::JMP64m); + Inst.clear(); Inst.addOperand(MCOperand::createReg(MemBaseReg)); // BaseReg Inst.addOperand(MCOperand::createImm(1)); // ScaleAmt Inst.addOperand(MCOperand::createReg(X86::NoRegister)); // IndexReg @@ -3540,9 +3554,10 @@ public: } private: - bool createMove(MCInst &Inst, const MCSymbol *Src, unsigned Reg, + void createMove(MCInst &Inst, const MCSymbol *Src, unsigned Reg, MCContext *Ctx) const { Inst.setOpcode(X86::MOV64rm); + Inst.clear(); Inst.addOperand(MCOperand::createReg(Reg)); Inst.addOperand(MCOperand::createReg(X86::RIP)); // BaseReg Inst.addOperand(MCOperand::createImm(1)); // ScaleAmt @@ -3551,13 +3566,12 @@ private: MCSymbolRefExpr::create(Src, MCSymbolRefExpr::VK_None, *Ctx))); // Displacement Inst.addOperand(MCOperand::createReg(X86::NoRegister)); // AddrSegmentReg - - return true; } - bool createLea(MCInst &Inst, const MCSymbol *Src, unsigned Reg, + void createLea(MCInst &Inst, const MCSymbol *Src, unsigned Reg, MCContext *Ctx) const { Inst.setOpcode(X86::LEA64r); + Inst.clear(); Inst.addOperand(MCOperand::createReg(Reg)); Inst.addOperand(MCOperand::createReg(X86::RIP)); // BaseReg Inst.addOperand(MCOperand::createImm(1)); // ScaleAmt @@ -3566,7 +3580,6 @@ private: MCSymbolRefExpr::create(Src, MCSymbolRefExpr::VK_None, *Ctx))); // Displacement Inst.addOperand(MCOperand::createReg(X86::NoRegister)); // AddrSegmentReg - return true; } }; diff --git a/bolt/test/X86/Inputs/dwarf5-debug-names-ftu-ltu-mix-helper.s b/bolt/test/X86/Inputs/dwarf5-debug-names-ftu-ltu-mix-helper.s new file mode 100644 index 0000000000000000000000000000000000000000..68eee45ec98330557edc8f54e232e10e4b66c885 --- /dev/null +++ b/bolt/test/X86/Inputs/dwarf5-debug-names-ftu-ltu-mix-helper.s @@ -0,0 +1,314 @@ +# struct AMono { +# int x; +# }; +# +# AMono globalMono; +# # clang++ -g2 -gdwarf-5 -gpubnames -S -fdebug-types-section -o + + .text + .file "helper.cpp" + .file 0 "/home" "helper.cpp" md5 0x3c0ac73d7b074961c6e8202230a76228 + .section .debug_info,"G",@progbits,6412503741467814911,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 6412503741467814911 # Type Signature + .long 35 # Type DIE Offset + .byte 1 # Abbrev [1] 0x18:0x20 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:0x10 DW_TAG_structure_type + .byte 5 # DW_AT_calling_convention + .byte 6 # DW_AT_name + .byte 4 # DW_AT_byte_size + .byte 0 # DW_AT_decl_file + .byte 1 # DW_AT_decl_line + .byte 3 # Abbrev [3] 0x29:0x9 DW_TAG_member + .byte 4 # DW_AT_name + .long 51 # DW_AT_type + .byte 0 # DW_AT_decl_file + .byte 2 # DW_AT_decl_line + .byte 0 # DW_AT_data_member_location + .byte 0 # End Of Children Mark + .byte 4 # Abbrev [4] 0x33:0x4 DW_TAG_base_type + .byte 5 # DW_AT_name + .byte 5 # DW_AT_encoding + .byte 4 # DW_AT_byte_size + .byte 0 # End Of Children Mark +.Ldebug_info_end0: + .type globalMono,@object # @globalMono + .bss + .globl globalMono + .p2align 2, 0x0 +globalMono: + .zero 4 + .size globalMono, 4 + + .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 19 # DW_TAG_structure_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 3 # 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 0 # EOM(1) + .byte 0 # EOM(2) + .byte 4 # 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 5 # 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 115 # DW_AT_addr_base + .byte 23 # DW_FORM_sec_offset + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 6 # Abbreviation Code + .byte 52 # DW_TAG_variable + .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 63 # DW_AT_external + .byte 25 # DW_FORM_flag_present + .byte 58 # DW_AT_decl_file + .byte 11 # DW_FORM_data1 + .byte 59 # DW_AT_decl_line + .byte 11 # DW_FORM_data1 + .byte 2 # DW_AT_location + .byte 24 # DW_FORM_exprloc + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 7 # Abbreviation Code + .byte 19 # DW_TAG_structure_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 5 # Abbrev [5] 0xc:0x27 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 + .long .Laddr_table_base0 # DW_AT_addr_base + .byte 6 # Abbrev [6] 0x1e:0xb DW_TAG_variable + .byte 3 # DW_AT_name + .long 41 # DW_AT_type + # DW_AT_external + .byte 0 # DW_AT_decl_file + .byte 5 # DW_AT_decl_line + .byte 2 # DW_AT_location + .byte 161 + .byte 0 + .byte 7 # Abbrev [7] 0x29:0x9 DW_TAG_structure_type + # DW_AT_declaration + .quad 6412503741467814911 # DW_AT_signature + .byte 0 # End Of Children Mark +.Ldebug_info_end1: + .section .debug_str_offsets,"",@progbits + .long 32 # 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 (git@github.com:llvm/llvm-project.git ced1fac8a32e35b63733bda27c7f5b9a2b635403)" # string offset=0 +.Linfo_string1: + .asciz "helper.cpp" # string offset=104 +.Linfo_string2: + .asciz "/home" # string offset=115 +.Linfo_string3: + .asciz "globalMono" # string offset=153 +.Linfo_string4: + .asciz "AMono" # string offset=164 +.Linfo_string5: + .asciz "x" # string offset=170 +.Linfo_string6: + .asciz "int" # string offset=172 + .section .debug_str_offsets,"",@progbits + .long .Linfo_string0 + .long .Linfo_string1 + .long .Linfo_string2 + .long .Linfo_string3 + .long .Linfo_string5 + .long .Linfo_string6 + .long .Linfo_string4 + .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 globalMono +.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 3 # Header: bucket count + .long 3 # 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 193495088 # Hash in Bucket 2 + .long 253228319 # Hash in Bucket 2 + .long -857151761 # Hash in Bucket 2 + .long .Linfo_string6 # String in Bucket 2: int + .long .Linfo_string4 # String in Bucket 2: AMono + .long .Linfo_string3 # String in Bucket 2: globalMono + .long .Lnames1-.Lnames_entries0 # Offset in Bucket 2 + .long .Lnames0-.Lnames_entries0 # Offset in Bucket 2 + .long .Lnames2-.Lnames_entries0 # Offset in Bucket 2 +.Lnames_abbrev_start0: + .byte 1 # 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 2 # Abbrev code + .byte 19 # DW_TAG_structure_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 19 # DW_TAG_structure_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 4 # Abbrev code + .byte 52 # DW_TAG_variable + .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 0 # End of abbrev list +.Lnames_abbrev_end0: +.Lnames_entries0: +.Lnames1: +.L1: + .byte 1 # Abbreviation code + .byte 0 # DW_IDX_type_unit + .long 51 # DW_IDX_die_offset + .byte 0 # DW_IDX_parent + # End of list: int +.Lnames0: +.L2: + .byte 2 # Abbreviation code + .byte 0 # DW_IDX_type_unit + .long 35 # DW_IDX_die_offset +.L3: # DW_IDX_parent + .byte 3 # Abbreviation code + .long 41 # DW_IDX_die_offset + .byte 0 # DW_IDX_parent + # End of list: AMono +.Lnames2: +.L0: + .byte 4 # Abbreviation code + .long 30 # DW_IDX_die_offset + .byte 0 # DW_IDX_parent + # End of list: globalMono + .p2align 2, 0x0 +.Lnames_end0: + .ident "clang version 19.0.0git (git@github.com:llvm/llvm-project.git ced1fac8a32e35b63733bda27c7f5b9a2b635403)" + .section ".note.GNU-stack","",@progbits + .addrsig + .section .debug_line,"",@progbits +.Lline_table_start0: diff --git a/bolt/test/X86/Inputs/dwarf5-debug-names-ftu-ltu-mix-helper1.s b/bolt/test/X86/Inputs/dwarf5-debug-names-ftu-ltu-mix-helper1.s new file mode 100644 index 0000000000000000000000000000000000000000..8b28c19dc87de8456314d4eb767d1cd90936e524 --- /dev/null +++ b/bolt/test/X86/Inputs/dwarf5-debug-names-ftu-ltu-mix-helper1.s @@ -0,0 +1,315 @@ +# struct BMono { +# int x; +# }; +# +# BMono globalMono1; +# clang++ -g2 -gdwarf-5 -gpubnames -S -fdebug-types-section -o + + + .text + .file "helper1.cpp" + .file 0 "/home" "helper1.cpp" md5 0x1fdaf911330b73495aed962bc02cfb3a + .section .debug_info,"G",@progbits,5884764266900841573,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 5884764266900841573 # Type Signature + .long 35 # Type DIE Offset + .byte 1 # Abbrev [1] 0x18:0x20 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:0x10 DW_TAG_structure_type + .byte 5 # DW_AT_calling_convention + .byte 6 # DW_AT_name + .byte 4 # DW_AT_byte_size + .byte 0 # DW_AT_decl_file + .byte 1 # DW_AT_decl_line + .byte 3 # Abbrev [3] 0x29:0x9 DW_TAG_member + .byte 4 # DW_AT_name + .long 51 # DW_AT_type + .byte 0 # DW_AT_decl_file + .byte 2 # DW_AT_decl_line + .byte 0 # DW_AT_data_member_location + .byte 0 # End Of Children Mark + .byte 4 # Abbrev [4] 0x33:0x4 DW_TAG_base_type + .byte 5 # DW_AT_name + .byte 5 # DW_AT_encoding + .byte 4 # DW_AT_byte_size + .byte 0 # End Of Children Mark +.Ldebug_info_end0: + .type globalMono1,@object # @globalMono1 + .bss + .globl globalMono1 + .p2align 2, 0x0 +globalMono1: + .zero 4 + .size globalMono1, 4 + + .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 19 # DW_TAG_structure_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 3 # 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 0 # EOM(1) + .byte 0 # EOM(2) + .byte 4 # 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 5 # 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 115 # DW_AT_addr_base + .byte 23 # DW_FORM_sec_offset + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 6 # Abbreviation Code + .byte 52 # DW_TAG_variable + .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 63 # DW_AT_external + .byte 25 # DW_FORM_flag_present + .byte 58 # DW_AT_decl_file + .byte 11 # DW_FORM_data1 + .byte 59 # DW_AT_decl_line + .byte 11 # DW_FORM_data1 + .byte 2 # DW_AT_location + .byte 24 # DW_FORM_exprloc + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 7 # Abbreviation Code + .byte 19 # DW_TAG_structure_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 5 # Abbrev [5] 0xc:0x27 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 + .long .Laddr_table_base0 # DW_AT_addr_base + .byte 6 # Abbrev [6] 0x1e:0xb DW_TAG_variable + .byte 3 # DW_AT_name + .long 41 # DW_AT_type + # DW_AT_external + .byte 0 # DW_AT_decl_file + .byte 5 # DW_AT_decl_line + .byte 2 # DW_AT_location + .byte 161 + .byte 0 + .byte 7 # Abbrev [7] 0x29:0x9 DW_TAG_structure_type + # DW_AT_declaration + .quad 5884764266900841573 # DW_AT_signature + .byte 0 # End Of Children Mark +.Ldebug_info_end1: + .section .debug_str_offsets,"",@progbits + .long 32 # 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 (git@github.com:llvm/llvm-project.git ced1fac8a32e35b63733bda27c7f5b9a2b635403)" # string offset=0 +.Linfo_string1: + .asciz "helper1.cpp" # string offset=104 +.Linfo_string2: + .asciz "/home" # string offset=116 +.Linfo_string3: + .asciz "globalMono1" # string offset=154 +.Linfo_string4: + .asciz "BMono" # string offset=166 +.Linfo_string5: + .asciz "x" # string offset=172 +.Linfo_string6: + .asciz "int" # string offset=174 + .section .debug_str_offsets,"",@progbits + .long .Linfo_string0 + .long .Linfo_string1 + .long .Linfo_string2 + .long .Linfo_string3 + .long .Linfo_string5 + .long .Linfo_string6 + .long .Linfo_string4 + .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 globalMono1 +.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 3 # Header: bucket count + .long 3 # 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 193495088 # Hash in Bucket 2 + .long 254414240 # Hash in Bucket 2 + .long 1778763008 # Hash in Bucket 2 + .long .Linfo_string6 # String in Bucket 2: int + .long .Linfo_string4 # String in Bucket 2: BMono + .long .Linfo_string3 # String in Bucket 2: globalMono1 + .long .Lnames1-.Lnames_entries0 # Offset in Bucket 2 + .long .Lnames0-.Lnames_entries0 # Offset in Bucket 2 + .long .Lnames2-.Lnames_entries0 # Offset in Bucket 2 +.Lnames_abbrev_start0: + .byte 1 # 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 2 # Abbrev code + .byte 19 # DW_TAG_structure_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 19 # DW_TAG_structure_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 4 # Abbrev code + .byte 52 # DW_TAG_variable + .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 0 # End of abbrev list +.Lnames_abbrev_end0: +.Lnames_entries0: +.Lnames1: +.L1: + .byte 1 # Abbreviation code + .byte 0 # DW_IDX_type_unit + .long 51 # DW_IDX_die_offset + .byte 0 # DW_IDX_parent + # End of list: int +.Lnames0: +.L2: + .byte 2 # Abbreviation code + .byte 0 # DW_IDX_type_unit + .long 35 # DW_IDX_die_offset +.L3: # DW_IDX_parent + .byte 3 # Abbreviation code + .long 41 # DW_IDX_die_offset + .byte 0 # DW_IDX_parent + # End of list: BMono +.Lnames2: +.L0: + .byte 4 # Abbreviation code + .long 30 # DW_IDX_die_offset + .byte 0 # DW_IDX_parent + # End of list: globalMono1 + .p2align 2, 0x0 +.Lnames_end0: + .ident "clang version 19.0.0git (git@github.com:llvm/llvm-project.git ced1fac8a32e35b63733bda27c7f5b9a2b635403)" + .section ".note.GNU-stack","",@progbits + .addrsig + .section .debug_line,"",@progbits +.Lline_table_start0: diff --git a/bolt/test/X86/Inputs/dwarf5-df-debug-names-ftu-ltu-mix-main.s b/bolt/test/X86/Inputs/dwarf5-df-debug-names-ftu-ltu-mix-main.s new file mode 100644 index 0000000000000000000000000000000000000000..69f6c5a5376a027615ecdf67a743a431fe542430 --- /dev/null +++ b/bolt/test/X86/Inputs/dwarf5-df-debug-names-ftu-ltu-mix-main.s @@ -0,0 +1,505 @@ +# struct ASplit { +# int x; +# }; +# +# ASplit globalSplit; +# int main() { +# return 0; +# } +# clang++ -g2 -gdwarf-5 -gpubnames -S -fdebug-types-section -gsplit-dwarf -fdebug-compilation-dir='.' + + .text + .file "main.cpp" + .file 0 "." "main.cpp" md5 0xbb74a3c2960dafa324547ebbd87d13ea + .section .debug_info.dwo,"e",@progbits + .long .Ldebug_info_dwo_end0-.Ldebug_info_dwo_start0 # Length of Unit +.Ldebug_info_dwo_start0: + .short 5 # DWARF version number + .byte 6 # DWARF Unit Type + .byte 8 # Address Size (in bytes) + .long 0 # Offset Into Abbrev. Section + .quad -8602855756067469281 # Type Signature + .long 33 # Type DIE Offset + .byte 1 # Abbrev [1] 0x18:0x1e DW_TAG_type_unit + .short 33 # DW_AT_language + .byte 1 # DW_AT_comp_dir + .byte 2 # DW_AT_dwo_name + .long 0 # DW_AT_stmt_list + .byte 2 # Abbrev [2] 0x21:0x10 DW_TAG_structure_type + .byte 5 # DW_AT_calling_convention + .byte 5 # DW_AT_name + .byte 4 # DW_AT_byte_size + .byte 0 # DW_AT_decl_file + .byte 1 # DW_AT_decl_line + .byte 3 # Abbrev [3] 0x27:0x9 DW_TAG_member + .byte 3 # DW_AT_name + .long 49 # DW_AT_type + .byte 0 # DW_AT_decl_file + .byte 2 # DW_AT_decl_line + .byte 0 # DW_AT_data_member_location + .byte 0 # End Of Children Mark + .byte 4 # Abbrev [4] 0x31: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_dwo_end0: + .text + .globl main # -- Begin function main + .p2align 4, 0x90 + .type main,@function +main: # @main +.Lfunc_begin0: + .loc 0 6 0 # main.cpp:6: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 7 3 prologue_end # main.cpp:7:3 + xorl %eax, %eax + .loc 0 7 3 epilogue_begin is_stmt 0 # main.cpp:7:3 + popq %rbp + .cfi_def_cfa %rsp, 8 + retq +.Ltmp1: +.Lfunc_end0: + .size main, .Lfunc_end0-main + .cfi_endproc + # -- End function + .type globalSplit,@object # @globalSplit + .bss + .globl globalSplit + .p2align 2, 0x0 +globalSplit: + .zero 4 + .size globalSplit, 4 + + .section .debug_abbrev,"",@progbits + .byte 1 # Abbreviation Code + .byte 74 # DW_TAG_skeleton_unit + .byte 0 # DW_CHILDREN_no + .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 27 # DW_AT_comp_dir + .byte 37 # DW_FORM_strx1 + .byte 118 # DW_AT_dwo_name + .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 0 # EOM(3) + .section .debug_info,"",@progbits +.Lcu_begin0: + .long .Ldebug_info_end0-.Ldebug_info_start0 # Length of Unit +.Ldebug_info_start0: + .short 5 # DWARF version number + .byte 4 # DWARF Unit Type + .byte 8 # Address Size (in bytes) + .long .debug_abbrev # Offset Into Abbrev. Section + .quad 5806847994123082226 + .byte 1 # Abbrev [1] 0x14:0x14 DW_TAG_skeleton_unit + .long .Lline_table_start0 # DW_AT_stmt_list + .long .Lstr_offsets_base0 # DW_AT_str_offsets_base + .byte 0 # DW_AT_comp_dir + .byte 1 # DW_AT_dwo_name + .byte 1 # DW_AT_low_pc + .long .Lfunc_end0-.Lfunc_begin0 # DW_AT_high_pc + .long .Laddr_table_base0 # DW_AT_addr_base +.Ldebug_info_end0: + .section .debug_str_offsets,"",@progbits + .long 12 # Length of String Offsets Set + .short 5 + .short 0 +.Lstr_offsets_base0: + .section .debug_str,"MS",@progbits,1 +.Lskel_string0: + .asciz "." # string offset=0 +.Lskel_string1: + .asciz "ASplit" # string offset=2 +.Lskel_string2: + .asciz "int" # string offset=9 +.Lskel_string3: + .asciz "globalSplit" # string offset=13 +.Lskel_string4: + .asciz "main" # string offset=25 +.Lskel_string5: + .asciz "main.dwo" # string offset=30 + .section .debug_str_offsets,"",@progbits + .long .Lskel_string0 + .long .Lskel_string5 + .section .debug_str_offsets.dwo,"e",@progbits + .long 40 # Length of String Offsets Set + .short 5 + .short 0 + .section .debug_str.dwo,"eMS",@progbits,1 +.Linfo_string0: + .asciz "globalSplit" # string offset=0 +.Linfo_string1: + .asciz "." # string offset=12 +.Linfo_string2: + .asciz "main.dwo" # string offset=14 +.Linfo_string3: + .asciz "x" # string offset=23 +.Linfo_string4: + .asciz "int" # string offset=25 +.Linfo_string5: + .asciz "ASplit" # string offset=29 +.Linfo_string6: + .asciz "main" # string offset=36 +.Linfo_string7: + .asciz "clang version 19.0.0git (git@github.com:llvm/llvm-project.git ced1fac8a32e35b63733bda27c7f5b9a2b635403)" # string offset=41 +.Linfo_string8: + .asciz "main.cpp" # string offset=145 + .section .debug_str_offsets.dwo,"e",@progbits + .long 0 + .long 12 + .long 14 + .long 23 + .long 25 + .long 29 + .long 36 + .long 41 + .long 145 + .section .debug_info.dwo,"e",@progbits + .long .Ldebug_info_dwo_end1-.Ldebug_info_dwo_start1 # Length of Unit +.Ldebug_info_dwo_start1: + .short 5 # DWARF version number + .byte 5 # DWARF Unit Type + .byte 8 # Address Size (in bytes) + .long 0 # Offset Into Abbrev. Section + .quad 5806847994123082226 + .byte 5 # Abbrev [5] 0x14:0x2e DW_TAG_compile_unit + .byte 7 # DW_AT_producer + .short 33 # DW_AT_language + .byte 8 # DW_AT_name + .byte 2 # DW_AT_dwo_name + .byte 6 # Abbrev [6] 0x1a:0xb DW_TAG_variable + .byte 0 # DW_AT_name + .long 37 # DW_AT_type + # DW_AT_external + .byte 0 # DW_AT_decl_file + .byte 5 # DW_AT_decl_line + .byte 2 # DW_AT_location + .byte 161 + .byte 0 + .byte 7 # Abbrev [7] 0x25:0x9 DW_TAG_structure_type + # DW_AT_declaration + .quad -8602855756067469281 # DW_AT_signature + .byte 8 # Abbrev [8] 0x2e:0xf DW_TAG_subprogram + .byte 1 # DW_AT_low_pc + .long .Lfunc_end0-.Lfunc_begin0 # DW_AT_high_pc + .byte 1 # DW_AT_frame_base + .byte 86 + .byte 6 # DW_AT_name + .byte 0 # DW_AT_decl_file + .byte 6 # DW_AT_decl_line + .long 61 # DW_AT_type + # DW_AT_external + .byte 4 # Abbrev [4] 0x3d: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_dwo_end1: + .section .debug_abbrev.dwo,"e",@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 27 # DW_AT_comp_dir + .byte 37 # DW_FORM_strx1 + .byte 118 # DW_AT_dwo_name + .byte 37 # DW_FORM_strx1 + .byte 16 # DW_AT_stmt_list + .byte 23 # DW_FORM_sec_offset + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 2 # Abbreviation Code + .byte 19 # DW_TAG_structure_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 3 # 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 0 # EOM(1) + .byte 0 # EOM(2) + .byte 4 # 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 5 # 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 118 # DW_AT_dwo_name + .byte 37 # DW_FORM_strx1 + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 6 # Abbreviation Code + .byte 52 # DW_TAG_variable + .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 63 # DW_AT_external + .byte 25 # DW_FORM_flag_present + .byte 58 # DW_AT_decl_file + .byte 11 # DW_FORM_data1 + .byte 59 # DW_AT_decl_line + .byte 11 # DW_FORM_data1 + .byte 2 # DW_AT_location + .byte 24 # DW_FORM_exprloc + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 7 # Abbreviation Code + .byte 19 # DW_TAG_structure_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 8 # Abbreviation Code + .byte 46 # DW_TAG_subprogram + .byte 0 # DW_CHILDREN_no + .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 0 # EOM(3) + .section .debug_line.dwo,"e",@progbits +.Ltmp2: + .long .Ldebug_line_end0-.Ldebug_line_start0 # unit length +.Ldebug_line_start0: + .short 5 + .byte 8 + .byte 0 + .long .Lprologue_end0-.Lprologue_start0 +.Lprologue_start0: + .byte 1 + .byte 1 + .byte 1 + .byte -5 + .byte 14 + .byte 1 + .byte 1 + .byte 1 + .byte 8 + .byte 1 + .byte 46 + .byte 0 + .byte 3 + .byte 1 + .byte 8 + .byte 2 + .byte 15 + .byte 5 + .byte 30 + .byte 1 + .ascii "main.cpp" + .byte 0 + .byte 0 + .byte 0xbb, 0x74, 0xa3, 0xc2 + .byte 0x96, 0x0d, 0xaf, 0xa3 + .byte 0x24, 0x54, 0x7e, 0xbb + .byte 0xd8, 0x7d, 0x13, 0xea +.Lprologue_end0: +.Ldebug_line_end0: + .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 globalSplit + .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 0 # Header: local type unit count + .long 1 # 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 + .quad -8602855756067469281 # Type unit 0 + .long 1 # Bucket 0 + .long 0 # Bucket 1 + .long 2 # Bucket 2 + .long 0 # Bucket 3 + .long 193495088 # Hash in Bucket 0 + .long 1785912162 # Hash in Bucket 2 + .long 2090499946 # Hash in Bucket 2 + .long -226250862 # Hash in Bucket 2 + .long .Lskel_string2 # String in Bucket 0: int + .long .Lskel_string3 # String in Bucket 2: globalSplit + .long .Lskel_string4 # String in Bucket 2: main + .long .Lskel_string1 # String in Bucket 2: ASplit + .long .Lnames1-.Lnames_entries0 # Offset in Bucket 0 + .long .Lnames2-.Lnames_entries0 # Offset in Bucket 2 + .long .Lnames3-.Lnames_entries0 # Offset in Bucket 2 + .long .Lnames0-.Lnames_entries0 # Offset in Bucket 2 +.Lnames_abbrev_start0: + .byte 1 # 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 2 # 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 3 # Abbrev code + .byte 52 # DW_TAG_variable + .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 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 5 # Abbrev code + .byte 19 # DW_TAG_structure_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 6 # Abbrev code + .byte 19 # DW_TAG_structure_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 0 # End of abbrev list +.Lnames_abbrev_end0: +.Lnames_entries0: +.Lnames1: +.L5: + .byte 1 # Abbreviation code + .byte 0 # DW_IDX_type_unit + .long 49 # DW_IDX_die_offset +.L1: # DW_IDX_parent + .byte 2 # Abbreviation code + .long 61 # DW_IDX_die_offset + .byte 0 # DW_IDX_parent + # End of list: int +.Lnames2: +.L0: + .byte 3 # Abbreviation code + .long 26 # DW_IDX_die_offset + .byte 0 # DW_IDX_parent + # End of list: globalSplit +.Lnames3: +.L2: + .byte 4 # Abbreviation code + .long 46 # DW_IDX_die_offset + .byte 0 # DW_IDX_parent + # End of list: main +.Lnames0: +.L4: + .byte 5 # Abbreviation code + .byte 0 # DW_IDX_type_unit + .long 33 # DW_IDX_die_offset +.L3: # DW_IDX_parent + .byte 6 # Abbreviation code + .long 37 # DW_IDX_die_offset + .byte 0 # DW_IDX_parent + # End of list: ASplit + .p2align 2, 0x0 +.Lnames_end0: + .ident "clang version 19.0.0git (git@github.com:llvm/llvm-project.git ced1fac8a32e35b63733bda27c7f5b9a2b635403)" + .section ".note.GNU-stack","",@progbits + .addrsig + .section .debug_line,"",@progbits +.Lline_table_start0: diff --git a/bolt/test/X86/dwarf5-debug-names-dw-at-specification.s b/bolt/test/X86/dwarf5-debug-names-dw-at-specification.s new file mode 100644 index 0000000000000000000000000000000000000000..ec5b425625ce9647d10a52b77e333c6bcf5d574d --- /dev/null +++ b/bolt/test/X86/dwarf5-debug-names-dw-at-specification.s @@ -0,0 +1,694 @@ +# RUN: llvm-mc -dwarf-version=5 -filetype=obj -triple x86_64-unknown-linux %s -o %tmain.o +# RUN: %clang %cflags -gdwarf-5 %tmain.o -o %tmain.exe +# RUN: llvm-bolt %tmain.exe -o %tmain.exe.bolt --update-debug-sections +# RUN: llvm-dwarfdump --debug-info -r 0 --debug-names %tmain.exe.bolt > %tlog.txt +# RUN: cat %tlog.txt | FileCheck -check-prefix=BOLT %s + +## Tests that BOLT correctly generates entries in .debug_names with DW_AT_specification. + +# BOLT: [[OFFSET1:0x[0-9a-f]*]]: Compile Unit +# BOLT: Name Index @ 0x0 +# BOLT-NEXT: Header { +# BOLT-NEXT: Length: 0x10F +# BOLT-NEXT: Format: DWARF32 +# BOLT-NEXT: Version: 5 +# BOLT-NEXT: CU count: 1 +# BOLT-NEXT: Local TU count: 0 +# BOLT-NEXT: Foreign TU count: 0 +# BOLT-NEXT: Bucket count: 9 +# BOLT-NEXT: Name count: 9 +# BOLT-NEXT: Abbreviations table size: 0x21 +# BOLT-NEXT: Augmentation: 'BOLT' +# BOLT-NEXT: } +# BOLT-NEXT: Compilation Unit offsets [ +# BOLT-NEXT: CU[0]: [[OFFSET1]] +# BOLT-NEXT: ] +# BOLT-NEXT: Abbreviations [ +# BOLT-NEXT: Abbreviation [[ABBREV1:0x[0-9a-f]*]] { +# BOLT-NEXT: Tag: DW_TAG_variable +# BOLT-NEXT: DW_IDX_die_offset: DW_FORM_ref4 +# BOLT-NEXT: DW_IDX_parent: DW_FORM_flag_present +# BOLT-NEXT: } +# BOLT-NEXT: Abbreviation [[ABBREV2:0x[0-9a-f]*]] { +# BOLT-NEXT: Tag: DW_TAG_structure_type +# BOLT-NEXT: DW_IDX_die_offset: DW_FORM_ref4 +# BOLT-NEXT: DW_IDX_parent: DW_FORM_flag_present +# BOLT-NEXT: } +# BOLT-NEXT: Abbreviation [[ABBREV3:0x[0-9a-f]*]] { +# BOLT-NEXT: Tag: DW_TAG_base_type +# BOLT-NEXT: DW_IDX_die_offset: DW_FORM_ref4 +# BOLT-NEXT: DW_IDX_parent: DW_FORM_flag_present +# BOLT-NEXT: } +# BOLT-NEXT: Abbreviation [[ABBREV4:0x[0-9a-f]*]] { +# BOLT-NEXT: Tag: DW_TAG_subprogram +# BOLT-NEXT: DW_IDX_die_offset: DW_FORM_ref4 +# BOLT-NEXT: DW_IDX_parent: DW_FORM_flag_present +# BOLT-NEXT: } +# BOLT-NEXT: ] +# BOLT-NEXT: Bucket 0 [ +# BOLT-NEXT: Name 1 { +# BOLT-NEXT: Hash: 0x5D3CA9E0 +# BOLT-NEXT: String: {{.+}} "_ZN1A15fully_specifiedE" +# BOLT-NEXT: Entry @ {{.+}} { +# BOLT-NEXT: Abbrev: [[ABBREV1]] +# BOLT-NEXT: Tag: DW_TAG_variable +# BOLT-NEXT: DW_IDX_die_offset: 0x00000024 +# BOLT-NEXT: DW_IDX_parent: +# BOLT-NEXT: } +# BOLT-NEXT: } +# BOLT-NEXT: Name 2 { +# BOLT-NEXT: Hash: 0x7C9DFC37 +# BOLT-NEXT: String: {{.+}} "smem" +# BOLT-NEXT: Entry @ {{.+}} { +# BOLT-NEXT: Abbrev: [[ABBREV1]] +# BOLT-NEXT: Tag: DW_TAG_variable +# BOLT-NEXT: DW_IDX_die_offset: 0x00000057 +# BOLT-NEXT: DW_IDX_parent: +# BOLT-NEXT: } +# BOLT-NEXT: } +# BOLT-NEXT: ] +# BOLT-NEXT: Bucket 1 [ +# BOLT-NEXT: Name 3 { +# BOLT-NEXT: Hash: 0x2B606 +# BOLT-NEXT: String: {{.+}} "A" +# BOLT-NEXT: Entry @ {{.+}} { +# BOLT-NEXT: Abbrev: [[ABBREV2]] +# BOLT-NEXT: Tag: DW_TAG_structure_type +# BOLT-NEXT: DW_IDX_die_offset: 0x0000002d +# BOLT-NEXT: DW_IDX_parent: +# BOLT-NEXT: } +# BOLT-NEXT: } +# BOLT-NEXT: ] +# BOLT-NEXT: Bucket 2 [ +# BOLT-NEXT: Name 4 { +# BOLT-NEXT: Hash: 0xB888030 +# BOLT-NEXT: String: {{.+}} "int" +# BOLT-NEXT: Entry @ {{.+}} { +# BOLT-NEXT: Abbrev: [[ABBREV3]] +# BOLT-NEXT: Tag: DW_TAG_base_type +# BOLT-NEXT: DW_IDX_die_offset: 0x00000044 +# BOLT-NEXT: DW_IDX_parent: +# BOLT-NEXT: } +# BOLT-NEXT: } +# BOLT-NEXT: ] +# BOLT-NEXT: Bucket 3 [ +# BOLT-NEXT: EMPTY +# BOLT-NEXT: ] +# BOLT-NEXT: Bucket 4 [ +# BOLT-NEXT: EMPTY +# BOLT-NEXT: ] +# BOLT-NEXT: Bucket 5 [ +# BOLT-NEXT: EMPTY +# BOLT-NEXT: ] +# BOLT-NEXT: Bucket 6 [ +# BOLT-NEXT: EMPTY +# BOLT-NEXT: ] +# BOLT-NEXT: Bucket 7 [ +# BOLT-NEXT: Name 5 { +# BOLT-NEXT: Hash: 0x65788E1C +# BOLT-NEXT: String: {{.+}} "fully_specified" +# BOLT-NEXT: Entry @ {{.+}} { +# BOLT-NEXT: Abbrev: [[ABBREV1]] +# BOLT-NEXT: Tag: DW_TAG_variable +# BOLT-NEXT: DW_IDX_die_offset: 0x00000024 +# BOLT-NEXT: DW_IDX_parent: +# BOLT-NEXT: } +# BOLT-NEXT: } +# BOLT-NEXT: Name 6 { +# BOLT-NEXT: Hash: 0x7C9A7F6A +# BOLT-NEXT: String: {{.+}} "main" +# BOLT-NEXT: Entry @ {{.+}} { +# BOLT-NEXT: Abbrev: [[ABBREV4]] +# BOLT-NEXT: Tag: DW_TAG_subprogram +# BOLT-NEXT: DW_IDX_die_offset: 0x00000070 +# BOLT-NEXT: DW_IDX_parent: +# BOLT-NEXT: } +# BOLT-NEXT: } +# BOLT-NEXT: ] +# BOLT-NEXT: Bucket 8 [ +# BOLT-NEXT: Name 7 { +# BOLT-NEXT: Hash: 0xCEF4CFB +# BOLT-NEXT: String: {{.+}} "__ARRAY_SIZE_TYPE__" +# BOLT-NEXT: Entry @ {{.+}} { +# BOLT-NEXT: Abbrev: [[ABBREV3]] +# BOLT-NEXT: Tag: DW_TAG_base_type +# BOLT-NEXT: DW_IDX_die_offset: 0x00000053 +# BOLT-NEXT: DW_IDX_parent: +# BOLT-NEXT: } +# BOLT-NEXT: } +# BOLT-NEXT: Name 8 { +# BOLT-NEXT: Hash: 0x48684B69 +# BOLT-NEXT: String: {{.+}} "_ZN1A4smemE" +# BOLT-NEXT: Entry @ {{.+}} { +# BOLT-NEXT: Abbrev: [[ABBREV1]] +# BOLT-NEXT: Tag: DW_TAG_variable +# BOLT-NEXT: DW_IDX_die_offset: 0x00000057 +# BOLT-NEXT: DW_IDX_parent: +# BOLT-NEXT: } +# BOLT-NEXT: } +# BOLT-NEXT: Name 9 { +# BOLT-NEXT: Hash: 0x7C952063 +# BOLT-NEXT: String: {{.+}} "char" +# BOLT-NEXT: Entry @ {{.+}} { +# BOLT-NEXT: Abbrev: [[ABBREV3]] +# BOLT-NEXT: Tag: DW_TAG_base_type +# BOLT-NEXT: DW_IDX_die_offset: 0x0000009e +# BOLT-NEXT: DW_IDX_parent: +# BOLT-NEXT: } +# BOLT-NEXT: } +# BOLT-NEXT: ] +# BOLT-NEXT: } + +# clang++ main.cpp -O2 -g2 -gdwarf-5 -gpubnames -S +# struct A { +# static int fully_specified; +# static int smem[]; +# }; +# +# int A::fully_specified; +# int A::smem[] = { 0, 1, 2, 3 }; +# int main(int argc, char *argv[]) { +# return 0; +# } + .text + .file "main.cpp" + .file 0 "/specification" "main.cpp" md5 0x6c1b1c014d300f2e0efd26584acae1a9 + .globl main # -- Begin function main + .p2align 4, 0x90 + .type main,@function +main: # @main +.Lfunc_begin0: + .cfi_startproc +# %bb.0: # %entry + #DEBUG_VALUE: main:argc <- $edi + #DEBUG_VALUE: main:argv <- $rsi + .loc 0 9 3 prologue_end # main.cpp:9:3 + xorl %eax, %eax + retq +.Ltmp0: +.Lfunc_end0: + .size main, .Lfunc_end0-main + .cfi_endproc + # -- End function + .type _ZN1A15fully_specifiedE,@object # @_ZN1A15fully_specifiedE + .bss + .globl _ZN1A15fully_specifiedE + .p2align 2, 0x0 +_ZN1A15fully_specifiedE: + .long 0 # 0x0 + .size _ZN1A15fully_specifiedE, 4 + + .type _ZN1A4smemE,@object # @_ZN1A4smemE + .data + .globl _ZN1A4smemE + .p2align 4, 0x0 +_ZN1A4smemE: + .long 0 # 0x0 + .long 1 # 0x1 + .long 2 # 0x2 + .long 3 # 0x3 + .size _ZN1A4smemE, 16 + + .section .debug_abbrev,"",@progbits + .byte 1 # 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 2 # Abbreviation Code + .byte 52 # DW_TAG_variable + .byte 0 # DW_CHILDREN_no + .byte 71 # DW_AT_specification + .byte 19 # DW_FORM_ref4 + .byte 2 # DW_AT_location + .byte 24 # DW_FORM_exprloc + .byte 110 # DW_AT_linkage_name + .byte 37 # DW_FORM_strx1 + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 3 # Abbreviation Code + .byte 19 # DW_TAG_structure_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 52 # DW_TAG_variable + .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 63 # DW_AT_external + .byte 25 # DW_FORM_flag_present + .byte 60 # DW_AT_declaration + .byte 25 # DW_FORM_flag_present + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 5 # 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 6 # Abbreviation Code + .byte 1 # DW_TAG_array_type + .byte 1 # DW_CHILDREN_yes + .byte 73 # DW_AT_type + .byte 19 # DW_FORM_ref4 + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 7 # Abbreviation Code + .byte 33 # DW_TAG_subrange_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 8 # Abbreviation Code + .byte 36 # DW_TAG_base_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 62 # DW_AT_encoding + .byte 11 # DW_FORM_data1 + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 9 # Abbreviation Code + .byte 52 # DW_TAG_variable + .byte 0 # DW_CHILDREN_no + .byte 71 # DW_AT_specification + .byte 19 # DW_FORM_ref4 + .byte 73 # DW_AT_type + .byte 19 # DW_FORM_ref4 + .byte 2 # DW_AT_location + .byte 24 # DW_FORM_exprloc + .byte 110 # DW_AT_linkage_name + .byte 37 # DW_FORM_strx1 + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 10 # Abbreviation Code + .byte 33 # DW_TAG_subrange_type + .byte 0 # DW_CHILDREN_no + .byte 73 # DW_AT_type + .byte 19 # DW_FORM_ref4 + .byte 55 # DW_AT_count + .byte 11 # DW_FORM_data1 + .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 122 # DW_AT_call_all_calls + .byte 25 # DW_FORM_flag_present + .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 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 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 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 0 # EOM(3) + .section .debug_info,"",@progbits +.Lcu_begin0: + .long .Ldebug_info_end0-.Ldebug_info_start0 # Length of Unit +.Ldebug_info_start0: + .short 5 # DWARF version number + .byte 1 # DWARF Unit Type + .byte 8 # Address Size (in bytes) + .long .debug_abbrev # Offset Into Abbrev. Section + .byte 1 # Abbrev [1] 0xc:0x96 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 2 # DW_AT_low_pc + .long .Lfunc_end0-.Lfunc_begin0 # DW_AT_high_pc + .long .Laddr_table_base0 # DW_AT_addr_base + .byte 2 # Abbrev [2] 0x23:0x9 DW_TAG_variable + .long 50 # DW_AT_specification + .byte 2 # DW_AT_location + .byte 161 + .byte 0 + .byte 8 # DW_AT_linkage_name + .byte 3 # Abbrev [3] 0x2c:0x17 DW_TAG_structure_type + .byte 5 # DW_AT_calling_convention + .byte 7 # DW_AT_name + .byte 1 # DW_AT_byte_size + .byte 0 # DW_AT_decl_file + .byte 1 # DW_AT_decl_line + .byte 4 # Abbrev [4] 0x32:0x8 DW_TAG_variable + .byte 3 # DW_AT_name + .long 67 # DW_AT_type + .byte 0 # DW_AT_decl_file + .byte 2 # DW_AT_decl_line + # DW_AT_external + # DW_AT_declaration + .byte 4 # Abbrev [4] 0x3a:0x8 DW_TAG_variable + .byte 5 # DW_AT_name + .long 71 # DW_AT_type + .byte 0 # DW_AT_decl_file + .byte 3 # DW_AT_decl_line + # DW_AT_external + # DW_AT_declaration + .byte 0 # End Of Children Mark + .byte 5 # Abbrev [5] 0x43:0x4 DW_TAG_base_type + .byte 4 # DW_AT_name + .byte 5 # DW_AT_encoding + .byte 4 # DW_AT_byte_size + .byte 6 # Abbrev [6] 0x47:0xb DW_TAG_array_type + .long 67 # DW_AT_type + .byte 7 # Abbrev [7] 0x4c:0x5 DW_TAG_subrange_type + .long 82 # DW_AT_type + .byte 0 # End Of Children Mark + .byte 8 # Abbrev [8] 0x52:0x4 DW_TAG_base_type + .byte 6 # DW_AT_name + .byte 8 # DW_AT_byte_size + .byte 7 # DW_AT_encoding + .byte 9 # Abbrev [9] 0x56:0xd DW_TAG_variable + .long 58 # DW_AT_specification + .long 99 # DW_AT_type + .byte 2 # DW_AT_location + .byte 161 + .byte 1 + .byte 9 # DW_AT_linkage_name + .byte 6 # Abbrev [6] 0x63:0xc DW_TAG_array_type + .long 67 # DW_AT_type + .byte 10 # Abbrev [10] 0x68:0x6 DW_TAG_subrange_type + .long 82 # DW_AT_type + .byte 4 # DW_AT_count + .byte 0 # End Of Children Mark + .byte 11 # Abbrev [11] 0x6f:0x24 DW_TAG_subprogram + .byte 2 # DW_AT_low_pc + .long .Lfunc_end0-.Lfunc_begin0 # DW_AT_high_pc + .byte 1 # DW_AT_frame_base + .byte 87 + # DW_AT_call_all_calls + .byte 10 # DW_AT_name + .byte 0 # DW_AT_decl_file + .byte 8 # DW_AT_decl_line + .long 67 # DW_AT_type + # DW_AT_external + .byte 12 # Abbrev [12] 0x7e:0xa DW_TAG_formal_parameter + .byte 1 # DW_AT_location + .byte 85 + .byte 11 # DW_AT_name + .byte 0 # DW_AT_decl_file + .byte 8 # DW_AT_decl_line + .long 67 # DW_AT_type + .byte 12 # Abbrev [12] 0x88:0xa DW_TAG_formal_parameter + .byte 1 # DW_AT_location + .byte 84 + .byte 12 # DW_AT_name + .byte 0 # DW_AT_decl_file + .byte 8 # DW_AT_decl_line + .long 147 # DW_AT_type + .byte 0 # End Of Children Mark + .byte 13 # Abbrev [13] 0x93:0x5 DW_TAG_pointer_type + .long 152 # DW_AT_type + .byte 13 # Abbrev [13] 0x98:0x5 DW_TAG_pointer_type + .long 157 # DW_AT_type + .byte 5 # Abbrev [5] 0x9d:0x4 DW_TAG_base_type + .byte 13 # DW_AT_name + .byte 6 # DW_AT_encoding + .byte 1 # DW_AT_byte_size + .byte 0 # End Of Children Mark +.Ldebug_info_end0: + .section .debug_str_offsets,"",@progbits + .long 60 # 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 (git@github.com:llvm/llvm-project.git ced1fac8a32e35b63733bda27c7f5b9a2b635403)" # string offset=0 +.Linfo_string1: + .asciz "main.cpp" # string offset=104 +.Linfo_string2: + .asciz "/specification" # string offset=113 +.Linfo_string3: + .asciz "A" # string offset=165 +.Linfo_string4: + .asciz "fully_specified" # string offset=167 +.Linfo_string5: + .asciz "int" # string offset=183 +.Linfo_string6: + .asciz "smem" # string offset=187 +.Linfo_string7: + .asciz "__ARRAY_SIZE_TYPE__" # string offset=192 +.Linfo_string8: + .asciz "_ZN1A15fully_specifiedE" # string offset=212 +.Linfo_string9: + .asciz "_ZN1A4smemE" # string offset=236 +.Linfo_string10: + .asciz "main" # string offset=248 +.Linfo_string11: + .asciz "argc" # string offset=253 +.Linfo_string12: + .asciz "argv" # string offset=258 +.Linfo_string13: + .asciz "char" # string offset=263 + .section .debug_str_offsets,"",@progbits + .long .Linfo_string0 + .long .Linfo_string1 + .long .Linfo_string2 + .long .Linfo_string4 + .long .Linfo_string5 + .long .Linfo_string6 + .long .Linfo_string7 + .long .Linfo_string3 + .long .Linfo_string8 + .long .Linfo_string9 + .long .Linfo_string10 + .long .Linfo_string11 + .long .Linfo_string12 + .long .Linfo_string13 + .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 _ZN1A15fully_specifiedE + .quad _ZN1A4smemE + .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 0 # Header: local type unit count + .long 0 # Header: foreign type unit count + .long 9 # Header: bucket count + .long 9 # 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 1 # Bucket 0 + .long 3 # Bucket 1 + .long 4 # Bucket 2 + .long 0 # Bucket 3 + .long 0 # Bucket 4 + .long 0 # Bucket 5 + .long 0 # Bucket 6 + .long 5 # Bucket 7 + .long 7 # Bucket 8 + .long 1564256736 # Hash in Bucket 0 + .long 2090728503 # Hash in Bucket 0 + .long 177670 # Hash in Bucket 1 + .long 193495088 # Hash in Bucket 2 + .long 1702399516 # Hash in Bucket 7 + .long 2090499946 # Hash in Bucket 7 + .long 217009403 # Hash in Bucket 8 + .long 1214794601 # Hash in Bucket 8 + .long 2090147939 # Hash in Bucket 8 + .long .Linfo_string8 # String in Bucket 0: _ZN1A15fully_specifiedE + .long .Linfo_string6 # String in Bucket 0: smem + .long .Linfo_string3 # String in Bucket 1: A + .long .Linfo_string5 # String in Bucket 2: int + .long .Linfo_string4 # String in Bucket 7: fully_specified + .long .Linfo_string10 # String in Bucket 7: main + .long .Linfo_string7 # String in Bucket 8: __ARRAY_SIZE_TYPE__ + .long .Linfo_string9 # String in Bucket 8: _ZN1A4smemE + .long .Linfo_string13 # String in Bucket 8: char + .long .Lnames4-.Lnames_entries0 # Offset in Bucket 0 + .long .Lnames5-.Lnames_entries0 # Offset in Bucket 0 + .long .Lnames0-.Lnames_entries0 # Offset in Bucket 1 + .long .Lnames1-.Lnames_entries0 # Offset in Bucket 2 + .long .Lnames3-.Lnames_entries0 # Offset in Bucket 7 + .long .Lnames7-.Lnames_entries0 # Offset in Bucket 7 + .long .Lnames2-.Lnames_entries0 # Offset in Bucket 8 + .long .Lnames6-.Lnames_entries0 # Offset in Bucket 8 + .long .Lnames8-.Lnames_entries0 # Offset in Bucket 8 +.Lnames_abbrev_start0: + .byte 1 # Abbrev code + .byte 52 # DW_TAG_variable + .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 19 # DW_TAG_structure_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 3 # 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 4 # 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 0 # End of abbrev list +.Lnames_abbrev_end0: +.Lnames_entries0: +.Lnames4: +.L3: + .byte 1 # Abbreviation code + .long 35 # DW_IDX_die_offset + .byte 0 # DW_IDX_parent + # End of list: _ZN1A15fully_specifiedE +.Lnames5: +.L4: + .byte 1 # Abbreviation code + .long 86 # DW_IDX_die_offset + .byte 0 # DW_IDX_parent + # End of list: smem +.Lnames0: +.L6: + .byte 2 # Abbreviation code + .long 44 # DW_IDX_die_offset + .byte 0 # DW_IDX_parent + # End of list: A +.Lnames1: +.L5: + .byte 3 # Abbreviation code + .long 67 # DW_IDX_die_offset + .byte 0 # DW_IDX_parent + # End of list: int +.Lnames3: + .byte 1 # Abbreviation code + .long 35 # DW_IDX_die_offset + .byte 0 # DW_IDX_parent + # End of list: fully_specified +.Lnames7: +.L0: + .byte 4 # Abbreviation code + .long 111 # DW_IDX_die_offset + .byte 0 # DW_IDX_parent + # End of list: main +.Lnames2: +.L2: + .byte 3 # Abbreviation code + .long 82 # DW_IDX_die_offset + .byte 0 # DW_IDX_parent + # End of list: __ARRAY_SIZE_TYPE__ +.Lnames6: + .byte 1 # Abbreviation code + .long 86 # DW_IDX_die_offset + .byte 0 # DW_IDX_parent + # End of list: _ZN1A4smemE +.Lnames8: +.L1: + .byte 3 # Abbreviation code + .long 157 # DW_IDX_die_offset + .byte 0 # DW_IDX_parent + # End of list: char + .p2align 2, 0x0 +.Lnames_end0: + .ident "clang version 19.0.0git (git@github.com:llvm/llvm-project.git ced1fac8a32e35b63733bda27c7f5b9a2b635403)" + .section ".note.GNU-stack","",@progbits + .addrsig + .section .debug_line,"",@progbits +.Lline_table_start0: diff --git a/bolt/test/X86/dwarf5-debug-names-generate-debug-names.test b/bolt/test/X86/dwarf5-debug-names-generate-debug-names.test index b8789a6ad2300a21c35a16fb65a36979ab3d82d9..b7d8fda63315fa6ff8f31d9b2b3e1faed6a49de5 100644 --- a/bolt/test/X86/dwarf5-debug-names-generate-debug-names.test +++ b/bolt/test/X86/dwarf5-debug-names-generate-debug-names.test @@ -14,15 +14,15 @@ ; BOLT: [[OFFSET2:0x[0-9a-f]*]]: Compile Unit ; BOLT: Name Index @ 0x0 { ; BOLT-NEXT: Header { -; BOLT-NEXT: Length: 0x103 +; BOLT-NEXT: Length: 0x155 ; BOLT-NEXT: Format: DWARF32 ; BOLT-NEXT: Version: 5 ; BOLT-NEXT: CU count: 2 ; BOLT-NEXT: Local TU count: 0 ; BOLT-NEXT: Foreign TU count: 0 -; BOLT-NEXT: Bucket count: 8 -; BOLT-NEXT: Name count: 8 -; BOLT-NEXT: Abbreviations table size: 0x19 +; BOLT-NEXT: Bucket count: 10 +; BOLT-NEXT: Name count: 10 +; BOLT-NEXT: Abbreviations table size: 0x29 ; BOLT-NEXT: Augmentation: 'BOLT' ; BOLT-NEXT: } ; BOLT-NEXT: Compilation Unit offsets [ @@ -31,124 +31,183 @@ ; BOLT-NEXT: ] ; BOLT-NEXT: Abbreviations [ ; BOLT-NEXT: Abbreviation [[ABBREV1:0x[0-9a-f]*]] { -; BOLT-NEXT: Tag: DW_TAG_base_type +; BOLT-NEXT: Tag: DW_TAG_subprogram ; BOLT-NEXT: DW_IDX_compile_unit: DW_FORM_data1 ; BOLT-NEXT: DW_IDX_die_offset: DW_FORM_ref4 +; BOLT-NEXT: DW_IDX_parent: DW_FORM_flag_present ; BOLT-NEXT: } ; BOLT-NEXT: Abbreviation [[ABBREV2:0x[0-9a-f]*]] { -; BOLT-NEXT: Tag: DW_TAG_subprogram -; BOLT-NEXT: DW_IDX_compile_unit: DW_FORM_data1 -; BOLT-NEXT: DW_IDX_die_offset: DW_FORM_ref4 +; BOLT-NEXT: Tag: DW_TAG_inlined_subroutine +; BOLT-NEXT: DW_IDX_compile_unit: DW_FORM_data1 +; BOLT-NEXT: DW_IDX_die_offset: DW_FORM_ref4 +; BOLT-NEXT: DW_IDX_parent: DW_FORM_ref4 ; BOLT-NEXT: } ; BOLT-NEXT: Abbreviation [[ABBREV3:0x[0-9a-f]*]] { ; BOLT-NEXT: Tag: DW_TAG_variable ; BOLT-NEXT: DW_IDX_compile_unit: DW_FORM_data1 ; BOLT-NEXT: DW_IDX_die_offset: DW_FORM_ref4 +; BOLT-NEXT: DW_IDX_parent: DW_FORM_flag_present +; BOLT-NEXT: } +; BOLT-NEXT: Abbreviation [[ABBREV4:0x[0-9a-f]*]] { +; BOLT-NEXT: Tag: DW_TAG_base_type +; BOLT-NEXT: DW_IDX_compile_unit: DW_FORM_data1 +; BOLT-NEXT: DW_IDX_die_offset: DW_FORM_ref4 +; BOLT-NEXT: DW_IDX_parent: DW_FORM_flag_present ; BOLT-NEXT: } ; BOLT-NEXT: ] ; BOLT-NEXT: Bucket 0 [ -; BOLT-NEXT: Name 1 { -; BOLT-NEXT: Hash: 0xB888030 -; BOLT-NEXT: String: {{.+}} "int" -; BOLT-NEXT: Entry @ {{.+}} { -; BOLT-NEXT: Abbrev: [[ABBREV1]] -; BOLT-NEXT: Tag: DW_TAG_base_type -; BOLT-NEXT: DW_IDX_compile_unit: 0x01 -; BOLT-NEXT: DW_IDX_die_offset: 0x00000033 +; BOLT-NEXT: Name 1 { +; BOLT-NEXT: Hash: 0x2124BB36 +; BOLT-NEXT: String: {{.+}} "useFoo" +; BOLT-NEXT: Entry @ {{.+}} { +; BOLT-NEXT: Abbrev: [[ABBREV1]] +; BOLT-NEXT: Tag: DW_TAG_subprogram +; BOLT-NEXT: DW_IDX_compile_unit: 0x01 +; BOLT-NEXT: DW_IDX_die_offset: 0x00000037 +; BOLT-NEXT: DW_IDX_parent: +; BOLT-NEXT: } +; BOLT-NEXT: Entry @ {{.+}} { +; BOLT-NEXT: Abbrev: [[ABBREV2]] +; BOLT-NEXT: Tag: DW_TAG_inlined_subroutine +; BOLT-NEXT: DW_IDX_compile_unit: 0x01 +; BOLT-NEXT: DW_IDX_die_offset: 0x00000081 +; BOLT-NEXT: DW_IDX_parent: Entry @ 0x14b +; BOLT-NEXT: } ; BOLT-NEXT: } -; BOLT-NEXT: Entry @ {{.+}} { -; BOLT-NEXT: Abbrev: [[ABBREV1]] -; BOLT-NEXT: Tag: DW_TAG_base_type -; BOLT-NEXT: DW_IDX_compile_unit: 0x00 -; BOLT-NEXT: DW_IDX_die_offset: 0x0000007f +; BOLT-NEXT: ] +; BOLT-NEXT: Bucket 1 [ +; BOLT-NEXT: EMPTY +; BOLT-NEXT: ] +; BOLT-NEXT: Bucket 2 [ +; BOLT-NEXT: Name 2 { +; BOLT-NEXT: Hash: 0xFDE4B5D2 +; BOLT-NEXT: String: {{.+}} "fooVar" +; BOLT-NEXT: Entry @ {{.+}} { +; BOLT-NEXT: Abbrev: [[ABBREV3]] +; BOLT-NEXT: Tag: DW_TAG_variable +; BOLT-NEXT: DW_IDX_compile_unit: 0x01 +; BOLT-NEXT: DW_IDX_die_offset: 0x00000028 +; BOLT-NEXT: DW_IDX_parent: +; BOLT-NEXT: } ; BOLT-NEXT: } -; BOLT-NEXT: } -; BOLT-NEXT: ] -; BOLT-NEXT: Bucket 1 [ -; BOLT-NEXT: Name 2 { -; BOLT-NEXT: Hash: 0xB887389 -; BOLT-NEXT: String: {{.+}} "foo" -; BOLT-NEXT: Entry @ {{.+}} { -; BOLT-NEXT: Abbrev: [[ABBREV2]] -; BOLT-NEXT: Tag: DW_TAG_subprogram -; BOLT-NEXT: DW_IDX_compile_unit: 0x01 -; BOLT-NEXT: DW_IDX_die_offset: 0x0000005e +; BOLT-NEXT: ] +; BOLT-NEXT: Bucket 3 [ +; BOLT-NEXT: EMPTY +; BOLT-NEXT: ] +; BOLT-NEXT: Bucket 4 [ +; BOLT-NEXT: EMPTY +; BOLT-NEXT: ] +; BOLT-NEXT: Bucket 5 [ +; BOLT-NEXT: EMPTY +; BOLT-NEXT: ] +; BOLT-NEXT: Bucket 6 [ +; BOLT-NEXT: Name 3 { +; BOLT-NEXT: Hash: 0xB88B3D2 +; BOLT-NEXT: String: {{.+}} "use" +; BOLT-NEXT: Entry @ {{.+}} { +; BOLT-NEXT: Abbrev: [[ABBREV1]] +; BOLT-NEXT: Tag: DW_TAG_subprogram +; BOLT-NEXT: DW_IDX_compile_unit: 0x00 +; BOLT-NEXT: DW_IDX_die_offset: 0x00000028 +; BOLT-NEXT: DW_IDX_parent: +; BOLT-NEXT: } ; BOLT-NEXT: } -; BOLT-NEXT: } -; BOLT-NEXT: Name 3 { -; BOLT-NEXT: Hash: 0x8C06E589 -; BOLT-NEXT: String: {{.+}} "_Z3usePiS_" -; BOLT-NEXT: Entry @ {{.+}} { -; BOLT-NEXT: Abbrev: [[ABBREV2]] -; BOLT-NEXT: Tag: DW_TAG_subprogram -; BOLT-NEXT: DW_IDX_compile_unit: 0x00 -; BOLT-NEXT: DW_IDX_die_offset: 0x00000028 +; BOLT-NEXT: Name 4 { +; BOLT-NEXT: Hash: 0x69A7307E +; BOLT-NEXT: String: {{.+}} "_Z6useFooPi" +; BOLT-NEXT: Entry @ {{.+}} { +; BOLT-NEXT: Abbrev: [[ABBREV1]] +; BOLT-NEXT: Tag: DW_TAG_subprogram +; BOLT-NEXT: DW_IDX_compile_unit: 0x01 +; BOLT-NEXT: DW_IDX_die_offset: 0x00000037 +; BOLT-NEXT: DW_IDX_parent: +; BOLT-NEXT: } +; BOLT-NEXT: Entry @ {{.+}} { +; BOLT-NEXT: Abbrev: [[ABBREV2]] +; BOLT-NEXT: Tag: DW_TAG_inlined_subroutine +; BOLT-NEXT: DW_IDX_compile_unit: 0x01 +; BOLT-NEXT: DW_IDX_die_offset: 0x00000081 +; BOLT-NEXT: DW_IDX_parent: Entry @ 0x14b +; BOLT-NEXT: } ; BOLT-NEXT: } -; BOLT-NEXT: } -; BOLT-NEXT: ] -; BOLT-NEXT: Bucket 2 [ -; BOLT-NEXT: Name 4 { -; BOLT-NEXT: Hash: 0xB88B3D2 -; BOLT-NEXT: String: {{.+}} "use" -; BOLT-NEXT: Entry @ {{.+}} { -; BOLT-NEXT: Abbrev: [[ABBREV2]] -; BOLT-NEXT: Tag: DW_TAG_subprogram -; BOLT-NEXT: DW_IDX_compile_unit: 0x00 -; BOLT-NEXT: DW_IDX_die_offset: 0x00000028 +; BOLT-NEXT: Name 5 { +; BOLT-NEXT: Hash: 0x7C9A7F6A +; BOLT-NEXT: String: {{.+}} "main" +; BOLT-NEXT: Entry @ {{.+}} { +; BOLT-NEXT: Abbrev: [[ABBREV1]] +; BOLT-NEXT: Tag: DW_TAG_subprogram +; BOLT-NEXT: DW_IDX_compile_unit: 0x00 +; BOLT-NEXT: DW_IDX_die_offset: 0x00000049 +; BOLT-NEXT: DW_IDX_parent: +; BOLT-NEXT: } ; BOLT-NEXT: } -; BOLT-NEXT: } -; BOLT-NEXT: Name 5 { -; BOLT-NEXT: Hash: 0x7C9A7F6A -; BOLT-NEXT: String: {{.+}} "main" -; BOLT-NEXT: Entry @ {{.+}} { -; BOLT-NEXT: Abbrev: [[ABBREV2]] -; BOLT-NEXT: Tag: DW_TAG_subprogram -; BOLT-NEXT: DW_IDX_compile_unit: 0x00 -; BOLT-NEXT: DW_IDX_die_offset: 0x00000049 +; BOLT-NEXT: Name 6 { +; BOLT-NEXT: Hash: 0xB5063CFE +; BOLT-NEXT: String: {{.+}} "_Z3fooi" +; BOLT-NEXT: Entry @ {{.+}} { +; BOLT-NEXT: Abbrev: [[ABBREV1]] +; BOLT-NEXT: Tag: DW_TAG_subprogram +; BOLT-NEXT: DW_IDX_compile_unit: 0x01 +; BOLT-NEXT: DW_IDX_die_offset: 0x0000005e +; BOLT-NEXT: DW_IDX_parent: +; BOLT-NEXT: } ; BOLT-NEXT: } -; BOLT-NEXT: } -; BOLT-NEXT: Name 6 { -; BOLT-NEXT: Hash: 0xFDE4B5D2 -; BOLT-NEXT: String: {{.+}} "fooVar" -; BOLT-NEXT: Entry @ {{.+}} { -; BOLT-NEXT: Abbrev: [[ABBREV3]] -; BOLT-NEXT: Tag: DW_TAG_variable -; BOLT-NEXT: DW_IDX_compile_unit: 0x01 -; BOLT-NEXT: DW_IDX_die_offset: 0x00000028 +; BOLT-NEXT: ] +; BOLT-NEXT: Bucket 7 [ +; BOLT-NEXT: Name 7 { +; BOLT-NEXT: Hash: 0x8C06E589 +; BOLT-NEXT: String: {{.+}} "_Z3usePiS_" +; BOLT-NEXT: Entry @ {{.+}} { +; BOLT-NEXT: Abbrev: [[ABBREV1]] +; BOLT-NEXT: Tag: DW_TAG_subprogram +; BOLT-NEXT: DW_IDX_compile_unit: 0x00 +; BOLT-NEXT: DW_IDX_die_offset: 0x00000028 +; BOLT-NEXT: DW_IDX_parent: +; BOLT-NEXT: } ; BOLT-NEXT: } -; BOLT-NEXT: } -; BOLT-NEXT: ] -; BOLT-NEXT: Bucket 3 [ -; BOLT-NEXT: Name 7 { -; BOLT-NEXT: Hash: 0x7C952063 -; BOLT-NEXT: String: {{.+}} "char" -; BOLT-NEXT: Entry @ {{.+}} { -; BOLT-NEXT: Abbrev: [[ABBREV1]] -; BOLT-NEXT: Tag: DW_TAG_base_type -; BOLT-NEXT: DW_IDX_compile_unit: 0x00 -; BOLT-NEXT: DW_IDX_die_offset: 0x00000092 +; BOLT-NEXT: ] +; BOLT-NEXT: Bucket 8 [ +; BOLT-NEXT: Name 8 { +; BOLT-NEXT: Hash: 0xB888030 +; BOLT-NEXT: String: {{.+}} "int" +; BOLT-NEXT: Entry @ {{.+}} { +; BOLT-NEXT: Abbrev: [[ABBREV4]] +; BOLT-NEXT: Tag: DW_TAG_base_type +; BOLT-NEXT: DW_IDX_compile_unit: 0x01 +; BOLT-NEXT: DW_IDX_die_offset: 0x00000033 +; BOLT-NEXT: DW_IDX_parent: +; BOLT-NEXT: } +; BOLT-NEXT: Entry @ 0x{{.+}} { +; BOLT-NEXT: Abbrev: [[ABBREV4]] +; BOLT-NEXT: Tag: DW_TAG_base_type +; BOLT-NEXT: DW_IDX_compile_unit: 0x00 +; BOLT-NEXT: DW_IDX_die_offset: 0x0000007f +; BOLT-NEXT: DW_IDX_parent: +; BOLT-NEXT: } ; BOLT-NEXT: } -; BOLT-NEXT: } -; BOLT-NEXT: ] -; BOLT-NEXT: Bucket 4 [ -; BOLT-NEXT: EMPTY -; BOLT-NEXT: ] -; BOLT-NEXT: Bucket 5 [ -; BOLT-NEXT: EMPTY -; BOLT-NEXT: ] -; BOLT-NEXT: Bucket 6 [ -; BOLT-NEXT: Name 8 { -; BOLT-NEXT: Hash: 0xB5063CFE -; BOLT-NEXT: String: {{.+}} "_Z3fooi" -; BOLT-NEXT: Entry @ {{.+}} { -; BOLT-NEXT: Abbrev: [[ABBREV2]] -; BOLT-NEXT: Tag: DW_TAG_subprogram -; BOLT-NEXT: DW_IDX_compile_unit: 0x01 -; BOLT-NEXT: DW_IDX_die_offset: 0x0000005e +; BOLT-NEXT: ] +; BOLT-NEXT: Bucket 9 [ +; BOLT-NEXT: Name 9 { +; BOLT-NEXT: Hash: 0xB887389 +; BOLT-NEXT: String: {{.+}} "foo" +; BOLT-NEXT: Entry @ 0x14b { +; BOLT-NEXT: Abbrev: [[ABBREV1]] +; BOLT-NEXT: Tag: DW_TAG_subprogram +; BOLT-NEXT: DW_IDX_compile_unit: 0x01 +; BOLT-NEXT: DW_IDX_die_offset: 0x0000005e +; BOLT-NEXT: DW_IDX_parent: +; BOLT-NEXT: } ; BOLT-NEXT: } -; BOLT-NEXT: } -; BOLT-NEXT: ] -; BOLT-NEXT: Bucket 7 [ -; BOLT-NEXT: EMPTY -; BOLT-NEXT: ] -; BOLT-NEXT: } +; BOLT-NEXT: Name 10 { +; BOLT-NEXT: Hash: 0x7C952063 +; BOLT-NEXT: String: {{.+}} "char" +; BOLT-NEXT: Entry @ {{.+}} { +; BOLT-NEXT: Abbrev: [[ABBREV4]] +; BOLT-NEXT: Tag: DW_TAG_base_type +; BOLT-NEXT: DW_IDX_compile_unit: 0x00 +; BOLT-NEXT: DW_IDX_die_offset: 0x00000092 +; BOLT-NEXT: DW_IDX_parent: +; BOLT-NEXT: } +; BOLT-NEXT: } +; BOLT-NEXT: ] +; BOLT-NEXT: } diff --git a/bolt/test/X86/dwarf5-debug-names.test b/bolt/test/X86/dwarf5-debug-names.test index de0e88d7a36ae5b35eb6528eb18c7a3ba5ce3cfe..ef11ee0c479b7f8416a38367d220bed4bf9a0559 100644 --- a/bolt/test/X86/dwarf5-debug-names.test +++ b/bolt/test/X86/dwarf5-debug-names.test @@ -11,7 +11,7 @@ ; BOLT: [[OFFSET2:0x[0-9a-f]*]]: Compile Unit ; BOLT: Name Index @ 0x0 { ; BOLT-NEXT: Header { -; BOLT-NEXT: Length: 0x1C2 +; BOLT-NEXT: Length: 0x1D4 ; BOLT-NEXT: Format: DWARF32 ; BOLT-NEXT: Version: 5 ; BOLT-NEXT: CU count: 2 @@ -19,7 +19,7 @@ ; BOLT-NEXT: Foreign TU count: 0 ; BOLT-NEXT: Bucket count: 14 ; BOLT-NEXT: Name count: 15 -; BOLT-NEXT: Abbreviations table size: 0x29 +; BOLT-NEXT: Abbreviations table size: 0x3D ; BOLT-NEXT: Augmentation: 'BOLT' ; BOLT-NEXT: } ; BOLT-NEXT: Compilation Unit offsets [ @@ -31,27 +31,38 @@ ; BOLT-NEXT: Tag: DW_TAG_structure_type ; BOLT-NEXT: DW_IDX_compile_unit: DW_FORM_data1 ; BOLT-NEXT: DW_IDX_die_offset: DW_FORM_ref4 +; BOLT-NEXT: DW_IDX_parent: DW_FORM_flag_present ; BOLT-NEXT: } ; BOLT-NEXT: Abbreviation [[ABBREV2:0x[0-9a-f]*]] { ; BOLT-NEXT: Tag: DW_TAG_namespace ; BOLT-NEXT: DW_IDX_compile_unit: DW_FORM_data1 ; BOLT-NEXT: DW_IDX_die_offset: DW_FORM_ref4 +; BOLT-NEXT: DW_IDX_parent: DW_FORM_flag_present ; BOLT-NEXT: } ; BOLT-NEXT: Abbreviation [[ABBREV3:0x[0-9a-f]*]] { ; BOLT-NEXT: Tag: DW_TAG_subprogram ; BOLT-NEXT: DW_IDX_compile_unit: DW_FORM_data1 ; BOLT-NEXT: DW_IDX_die_offset: DW_FORM_ref4 +; BOLT-NEXT: DW_IDX_parent: DW_FORM_flag_present ; BOLT-NEXT: } ; BOLT-NEXT: Abbreviation [[ABBREV4:0x[0-9a-f]*]] { ; BOLT-NEXT: Tag: DW_TAG_base_type ; BOLT-NEXT: DW_IDX_compile_unit: DW_FORM_data1 ; BOLT-NEXT: DW_IDX_die_offset: DW_FORM_ref4 +; BOLT-NEXT: DW_IDX_parent: DW_FORM_flag_present ; BOLT-NEXT: } ; BOLT-NEXT: Abbreviation [[ABBREV5:0x[0-9a-f]*]] { ; BOLT-NEXT: Tag: DW_TAG_variable ; BOLT-NEXT: DW_IDX_compile_unit: DW_FORM_data1 ; BOLT-NEXT: DW_IDX_die_offset: DW_FORM_ref4 +; BOLT-NEXT: DW_IDX_parent: DW_FORM_flag_present ; BOLT-NEXT: } +; BOLT-NEXT: Abbreviation [[ABBREV6:0x[0-9a-f]*]] { +; BOLT-NEXT: Tag: DW_TAG_structure_type +; BOLT-NEXT: DW_IDX_compile_unit: DW_FORM_data1 +; BOLT-NEXT: DW_IDX_die_offset: DW_FORM_ref4 +; BOLT-NEXT: DW_IDX_parent: DW_FORM_ref4 +; BOLT-NEXT: } ; BOLT-NEXT: ] ; BOLT-NEXT: Bucket 0 [ ; BOLT-NEXT: Name 1 { @@ -62,6 +73,7 @@ ; BOLT-NEXT: Tag: DW_TAG_structure_type ; BOLT-NEXT: DW_IDX_compile_unit: 0x00 ; BOLT-NEXT: DW_IDX_die_offset: 0x0000002f +; BOLT-NEXT: DW_IDX_parent: ; BOLT-NEXT: } ; BOLT-NEXT: } ; BOLT-NEXT: ] @@ -74,6 +86,7 @@ ; BOLT-NEXT: Tag: DW_TAG_structure_type ; BOLT-NEXT: DW_IDX_compile_unit: 0x00 ; BOLT-NEXT: DW_IDX_die_offset: 0x000000eb +; BOLT-NEXT: DW_IDX_parent: ; BOLT-NEXT: } ; BOLT-NEXT: } ; BOLT-NEXT: ] @@ -81,17 +94,12 @@ ; BOLT-NEXT: Name 3 { ; BOLT-NEXT: Hash: 0x8CFC710C ; BOLT-NEXT: String: {{.+}} "(anonymous namespace)" -; BOLT-NEXT: Entry @ {{.+}} { -; BOLT-NEXT: Abbrev: [[ABBREV2]] -; BOLT-NEXT: Tag: DW_TAG_namespace -; BOLT-NEXT: DW_IDX_compile_unit: 0x00 -; BOLT-NEXT: DW_IDX_die_offset: 0x00000061 -; BOLT-NEXT: } -; BOLT-NEXT: Entry @ {{.+}} { +; BOLT-NEXT: Entry @ [[ENTRY:0x[0-9a-f]*]] { ; BOLT-NEXT: Abbrev: [[ABBREV2]] ; BOLT-NEXT: Tag: DW_TAG_namespace ; BOLT-NEXT: DW_IDX_compile_unit: 0x00 ; BOLT-NEXT: DW_IDX_die_offset: 0x00000061 +; BOLT-NEXT: DW_IDX_parent: ; BOLT-NEXT: } ; BOLT-NEXT: } ; BOLT-NEXT: Name 4 { @@ -102,6 +110,7 @@ ; BOLT-NEXT: Tag: DW_TAG_structure_type ; BOLT-NEXT: DW_IDX_compile_unit: 0x01 ; BOLT-NEXT: DW_IDX_die_offset: 0x0000005a +; BOLT-NEXT: DW_IDX_parent: ; BOLT-NEXT: } ; BOLT-NEXT: } ; BOLT-NEXT: ] @@ -120,6 +129,7 @@ ; BOLT-NEXT: Tag: DW_TAG_structure_type ; BOLT-NEXT: DW_IDX_compile_unit: 0x00 ; BOLT-NEXT: DW_IDX_die_offset: 0x000000c9 +; BOLT-NEXT: DW_IDX_parent: ; BOLT-NEXT: } ; BOLT-NEXT: } ; BOLT-NEXT: Name 6 { @@ -130,6 +140,7 @@ ; BOLT-NEXT: Tag: DW_TAG_subprogram ; BOLT-NEXT: DW_IDX_compile_unit: 0x01 ; BOLT-NEXT: DW_IDX_die_offset: 0x00000033 +; BOLT-NEXT: DW_IDX_parent: ; BOLT-NEXT: } ; BOLT-NEXT: } ; BOLT-NEXT: Name 7 { @@ -140,12 +151,14 @@ ; BOLT-NEXT: Tag: DW_TAG_base_type ; BOLT-NEXT: DW_IDX_compile_unit: 0x01 ; BOLT-NEXT: DW_IDX_die_offset: 0x0000009f +; BOLT-NEXT: DW_IDX_parent: ; BOLT-NEXT: } ; BOLT-NEXT: Entry @ {{.+}} { ; BOLT-NEXT: Abbrev: [[ABBREV4]] ; BOLT-NEXT: Tag: DW_TAG_base_type ; BOLT-NEXT: DW_IDX_compile_unit: 0x00 ; BOLT-NEXT: DW_IDX_die_offset: 0x000000c5 +; BOLT-NEXT: DW_IDX_parent: ; BOLT-NEXT: } ; BOLT-NEXT: } ; BOLT-NEXT: ] @@ -158,6 +171,7 @@ ; BOLT-NEXT: Tag: DW_TAG_structure_type ; BOLT-NEXT: DW_IDX_compile_unit: 0x00 ; BOLT-NEXT: DW_IDX_die_offset: 0x0000003f +; BOLT-NEXT: DW_IDX_parent: ; BOLT-NEXT: } ; BOLT-NEXT: } ; BOLT-NEXT: Name 9 { @@ -168,6 +182,7 @@ ; BOLT-NEXT: Tag: DW_TAG_variable ; BOLT-NEXT: DW_IDX_compile_unit: 0x01 ; BOLT-NEXT: DW_IDX_die_offset: 0x00000024 +; BOLT-NEXT: DW_IDX_parent: ; BOLT-NEXT: } ; BOLT-NEXT: } ; BOLT-NEXT: ] @@ -180,6 +195,7 @@ ; BOLT-NEXT: Tag: DW_TAG_subprogram ; BOLT-NEXT: DW_IDX_compile_unit: 0x01 ; BOLT-NEXT: DW_IDX_die_offset: 0x00000033 +; BOLT-NEXT: DW_IDX_parent: ; BOLT-NEXT: } ; BOLT-NEXT: } ; BOLT-NEXT: ] @@ -192,6 +208,7 @@ ; BOLT-NEXT: Tag: DW_TAG_variable ; BOLT-NEXT: DW_IDX_compile_unit: 0x00 ; BOLT-NEXT: DW_IDX_die_offset: 0x00000024 +; BOLT-NEXT: DW_IDX_parent: ; BOLT-NEXT: } ; BOLT-NEXT: } ; BOLT-NEXT: ] @@ -207,12 +224,14 @@ ; BOLT-NEXT: Tag: DW_TAG_base_type ; BOLT-NEXT: DW_IDX_compile_unit: 0x01 ; BOLT-NEXT: DW_IDX_die_offset: 0x0000002f +; BOLT-NEXT: DW_IDX_parent: ; BOLT-NEXT: } ; BOLT-NEXT: Entry @ {{.+}} { ; BOLT-NEXT: Abbrev: [[ABBREV4]] ; BOLT-NEXT: Tag: DW_TAG_base_type ; BOLT-NEXT: DW_IDX_compile_unit: 0x00 ; BOLT-NEXT: DW_IDX_die_offset: 0x0000005d +; BOLT-NEXT: DW_IDX_parent: ; BOLT-NEXT: } ; BOLT-NEXT: } ; BOLT-NEXT: Name 13 { @@ -223,12 +242,14 @@ ; BOLT-NEXT: Tag: DW_TAG_structure_type ; BOLT-NEXT: DW_IDX_compile_unit: 0x01 ; BOLT-NEXT: DW_IDX_die_offset: 0x00000078 +; BOLT-NEXT: DW_IDX_parent: ; BOLT-NEXT: } ; BOLT-NEXT: Entry @ {{.+}} { ; BOLT-NEXT: Abbrev: [[ABBREV1]] ; BOLT-NEXT: Tag: DW_TAG_structure_type ; BOLT-NEXT: DW_IDX_compile_unit: 0x00 ; BOLT-NEXT: DW_IDX_die_offset: 0x00000104 +; BOLT-NEXT: DW_IDX_parent: ; BOLT-NEXT: } ; BOLT-NEXT: } ; BOLT-NEXT: Name 14 { @@ -239,6 +260,7 @@ ; BOLT-NEXT: Tag: DW_TAG_subprogram ; BOLT-NEXT: DW_IDX_compile_unit: 0x00 ; BOLT-NEXT: DW_IDX_die_offset: 0x00000073 +; BOLT-NEXT: DW_IDX_parent: ; BOLT-NEXT: } ; BOLT-NEXT: } ; BOLT-NEXT: ] @@ -250,10 +272,11 @@ ; BOLT-NEXT: Hash: 0x59796A ; BOLT-NEXT: String: {{.+}} "t1" ; BOLT-NEXT: Entry @ {{.+}} { -; BOLT-NEXT: Abbrev: [[ABBREV1]] +; BOLT-NEXT: Abbrev: [[ABBREV6]] ; BOLT-NEXT: Tag: DW_TAG_structure_type ; BOLT-NEXT: DW_IDX_compile_unit: 0x00 ; BOLT-NEXT: DW_IDX_die_offset: 0x00000062 +; BOLT-NEXT: DW_IDX_parent: Entry @ [[ENTRY]] ; BOLT-NEXT: } ; BOLT-NEXT: } ; BOLT-NEXT: ] diff --git a/bolt/test/X86/dwarf5-df-debug-names-generate-debug-names.test b/bolt/test/X86/dwarf5-df-debug-names-generate-debug-names.test index 3be327b780e525ad55d83441b03f6c4bd0ac2e44..b0b6707a4ea5cb4174355fbf75428e3890d889dc 100644 --- a/bolt/test/X86/dwarf5-df-debug-names-generate-debug-names.test +++ b/bolt/test/X86/dwarf5-df-debug-names-generate-debug-names.test @@ -17,7 +17,7 @@ ; BOLT: [[OFFSET2:0x[0-9a-f]*]]: Compile Unit ; BOLT: Name Index @ 0x0 { ; BOLT-NEXT: Header { -; BOLT-NEXT: Length: 0x148 +; BOLT-NEXT: Length: 0x14E ; BOLT-NEXT: Format: DWARF32 ; BOLT-NEXT: Version: 5 ; BOLT-NEXT: CU count: 2 @@ -25,7 +25,7 @@ ; BOLT-NEXT: Foreign TU count: 0 ; BOLT-NEXT: Bucket count: 11 ; BOLT-NEXT: Name count: 11 -; BOLT-NEXT: Abbreviations table size: 0x19 +; BOLT-NEXT: Abbreviations table size: 0x1F ; BOLT-NEXT: Augmentation: 'BOLT' ; BOLT-NEXT: } ; BOLT-NEXT: Compilation Unit offsets [ @@ -37,16 +37,19 @@ ; BOLT-NEXT: Tag: DW_TAG_variable ; BOLT-NEXT: DW_IDX_compile_unit: DW_FORM_data1 ; BOLT-NEXT: DW_IDX_die_offset: DW_FORM_ref4 +; BOLT-NEXT: DW_IDX_parent: DW_FORM_flag_present ; BOLT-NEXT: } ; BOLT-NEXT: Abbreviation [[ABBREV2:0x[0-9a-f]*]] { ; BOLT-NEXT: Tag: DW_TAG_base_type ; BOLT-NEXT: DW_IDX_compile_unit: DW_FORM_data1 ; BOLT-NEXT: DW_IDX_die_offset: DW_FORM_ref4 +; BOLT-NEXT: DW_IDX_parent: DW_FORM_flag_present ; BOLT-NEXT: } ; BOLT-NEXT: Abbreviation [[ABBREV3:0x[0-9a-f]*]] { ; BOLT-NEXT: Tag: DW_TAG_subprogram ; BOLT-NEXT: DW_IDX_compile_unit: DW_FORM_data1 ; BOLT-NEXT: DW_IDX_die_offset: DW_FORM_ref4 +; BOLT-NEXT: DW_IDX_parent: DW_FORM_flag_present ; BOLT-NEXT: } ; BOLT-NEXT: ] ; BOLT-NEXT: Bucket 0 [ @@ -58,6 +61,7 @@ ; BOLT-NEXT: Tag: DW_TAG_variable ; BOLT-NEXT: DW_IDX_compile_unit: 0x00 ; BOLT-NEXT: DW_IDX_die_offset: 0x00000029 +; BOLT-NEXT: DW_IDX_parent: ; BOLT-NEXT: } ; BOLT-NEXT: } ; BOLT-NEXT: Name 2 { @@ -68,6 +72,7 @@ ; BOLT-NEXT: Tag: DW_TAG_base_type ; BOLT-NEXT: DW_IDX_compile_unit: 0x00 ; BOLT-NEXT: DW_IDX_die_offset: 0x0000008c +; BOLT-NEXT: DW_IDX_parent: ; BOLT-NEXT: } ; BOLT-NEXT: } ; BOLT-NEXT: ] @@ -80,6 +85,7 @@ ; BOLT-NEXT: Tag: DW_TAG_variable ; BOLT-NEXT: DW_IDX_compile_unit: 0x01 ; BOLT-NEXT: DW_IDX_die_offset: 0x00000029 +; BOLT-NEXT: DW_IDX_parent: ; BOLT-NEXT: } ; BOLT-NEXT: } ; BOLT-NEXT: Name 4 { @@ -90,6 +96,7 @@ ; BOLT-NEXT: Tag: DW_TAG_variable ; BOLT-NEXT: DW_IDX_compile_unit: 0x01 ; BOLT-NEXT: DW_IDX_die_offset: 0x0000001a +; BOLT-NEXT: DW_IDX_parent: ; BOLT-NEXT: } ; BOLT-NEXT: } ; BOLT-NEXT: ] @@ -102,6 +109,7 @@ ; BOLT-NEXT: Tag: DW_TAG_subprogram ; BOLT-NEXT: DW_IDX_compile_unit: 0x00 ; BOLT-NEXT: DW_IDX_die_offset: 0x00000034 +; BOLT-NEXT: DW_IDX_parent: ; BOLT-NEXT: } ; BOLT-NEXT: } ; BOLT-NEXT: ] @@ -114,6 +122,7 @@ ; BOLT-NEXT: Tag: DW_TAG_subprogram ; BOLT-NEXT: DW_IDX_compile_unit: 0x01 ; BOLT-NEXT: DW_IDX_die_offset: 0x00000034 +; BOLT-NEXT: DW_IDX_parent: ; BOLT-NEXT: } ; BOLT-NEXT: } ; BOLT-NEXT: ] @@ -129,6 +138,7 @@ ; BOLT-NEXT: Tag: DW_TAG_subprogram ; BOLT-NEXT: DW_IDX_compile_unit: 0x00 ; BOLT-NEXT: DW_IDX_die_offset: 0x00000034 +; BOLT-NEXT: DW_IDX_parent: ; BOLT-NEXT: } ; BOLT-NEXT: } ; BOLT-NEXT: ] @@ -141,12 +151,14 @@ ; BOLT-NEXT: Tag: DW_TAG_base_type ; BOLT-NEXT: DW_IDX_compile_unit: 0x00 ; BOLT-NEXT: DW_IDX_die_offset: 0x00000025 +; BOLT-NEXT: DW_IDX_parent: ; BOLT-NEXT: } ; BOLT-NEXT: Entry @ {{.+}} { ; BOLT-NEXT: Abbrev: [[ABBREV2]] ; BOLT-NEXT: Tag: DW_TAG_base_type ; BOLT-NEXT: DW_IDX_compile_unit: 0x01 ; BOLT-NEXT: DW_IDX_die_offset: 0x00000025 +; BOLT-NEXT: DW_IDX_parent: ; BOLT-NEXT: } ; BOLT-NEXT: } ; BOLT-NEXT: ] @@ -159,6 +171,7 @@ ; BOLT-NEXT: Tag: DW_TAG_subprogram ; BOLT-NEXT: DW_IDX_compile_unit: 0x01 ; BOLT-NEXT: DW_IDX_die_offset: 0x00000034 +; BOLT-NEXT: DW_IDX_parent: ; BOLT-NEXT: } ; BOLT-NEXT: } ; BOLT-NEXT: Name 10 { @@ -169,6 +182,7 @@ ; BOLT-NEXT: Tag: DW_TAG_subprogram ; BOLT-NEXT: DW_IDX_compile_unit: 0x00 ; BOLT-NEXT: DW_IDX_die_offset: 0x00000057 +; BOLT-NEXT: DW_IDX_parent: ; BOLT-NEXT: } ; BOLT-NEXT: } ; BOLT-NEXT: ] @@ -187,6 +201,7 @@ ; BOLT-NEXT: Tag: DW_TAG_variable ; BOLT-NEXT: DW_IDX_compile_unit: 0x00 ; BOLT-NEXT: DW_IDX_die_offset: 0x0000001a +; BOLT-NEXT: DW_IDX_parent: ; BOLT-NEXT: } ; BOLT-NEXT: } ; BOLT-NEXT: ] diff --git a/bolt/test/X86/dwarf5-df-debug-names.test b/bolt/test/X86/dwarf5-df-debug-names.test index 0352d0ff720822ea0a9bc5eeb5aedf8395c61925..d53f2bd13620fca52c4514c3fc019e75da10d898 100644 --- a/bolt/test/X86/dwarf5-df-debug-names.test +++ b/bolt/test/X86/dwarf5-df-debug-names.test @@ -14,136 +14,148 @@ ; BOLT: [[OFFSET:0x[0-9a-f]*]]: Compile Unit ; BOLT: [[OFFSET1:0x[0-9a-f]*]]: Compile Unit -: BOLT: Name Index @ 0x0 { -: BOLT-NEXT: Header { -: BOLT-NEXT: Length: 0xF4 -: BOLT-NEXT: Format: DWARF32 -: BOLT-NEXT: Version: 5 -: BOLT-NEXT: CU count: 2 -: BOLT-NEXT: Local TU count: 0 -: BOLT-NEXT: Foreign TU count: 0 -: BOLT-NEXT: Bucket count: 7 -: BOLT-NEXT: Name count: 7 -: BOLT-NEXT: Abbreviations table size: 0x21 -: BOLT-NEXT: Augmentation: 'BOLT' -: BOLT-NEXT: } -: BOLT-NEXT: Compilation Unit offsets [ -: BOLT-NEXT: CU[0]: [[OFFSET]] -: BOLT-NEXT: CU[1]: [[OFFSET1]] -: BOLT-NEXT: ] -: BOLT-NEXT: Abbreviations [ -: BOLT-NEXT: Abbreviation [[ABBREV1:0x[0-9a-f]*]] { -: BOLT-NEXT: Tag: DW_TAG_structure_type -: BOLT-NEXT: DW_IDX_compile_unit: DW_FORM_data1 -: BOLT-NEXT: DW_IDX_die_offset: DW_FORM_ref4 -: BOLT-NEXT: } -: BOLT-NEXT: Abbreviation [[ABBREV2:0x[0-9a-f]*]] { -: BOLT-NEXT: Tag: DW_TAG_base_type -: BOLT-NEXT: DW_IDX_compile_unit: DW_FORM_data1 -: BOLT-NEXT: DW_IDX_die_offset: DW_FORM_ref4 -: BOLT-NEXT: } -: BOLT-NEXT: Abbreviation [[ABBREV3:0x[0-9a-f]*]] { -: BOLT-NEXT: Tag: DW_TAG_variable -: BOLT-NEXT: DW_IDX_compile_unit: DW_FORM_data1 -: BOLT-NEXT: DW_IDX_die_offset: DW_FORM_ref4 -: BOLT-NEXT: } -: BOLT-NEXT: Abbreviation [[ABBREV4:0x[0-9a-f]*]] { -: BOLT-NEXT: Tag: DW_TAG_subprogram -: BOLT-NEXT: DW_IDX_compile_unit: DW_FORM_data1 -: BOLT-NEXT: DW_IDX_die_offset: DW_FORM_ref4 -: BOLT-NEXT: } -: BOLT-NEXT: ] -: BOLT-NEXT: Bucket 0 [ -: BOLT-NEXT: EMPTY -: BOLT-NEXT: ] -: BOLT-NEXT: Bucket 1 [ -: BOLT-NEXT: Name 1 { -: BOLT-NEXT: Hash: 0x7C96E4DB -: BOLT-NEXT: String: {{.+}} "Foo2" -: BOLT-NEXT: Entry @ {{.+}} { -: BOLT-NEXT: Abbrev: [[ABBREV1]] -: BOLT-NEXT: Tag: DW_TAG_structure_type -: BOLT-NEXT: DW_IDX_compile_unit: 0x00 -: BOLT-NEXT: DW_IDX_die_offset: 0x00000068 -: BOLT-NEXT: } -: BOLT-NEXT: } -: BOLT-NEXT: ] -: BOLT-NEXT: Bucket 2 [ -: BOLT-NEXT: Name 2 { -: BOLT-NEXT: Hash: 0xBA564846 -: BOLT-NEXT: String: {{.+}} "Foo2Int" -: BOLT-NEXT: Entry @ {{.+}} { -: BOLT-NEXT: Abbrev: [[ABBREV1]] -: BOLT-NEXT: Tag: DW_TAG_structure_type -: BOLT-NEXT: DW_IDX_compile_unit: 0x01 -: BOLT-NEXT: DW_IDX_die_offset: 0x00000025 -: BOLT-NEXT: } -: BOLT-NEXT: } -: BOLT-NEXT: ] -: BOLT-NEXT: Bucket 3 [ -: BOLT-NEXT: Name 3 { -: BOLT-NEXT: Hash: 0xB888030 -: BOLT-NEXT: String: {{.+}} "int" -: BOLT-NEXT: Entry @ {{.+}} { -: BOLT-NEXT: Abbrev: [[ABBREV2]] -: BOLT-NEXT: Tag: DW_TAG_base_type -: BOLT-NEXT: DW_IDX_compile_unit: 0x01 -: BOLT-NEXT: DW_IDX_die_offset: 0x00000043 -: BOLT-NEXT: } -: BOLT-NEXT: Entry @ {{.+}} { -: BOLT-NEXT: Abbrev: [[ABBREV2]] -: BOLT-NEXT: Tag: DW_TAG_base_type -: BOLT-NEXT: DW_IDX_compile_unit: 0x00 -: BOLT-NEXT: DW_IDX_die_offset: 0x00000056 -: BOLT-NEXT: } -: BOLT-NEXT: } -: BOLT-NEXT: Name 4 { -: BOLT-NEXT: Hash: 0xF73809C -: BOLT-NEXT: String: {{.+}} "Foo2a" -: BOLT-NEXT: Entry @ {{.+}} { -: BOLT-NEXT: Abbrev: [[ABBREV1]] -: BOLT-NEXT: Tag: DW_TAG_structure_type -: BOLT-NEXT: DW_IDX_compile_unit: 0x00 -: BOLT-NEXT: DW_IDX_die_offset: 0x00000078 -: BOLT-NEXT: } -: BOLT-NEXT: } -: BOLT-NEXT: Name 5 { -: BOLT-NEXT: Hash: 0x7C96CB76 -: BOLT-NEXT: String: {{.+}} "fint" -: BOLT-NEXT: Entry @ {{.+}} { -: BOLT-NEXT: Abbrev: [[ABBREV3]] -: BOLT-NEXT: Tag: DW_TAG_variable -: BOLT-NEXT: DW_IDX_compile_unit: 0x01 -: BOLT-NEXT: DW_IDX_die_offset: 0x0000001a -: BOLT-NEXT: } -: BOLT-NEXT: } -: BOLT-NEXT: Name 6 { -: BOLT-NEXT: Hash: 0x7C9A7F6A -: BOLT-NEXT: String: {{.+}} "main" -: BOLT-NEXT: Entry @ {{.+}} { -: BOLT-NEXT: Abbrev: [[ABBREV4]] -: BOLT-NEXT: Tag: DW_TAG_subprogram -: BOLT-NEXT: DW_IDX_compile_unit: 0x00 -: BOLT-NEXT: DW_IDX_die_offset: 0x0000001a -: BOLT-NEXT: } -: BOLT-NEXT: } -: BOLT-NEXT: ] -: BOLT-NEXT: Bucket 4 [ -: BOLT-NEXT: EMPTY -: BOLT-NEXT: ] -: BOLT-NEXT: Bucket 5 [ -: BOLT-NEXT: Name 7 { -: BOLT-NEXT: Hash: 0x7C952063 -: BOLT-NEXT: String: {{.+}} "char" -: BOLT-NEXT: Entry @ {{.+}} { -: BOLT-NEXT: Abbrev: [[ABBREV2]] -: BOLT-NEXT: Tag: DW_TAG_base_type -: BOLT-NEXT: DW_IDX_compile_unit: 0x00 -: BOLT-NEXT: DW_IDX_die_offset: 0x00000064 -: BOLT-NEXT: } -: BOLT-NEXT: } -: BOLT-NEXT: ] -: BOLT-NEXT: Bucket 6 [ -: BOLT-NEXT: EMPTY -: BOLT-NEXT: ] -: BOLT-NEXT: } +; BOLT: Name Index @ 0x0 { +; BOLT-NEXT: Header { +; BOLT-NEXT: Length: 0xFC +; BOLT-NEXT: Format: DWARF32 +; BOLT-NEXT: Version: 5 +; BOLT-NEXT: CU count: 2 +; BOLT-NEXT: Local TU count: 0 +; BOLT-NEXT: Foreign TU count: 0 +; BOLT-NEXT: Bucket count: 7 +; BOLT-NEXT: Name count: 7 +; BOLT-NEXT: Abbreviations table size: 0x29 +; BOLT-NEXT: Augmentation: 'BOLT' +; BOLT-NEXT: } +; BOLT-NEXT: Compilation Unit offsets [ +; BOLT-NEXT: CU[0]: [[OFFSET]] +; BOLT-NEXT: CU[1]: [[OFFSET1]] +; BOLT-NEXT: ] +; BOLT-NEXT: Abbreviations [ +; BOLT-NEXT: Abbreviation [[ABBREV1:0x[0-9a-f]*]] { +; BOLT-NEXT: Tag: DW_TAG_structure_type +; BOLT-NEXT: DW_IDX_compile_unit: DW_FORM_data1 +; BOLT-NEXT: DW_IDX_die_offset: DW_FORM_ref4 +; BOLT-NEXT: DW_IDX_parent: DW_FORM_flag_present +; BOLT-NEXT: } +; BOLT-NEXT: Abbreviation [[ABBREV2:0x[0-9a-f]*]] { +; BOLT-NEXT: Tag: DW_TAG_base_type +; BOLT-NEXT: DW_IDX_compile_unit: DW_FORM_data1 +; BOLT-NEXT: DW_IDX_die_offset: DW_FORM_ref4 +; BOLT-NEXT: DW_IDX_parent: DW_FORM_flag_present +; BOLT-NEXT: } +; BOLT-NEXT: Abbreviation [[ABBREV3:0x[0-9a-f]*]] { +; BOLT-NEXT: Tag: DW_TAG_variable +; BOLT-NEXT: DW_IDX_compile_unit: DW_FORM_data1 +; BOLT-NEXT: DW_IDX_die_offset: DW_FORM_ref4 +; BOLT-NEXT: DW_IDX_parent: DW_FORM_flag_present +; BOLT-NEXT: } +; BOLT-NEXT: Abbreviation [[ABBREV4:0x[0-9a-f]*]] { +; BOLT-NEXT: Tag: DW_TAG_subprogram +; BOLT-NEXT: DW_IDX_compile_unit: DW_FORM_data1 +; BOLT-NEXT: DW_IDX_die_offset: DW_FORM_ref4 +; BOLT-NEXT: DW_IDX_parent: DW_FORM_flag_present +; BOLT-NEXT: } +; BOLT-NEXT: ] +; BOLT-NEXT: Bucket 0 [ +; BOLT-NEXT: EMPTY +; BOLT-NEXT: ] +; BOLT-NEXT: Bucket 1 [ +; BOLT-NEXT: Name 1 { +; BOLT-NEXT: Hash: 0x7C96E4DB +; BOLT-NEXT: String: {{.+}} "Foo2" +; BOLT-NEXT: Entry @ {{.+}} { +; BOLT-NEXT: Abbrev: [[ABBREV1]] +; BOLT-NEXT: Tag: DW_TAG_structure_type +; BOLT-NEXT: DW_IDX_compile_unit: 0x00 +; BOLT-NEXT: DW_IDX_die_offset: 0x00000068 +; BOLT-NEXT: DW_IDX_parent: +; BOLT-NEXT: } +; BOLT-NEXT: } +; BOLT-NEXT: ] +; BOLT-NEXT: Bucket 2 [ +; BOLT-NEXT: Name 2 { +; BOLT-NEXT: Hash: 0xBA564846 +; BOLT-NEXT: String: {{.+}} "Foo2Int" +; BOLT-NEXT: Entry @ {{.+}} { +; BOLT-NEXT: Abbrev: [[ABBREV1]] +; BOLT-NEXT: Tag: DW_TAG_structure_type +; BOLT-NEXT: DW_IDX_compile_unit: 0x01 +; BOLT-NEXT: DW_IDX_die_offset: 0x00000025 +; BOLT-NEXT: DW_IDX_parent: +; BOLT-NEXT: } +; BOLT-NEXT: } +; BOLT-NEXT: ] +; BOLT-NEXT: Bucket 3 [ +; BOLT-NEXT: Name 3 { +; BOLT-NEXT: Hash: 0xB888030 +; BOLT-NEXT: String: {{.+}} "int" +; BOLT-NEXT: Entry @ {{.+}} { +; BOLT-NEXT: Abbrev: [[ABBREV2]] +; BOLT-NEXT: Tag: DW_TAG_base_type +; BOLT-NEXT: DW_IDX_compile_unit: 0x01 +; BOLT-NEXT: DW_IDX_die_offset: 0x00000043 +; BOLT-NEXT: DW_IDX_parent: +; BOLT-NEXT: } +; BOLT-NEXT: Entry @ {{.+}} { +; BOLT-NEXT: Abbrev: [[ABBREV2]] +; BOLT-NEXT: Tag: DW_TAG_base_type +; BOLT-NEXT: DW_IDX_compile_unit: 0x00 +; BOLT-NEXT: DW_IDX_die_offset: 0x00000056 +; BOLT-NEXT: DW_IDX_parent: +; BOLT-NEXT: } +; BOLT-NEXT: } +; BOLT-NEXT: Name 4 { +; BOLT-NEXT: Hash: 0xF73809C +; BOLT-NEXT: String: {{.+}} "Foo2a" +; BOLT-NEXT: Entry @ {{.+}} { +; BOLT-NEXT: Abbrev: [[ABBREV1]] +; BOLT-NEXT: Tag: DW_TAG_structure_type +; BOLT-NEXT: DW_IDX_compile_unit: 0x00 +; BOLT-NEXT: DW_IDX_die_offset: 0x00000078 +; BOLT-NEXT: DW_IDX_parent: +; BOLT-NEXT: } +; BOLT-NEXT: } +; BOLT-NEXT: Name 5 { +; BOLT-NEXT: Hash: 0x7C96CB76 +; BOLT-NEXT: String: {{.+}} "fint" +; BOLT-NEXT: Entry @ {{.+}} { +; BOLT-NEXT: Abbrev: [[ABBREV3]] +; BOLT-NEXT: Tag: DW_TAG_variable +; BOLT-NEXT: DW_IDX_compile_unit: 0x01 +; BOLT-NEXT: DW_IDX_die_offset: 0x0000001a +; BOLT-NEXT: DW_IDX_parent: +; BOLT-NEXT: } +; BOLT-NEXT: } +; BOLT-NEXT: Name 6 { +; BOLT-NEXT: Hash: 0x7C9A7F6A +; BOLT-NEXT: String: {{.+}} "main" +; BOLT-NEXT: Entry @ {{.+}} { +; BOLT-NEXT: Abbrev: [[ABBREV4]] +; BOLT-NEXT: Tag: DW_TAG_subprogram +; BOLT-NEXT: DW_IDX_compile_unit: 0x00 +; BOLT-NEXT: DW_IDX_die_offset: 0x0000001a +; BOLT-NEXT: DW_IDX_parent: +; BOLT-NEXT: } +; BOLT-NEXT: } +; BOLT-NEXT: ] +; BOLT-NEXT: Bucket 4 [ +; BOLT-NEXT: EMPTY +; BOLT-NEXT: ] +; BOLT-NEXT: Bucket 5 [ +; BOLT-NEXT: Name 7 { +; BOLT-NEXT: Hash: 0x7C952063 +; BOLT-NEXT: String: {{.+}} "char" +; BOLT-NEXT: Entry @ {{.+}} { +; BOLT-NEXT: Abbrev: [[ABBREV2]] +; BOLT-NEXT: Tag: DW_TAG_base_type +; BOLT-NEXT: DW_IDX_compile_unit: 0x00 +; BOLT-NEXT: DW_IDX_die_offset: 0x00000064 +; BOLT-NEXT: DW_IDX_parent: +; BOLT-NEXT: } +; BOLT-NEXT: } +; BOLT-NEXT: ] +; BOLT-NEXT: Bucket 6 [ +; BOLT-NEXT: EMPTY +; BOLT-NEXT: ] +; BOLT-NEXT: } diff --git a/bolt/test/X86/dwarf5-df-main-debug-names-ftu-ltu-mix.test b/bolt/test/X86/dwarf5-df-main-debug-names-ftu-ltu-mix.test new file mode 100644 index 0000000000000000000000000000000000000000..3a0260fd0bfb91707a0e56f3451f492d688f8a44 --- /dev/null +++ b/bolt/test/X86/dwarf5-df-main-debug-names-ftu-ltu-mix.test @@ -0,0 +1,59 @@ +; RUN: rm -rf %t +; RUN: mkdir %t +; RUN: cd %t +; RUN: llvm-mc -dwarf-version=5 -filetype=obj -triple x86_64-unknown-linux %p/Inputs/dwarf5-df-debug-names-ftu-ltu-mix-main.s \ +; RUN: -split-dwarf-file=main.dwo -o main.o +; RUN: llvm-mc -dwarf-version=5 -filetype=obj -triple x86_64-unknown-linux %p/Inputs/dwarf5-debug-names-ftu-ltu-mix-helper.s -o helper.o +; RUN: llvm-mc -dwarf-version=5 -filetype=obj -triple x86_64-unknown-linux %p/Inputs/dwarf5-debug-names-ftu-ltu-mix-helper1.s -o helper1.o +; RUN: %clang %cflags -gdwarf-5 -gsplit-dwarf=split main.o helper.o helper1.o -o main.exe -fno-pic -no-pie +; RUN: llvm-bolt main.exe -o main.exe.bolt --update-debug-sections --create-debug-names-section=true +; RUN: llvm-dwarfdump --debug-names main.exe.bolt | FileCheck -check-prefix=BOLT %s + +;; Tests BOLT correctly sets foreign TU Index when there are local TUs. + +; BOLT: Compilation Unit offsets [ +; BOLT-NEXT: CU[0]: {{.+}} +; BOLT-NEXT: CU[1]: {{.+}} +; BOLT-NEXT: CU[2]: {{.+}} +; BOLT-NEXT: ] +; BOLT-NEXT: Local Type Unit offsets [ +; BOLT-NEXT: LocalTU[0]: {{.+}} +; BOLT-NEXT: LocalTU[1]: {{.+}} +; BOLT-NEXT: ] +; BOLT-NEXT: Foreign Type Unit signatures [ +; BOLT-NEXT: ForeignTU[0]: 0x889c84450dac881f +; BOLT-NEXT: ] +; BOLT: Name 3 { +; BOLT-NEXT: Hash: 0x6A05C500 +; BOLT-NEXT: String: {{.+}} "globalMono1" +; BOLT-NEXT: Entry @ {{.+}} { +; BOLT-NEXT: Abbrev: 0x5 +; BOLT-NEXT: Tag: DW_TAG_variable +; BOLT-NEXT: DW_IDX_compile_unit: 0x02 +; BOLT-NEXT: DW_IDX_die_offset: 0x0000001e +; BOLT-NEXT: DW_IDX_parent: +; BOLT-NEXT: } +; BOLT-NEXT: } +; BOLT: Name 6 { +; BOLT-NEXT: Hash: 0xF283AF92 +; BOLT-NEXT: String: {{.+}} "ASplit" +; BOLT-NEXT: Entry @ {{.+}} { +; BOLT-NEXT: Abbrev: 0x7 +; BOLT-NEXT: Tag: DW_TAG_structure_type +; BOLT-NEXT: DW_IDX_type_unit: 0x02 +; BOLT-NEXT: DW_IDX_compile_unit: 0x00 +; BOLT-NEXT: DW_IDX_die_offset: 0x00000021 +; BOLT-NEXT: DW_IDX_parent: +; BOLT-NEXT: } +; BOLT-NEXT: } +; BOLT: Name 7 { +; BOLT-NEXT: Hash: 0xF17F51F +; BOLT-NEXT: String: {{.+}} "AMono" +; BOLT-NEXT: Entry @ {{.+}} { +; BOLT-NEXT: Abbrev: 0x4 +; BOLT-NEXT: Tag: DW_TAG_structure_type +; BOLT-NEXT: DW_IDX_type_unit: 0x00 +; BOLT-NEXT: DW_IDX_die_offset: 0x00000023 +; BOLT-NEXT: DW_IDX_parent: +; BOLT-NEXT: } +; BOLT-NEXT: } diff --git a/bolt/test/X86/dwarf5-df-one-cu-debug-names.test b/bolt/test/X86/dwarf5-df-one-cu-debug-names.test index 246ce7efb3bad66eec5c8aed14893e40114aed88..bf1cad81040bd93b204d221482b4377def89aaa3 100644 --- a/bolt/test/X86/dwarf5-df-one-cu-debug-names.test +++ b/bolt/test/X86/dwarf5-df-one-cu-debug-names.test @@ -13,7 +13,7 @@ ; BOLT: [[OFFSET:0x[0-9a-f]*]]: Compile Unit ; BOLT: Name Index @ 0x0 { ; BOLT-NEXT: Header { -; BOLT-NEXT: Length: 0xA9 +; BOLT-NEXT: Length: 0xAF ; BOLT-NEXT: Format: DWARF32 ; BOLT-NEXT: Version: 5 ; BOLT-NEXT: CU count: 1 @@ -21,7 +21,7 @@ ; BOLT-NEXT: Foreign TU count: 0 ; BOLT-NEXT: Bucket count: 5 ; BOLT-NEXT: Name count: 5 -; BOLT-NEXT: Abbreviations table size: 0x13 +; BOLT-NEXT: Abbreviations table size: 0x19 ; BOLT-NEXT: Augmentation: 'BOLT' ; BOLT-NEXT: } ; BOLT-NEXT: Compilation Unit offsets [ @@ -31,14 +31,17 @@ ; BOLT-NEXT: Abbreviation [[ABBREV1:0x[0-9a-f]*]] { ; BOLT-NEXT: Tag: DW_TAG_structure_type ; BOLT-NEXT: DW_IDX_die_offset: DW_FORM_ref4 +; BOLT-NEXT: DW_IDX_parent: DW_FORM_flag_present ; BOLT-NEXT: } ; BOLT-NEXT: Abbreviation [[ABBREV2:0x[0-9a-f]*]] { ; BOLT-NEXT: Tag: DW_TAG_subprogram ; BOLT-NEXT: DW_IDX_die_offset: DW_FORM_ref4 +; BOLT-NEXT: DW_IDX_parent: DW_FORM_flag_present ; BOLT-NEXT: } ; BOLT-NEXT: Abbreviation [[ABBREV3:0x[0-9a-f]*]] { ; BOLT-NEXT: Tag: DW_TAG_base_type ; BOLT-NEXT: DW_IDX_die_offset: DW_FORM_ref4 +; BOLT-NEXT: DW_IDX_parent: DW_FORM_flag_present ; BOLT-NEXT: } ; BOLT-NEXT: ] ; BOLT-NEXT: Bucket 0 [ @@ -52,6 +55,7 @@ ; BOLT-NEXT: Abbrev: [[ABBREV1]] ; BOLT-NEXT: Tag: DW_TAG_structure_type ; BOLT-NEXT: DW_IDX_die_offset: 0x00000068 +; BOLT-NEXT: DW_IDX_parent: ; BOLT-NEXT: } ; BOLT-NEXT: } ; BOLT-NEXT: Name 2 { @@ -61,6 +65,7 @@ ; BOLT-NEXT: Abbrev: [[ABBREV2]] ; BOLT-NEXT: Tag: DW_TAG_subprogram ; BOLT-NEXT: DW_IDX_die_offset: 0x0000001a +; BOLT-NEXT: DW_IDX_parent: ; BOLT-NEXT: } ; BOLT-NEXT: } ; BOLT-NEXT: ] @@ -75,6 +80,7 @@ ; BOLT-NEXT: Abbrev: [[ABBREV3]] ; BOLT-NEXT: Tag: DW_TAG_base_type ; BOLT-NEXT: DW_IDX_die_offset: 0x00000056 +; BOLT-NEXT: DW_IDX_parent: ; BOLT-NEXT: } ; BOLT-NEXT: } ; BOLT-NEXT: ] @@ -86,6 +92,7 @@ ; BOLT-NEXT: Abbrev: [[ABBREV1]] ; BOLT-NEXT: Tag: DW_TAG_structure_type ; BOLT-NEXT: DW_IDX_die_offset: 0x00000078 +; BOLT-NEXT: DW_IDX_parent: ; BOLT-NEXT: } ; BOLT-NEXT: } ; BOLT-NEXT: Name 5 { @@ -95,6 +102,7 @@ ; BOLT-NEXT: Abbrev: [[ABBREV3]] ; BOLT-NEXT: Tag: DW_TAG_base_type ; BOLT-NEXT: DW_IDX_die_offset: 0x00000064 +; BOLT-NEXT: DW_IDX_parent: ; BOLT-NEXT: } ; BOLT-NEXT: } ; BOLT-NEXT: ] diff --git a/bolt/test/X86/dwarf5-df-types-debug-names.test b/bolt/test/X86/dwarf5-df-types-debug-names.test index fdb962b80c75122bd1948de5da12610ab43b2c82..f5a2c9c10353e9a98e41f5d6701545a29ffeaba8 100644 --- a/bolt/test/X86/dwarf5-df-types-debug-names.test +++ b/bolt/test/X86/dwarf5-df-types-debug-names.test @@ -25,7 +25,7 @@ ; BOLT: Name Index @ 0x0 { ; BOLT-NEXT: Header { -; BOLT-NEXT: Length: 0x174 +; BOLT-NEXT: Length: 0x17E ; BOLT-NEXT: Format: DWARF32 ; BOLT-NEXT: Version: 5 ; BOLT-NEXT: CU count: 2 @@ -33,7 +33,7 @@ ; BOLT-NEXT: Foreign TU count: 4 ; BOLT-NEXT: Bucket count: 9 ; BOLT-NEXT: Name count: 9 -; BOLT-NEXT: Abbreviations table size: 0x2D +; BOLT-NEXT: Abbreviations table size: 0x37 ; BOLT-NEXT: Augmentation: 'BOLT' ; BOLT-NEXT: } ; BOLT-NEXT: Compilation Unit offsets [ @@ -52,27 +52,32 @@ ; BOLT-NEXT: DW_IDX_type_unit: DW_FORM_data1 ; BOLT-NEXT: DW_IDX_compile_unit: DW_FORM_data1 ; BOLT-NEXT: DW_IDX_die_offset: DW_FORM_ref4 +; BOLT-NEXT: DW_IDX_parent: DW_FORM_flag_present ; BOLT-NEXT: } ; BOLT-NEXT: Abbreviation [[ABBREV1:0x[0-9a-f]*]] { ; BOLT-NEXT: Tag: DW_TAG_subprogram ; BOLT-NEXT: DW_IDX_compile_unit: DW_FORM_data1 ; BOLT-NEXT: DW_IDX_die_offset: DW_FORM_ref4 +; BOLT-NEXT: DW_IDX_parent: DW_FORM_flag_present ; BOLT-NEXT: } ; BOLT-NEXT: Abbreviation [[ABBREV2:0x[0-9a-f]*]] { ; BOLT-NEXT: Tag: DW_TAG_variable ; BOLT-NEXT: DW_IDX_compile_unit: DW_FORM_data1 ; BOLT-NEXT: DW_IDX_die_offset: DW_FORM_ref4 +; BOLT-NEXT: DW_IDX_parent: DW_FORM_flag_present ; BOLT-NEXT: } ; BOLT-NEXT: Abbreviation [[ABBREV3:0x[0-9a-f]*]] { ; BOLT-NEXT: Tag: DW_TAG_base_type ; BOLT-NEXT: DW_IDX_compile_unit: DW_FORM_data1 ; BOLT-NEXT: DW_IDX_die_offset: DW_FORM_ref4 +; BOLT-NEXT: DW_IDX_parent: DW_FORM_flag_present ; BOLT-NEXT: } ; BOLT-NEXT: Abbreviation [[ABBREV4:0x[0-9a-f]*]] { ; BOLT-NEXT: Tag: DW_TAG_base_type ; BOLT-NEXT: DW_IDX_type_unit: DW_FORM_data1 ; BOLT-NEXT: DW_IDX_compile_unit: DW_FORM_data1 ; BOLT-NEXT: DW_IDX_die_offset: DW_FORM_ref4 +; BOLT-NEXT: DW_IDX_parent: DW_FORM_flag_present ; BOLT-NEXT: } ; BOLT-NEXT: ] ; BOLT-NEXT: Bucket 0 [ @@ -88,6 +93,7 @@ ; BOLT-NEXT: DW_IDX_type_unit: 0x00 ; BOLT-NEXT: DW_IDX_compile_unit: 0x00 ; BOLT-NEXT: DW_IDX_die_offset: 0x00000021 +; BOLT-NEXT: DW_IDX_parent: ; BOLT-NEXT: } ; BOLT-NEXT: } ; BOLT-NEXT: Name 2 { @@ -98,6 +104,7 @@ ; BOLT-NEXT: Tag: DW_TAG_subprogram ; BOLT-NEXT: DW_IDX_compile_unit: 0x01 ; BOLT-NEXT: DW_IDX_die_offset: 0x00000029 +; BOLT-NEXT: DW_IDX_parent: ; BOLT-NEXT: } ; BOLT-NEXT: } ; BOLT-NEXT: Name 3 { @@ -108,6 +115,7 @@ ; BOLT-NEXT: Tag: DW_TAG_variable ; BOLT-NEXT: DW_IDX_compile_unit: 0x01 ; BOLT-NEXT: DW_IDX_die_offset: 0x0000001a +; BOLT-NEXT: DW_IDX_parent: ; BOLT-NEXT: } ; BOLT-NEXT: } ; BOLT-NEXT: ] @@ -120,6 +128,7 @@ ; BOLT-NEXT: Tag: DW_TAG_base_type ; BOLT-NEXT: DW_IDX_compile_unit: 0x01 ; BOLT-NEXT: DW_IDX_die_offset: 0x00000025 +; BOLT-NEXT: DW_IDX_parent: ; BOLT-NEXT: } ; BOLT-NEXT: Entry @ {{.+}} { ; BOLT-NEXT: Abbrev: 0x5 @@ -127,12 +136,14 @@ ; BOLT-NEXT: DW_IDX_type_unit: 0x02 ; BOLT-NEXT: DW_IDX_compile_unit: 0x01 ; BOLT-NEXT: DW_IDX_die_offset: 0x0000003f +; BOLT-NEXT: DW_IDX_parent: ; BOLT-NEXT: } ; BOLT-NEXT: Entry @ {{.+}} { ; BOLT-NEXT: Abbrev: [[ABBREV3]] ; BOLT-NEXT: Tag: DW_TAG_base_type ; BOLT-NEXT: DW_IDX_compile_unit: 0x00 ; BOLT-NEXT: DW_IDX_die_offset: 0x00000056 +; BOLT-NEXT: DW_IDX_parent: ; BOLT-NEXT: } ; BOLT-NEXT: } ; BOLT-NEXT: ] @@ -145,6 +156,7 @@ ; BOLT-NEXT: Tag: DW_TAG_subprogram ; BOLT-NEXT: DW_IDX_compile_unit: 0x01 ; BOLT-NEXT: DW_IDX_die_offset: 0x00000029 +; BOLT-NEXT: DW_IDX_parent: ; BOLT-NEXT: } ; BOLT-NEXT: } ; BOLT-NEXT: Name 6 { @@ -156,6 +168,7 @@ ; BOLT-NEXT: DW_IDX_type_unit: 0x01 ; BOLT-NEXT: DW_IDX_compile_unit: 0x00 ; BOLT-NEXT: DW_IDX_die_offset: 0x00000021 +; BOLT-NEXT: DW_IDX_parent: ; BOLT-NEXT: } ; BOLT-NEXT: Entry @ {{.+}} { ; BOLT-NEXT: Abbrev: [[ABBREV]] @@ -163,6 +176,7 @@ ; BOLT-NEXT: DW_IDX_type_unit: 0x03 ; BOLT-NEXT: DW_IDX_compile_unit: 0x01 ; BOLT-NEXT: DW_IDX_die_offset: 0x00000021 +; BOLT-NEXT: DW_IDX_parent: ; BOLT-NEXT: } ; BOLT-NEXT: } ; BOLT-NEXT: Name 7 { @@ -174,6 +188,7 @@ ; BOLT-NEXT: DW_IDX_type_unit: 0x02 ; BOLT-NEXT: DW_IDX_compile_unit: 0x01 ; BOLT-NEXT: DW_IDX_die_offset: 0x00000021 +; BOLT-NEXT: DW_IDX_parent: ; BOLT-NEXT: } ; BOLT-NEXT: } ; BOLT-NEXT: ] @@ -195,6 +210,7 @@ ; BOLT-NEXT: Tag: DW_TAG_subprogram ; BOLT-NEXT: DW_IDX_compile_unit: 0x00 ; BOLT-NEXT: DW_IDX_die_offset: 0x0000001a +; BOLT-NEXT: DW_IDX_parent: ; BOLT-NEXT: } ; BOLT-NEXT: } ; BOLT-NEXT: ] @@ -208,6 +224,7 @@ ; BOLT-NEXT: DW_IDX_type_unit: 0x00 ; BOLT-NEXT: DW_IDX_compile_unit: 0x00 ; BOLT-NEXT: DW_IDX_die_offset: 0x00000036 +; BOLT-NEXT: DW_IDX_parent: ; BOLT-NEXT: } ; BOLT-NEXT: Entry @ {{.+}} { ; BOLT-NEXT: Abbrev: 0x5 @@ -215,6 +232,7 @@ ; BOLT-NEXT: DW_IDX_type_unit: 0x01 ; BOLT-NEXT: DW_IDX_compile_unit: 0x00 ; BOLT-NEXT: DW_IDX_die_offset: 0x00000048 +; BOLT-NEXT: DW_IDX_parent: ; BOLT-NEXT: } ; BOLT-NEXT: Entry @ {{.+}} { ; BOLT-NEXT: Abbrev: 0x5 @@ -222,12 +240,14 @@ ; BOLT-NEXT: DW_IDX_type_unit: 0x03 ; BOLT-NEXT: DW_IDX_compile_unit: 0x01 ; BOLT-NEXT: DW_IDX_die_offset: 0x00000048 +; BOLT-NEXT: DW_IDX_parent: ; BOLT-NEXT: } ; BOLT-NEXT: Entry @ {{.+}} { ; BOLT-NEXT: Abbrev: [[ABBREV3]] ; BOLT-NEXT: Tag: DW_TAG_base_type ; BOLT-NEXT: DW_IDX_compile_unit: 0x00 ; BOLT-NEXT: DW_IDX_die_offset: 0x00000064 +; BOLT-NEXT: DW_IDX_parent: ; BOLT-NEXT: } ; BOLT-NEXT: } ; BOLT-NEXT: ] diff --git a/bolt/test/X86/dwarf5-df-types-one-cu-debug-names.test b/bolt/test/X86/dwarf5-df-types-one-cu-debug-names.test index 1c77583f50883f5e26a1a9019c6f32f341a8e4c6..2a489d86f5d7def0a5ea8e1cbbec48c15955213b 100644 --- a/bolt/test/X86/dwarf5-df-types-one-cu-debug-names.test +++ b/bolt/test/X86/dwarf5-df-types-one-cu-debug-names.test @@ -17,7 +17,7 @@ ; BOLT: [[OFFSET:0x[0-9a-f]*]]: Compile Unit ; BOLT: Name Index @ 0x0 { ; BOLT-NEXT: Header { -; BOLT-NEXT: Length: 0xD1 +; BOLT-NEXT: Length: 0xD9 ; BOLT-NEXT: Format: DWARF32 ; BOLT-NEXT: Version: 5 ; BOLT-NEXT: CU count: 1 @@ -25,7 +25,7 @@ ; BOLT-NEXT: Foreign TU count: 2 ; BOLT-NEXT: Bucket count: 5 ; BOLT-NEXT: Name count: 5 -; BOLT-NEXT: Abbreviations table size: 0x1D +; BOLT-NEXT: Abbreviations table size: 0x25 ; BOLT-NEXT: Augmentation: 'BOLT' ; BOLT-NEXT: } ; BOLT-NEXT: Compilation Unit offsets [ @@ -40,19 +40,23 @@ ; BOLT-NEXT: Tag: DW_TAG_structure_type ; BOLT-NEXT: DW_IDX_type_unit: DW_FORM_data1 ; BOLT-NEXT: DW_IDX_die_offset: DW_FORM_ref4 +; BOLT-NEXT: DW_IDX_parent: DW_FORM_flag_present ; BOLT-NEXT: } ; BOLT-NEXT: Abbreviation [[ABBREV2:0x[0-9a-f]*]] { ; BOLT-NEXT: Tag: DW_TAG_subprogram ; BOLT-NEXT: DW_IDX_die_offset: DW_FORM_ref4 +; BOLT-NEXT: DW_IDX_parent: DW_FORM_flag_present ; BOLT-NEXT: } ; BOLT-NEXT: Abbreviation [[ABBREV3:0x[0-9a-f]*]] { ; BOLT-NEXT: Tag: DW_TAG_base_type ; BOLT-NEXT: DW_IDX_die_offset: DW_FORM_ref4 +; BOLT-NEXT: DW_IDX_parent: DW_FORM_flag_present ; BOLT-NEXT: } ; BOLT-NEXT: Abbreviation [[ABBREV4:0x[0-9a-f]*]] { ; BOLT-NEXT: Tag: DW_TAG_base_type ; BOLT-NEXT: DW_IDX_type_unit: DW_FORM_data1 ; BOLT-NEXT: DW_IDX_die_offset: DW_FORM_ref4 +; BOLT-NEXT: DW_IDX_parent: DW_FORM_flag_present ; BOLT-NEXT: } ; BOLT-NEXT: ] ; BOLT-NEXT: Bucket 0 [ @@ -67,6 +71,7 @@ ; BOLT-NEXT: Tag: DW_TAG_structure_type ; BOLT-NEXT: DW_IDX_type_unit: 0x00 ; BOLT-NEXT: DW_IDX_die_offset: 0x00000021 +; BOLT-NEXT: DW_IDX_parent: ; BOLT-NEXT: } ; BOLT-NEXT: } ; BOLT-NEXT: Name 2 { @@ -76,6 +81,7 @@ ; BOLT-NEXT: Abbrev: [[ABBREV2]] ; BOLT-NEXT: Tag: DW_TAG_subprogram ; BOLT-NEXT: DW_IDX_die_offset: 0x0000001a +; BOLT-NEXT: DW_IDX_parent: ; BOLT-NEXT: } ; BOLT-NEXT: } ; BOLT-NEXT: ] @@ -90,6 +96,7 @@ ; BOLT-NEXT: Abbrev: [[ABBREV3]] ; BOLT-NEXT: Tag: DW_TAG_base_type ; BOLT-NEXT: DW_IDX_die_offset: 0x00000056 +; BOLT-NEXT: DW_IDX_parent: ; BOLT-NEXT: } ; BOLT-NEXT: } ; BOLT-NEXT: ] @@ -102,6 +109,7 @@ ; BOLT-NEXT: Tag: DW_TAG_structure_type ; BOLT-NEXT: DW_IDX_type_unit: 0x01 ; BOLT-NEXT: DW_IDX_die_offset: 0x00000021 +; BOLT-NEXT: DW_IDX_parent: ; BOLT-NEXT: } ; BOLT-NEXT: } ; BOLT-NEXT: Name 5 { @@ -112,17 +120,20 @@ ; BOLT-NEXT: Tag: DW_TAG_base_type ; BOLT-NEXT: DW_IDX_type_unit: 0x00 ; BOLT-NEXT: DW_IDX_die_offset: 0x00000036 +; BOLT-NEXT: DW_IDX_parent: ; BOLT-NEXT: } ; BOLT-NEXT: Entry @ {{.+}} { ; BOLT-NEXT: Abbrev: [[ABBREV4]] ; BOLT-NEXT: Tag: DW_TAG_base_type ; BOLT-NEXT: DW_IDX_type_unit: 0x01 ; BOLT-NEXT: DW_IDX_die_offset: 0x00000048 +; BOLT-NEXT: DW_IDX_parent: ; BOLT-NEXT: } ; BOLT-NEXT: Entry @ {{.+}} { ; BOLT-NEXT: Abbrev: [[ABBREV3]] ; BOLT-NEXT: Tag: DW_TAG_base_type ; BOLT-NEXT: DW_IDX_die_offset: 0x00000064 +; BOLT-NEXT: DW_IDX_parent: ; BOLT-NEXT: } ; BOLT-NEXT: } ; BOLT-NEXT: ] diff --git a/bolt/test/X86/dwarf5-one-cu-debug-names.test b/bolt/test/X86/dwarf5-one-cu-debug-names.test index e7754521d61cbe8f5c919a0c0d7ea6a8106b91fa..74d6b3041c93359564e758ce629c2f7e5d4b0439 100644 --- a/bolt/test/X86/dwarf5-one-cu-debug-names.test +++ b/bolt/test/X86/dwarf5-one-cu-debug-names.test @@ -9,7 +9,7 @@ ; BOLT: [[OFFSET1:0x[0-9a-f]*]]: Compile Unit ; BOLT: Name Index @ 0x0 { ; BOLT-NEXT: Header { -; BOLT-NEXT: Length: 0x13E +; BOLT-NEXT: Length: 0x14F ; BOLT-NEXT: Format: DWARF32 ; BOLT-NEXT: Version: 5 ; BOLT-NEXT: CU count: 1 @@ -17,7 +17,7 @@ ; BOLT-NEXT: Foreign TU count: 0 ; BOLT-NEXT: Bucket count: 11 ; BOLT-NEXT: Name count: 11 -; BOLT-NEXT: Abbreviations table size: 0x1F +; BOLT-NEXT: Abbreviations table size: 0x31 ; BOLT-NEXT: Augmentation: 'BOLT' ; BOLT-NEXT: } ; BOLT-NEXT: Compilation Unit offsets [ @@ -27,22 +27,32 @@ ; BOLT-NEXT: Abbreviation [[ABBREV1:0x[0-9a-f]*]] { ; BOLT-NEXT: Tag: DW_TAG_structure_type ; BOLT-NEXT: DW_IDX_die_offset: DW_FORM_ref4 +; BOLT-NEXT: DW_IDX_parent: DW_FORM_flag_present ; BOLT-NEXT: } ; BOLT-NEXT: Abbreviation [[ABBREV2:0x[0-9a-f]*]] { ; BOLT-NEXT: Tag: DW_TAG_base_type ; BOLT-NEXT: DW_IDX_die_offset: DW_FORM_ref4 +; BOLT-NEXT: DW_IDX_parent: DW_FORM_flag_present ; BOLT-NEXT: } ; BOLT-NEXT: Abbreviation [[ABBREV3:0x[0-9a-f]*]] { +; BOLT-NEXT: Tag: DW_TAG_structure_type +; BOLT-NEXT: DW_IDX_die_offset: DW_FORM_ref4 +; BOLT-NEXT: DW_IDX_parent: DW_FORM_ref4 +; BOLT-NEXT: } +; BOLT-NEXT: Abbreviation [[ABBREV4:0x[0-9a-f]*]] { ; BOLT-NEXT: Tag: DW_TAG_variable ; BOLT-NEXT: DW_IDX_die_offset: DW_FORM_ref4 +; BOLT-NEXT: DW_IDX_parent: DW_FORM_flag_present ; BOLT-NEXT: } -; BOLT-NEXT: Abbreviation [[ABBREV4:0x[0-9a-f]*]] { +; BOLT-NEXT: Abbreviation [[ABBREV5:0x[0-9a-f]*]] { ; BOLT-NEXT: Tag: DW_TAG_subprogram ; BOLT-NEXT: DW_IDX_die_offset: DW_FORM_ref4 +; BOLT-NEXT: DW_IDX_parent: DW_FORM_flag_present ; BOLT-NEXT: } -; BOLT-NEXT: Abbreviation [[ABBREV5:0x[0-9a-f]*]] { +; BOLT-NEXT: Abbreviation [[ABBREV6:0x[0-9a-f]*]] { ; BOLT-NEXT: Tag: DW_TAG_namespace ; BOLT-NEXT: DW_IDX_die_offset: DW_FORM_ref4 +; BOLT-NEXT: DW_IDX_parent: DW_FORM_flag_present ; BOLT-NEXT: } ; BOLT-NEXT: ] ; BOLT-NEXT: Bucket 0 [ @@ -53,6 +63,7 @@ ; BOLT-NEXT: Abbrev: [[ABBREV1]] ; BOLT-NEXT: Tag: DW_TAG_structure_type ; BOLT-NEXT: DW_IDX_die_offset: 0x00000104 +; BOLT-NEXT: DW_IDX_parent: ; BOLT-NEXT: } ; BOLT-NEXT: } ; BOLT-NEXT: Name 2 { @@ -62,6 +73,7 @@ ; BOLT-NEXT: Abbrev: [[ABBREV2]] ; BOLT-NEXT: Tag: DW_TAG_base_type ; BOLT-NEXT: DW_IDX_die_offset: 0x000000c5 +; BOLT-NEXT: DW_IDX_parent: ; BOLT-NEXT: } ; BOLT-NEXT: } ; BOLT-NEXT: ] @@ -73,6 +85,7 @@ ; BOLT-NEXT: Abbrev: [[ABBREV1]] ; BOLT-NEXT: Tag: DW_TAG_structure_type ; BOLT-NEXT: DW_IDX_die_offset: 0x000000c9 +; BOLT-NEXT: DW_IDX_parent: ; BOLT-NEXT: } ; BOLT-NEXT: } ; BOLT-NEXT: Name 4 { @@ -82,6 +95,7 @@ ; BOLT-NEXT: Abbrev: [[ABBREV1]] ; BOLT-NEXT: Tag: DW_TAG_structure_type ; BOLT-NEXT: DW_IDX_die_offset: 0x0000003f +; BOLT-NEXT: DW_IDX_parent: ; BOLT-NEXT: } ; BOLT-NEXT: } ; BOLT-NEXT: ] @@ -93,6 +107,7 @@ ; BOLT-NEXT: Abbrev: [[ABBREV1]] ; BOLT-NEXT: Tag: DW_TAG_structure_type ; BOLT-NEXT: DW_IDX_die_offset: 0x000000eb +; BOLT-NEXT: DW_IDX_parent: ; BOLT-NEXT: } ; BOLT-NEXT: } ; BOLT-NEXT: ] @@ -107,18 +122,20 @@ ; BOLT-NEXT: Hash: 0x59796A ; BOLT-NEXT: String: {{.+}} "t1" ; BOLT-NEXT: Entry @ {{.+}} { -; BOLT-NEXT: Abbrev: [[ABBREV1]] +; BOLT-NEXT: Abbrev: [[ABBREV3]] ; BOLT-NEXT: Tag: DW_TAG_structure_type ; BOLT-NEXT: DW_IDX_die_offset: 0x00000062 +; BOLT-NEXT: DW_IDX_parent: Entry @ 0x14d ; BOLT-NEXT: } ; BOLT-NEXT: } ; BOLT-NEXT: Name 7 { ; BOLT-NEXT: Hash: 0x5979AC ; BOLT-NEXT: String: {{.+}} "v1" ; BOLT-NEXT: Entry @ {{.+}} { -; BOLT-NEXT: Abbrev: [[ABBREV3]] +; BOLT-NEXT: Abbrev: [[ABBREV4]] ; BOLT-NEXT: Tag: DW_TAG_variable ; BOLT-NEXT: DW_IDX_die_offset: 0x00000024 +; BOLT-NEXT: DW_IDX_parent: ; BOLT-NEXT: } ; BOLT-NEXT: } ; BOLT-NEXT: ] @@ -130,6 +147,7 @@ ; BOLT-NEXT: Abbrev: [[ABBREV2]] ; BOLT-NEXT: Tag: DW_TAG_base_type ; BOLT-NEXT: DW_IDX_die_offset: 0x0000005d +; BOLT-NEXT: DW_IDX_parent: ; BOLT-NEXT: } ; BOLT-NEXT: } ; BOLT-NEXT: ] @@ -141,15 +159,17 @@ ; BOLT-NEXT: Abbrev: [[ABBREV1]] ; BOLT-NEXT: Tag: DW_TAG_structure_type ; BOLT-NEXT: DW_IDX_die_offset: 0x0000002f +; BOLT-NEXT: DW_IDX_parent: ; BOLT-NEXT: } ; BOLT-NEXT: } ; BOLT-NEXT: Name 10 { ; BOLT-NEXT: Hash: 0x7C9A7F6A ; BOLT-NEXT: String: {{.+}} "main" ; BOLT-NEXT: Entry @ {{.+}} { -; BOLT-NEXT: Abbrev: [[ABBREV4]] +; BOLT-NEXT: Abbrev: [[ABBREV5]] ; BOLT-NEXT: Tag: DW_TAG_subprogram ; BOLT-NEXT: DW_IDX_die_offset: 0x00000073 +; BOLT-NEXT: DW_IDX_parent: ; BOLT-NEXT: } ; BOLT-NEXT: } ; BOLT-NEXT: ] @@ -157,15 +177,11 @@ ; BOLT-NEXT: Name 11 { ; BOLT-NEXT: Hash: 0x8CFC710C ; BOLT-NEXT: String: {{.+}} "(anonymous namespace)" -; BOLT-NEXT: Entry @ {{.+}} { -; BOLT-NEXT: Abbrev: [[ABBREV5]] -; BOLT-NEXT: Tag: DW_TAG_namespace -; BOLT-NEXT: DW_IDX_die_offset: 0x00000061 -; BOLT-NEXT: } -; BOLT-NEXT: Entry @ {{.+}} { -; BOLT-NEXT: Abbrev: [[ABBREV5]] +; BOLT-NEXT: Entry @ 0x14d { +; BOLT-NEXT: Abbrev: [[ABBREV6]] ; BOLT-NEXT: Tag: DW_TAG_namespace ; BOLT-NEXT: DW_IDX_die_offset: 0x00000061 +; BOLT-NEXT: DW_IDX_parent: ; BOLT-NEXT: } ; BOLT-NEXT: } ; BOLT-NEXT: ] diff --git a/bolt/test/X86/dwarf5-types-debug-names.test b/bolt/test/X86/dwarf5-types-debug-names.test index 6a26477d4cdb5578d22fdff3ce7afa9cbfd6104a..94624298e289de7c3b02f018d75bf8ccf3623371 100644 --- a/bolt/test/X86/dwarf5-types-debug-names.test +++ b/bolt/test/X86/dwarf5-types-debug-names.test @@ -14,7 +14,7 @@ ; BOLT: Name Index @ 0x0 { ; BOLT: Header { -; BOLT: Length: 0xE1 +; BOLT: Length: 0xE9 ; BOLT: Format: DWARF32 ; BOLT: Version: 5 ; BOLT: CU count: 2 @@ -22,7 +22,7 @@ ; BOLT: Foreign TU count: 0 ; BOLT: Bucket count: 6 ; BOLT: Name count: 6 -; BOLT: Abbreviations table size: 0x21 +; BOLT: Abbreviations table size: 0x29 ; BOLT: Augmentation: 'BOLT' ; BOLT: } ; BOLT: Compilation Unit offsets [ @@ -37,21 +37,25 @@ ; BOLT: Tag: DW_TAG_structure_type ; BOLT: DW_IDX_type_unit: DW_FORM_data1 ; BOLT: DW_IDX_die_offset: DW_FORM_ref4 +; BOLT: DW_IDX_parent: DW_FORM_flag_present ; BOLT: } ; BOLT: Abbreviation [[ABBREV1:0x[0-9a-f]*]] { ; BOLT: Tag: DW_TAG_subprogram ; BOLT: DW_IDX_compile_unit: DW_FORM_data1 ; BOLT: DW_IDX_die_offset: DW_FORM_ref4 +; BOLT: DW_IDX_parent: DW_FORM_flag_present ; BOLT: } ; BOLT: Abbreviation [[ABBREV2:0x[0-9a-f]*]] { ; BOLT: Tag: DW_TAG_base_type ; BOLT: DW_IDX_compile_unit: DW_FORM_data1 ; BOLT: DW_IDX_die_offset: DW_FORM_ref4 +; BOLT: DW_IDX_parent: DW_FORM_flag_present ; BOLT: } ; BOLT: Abbreviation [[ABBREV3:0x[0-9a-f]*]] { ; BOLT: Tag: DW_TAG_base_type ; BOLT: DW_IDX_type_unit: DW_FORM_data1 ; BOLT: DW_IDX_die_offset: DW_FORM_ref4 +; BOLT: DW_IDX_parent: DW_FORM_flag_present ; BOLT: } ; BOLT: ] ; BOLT: Bucket 0 [ @@ -63,6 +67,7 @@ ; BOLT: Tag: DW_TAG_structure_type ; BOLT: DW_IDX_type_unit: 0x00 ; BOLT: DW_IDX_die_offset: 0x00000023 +; BOLT: DW_IDX_parent: ; BOLT: } ; BOLT: } ; BOLT: ] @@ -75,6 +80,7 @@ ; BOLT: Tag: DW_TAG_subprogram ; BOLT: DW_IDX_compile_unit: 0x01 ; BOLT: DW_IDX_die_offset: 0x00000024 +; BOLT: DW_IDX_parent: ; BOLT: } ; BOLT: } ; BOLT: ] @@ -87,6 +93,7 @@ ; BOLT: Tag: DW_TAG_base_type ; BOLT: DW_IDX_compile_unit: 0x01 ; BOLT: DW_IDX_die_offset: 0x00000040 +; BOLT: DW_IDX_parent: ; BOLT: } ; BOLT: } ; BOLT: ] @@ -99,6 +106,7 @@ ; BOLT: Tag: DW_TAG_subprogram ; BOLT: DW_IDX_compile_unit: 0x01 ; BOLT: DW_IDX_die_offset: 0x00000024 +; BOLT: DW_IDX_parent: ; BOLT: } ; BOLT: } ; BOLT: ] @@ -111,6 +119,7 @@ ; BOLT: Tag: DW_TAG_subprogram ; BOLT: DW_IDX_compile_unit: 0x00 ; BOLT: DW_IDX_die_offset: 0x00000024 +; BOLT: DW_IDX_parent: ; BOLT: } ; BOLT: } ; BOLT: ] @@ -123,6 +132,7 @@ ; BOLT: Tag: DW_TAG_base_type ; BOLT: DW_IDX_type_unit: 0x00 ; BOLT: DW_IDX_die_offset: 0x00000038 +; BOLT: DW_IDX_parent: ; BOLT: } ; BOLT: } ; BOLT: ] diff --git a/bolt/test/X86/dwarf5-types-one-cu-debug-names.test b/bolt/test/X86/dwarf5-types-one-cu-debug-names.test index 00a1319a557869e9ee2ab1da01931b4a76df602a..02c0ef81351f1f842f1167b0a097024bc1368a4c 100644 --- a/bolt/test/X86/dwarf5-types-one-cu-debug-names.test +++ b/bolt/test/X86/dwarf5-types-one-cu-debug-names.test @@ -11,7 +11,7 @@ ; BOLT:Name Index @ 0x0 { ; BOLT-NEXT: Header { -; BOLT-NEXT: Length: 0xA3 +; BOLT-NEXT: Length: 0xAB ; BOLT-NEXT: Format: DWARF32 ; BOLT-NEXT: Version: 5 ; BOLT-NEXT: CU count: 1 @@ -19,7 +19,7 @@ ; BOLT-NEXT: Foreign TU count: 0 ; BOLT-NEXT: Bucket count: 4 ; BOLT-NEXT: Name count: 4 -; BOLT-NEXT: Abbreviations table size: 0x1D +; BOLT-NEXT: Abbreviations table size: 0x25 ; BOLT-NEXT: Augmentation: 'BOLT' ; BOLT-NEXT: } ; BOLT-NEXT: Compilation Unit offsets [ @@ -32,20 +32,24 @@ ; BOLT-NEXT: Abbreviation [[ABBREV:0x[0-9a-f]*]] { ; BOLT-NEXT: Tag: DW_TAG_base_type ; BOLT-NEXT: DW_IDX_die_offset: DW_FORM_ref4 +; BOLT-NEXT: DW_IDX_parent: DW_FORM_flag_present ; BOLT-NEXT: } ; BOLT-NEXT: Abbreviation [[ABBREV1:0x[0-9a-f]*]] { ; BOLT-NEXT: Tag: DW_TAG_structure_type ; BOLT-NEXT: DW_IDX_type_unit: DW_FORM_data1 ; BOLT-NEXT: DW_IDX_die_offset: DW_FORM_ref4 +; BOLT-NEXT: DW_IDX_parent: DW_FORM_flag_present ; BOLT-NEXT: } ; BOLT-NEXT: Abbreviation [[ABBREV2:0x[0-9a-f]*]] { ; BOLT-NEXT: Tag: DW_TAG_subprogram ; BOLT-NEXT: DW_IDX_die_offset: DW_FORM_ref4 +; BOLT-NEXT: DW_IDX_parent: DW_FORM_flag_present ; BOLT-NEXT: } ; BOLT-NEXT: Abbreviation [[ABBREV3:0x[0-9a-f]*]] { ; BOLT-NEXT: Tag: DW_TAG_base_type ; BOLT-NEXT: DW_IDX_type_unit: DW_FORM_data1 ; BOLT-NEXT: DW_IDX_die_offset: DW_FORM_ref4 +; BOLT-NEXT: DW_IDX_parent: DW_FORM_flag_present ; BOLT-NEXT: } ; BOLT-NEXT: ] ; BOLT-NEXT: Bucket 0 [ @@ -56,6 +60,7 @@ ; BOLT-NEXT: Abbrev: [[ABBREV]] ; BOLT-NEXT: Tag: DW_TAG_base_type ; BOLT-NEXT: DW_IDX_die_offset: 0x0000003f +; BOLT-NEXT: DW_IDX_parent: ; BOLT-NEXT: } ; BOLT-NEXT: } ; BOLT-NEXT: Name 2 { @@ -66,6 +71,7 @@ ; BOLT-NEXT: Tag: DW_TAG_structure_type ; BOLT-NEXT: DW_IDX_type_unit: 0x00 ; BOLT-NEXT: DW_IDX_die_offset: 0x00000023 +; BOLT-NEXT: DW_IDX_parent: ; BOLT-NEXT: } ; BOLT-NEXT: } ; BOLT-NEXT: ] @@ -80,6 +86,7 @@ ; BOLT-NEXT: Abbrev: [[ABBREV2]] ; BOLT-NEXT: Tag: DW_TAG_subprogram ; BOLT-NEXT: DW_IDX_die_offset: 0x00000024 +; BOLT-NEXT: DW_IDX_parent: ; BOLT-NEXT: } ; BOLT-NEXT: } ; BOLT-NEXT: ] @@ -92,6 +99,7 @@ ; BOLT-NEXT: Tag: DW_TAG_base_type ; BOLT-NEXT: DW_IDX_type_unit: 0x00 ; BOLT-NEXT: DW_IDX_die_offset: 0x00000038 +; BOLT-NEXT: DW_IDX_parent: ; BOLT-NEXT: } ; BOLT-NEXT: } ; BOLT-NEXT: ] diff --git a/bolt/test/X86/linux-pci-fixup.s b/bolt/test/X86/linux-pci-fixup.s new file mode 100644 index 0000000000000000000000000000000000000000..a574ba84c4df11efac6a28e0decf68041dce1d4f --- /dev/null +++ b/bolt/test/X86/linux-pci-fixup.s @@ -0,0 +1,41 @@ +# REQUIRES: system-linux + +# RUN: llvm-mc -filetype=obj -triple x86_64-unknown-unknown %s -o %t.o +# RUN: %clang %cflags -nostdlib %t.o -o %t.exe \ +# RUN: -Wl,--image-base=0xffffffff80000000,--no-dynamic-linker,--no-eh-frame-hdr,--no-pie +# RUN: llvm-bolt %t.exe --print-normalized -o %t.out |& FileCheck %s + +## Check that BOLT correctly parses the Linux kernel .pci_fixup section and +## verify that PCI fixup hook in the middle of a function is detected. + +# CHECK: BOLT-INFO: Linux kernel binary detected +# CHECK: BOLT-WARNING: PCI fixup detected in the middle of function _start +# CHECK: BOLT-INFO: parsed 2 PCI fixup entries + + .text + .globl _start + .type _start, %function +_start: + nop +.L0: + ret + .size _start, .-_start + +## PCI fixup table. + .section .pci_fixup,"a",@progbits + + .short 0x8086 # vendor + .short 0xbeef # device + .long 0xffffffff # class + .long 0x0 # class shift + .long _start - . # fixup + + .short 0x8086 # vendor + .short 0xbad # device + .long 0xffffffff # class + .long 0x0 # class shift + .long .L0 - . # fixup + +## Fake Linux Kernel sections. + .section __ksymtab,"a",@progbits + .section __ksymtab_gpl,"a",@progbits diff --git a/bolt/test/X86/reader-stale-yaml.test b/bolt/test/X86/reader-stale-yaml.test index 533ed917c1aeb07f032bb888bac1560da8975c79..f4a8865b1f9a46506ecd068cf4fb0c25d51e0b66 100644 --- a/bolt/test/X86/reader-stale-yaml.test +++ b/bolt/test/X86/reader-stale-yaml.test @@ -14,6 +14,10 @@ RUN: --profile-ignore-hash=1 --profile-use-dfs=0 --debug-only=bolt-prof 2>&1 | RUN: llvm-bolt %t.exe -o %t.null --b %p/Inputs/blarge_profile_stale.yaml \ RUN: --print-cfg --print-only=SolveCubic --infer-stale-profile=1 \ RUN: --profile-ignore-hash=1 --profile-use-dfs=0 --debug-only=bolt-prof 2>&1 | FileCheck %s -check-prefix=CHECK2 +# Testing skipped function +RUN: llvm-bolt %t.exe -o %t.null --b %p/Inputs/blarge_profile_stale.yaml \ +RUN: --print-cfg --print-only=usqrt --infer-stale-profile=1 --skip-funcs=usqrt \ +RUN: --profile-ignore-hash=1 --profile-use-dfs=0 CHECK0: BOLT-INFO: 2 out of 7 functions in the binary (28.6%) have non-empty execution profile CHECK0: BOLT-WARNING: 2 (100.0% of all profiled) functions have invalid (possibly stale) profile diff --git a/bolt/unittests/Core/MCPlusBuilder.cpp b/bolt/unittests/Core/MCPlusBuilder.cpp index 63448039c53e677e33bdb2e7f4472f22e297a748..daf9f392b8228198fcf77807ef1e5a9a557288a5 100644 --- a/bolt/unittests/Core/MCPlusBuilder.cpp +++ b/bolt/unittests/Core/MCPlusBuilder.cpp @@ -134,9 +134,8 @@ TEST_P(MCPlusBuilderTester, ReplaceRegWithImm) { TEST_P(MCPlusBuilderTester, Annotation) { MCInst Inst; - bool Success = BC->MIB->createTailCall(Inst, BC->Ctx->createNamedTempSymbol(), - BC->Ctx.get()); - ASSERT_TRUE(Success); + BC->MIB->createTailCall(Inst, BC->Ctx->createNamedTempSymbol(), + BC->Ctx.get()); MCSymbol *LPSymbol = BC->Ctx->createNamedTempSymbol("LP"); uint64_t Value = INT32_MIN; // Test encodeAnnotationImm using this indirect way @@ -151,9 +150,8 @@ TEST_P(MCPlusBuilderTester, Annotation) { // Large int64 should trigger an out of range assertion Value = 0x1FF'FFFF'FFFF'FFFFULL; Inst.clear(); - Success = BC->MIB->createTailCall(Inst, BC->Ctx->createNamedTempSymbol(), - BC->Ctx.get()); - ASSERT_TRUE(Success); + BC->MIB->createTailCall(Inst, BC->Ctx->createNamedTempSymbol(), + BC->Ctx.get()); ASSERT_DEATH(BC->MIB->addEHInfo(Inst, MCPlus::MCLandingPad(LPSymbol, Value)), "annotation value out of range"); } diff --git a/clang-tools-extra/clang-tidy/bugprone/UnusedReturnValueCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/UnusedReturnValueCheck.cpp index 1252b2f23805a1e9b1f0f2e1c1843b965df9d019..73373147e96fc9efb091c2f66aa1f49544db6ed0 100644 --- a/clang-tools-extra/clang-tidy/bugprone/UnusedReturnValueCheck.cpp +++ b/clang-tools-extra/clang-tidy/bugprone/UnusedReturnValueCheck.cpp @@ -11,6 +11,8 @@ #include "../utils/OptionsUtils.h" #include "clang/AST/ASTContext.h" #include "clang/ASTMatchers/ASTMatchFinder.h" +#include "clang/ASTMatchers/ASTMatchers.h" +#include "clang/Basic/OperatorKinds.h" using namespace clang::ast_matchers; using namespace clang::ast_matchers::internal; @@ -28,6 +30,18 @@ AST_MATCHER_P(FunctionDecl, isInstantiatedFrom, Matcher, return InnerMatcher.matches(InstantiatedFrom ? *InstantiatedFrom : Node, Finder, Builder); } + +constexpr std::initializer_list + AssignmentOverloadedOperatorKinds = { + OO_Equal, OO_PlusEqual, OO_MinusEqual, OO_StarEqual, + OO_SlashEqual, OO_PercentEqual, OO_CaretEqual, OO_AmpEqual, + OO_PipeEqual, OO_LessLessEqual, OO_GreaterGreaterEqual, OO_PlusPlus, + OO_MinusMinus}; + +AST_MATCHER(FunctionDecl, isAssignmentOverloadedOperator) { + return llvm::is_contained(AssignmentOverloadedOperatorKinds, + Node.getOverloadedOperator()); +} } // namespace UnusedReturnValueCheck::UnusedReturnValueCheck(llvm::StringRef Name, @@ -159,6 +173,8 @@ void UnusedReturnValueCheck::storeOptions(ClangTidyOptions::OptionMap &Opts) { void UnusedReturnValueCheck::registerMatchers(MatchFinder *Finder) { auto MatchedDirectCallExpr = expr(callExpr(callee(functionDecl( + // Don't match copy or move assignment operator. + unless(isAssignmentOverloadedOperator()), // Don't match void overloads of checked functions. unless(returns(voidType())), anyOf(isInstantiatedFrom(matchers::matchesAnyListedName( diff --git a/clang-tools-extra/clang-tidy/readability/ImplicitBoolConversionCheck.cpp b/clang-tools-extra/clang-tidy/readability/ImplicitBoolConversionCheck.cpp index 4f02950e7794cbea6f4a1249da136e7193acd399..74152c6034510b9e4b881c6c4e00ec20ca821c09 100644 --- a/clang-tools-extra/clang-tidy/readability/ImplicitBoolConversionCheck.cpp +++ b/clang-tools-extra/clang-tidy/readability/ImplicitBoolConversionCheck.cpp @@ -81,8 +81,7 @@ void fixGenericExprCastToBool(DiagnosticBuilder &Diag, const Expr *SubExpr = Cast->getSubExpr(); - bool NeedInnerParens = - SubExpr != nullptr && utils::fixit::areParensNeededForStatement(*SubExpr); + bool NeedInnerParens = utils::fixit::areParensNeededForStatement(*SubExpr); bool NeedOuterParens = Parent != nullptr && utils::fixit::areParensNeededForStatement(*Parent); diff --git a/clang-tools-extra/clangd/ClangdServer.cpp b/clang-tools-extra/clangd/ClangdServer.cpp index 2907e3ba3c303c656b286657419ecc3adcda35a7..5790273d625ef14f7ae06ff608b88cd65926e808 100644 --- a/clang-tools-extra/clangd/ClangdServer.cpp +++ b/clang-tools-extra/clangd/ClangdServer.cpp @@ -523,7 +523,7 @@ void ClangdServer::formatFile(PathRef File, std::optional Rng, auto Action = [File = File.str(), Code = std::move(*Code), Ranges = std::vector{RequestedRange}, CB = std::move(CB), this]() mutable { - format::FormatStyle Style = getFormatStyleForFile(File, Code, TFS); + format::FormatStyle Style = getFormatStyleForFile(File, Code, TFS, true); tooling::Replacements IncludeReplaces = format::sortIncludes(Style, Code, Ranges, File); auto Changed = tooling::applyAllReplacements(Code, IncludeReplaces); @@ -551,7 +551,7 @@ void ClangdServer::formatOnType(PathRef File, Position Pos, auto Action = [File = File.str(), Code = std::move(*Code), TriggerText = TriggerText.str(), CursorPos = *CursorPos, CB = std::move(CB), this]() mutable { - auto Style = getFormatStyleForFile(File, Code, TFS); + auto Style = getFormatStyleForFile(File, Code, TFS, false); std::vector Result; for (const tooling::Replacement &R : formatIncremental(Code, CursorPos, TriggerText, Style)) @@ -605,7 +605,7 @@ void ClangdServer::rename(PathRef File, Position Pos, llvm::StringRef NewName, if (Opts.WantFormat) { auto Style = getFormatStyleForFile(File, InpAST->Inputs.Contents, - *InpAST->Inputs.TFS); + *InpAST->Inputs.TFS, false); llvm::Error Err = llvm::Error::success(); for (auto &E : R->GlobalChanges) Err = @@ -762,7 +762,7 @@ void ClangdServer::applyTweak(PathRef File, Range Sel, StringRef TweakID, for (auto &It : (*Effect)->ApplyEdits) { Edit &E = It.second; format::FormatStyle Style = - getFormatStyleForFile(File, E.InitialCode, TFS); + getFormatStyleForFile(File, E.InitialCode, TFS, false); if (llvm::Error Err = reformatEdit(E, Style)) elog("Failed to format {0}: {1}", It.first(), std::move(Err)); } @@ -825,7 +825,7 @@ void ClangdServer::findHover(PathRef File, Position Pos, if (!InpAST) return CB(InpAST.takeError()); format::FormatStyle Style = getFormatStyleForFile( - File, InpAST->Inputs.Contents, *InpAST->Inputs.TFS); + File, InpAST->Inputs.Contents, *InpAST->Inputs.TFS, false); CB(clangd::getHover(InpAST->AST, Pos, std::move(Style), Index)); }; diff --git a/clang-tools-extra/clangd/CodeComplete.cpp b/clang-tools-extra/clangd/CodeComplete.cpp index 0e5f08cec440cefc0a7169ba00d66c88726d0ab6..036eb9808ea082be28229e849382927522b47fbd 100644 --- a/clang-tools-extra/clangd/CodeComplete.cpp +++ b/clang-tools-extra/clangd/CodeComplete.cpp @@ -1628,7 +1628,7 @@ public: IsUsingDeclaration = Recorder->CCContext.isUsingDeclaration(); auto Style = getFormatStyleForFile(SemaCCInput.FileName, SemaCCInput.ParseInput.Contents, - *SemaCCInput.ParseInput.TFS); + *SemaCCInput.ParseInput.TFS, false); const auto NextToken = findTokenAfterCompletionPoint( Recorder->CCSema->getPreprocessor().getCodeCompletionLoc(), Recorder->CCSema->getSourceManager(), Recorder->CCSema->LangOpts); @@ -1719,7 +1719,7 @@ public: ProxSources[FileName].Cost = 0; FileProximity.emplace(ProxSources); - auto Style = getFormatStyleForFile(FileName, Content, TFS); + auto Style = getFormatStyleForFile(FileName, Content, TFS, false); // This will only insert verbatim headers. Inserter.emplace(FileName, Content, Style, /*BuildDir=*/"", /*HeaderSearchInfo=*/nullptr); diff --git a/clang-tools-extra/clangd/IncludeCleaner.cpp b/clang-tools-extra/clangd/IncludeCleaner.cpp index 7375b7b08609176a95ad5ab5b9935277a460558b..8e48f546d94e7799ca727a5e3de0895c90fd69cd 100644 --- a/clang-tools-extra/clangd/IncludeCleaner.cpp +++ b/clang-tools-extra/clangd/IncludeCleaner.cpp @@ -116,7 +116,7 @@ std::vector generateMissingIncludeDiagnostics( const SourceManager &SM = AST.getSourceManager(); const FileEntry *MainFile = SM.getFileEntryForID(SM.getMainFileID()); - auto FileStyle = getFormatStyleForFile(AST.tuPath(), Code, TFS); + auto FileStyle = getFormatStyleForFile(AST.tuPath(), Code, TFS, false); tooling::HeaderIncludes HeaderIncludes(AST.tuPath(), Code, FileStyle.IncludeStyle); diff --git a/clang-tools-extra/clangd/JSONTransport.cpp b/clang-tools-extra/clangd/JSONTransport.cpp index 346c7dfb66a1dbb01709e31ed6386470f42749b4..3c0e198433f36004056bdd995081dc3d30ca6de4 100644 --- a/clang-tools-extra/clangd/JSONTransport.cpp +++ b/clang-tools-extra/clangd/JSONTransport.cpp @@ -107,8 +107,7 @@ public: return error(std::make_error_code(std::errc::operation_canceled), "Got signal, shutting down"); if (ferror(In)) - return llvm::errorCodeToError( - std::error_code(errno, std::system_category())); + return llvm::errorCodeToError(llvm::errnoAsErrorCode()); if (readRawMessage(JSON)) { ThreadCrashReporter ScopedReporter([&JSON]() { auto &OS = llvm::errs(); diff --git a/clang-tools-extra/clangd/ParsedAST.cpp b/clang-tools-extra/clangd/ParsedAST.cpp index 862f06196a7100a553f28c67614fb6bc3635c788..3ff759415f7c8b24fab5a3a538c13755dd14544f 100644 --- a/clang-tools-extra/clangd/ParsedAST.cpp +++ b/clang-tools-extra/clangd/ParsedAST.cpp @@ -626,7 +626,7 @@ ParsedAST::build(llvm::StringRef Filename, const ParseInputs &Inputs, // (e.g. incomplete type) and attach include insertion fixes to diagnostics. if (Inputs.Index && !BuildDir.getError()) { auto Style = - getFormatStyleForFile(Filename, Inputs.Contents, *Inputs.TFS); + getFormatStyleForFile(Filename, Inputs.Contents, *Inputs.TFS, false); auto Inserter = std::make_shared( Filename, Inputs.Contents, Style, BuildDir.get(), &Clang->getPreprocessor().getHeaderSearchInfo()); diff --git a/clang-tools-extra/clangd/Protocol.cpp b/clang-tools-extra/clangd/Protocol.cpp index 8aa18bb0058abe35b469e8321fc806325cad7f45..c6553e00dcae28209da96ff0eb6a7dd2288d008f 100644 --- a/clang-tools-extra/clangd/Protocol.cpp +++ b/clang-tools-extra/clangd/Protocol.cpp @@ -1412,7 +1412,7 @@ bool fromJSON(const llvm::json::Value &Params, ReferenceParams &R, } llvm::json::Value toJSON(SymbolTag Tag) { - return llvm::json::Value{static_cast(Tag)}; + return llvm::json::Value(static_cast(Tag)); } llvm::json::Value toJSON(const CallHierarchyItem &I) { diff --git a/clang-tools-extra/clangd/SourceCode.cpp b/clang-tools-extra/clangd/SourceCode.cpp index 3e741f6e0b536ba44bafc8245fa01e4a219fa2d6..3af99b9db056da5780dad816be27dc7a0c1c4b25 100644 --- a/clang-tools-extra/clangd/SourceCode.cpp +++ b/clang-tools-extra/clangd/SourceCode.cpp @@ -582,7 +582,21 @@ std::optional digestFile(const SourceManager &SM, FileID FID) { format::FormatStyle getFormatStyleForFile(llvm::StringRef File, llvm::StringRef Content, - const ThreadsafeFS &TFS) { + const ThreadsafeFS &TFS, + bool FormatFile) { + // Unless we're formatting a substantial amount of code (the entire file + // or an arbitrarily large range), skip libFormat's heuristic check for + // .h files that tries to determine whether the file contains objective-c + // code. (This is accomplished by passing empty code contents to getStyle(). + // The heuristic is the only thing that looks at the contents.) + // This is a workaround for PR60151, a known issue in libFormat where this + // heuristic can OOM on large files. If we *are* formatting the entire file, + // there's no point in doing this because the actual format::reformat() call + // will run into the same OOM; we'd just be risking inconsistencies between + // clangd and clang-format on smaller .h files where they disagree on what + // language is detected. + if (!FormatFile) + Content = {}; auto Style = format::getStyle(format::DefaultFormatStyle, File, format::DefaultFallbackStyle, Content, TFS.view(/*CWD=*/std::nullopt).get()); diff --git a/clang-tools-extra/clangd/SourceCode.h b/clang-tools-extra/clangd/SourceCode.h index a1bb44c176120210aca1fa5f73ee2d5fc47d21e9..028549f659d60aad310db71ac12a1ec95467f654 100644 --- a/clang-tools-extra/clangd/SourceCode.h +++ b/clang-tools-extra/clangd/SourceCode.h @@ -171,9 +171,13 @@ std::optional getCanonicalPath(const FileEntryRef F, /// FIXME: should we be caching the .clang-format file search? /// This uses format::DefaultFormatStyle and format::DefaultFallbackStyle, /// though the latter may have been overridden in main()! +/// \p FormatFile indicates whether the returned FormatStyle is used +/// to format the entire main file (or a range selected by the user +/// which can be arbitrarily long). format::FormatStyle getFormatStyleForFile(llvm::StringRef File, llvm::StringRef Content, - const ThreadsafeFS &TFS); + const ThreadsafeFS &TFS, + bool FormatFile); /// Cleanup and format the given replacements. llvm::Expected diff --git a/clang-tools-extra/clangd/tool/Check.cpp b/clang-tools-extra/clangd/tool/Check.cpp index b5c4d145619df33a5da26c5704f79776d6d4c3d6..45e2e1e278deafa4843d8f7945472b961f7519a4 100644 --- a/clang-tools-extra/clangd/tool/Check.cpp +++ b/clang-tools-extra/clangd/tool/Check.cpp @@ -226,7 +226,7 @@ public: // FIXME: Check that resource-dir/built-in-headers exist? - Style = getFormatStyleForFile(File, Inputs.Contents, TFS); + Style = getFormatStyleForFile(File, Inputs.Contents, TFS, false); return true; } diff --git a/clang-tools-extra/clangd/unittests/DiagnosticsTests.cpp b/clang-tools-extra/clangd/unittests/DiagnosticsTests.cpp index 2f6dd0611b6621bf5dca556b3b44ebe360a1a1e4..25d2f03e0b366b0d627bdbdd09d4e5beef4ed270 100644 --- a/clang-tools-extra/clangd/unittests/DiagnosticsTests.cpp +++ b/clang-tools-extra/clangd/unittests/DiagnosticsTests.cpp @@ -544,7 +544,7 @@ TEST(DiagnosticTest, RespectsDiagnosticConfig) { Diag(Main.range("ret"), "void function 'x' should not return a value"))); Config Cfg; - Cfg.Diagnostics.Suppress.insert("return-type"); + Cfg.Diagnostics.Suppress.insert("return-mismatch"); WithContextValue WithCfg(Config::Key, std::move(Cfg)); EXPECT_THAT(TU.build().getDiagnostics(), ElementsAre(Diag(Main.range(), diff --git a/clang-tools-extra/clangd/unittests/SelectionTests.cpp b/clang-tools-extra/clangd/unittests/SelectionTests.cpp index 754e8c287c514869506c7efde8816f340d664466..db516a1f62a35773b9e46932fec066984afb8a93 100644 --- a/clang-tools-extra/clangd/unittests/SelectionTests.cpp +++ b/clang-tools-extra/clangd/unittests/SelectionTests.cpp @@ -10,6 +10,7 @@ #include "SourceCode.h" #include "TestTU.h" #include "support/TestTracer.h" +#include "clang/AST/ASTConcept.h" #include "clang/AST/Decl.h" #include "llvm/Support/Casting.h" #include "gmock/gmock.h" @@ -893,6 +894,33 @@ TEST(SelectionTest, DeclContextLambda) { EXPECT_TRUE(ST.commonAncestor()->getDeclContext().isFunctionOrMethod()); } +TEST(SelectionTest, UsingConcepts) { + llvm::Annotations Test(R"cpp( +namespace ns { +template +concept Foo = true; +} + +using ns::Foo; + +template +auto Func(Fo^o auto V) -> Fo^o decltype(auto) { + Fo^o auto W = V; + return W; +} +)cpp"); + auto TU = TestTU::withCode(Test.code()); + TU.ExtraArgs.emplace_back("-std=c++2c"); + auto AST = TU.build(); + for (auto Point : Test.points()) { + auto ST = SelectionTree::createRight(AST.getASTContext(), AST.getTokens(), + Point, Point); + auto *C = ST.commonAncestor()->ASTNode.get(); + EXPECT_TRUE(C && C->getFoundDecl() && + C->getFoundDecl()->getKind() == Decl::UsingShadow); + } +} + } // namespace } // namespace clangd } // namespace clang diff --git a/clang-tools-extra/clangd/unittests/SourceCodeTests.cpp b/clang-tools-extra/clangd/unittests/SourceCodeTests.cpp index 1be5b7f6a8dbbadab21c00c58bb57f9ef7571fb2..801d535c1b9d0dc438415cba163821b413677912 100644 --- a/clang-tools-extra/clangd/unittests/SourceCodeTests.cpp +++ b/clang-tools-extra/clangd/unittests/SourceCodeTests.cpp @@ -1090,6 +1090,44 @@ TEST(ApplyEditsTest, EndLineOutOfRange) { FailedWithMessage("Line value is out of range (100)")); } +TEST(FormatStyleForFile, LanguageGuessingHeuristic) { + StringRef ObjCContent = "@interface Foo\n@end\n"; + StringRef CppContent = "class Foo {};\n"; + using LK = format::FormatStyle::LanguageKind; + struct TestCase { + llvm::StringRef Filename; + llvm::StringRef Contents; + bool FormatFile; + LK ExpectedLanguage; + } TestCases[] = { + // If the file extension identifies the file as ObjC, the guessed + // language should be ObjC regardless of content or FormatFile flag. + {"foo.mm", ObjCContent, true, LK::LK_ObjC}, + {"foo.mm", ObjCContent, false, LK::LK_ObjC}, + {"foo.mm", CppContent, true, LK::LK_ObjC}, + {"foo.mm", CppContent, false, LK::LK_ObjC}, + + // If the file extension is ambiguous like .h, FormatFile=true should + // result in using libFormat's heuristic to guess the language based + // on the file contents. + {"foo.h", ObjCContent, true, LK::LK_ObjC}, + {"foo.h", CppContent, true, LK::LK_Cpp}, + + // With FomatFile=false, the language guessing heuristic should be + // bypassed + {"foo.h", ObjCContent, false, LK::LK_Cpp}, + {"foo.h", CppContent, false, LK::LK_Cpp}, + }; + + MockFS FS; + for (const auto &[Filename, Contents, FormatFile, ExpectedLanguage] : + TestCases) { + EXPECT_EQ( + getFormatStyleForFile(Filename, Contents, FS, FormatFile).Language, + ExpectedLanguage); + } +} + } // namespace } // namespace clangd } // namespace clang diff --git a/clang-tools-extra/clangd/unittests/tweaks/ExtractVariableTests.cpp b/clang-tools-extra/clangd/unittests/tweaks/ExtractVariableTests.cpp index 42dd612eeeec46c3e65383af5f085e662a3359aa..656b62c9a1f4e17ec1fd8aaab60348340114383d 100644 --- a/clang-tools-extra/clangd/unittests/tweaks/ExtractVariableTests.cpp +++ b/clang-tools-extra/clangd/unittests/tweaks/ExtractVariableTests.cpp @@ -72,6 +72,22 @@ TEST_F(ExtractVariableTest, Test) { )cpp"; EXPECT_UNAVAILABLE(NoCrashCasesC); + ExtraArgs = {"-xc"}; + const char *NoCrashDesignator = R"cpp( + struct A { + struct { + int x; + }; + }; + struct B { + int y; + }; + void foo(struct B *b) { + struct A a = {.x=b[[->]]y}; + } + )cpp"; + EXPECT_AVAILABLE(NoCrashDesignator); + ExtraArgs = {"-xobjective-c"}; const char *AvailableObjC = R"cpp( __attribute__((objc_root_class)) diff --git a/clang-tools-extra/docs/ReleaseNotes.rst b/clang-tools-extra/docs/ReleaseNotes.rst index a005adf76b8b5be2ce899707fd8fc812d8d3253b..44680f79de6f543e84cc05fb39c2c97a5e1a5dfa 100644 --- a/clang-tools-extra/docs/ReleaseNotes.rst +++ b/clang-tools-extra/docs/ReleaseNotes.rst @@ -152,9 +152,9 @@ Changes in existing checks - Improved :doc:`bugprone-unused-return-value ` check by updating the - parameter `CheckedFunctions` to support regexp and avoiding false postive for + parameter `CheckedFunctions` to support regexp, avoiding false positive for function with the same prefix as the default argument, e.g. ``std::unique_ptr`` - and ``std::unique``. + and ``std::unique``, avoiding false positive for assignment operator overloading. - Improved :doc:`bugprone-use-after-move ` check to also handle diff --git a/clang-tools-extra/docs/clang-tidy/checks/bugprone/unused-return-value.rst b/clang-tools-extra/docs/clang-tidy/checks/bugprone/unused-return-value.rst index 9c01ef50b538144b24489bef69321a445c358554..9205ba98729c4b9a0b441a90d50c34f6138a06e6 100644 --- a/clang-tools-extra/docs/clang-tidy/checks/bugprone/unused-return-value.rst +++ b/clang-tools-extra/docs/clang-tidy/checks/bugprone/unused-return-value.rst @@ -5,6 +5,8 @@ bugprone-unused-return-value Warns on unused function return values. The checked functions can be configured. +Operator overloading with assignment semantics are ignored. + Options ------- diff --git a/clang-tools-extra/include-cleaner/unittests/WalkASTTest.cpp b/clang-tools-extra/include-cleaner/unittests/WalkASTTest.cpp index 5dc88157e13af01af2d0492a39e2aaf695e5613d..dac3f39e1a65842a700b0c7c2e0e28ae641c79aa 100644 --- a/clang-tools-extra/include-cleaner/unittests/WalkASTTest.cpp +++ b/clang-tools-extra/include-cleaner/unittests/WalkASTTest.cpp @@ -548,9 +548,7 @@ TEST(WalkAST, Concepts) { testWalk(Concept, "template requires ^Foo void func() {}"); testWalk(Concept, "template void func() requires ^Foo {}"); testWalk(Concept, "void func(^Foo auto x) {}"); - // FIXME: Foo should be explicitly referenced. - testWalk("template concept Foo = true;", - "void func() { ^Foo auto x = 1; }"); + testWalk(Concept, "void func() { ^Foo auto x = 1; }"); } TEST(WalkAST, FriendDecl) { diff --git a/clang-tools-extra/test/clang-tidy/checkers/bugprone/unused-return-value-avoid-assignment.cpp b/clang-tools-extra/test/clang-tidy/checkers/bugprone/unused-return-value-avoid-assignment.cpp new file mode 100644 index 0000000000000000000000000000000000000000..564c07a724ccdec9305c70ea24acf1f5333a4b04 --- /dev/null +++ b/clang-tools-extra/test/clang-tidy/checkers/bugprone/unused-return-value-avoid-assignment.cpp @@ -0,0 +1,55 @@ +// RUN: %check_clang_tidy %s bugprone-unused-return-value %t \ +// RUN: -config='{CheckOptions: \ +// RUN: {bugprone-unused-return-value.CheckedFunctions: "::*"}}' \ +// RUN: -- + +struct S1 { + S1(){}; + S1(S1 const &); + S1(S1 &&); + S1 &operator=(S1 const &); + S1 &operator=(S1 &&); + S1 &operator+=(S1); + S1 &operator++(); + S1 &operator++(int); + S1 &operator--(); + S1 &operator--(int); +}; + +struct S2 { + S2(){}; + S2(S2 const &); + S2(S2 &&); +}; + +S2 &operator-=(S2&, int); +S2 &operator++(S2 &); +S2 &operator++(S2 &, int); + +S1 returnValue(); +S1 const &returnRef(); + +void bar() { + returnValue(); + // CHECK-MESSAGES: [[@LINE-1]]:3: warning: the value returned by this function should not be disregarded; neglecting it may lead to errors + + S1 a{}; + a = returnValue(); + a.operator=(returnValue()); + + a = returnRef(); + a.operator=(returnRef()); + + a += returnRef(); + + a++; + ++a; + a--; + --a; + + S2 b{}; + + b -= 1; + b++; + ++b; +} diff --git a/clang/bindings/python/clang/cindex.py b/clang/bindings/python/clang/cindex.py index 44a34ca196274c0a38f1f9675db4337fe3e5f1e4..302d99dccd77b5fec1e82acf428273c256d8b2f9 100644 --- a/clang/bindings/python/clang/cindex.py +++ b/clang/bindings/python/clang/cindex.py @@ -1091,6 +1091,29 @@ CursorKind.OMP_ARRAY_SECTION_EXPR = CursorKind(147) # Represents an @available(...) check. CursorKind.OBJC_AVAILABILITY_CHECK_EXPR = CursorKind(148) +# Fixed point literal. +CursorKind.FIXED_POINT_LITERAL = CursorKind(149) + +# OpenMP 5.0 [2.1.4, Array Shaping]. +CursorKind.OMP_ARRAY_SHAPING_EXPR = CursorKind(150) + +# OpenMP 5.0 [2.1.6 Iterators]. +CursorKind.OMP_ITERATOR_EXPR = CursorKind(151) + +# OpenCL's addrspace_cast<> expression. +CursorKind.CXX_ADDRSPACE_CAST_EXPR = CursorKind(152) + +# Expression that references a C++20 concept. +CursorKind.CONCEPT_SPECIALIZATION_EXPR = CursorKind(153) + +# Expression that references a C++20 requires expression. +CursorKind.REQUIRES_EXPR = CursorKind(154) + +# Expression that references a C++20 parenthesized list aggregate initializer. +CursorKind.CXX_PAREN_LIST_INIT_EXPR = CursorKind(155) + +# Represents a C++26 pack indexing expression. +CursorKind.PACK_INDEXING_EXPR = CursorKind(156) # A statement whose specific kind is not exposed via this interface. # @@ -1312,6 +1335,114 @@ CursorKind.OMP_TARGET_SIMD_DIRECTIVE = CursorKind(270) # OpenMP teams distribute directive. CursorKind.OMP_TEAMS_DISTRIBUTE_DIRECTIVE = CursorKind(271) +# OpenMP teams distribute simd directive. +CursorKind.OMP_TEAMS_DISTRIBUTE_DIRECTIVE = CursorKind(272) + +# OpenMP teams distribute parallel for simd directive. +CursorKind.OMP_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_DIRECTIVE = CursorKind(273) + +# OpenMP teams distribute parallel for directive. +CursorKind.OMP_TEAMS_DISTRIBUTE_PARALLEL_FOR_DIRECTIVE = CursorKind(274) + +# OpenMP target teams directive. +CursorKind.OMP_TARGET_TEAMS_DIRECTIVE = CursorKind(275) + +# OpenMP target teams distribute directive. +CursorKind.OMP_TARGET_TEAMS_DISTRIBUTE_DIRECTIVE = CursorKind(276) + +# OpenMP target teams distribute parallel for directive. +CursorKind.OMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_DIRECTIVE = CursorKind(277) + +# OpenMP target teams distribute parallel for simd directive. +CursorKind.OMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_DIRECTIVE = CursorKind(278) + +# OpenMP target teams distribute simd directive. +CursorKind.OMP_TARGET_TEAMS_DISTRIBUTE_SIMD_DIRECTIVE = CursorKind(279) + +# C++2a std::bit_cast expression. +CursorKind.BUILTIN_BIT_CAST_EXPR = CursorKind(280) + +# OpenMP master taskloop directive. +CursorKind.OMP_MASTER_TASK_LOOP_DIRECTIVE = CursorKind(281) + +# OpenMP parallel master taskloop directive. +CursorKind.OMP_PARALLEL_MASTER_TASK_LOOP_DIRECTIVE = CursorKind(282) + +# OpenMP master taskloop simd directive. +CursorKind.OMP_MASTER_TASK_LOOP_SIMD_DIRECTIVE = CursorKind(283) + +# OpenMP parallel master taskloop simd directive. +CursorKind.OMP_PARALLEL_MASTER_TASK_LOOP_SIMD_DIRECTIVE = CursorKind(284) + +# OpenMP parallel master directive. +CursorKind.OMP_PARALLEL_MASTER_DIRECTIVE = CursorKind(285) + +# OpenMP depobj directive. +CursorKind.OMP_DEPOBJ_DIRECTIVE = CursorKind(286) + +# OpenMP scan directive. +CursorKind.OMP_SCAN_DIRECTIVE = CursorKind(287) + +# OpenMP tile directive. +CursorKind.OMP_TILE_DIRECTIVE = CursorKind(288) + +# OpenMP canonical loop. +CursorKind.OMP_CANONICAL_LOOP = CursorKind(289) + +# OpenMP interop directive. +CursorKind.OMP_INTEROP_DIRECTIVE = CursorKind(290) + +# OpenMP dispatch directive. +CursorKind.OMP_DISPATCH_DIRECTIVE = CursorKind(291) + +# OpenMP masked directive. +CursorKind.OMP_MASKED_DIRECTIVE = CursorKind(292) + +# OpenMP unroll directive. +CursorKind.OMP_UNROLL_DIRECTIVE = CursorKind(293) + +# OpenMP metadirective directive. +CursorKind.OMP_META_DIRECTIVE = CursorKind(294) + +# OpenMP loop directive. +CursorKind.OMP_GENERIC_LOOP_DIRECTIVE = CursorKind(295) + +# OpenMP teams loop directive. +CursorKind.OMP_TEAMS_GENERIC_LOOP_DIRECTIVE = CursorKind(296) + +# OpenMP target teams loop directive. +CursorKind.OMP_TARGET_TEAMS_GENERIC_LOOP_DIRECTIVE = CursorKind(297) + +# OpenMP parallel loop directive. +CursorKind.OMP_PARALLEL_GENERIC_LOOP_DIRECTIVE = CursorKind(298) + +# OpenMP target parallel loop directive. +CursorKind.OMP_TARGET_PARALLEL_GENERIC_LOOP_DIRECTIVE = CursorKind(299) + +# OpenMP parallel masked directive. +CursorKind.OMP_PARALLEL_MASKED_DIRECTIVE = CursorKind(300) + +# OpenMP masked taskloop directive. +CursorKind.OMP_MASKED_TASK_LOOP_DIRECTIVE = CursorKind(301) + +# OpenMP masked taskloop simd directive. +CursorKind.OMP_MASKED_TASK_LOOP_SIMD_DIRECTIVE = CursorKind(302) + +# OpenMP parallel masked taskloop directive. +CursorKind.OMP_PARALLEL_MASKED_TASK_LOOP_DIRECTIVE = CursorKind(303) + +# OpenMP parallel masked taskloop simd directive. +CursorKind.OMP_PARALLEL_MASKED_TASK_LOOP_SIMD_DIRECTIVE = CursorKind(304) + +# OpenMP error directive. +CursorKind.OMP_ERROR_DIRECTIVE = CursorKind(305) + +# OpenMP scope directive. +CursorKind.OMP_SCOPE_DIRECTIVE = CursorKind(306) + +# OpenACC Compute Construct. +CursorKind.OPEN_ACC_COMPUTE_DIRECTIVE = CursorKind(320) + ### # Other Kinds @@ -1349,6 +1480,24 @@ CursorKind.VISIBILITY_ATTR = CursorKind(417) CursorKind.DLLEXPORT_ATTR = CursorKind(418) CursorKind.DLLIMPORT_ATTR = CursorKind(419) +CursorKind.NS_RETURNS_RETAINED = CursorKind(420) +CursorKind.NS_RETURNS_NOT_RETAINED = CursorKind(421) +CursorKind.NS_RETURNS_AUTORELEASED = CursorKind(422) +CursorKind.NS_CONSUMES_SELF = CursorKind(423) +CursorKind.NS_CONSUMED = CursorKind(424) +CursorKind.OBJC_EXCEPTION = CursorKind(425) +CursorKind.OBJC_NSOBJECT = CursorKind(426) +CursorKind.OBJC_INDEPENDENT_CLASS = CursorKind(427) +CursorKind.OBJC_PRECISE_LIFETIME = CursorKind(428) +CursorKind.OBJC_RETURNS_INNER_POINTER = CursorKind(429) +CursorKind.OBJC_REQUIRES_SUPER = CursorKind(430) +CursorKind.OBJC_ROOT_CLASS = CursorKind(431) +CursorKind.OBJC_SUBCLASSING_RESTRICTED = CursorKind(432) +CursorKind.OBJC_EXPLICIT_PROTOCOL_IMPL = CursorKind(433) +CursorKind.OBJC_DESIGNATED_INITIALIZER = CursorKind(434) +CursorKind.OBJC_RUNTIME_VISIBLE = CursorKind(435) +CursorKind.OBJC_BOXABLE = CursorKind(436) +CursorKind.FLAG_ENUM = CursorKind(437) CursorKind.CONVERGENT_ATTR = CursorKind(438) CursorKind.WARN_UNUSED_ATTR = CursorKind(439) CursorKind.WARN_UNUSED_RESULT_ATTR = CursorKind(440) @@ -1395,6 +1544,11 @@ TemplateArgumentKind.TYPE = TemplateArgumentKind(1) TemplateArgumentKind.DECLARATION = TemplateArgumentKind(2) TemplateArgumentKind.NULLPTR = TemplateArgumentKind(3) TemplateArgumentKind.INTEGRAL = TemplateArgumentKind(4) +TemplateArgumentKind.TEMPLATE = TemplateArgumentKind(5) +TemplateArgumentKind.TEMPLATE_EXPANSION = TemplateArgumentKind(6) +TemplateArgumentKind.EXPRESSION = TemplateArgumentKind(7) +TemplateArgumentKind.PACK = TemplateArgumentKind(8) +TemplateArgumentKind.INVALID = TemplateArgumentKind(9) ### Exception Specification Kinds ### class ExceptionSpecificationKind(BaseEnumeration): @@ -2240,9 +2394,26 @@ TypeKind.OCLEVENT = TypeKind(158) TypeKind.OCLQUEUE = TypeKind(159) TypeKind.OCLRESERVEID = TypeKind(160) +TypeKind.OBJCOBJECT = TypeKind(161) +TypeKind.OBJCCLASS = TypeKind(162) +TypeKind.ATTRIBUTED = TypeKind(163) + +TypeKind.OCLINTELSUBGROUPAVCMCEPAYLOAD = TypeKind(164) +TypeKind.OCLINTELSUBGROUPAVCIMEPAYLOAD = TypeKind(165) +TypeKind.OCLINTELSUBGROUPAVCREFPAYLOAD = TypeKind(166) +TypeKind.OCLINTELSUBGROUPAVCSICPAYLOAD = TypeKind(167) +TypeKind.OCLINTELSUBGROUPAVCMCERESULT = TypeKind(168) +TypeKind.OCLINTELSUBGROUPAVCIMERESULT = TypeKind(169) +TypeKind.OCLINTELSUBGROUPAVCREFRESULT = TypeKind(170) +TypeKind.OCLINTELSUBGROUPAVCSICRESULT = TypeKind(171) +TypeKind.OCLINTELSUBGROUPAVCIMERESULTSINGLEREFERENCESTREAMOUT = TypeKind(172) +TypeKind.OCLINTELSUBGROUPAVCIMERESULTSDUALREFERENCESTREAMOUT = TypeKind(173) +TypeKind.OCLINTELSUBGROUPAVCIMERESULTSSINGLEREFERENCESTREAMIN = TypeKind(174) +TypeKind.OCLINTELSUBGROUPAVCIMEDUALREFERENCESTREAMIN = TypeKind(175) + TypeKind.EXTVECTOR = TypeKind(176) TypeKind.ATOMIC = TypeKind(177) - +TypeKind.BTFTAGATTRIBUTED = TypeKind(178) class RefQualifierKind(BaseEnumeration): """Describes a specific ref-qualifier of a type.""" diff --git a/clang/cmake/caches/Fuchsia-stage2.cmake b/clang/cmake/caches/Fuchsia-stage2.cmake index db7430b3344c3e76c15b0038ad9011a0c8e2fecb..bc1a05345ce237222f1a85292f84494f911c86f9 100644 --- a/clang/cmake/caches/Fuchsia-stage2.cmake +++ b/clang/cmake/caches/Fuchsia-stage2.cmake @@ -11,6 +11,7 @@ set(LLVM_ENABLE_RUNTIMES "compiler-rt;libcxx;libcxxabi;libunwind" CACHE STRING " set(LLVM_ENABLE_BACKTRACES OFF CACHE BOOL "") set(LLVM_ENABLE_DIA_SDK OFF CACHE BOOL "") +set(LLVM_ENABLE_FATLTO OFF CACHE BOOL "") set(LLVM_ENABLE_HTTPLIB ON CACHE BOOL "") set(LLVM_ENABLE_LIBCXX ON CACHE BOOL "") set(LLVM_ENABLE_LIBEDIT OFF CACHE BOOL "") diff --git a/clang/cmake/caches/Fuchsia.cmake b/clang/cmake/caches/Fuchsia.cmake index fe925901eb3dce7759578b57c7bc76f0130431e9..df69d7d0dd414beb8be6752acae171cf6fd5272e 100644 --- a/clang/cmake/caches/Fuchsia.cmake +++ b/clang/cmake/caches/Fuchsia.cmake @@ -65,6 +65,8 @@ set(_FUCHSIA_BOOTSTRAP_PASSTHROUGH LLDB_EMBED_PYTHON_HOME LLDB_PYTHON_HOME LLDB_PYTHON_RELATIVE_PATH + LLDB_TEST_USE_VENDOR_PACKAGES + LLDB_TEST_USER_ARGS Python3_EXECUTABLE Python3_LIBRARIES Python3_INCLUDE_DIRS diff --git a/clang/docs/ClangFormatStyleOptions.rst b/clang/docs/ClangFormatStyleOptions.rst index 5b00a8f4c00fb81ebb95d9be945db223b2561803..35b6d0a2b52b67b63362bf45e0a6aa4726c05415 100644 --- a/clang/docs/ClangFormatStyleOptions.rst +++ b/clang/docs/ClangFormatStyleOptions.rst @@ -6158,6 +6158,70 @@ the configuration (without a prefix: ``Auto``). **TabWidth** (``Unsigned``) :versionbadge:`clang-format 3.7` :ref:`¶ ` The number of columns used for tab stops. +.. _TableGenBreakInsideDAGArg: + +**TableGenBreakInsideDAGArg** (``DAGArgStyle``) :versionbadge:`clang-format 19` :ref:`¶ ` + The styles of the line break inside the DAGArg in TableGen. + + Possible values: + + * ``DAS_DontBreak`` (in configuration: ``DontBreak``) + Never break inside DAGArg. + + .. code-block:: c++ + + let DAGArgIns = (ins i32:$src1, i32:$src2); + + * ``DAS_BreakElements`` (in configuration: ``BreakElements``) + Break inside DAGArg after each list element but for the last. + This aligns to the first element. + + .. code-block:: c++ + + let DAGArgIns = (ins i32:$src1, + i32:$src2); + + * ``DAS_BreakAll`` (in configuration: ``BreakAll``) + Break inside DAGArg after the operator and the all elements. + + .. code-block:: c++ + + let DAGArgIns = (ins + i32:$src1, + i32:$src2 + ); + + + +.. _TableGenBreakingDAGArgOperators: + +**TableGenBreakingDAGArgOperators** (``List of Strings``) :versionbadge:`clang-format 19` :ref:`¶ ` + Works only when TableGenBreakInsideDAGArg is not DontBreak. + The string list needs to consist of identifiers in TableGen. + If any identifier is specified, this limits the line breaks by + TableGenBreakInsideDAGArg option only on DAGArg values beginning with + the specified identifiers. + + For example the configuration, + + .. code-block:: c++ + + TableGenBreakInsideDAGArg: BreakAll + TableGenBreakingDAGArgOperators: ['ins', 'outs'] + + makes the line break only occurs inside DAGArgs beginning with the + specified identifiers 'ins' and 'outs'. + + + .. code-block:: c++ + + let DAGArgIns = (ins + i32:$src1, + i32:$src2 + ); + let DAGArgOtherID = (other i32:$other1, i32:$other2); + let DAGArgBang = (!cast("Some") i32:$src1, i32:$src2) + .. _TypeNames: **TypeNames** (``List of Strings``) :versionbadge:`clang-format 17` :ref:`¶ ` diff --git a/clang/docs/LanguageExtensions.rst b/clang/docs/LanguageExtensions.rst index 06af93fd3c15ca8ce3da56190a024f3ee3ffb5e4..13d7261d83d7f1e6625cf6c9c787e096ad5731a6 100644 --- a/clang/docs/LanguageExtensions.rst +++ b/clang/docs/LanguageExtensions.rst @@ -13,6 +13,7 @@ Clang Language Extensions BlockLanguageSpec Block-ABI-Apple AutomaticReferenceCounting + PointerAuthentication MatrixTypes Introduction @@ -3443,6 +3444,21 @@ Query for this feature with ``__has_builtin(__builtin_debugtrap)``. Query for this feature with ``__has_builtin(__builtin_trap)``. +``__builtin_arm_trap`` +---------------------- + +``__builtin_arm_trap`` is an AArch64 extension to ``__builtin_trap`` which also accepts a compile-time constant value, encoded directly into the trap instruction for later inspection. + +**Syntax**: + +.. code-block:: c++ + + __builtin_arm_trap(const unsigned short payload) + +**Description** + +``__builtin_arm_trap`` is lowered to the ``llvm.aarch64.break`` builtin, and then to ``brk #payload``. + ``__builtin_nondeterministic_value`` ------------------------------------ @@ -4303,6 +4319,10 @@ reordering of memory accesses and side effect instructions. Other instructions like simple arithmetic may be reordered around the intrinsic. If you expect to have no reordering at all, use inline assembly instead. +Pointer Authentication +^^^^^^^^^^^^^^^^^^^^^^ +See :doc:`PointerAuthentication`. + X86/X86-64 Language Extensions ------------------------------ diff --git a/clang/docs/PointerAuthentication.rst b/clang/docs/PointerAuthentication.rst new file mode 100644 index 0000000000000000000000000000000000000000..19b3384293aedef5211a8d80a92efb1ba16c8cf7 --- /dev/null +++ b/clang/docs/PointerAuthentication.rst @@ -0,0 +1,485 @@ +Pointer Authentication +====================== + +.. contents:: + :local: + +Introduction +------------ + +Pointer authentication is a technology which offers strong probabilistic +protection against exploiting a broad class of memory bugs to take control of +program execution. When adopted consistently in a language ABI, it provides +a form of relatively fine-grained control flow integrity (CFI) check that +resists both return-oriented programming (ROP) and jump-oriented programming +(JOP) attacks. + +While pointer authentication can be implemented purely in software, direct +hardware support (e.g. as provided by Armv8.3 PAuth) can dramatically improve +performance and code size. Similarly, while pointer authentication +can be implemented on any architecture, taking advantage of the (typically) +excess addressing range of a target with 64-bit pointers minimizes the impact +on memory performance and can allow interoperation with existing code (by +disabling pointer authentication dynamically). This document will generally +attempt to present the pointer authentication feature independent of any +hardware implementation or ABI. Considerations that are +implementation-specific are clearly identified throughout. + +Note that there are several different terms in use: + +- **Pointer authentication** is a target-independent language technology. + +- **PAuth** (sometimes referred to as **PAC**, for Pointer Authentication + Codes) is an AArch64 architecture extension that provides hardware support + for pointer authentication. Additional extensions either modify some of the + PAuth instruction behavior (notably FPAC), or provide new instruction + variants (PAuth_LR). + +- **Armv8.3** is an AArch64 architecture revision that makes PAuth mandatory. + +- **arm64e** is a specific ABI (not yet fully stable) for implementing pointer + authentication using PAuth on certain Apple operating systems. + +This document serves four purposes: + +- It describes the basic ideas of pointer authentication. + +- It documents several language extensions that are useful on targets using + pointer authentication. + +- It will eventually present a theory of operation for the security mitigation, + describing the basic requirements for correctness, various weaknesses in the + mechanism, and ways in which programmers can strengthen its protections + (including recommendations for language implementors). + +- It will eventually document the language ABIs currently used for C, C++, + Objective-C, and Swift on arm64e, although these are not yet stable on any + target. + +Basic Concepts +-------------- + +The simple address of an object or function is a **raw pointer**. A raw +pointer can be **signed** to produce a **signed pointer**. A signed pointer +can be then **authenticated** in order to verify that it was **validly signed** +and extract the original raw pointer. These terms reflect the most likely +implementation technique: computing and storing a cryptographic signature along +with the pointer. + +An **abstract signing key** is a name which refers to a secret key which is +used to sign and authenticate pointers. The concrete key value for a +particular name is consistent throughout a process. + +A **discriminator** is an arbitrary value used to **diversify** signed pointers +so that one validly-signed pointer cannot simply be copied over another. +A discriminator is simply opaque data of some implementation-defined size that +is included in the signature as a salt (see `Discriminators`_ for details.) + +Nearly all aspects of pointer authentication use just these two primary +operations: + +- ``sign(raw_pointer, key, discriminator)`` produces a signed pointer given + a raw pointer, an abstract signing key, and a discriminator. + +- ``auth(signed_pointer, key, discriminator)`` produces a raw pointer given + a signed pointer, an abstract signing key, and a discriminator. + +``auth(sign(raw_pointer, key, discriminator), key, discriminator)`` must +succeed and produce ``raw_pointer``. ``auth`` applied to a value that was +ultimately produced in any other way is expected to fail, which halts the +program either: + +- immediately, on implementations that enforce ``auth`` success (e.g., when + using compiler-generated ``auth`` failure checks, or Armv8.3 with the FPAC + extension), or + +- when the resulting pointer value is used, on implementations that don't. + +However, regardless of the implementation's handling of ``auth`` failures, it +is permitted for ``auth`` to fail to detect that a signed pointer was not +produced in this way, in which case it may return anything; this is what makes +pointer authentication a probabilistic mitigation rather than a perfect one. + +There are two secondary operations which are required only to implement certain +intrinsics in ````: + +- ``strip(signed_pointer, key)`` produces a raw pointer given a signed pointer + and a key without verifying its validity, unlike ``auth``. This is useful + for certain kinds of tooling, such as crash backtraces; it should generally + not be used in the basic language ABI except in very careful ways. + +- ``sign_generic(value)`` produces a cryptographic signature for arbitrary + data, not necessarily a pointer. This is useful for efficiently verifying + that non-pointer data has not been tampered with. + +Whenever any of these operations is called for, the key value must be known +statically. This is because the layout of a signed pointer may vary according +to the signing key. (For example, in Armv8.3, the layout of a signed pointer +depends on whether Top Byte Ignore (TBI) is enabled, which can be set +independently for I and D keys.) + +.. admonition:: Note for API designers and language implementors + + These are the *primitive* operations of pointer authentication, provided for + clarity of description. They are not suitable either as high-level + interfaces or as primitives in a compiler IR because they expose raw + pointers. Raw pointers require special attention in the language + implementation to avoid the accidental creation of exploitable code + sequences. + +The following details are all implementation-defined: + +- the nature of a signed pointer +- the size of a discriminator +- the number and nature of the signing keys +- the implementation of the ``sign``, ``auth``, ``strip``, and ``sign_generic`` + operations + +While the use of the terms "sign" and "signed pointer" suggest the use of +a cryptographic signature, other implementations may be possible. See +`Alternative implementations`_ for an exploration of implementation options. + +.. admonition:: Implementation example: Armv8.3 + + Readers may find it helpful to know how these terms map to Armv8.3 PAuth: + + - A signed pointer is a pointer with a signature stored in the + otherwise-unused high bits. The kernel configures the address width based + on the system's addressing needs, and enables TBI for I or D keys as + needed. The bits above the address bits and below the TBI bits (if + enabled) are unused. The signature width then depends on this addressing + configuration. + + - A discriminator is a 64-bit integer. Constant discriminators are 16-bit + integers. Blending a constant discriminator into an address consists of + replacing the top 16 bits of the pointer containing the address with the + constant. Pointers used for blending purposes should only have address + bits, since higher bits will be at least partially overwritten with the + constant discriminator. + + - There are five 128-bit signing-key registers, each of which can only be + directly read or set by privileged code. Of these, four are used for + signing pointers, and the fifth is used only for ``sign_generic``. The key + data is simply a pepper added to the hash, not an encryption key, and so + can be initialized using random data. + + - ``sign`` computes a cryptographic hash of the pointer, discriminator, and + signing key, and stores it in the high bits as the signature. ``auth`` + removes the signature, computes the same hash, and compares the result with + the stored signature. ``strip`` removes the signature without + authenticating it. While ``aut*`` instructions do not themselves trap on + failure in Armv8.3 PAuth, they do with the later optional FPAC extension. + An implementation can also choose to emulate this trapping behavior by + emitting additional instructions around ``aut*``. + + - ``sign_generic`` corresponds to the ``pacga`` instruction, which takes two + 64-bit values and produces a 64-bit cryptographic hash. Implementations of + this instruction are not required to produce meaningful data in all bits of + the result. + +Discriminators +~~~~~~~~~~~~~~ + +A discriminator is arbitrary extra data which alters the signature calculated +for a pointer. When two pointers are signed differently --- either with +different keys or with different discriminators --- an attacker cannot simply +replace one pointer with the other. + +To use standard cryptographic terminology, a discriminator acts as a +`salt `_ in the signing of a +pointer, and the key data acts as a +`pepper `_. That is, +both the discriminator and key data are ultimately just added as inputs to the +signing algorithm along with the pointer, but they serve significantly +different roles. The key data is a common secret added to every signature, +whereas the discriminator is a value that can be derived from +the context in which a specific pointer is signed. However, unlike a password +salt, it's important that discriminators be *independently* derived from the +circumstances of the signing; they should never simply be stored alongside +a pointer. Discriminators are then re-derived in authentication operations. + +The intrinsic interface in ```` allows an arbitrary discriminator +value to be provided, but can only be used when running normal code. The +discriminators used by language ABIs must be restricted to make it feasible for +the loader to sign pointers stored in global memory without needing excessive +amounts of metadata. Under these restrictions, a discriminator may consist of +either or both of the following: + +- The address at which the pointer is stored in memory. A pointer signed with + a discriminator which incorporates its storage address is said to have + **address diversity**. In general, using address diversity means that + a pointer cannot be reliably copied by an attacker to or from a different + memory location. However, an attacker may still be able to attack a larger + call sequence if they can alter the address through which the pointer is + accessed. Furthermore, some situations cannot use address diversity because + of language or other restrictions. + +- A constant integer, called a **constant discriminator**. A pointer signed + with a non-zero constant discriminator is said to have **constant + diversity**. If the discriminator is specific to a single declaration, it is + said to have **declaration diversity**; if the discriminator is specific to + a type of value, it is said to have **type diversity**. For example, C++ + v-tables on arm64e sign their component functions using a hash of their + method names and signatures, which provides declaration diversity; similarly, + C++ member function pointers sign their invocation functions using a hash of + the member pointer type, which provides type diversity. + +The implementation may need to restrict constant discriminators to be +significantly smaller than the full size of a discriminator. For example, on +arm64e, constant discriminators are only 16-bit values. This is believed to +not significantly weaken the mitigation, since collisions remain uncommon. + +The algorithm for blending a constant discriminator with a storage address is +implementation-defined. + +.. _Signing schemas: + +Signing Schemas +~~~~~~~~~~~~~~~ + +Correct use of pointer authentication requires the signing code and the +authenticating code to agree about the **signing schema** for the pointer: + +- the abstract signing key with which the pointer should be signed and +- an algorithm for computing the discriminator. + +As described in the section above on `Discriminators`_, in most situations, the +discriminator is produced by taking a constant discriminator and optionally +blending it with the storage address of the pointer. In these situations, the +signing schema breaks down even more simply: + +- the abstract signing key, +- a constant discriminator, and +- whether to use address diversity. + +It is important that the signing schema be independently derived at all signing +and authentication sites. Preferably, the schema should be hard-coded +everywhere it is needed, but at the very least, it must not be derived by +inspecting information stored along with the pointer. + +Language Features +----------------- + +There is currently one main pointer authentication language feature: + +- The language provides the ```` intrinsic interface for manually + signing and authenticating pointers in code. These can be used in + circumstances where very specific behavior is required. + + +Language Extensions +~~~~~~~~~~~~~~~~~~~ + +Feature Testing +^^^^^^^^^^^^^^^ + +Whether the current target uses pointer authentication can be tested for with +a number of different tests. + +- ``__has_feature(ptrauth_intrinsics)`` is true if ```` provides its + normal interface. This may be true even on targets where pointer + authentication is not enabled by default. + +```` +~~~~~~~~~~~~~~~ + +This header defines the following types and operations: + +``ptrauth_key`` +^^^^^^^^^^^^^^^ + +This ``enum`` is the type of abstract signing keys. In addition to defining +the set of implementation-specific signing keys (for example, Armv8.3 defines +``ptrauth_key_asia``), it also defines some portable aliases for those keys. +For example, ``ptrauth_key_function_pointer`` is the key generally used for +C function pointers, which will generally be suitable for other +function-signing schemas. + +In all the operation descriptions below, key values must be constant values +corresponding to one of the implementation-specific abstract signing keys from +this ``enum``. + +``ptrauth_extra_data_t`` +^^^^^^^^^^^^^^^^^^^^^^^^ + +This is a ``typedef`` of a standard integer type of the correct size to hold +a discriminator value. + +In the signing and authentication operation descriptions below, discriminator +values must have either pointer type or integer type. If the discriminator is +an integer, it will be coerced to ``ptrauth_extra_data_t``. + +``ptrauth_blend_discriminator`` +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. code-block:: c + + ptrauth_blend_discriminator(pointer, integer) + +Produce a discriminator value which blends information from the given pointer +and the given integer. + +Implementations may ignore some bits from each value, which is to say, the +blending algorithm may be chosen for speed and convenience over theoretical +strength as a hash-combining algorithm. For example, arm64e simply overwrites +the high 16 bits of the pointer with the low 16 bits of the integer, which can +be done in a single instruction with an immediate integer. + +``pointer`` must have pointer type, and ``integer`` must have integer type. The +result has type ``ptrauth_extra_data_t``. + +``ptrauth_strip`` +^^^^^^^^^^^^^^^^^ + +.. code-block:: c + + ptrauth_strip(signedPointer, key) + +Given that ``signedPointer`` matches the layout for signed pointers signed with +the given key, extract the raw pointer from it. This operation does not trap +and cannot fail, even if the pointer is not validly signed. + +``ptrauth_sign_unauthenticated`` +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. code-block:: c + + ptrauth_sign_unauthenticated(pointer, key, discriminator) + +Produce a signed pointer for the given raw pointer without applying any +authentication or extra treatment. This operation is not required to have the +same behavior on a null pointer that the language implementation would. + +This is a treacherous operation that can easily result in signing oracles. +Programs should use it seldom and carefully. + +``ptrauth_auth_and_resign`` +^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. code-block:: c + + ptrauth_auth_and_resign(pointer, oldKey, oldDiscriminator, newKey, newDiscriminator) + +Authenticate that ``pointer`` is signed with ``oldKey`` and +``oldDiscriminator`` and then resign the raw-pointer result of that +authentication with ``newKey`` and ``newDiscriminator``. + +``pointer`` must have pointer type. The result will have the same type as +``pointer``. This operation is not required to have the same behavior on +a null pointer that the language implementation would. + +The code sequence produced for this operation must not be directly attackable. +However, if the discriminator values are not constant integers, their +computations may still be attackable. In the future, Clang should be enhanced +to guaranteed non-attackability if these expressions are safely-derived. + +``ptrauth_auth_data`` +^^^^^^^^^^^^^^^^^^^^^ + +.. code-block:: c + + ptrauth_auth_data(pointer, key, discriminator) + +Authenticate that ``pointer`` is signed with ``key`` and ``discriminator`` and +remove the signature. + +``pointer`` must have object pointer type. The result will have the same type +as ``pointer``. This operation is not required to have the same behavior on +a null pointer that the language implementation would. + +In the future when Clang makes safe derivation guarantees, the result of +this operation should be considered safely-derived. + +``ptrauth_sign_generic_data`` +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. code-block:: c + + ptrauth_sign_generic_data(value1, value2) + +Computes a signature for the given pair of values, incorporating a secret +signing key. + +This operation can be used to verify that arbitrary data has not been tampered +with by computing a signature for the data, storing that signature, and then +repeating this process and verifying that it yields the same result. This can +be reasonably done in any number of ways; for example, a library could compute +an ordinary checksum of the data and just sign the result in order to get the +tamper-resistance advantages of the secret signing key (since otherwise an +attacker could reliably overwrite both the data and the checksum). + +``value1`` and ``value2`` must be either pointers or integers. If the integers +are larger than ``uintptr_t`` then data not representable in ``uintptr_t`` may +be discarded. + +The result will have type ``ptrauth_generic_signature_t``, which is an integer +type. Implementations are not required to make all bits of the result equally +significant; in particular, some implementations are known to not leave +meaningful data in the low bits. + + + +Alternative Implementations +--------------------------- + +Signature Storage +~~~~~~~~~~~~~~~~~ + +It is not critical for the security of pointer authentication that the +signature be stored "together" with the pointer, as it is in Armv8.3. An +implementation could just as well store the signature in a separate word, so +that the ``sizeof`` a signed pointer would be larger than the ``sizeof`` a raw +pointer. + +Storing the signature in the high bits, as Armv8.3 does, has several trade-offs: + +- Disadvantage: there are substantially fewer bits available for the signature, + weakening the mitigation by making it much easier for an attacker to simply + guess the correct signature. + +- Disadvantage: future growth of the address space will necessarily further + weaken the mitigation. + +- Advantage: memory layouts don't change, so it's possible for + pointer-authentication-enabled code (for example, in a system library) to + efficiently interoperate with existing code, as long as pointer + authentication can be disabled dynamically. + +- Advantage: the size of a signed pointer doesn't grow, which might + significantly increase memory requirements, code size, and register pressure. + +- Advantage: the size of a signed pointer is the same as a raw pointer, so + generic APIs which work in types like `void *` (such as `dlsym`) can still + return signed pointers. This means that clients of these APIs will not + require insecure code in order to correctly receive a function pointer. + +Hashing vs. Encrypting Pointers +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Armv8.3 implements ``sign`` by computing a cryptographic hash and storing that +in the spare bits of the pointer. This means that there are relatively few +possible values for the valid signed pointer, since the bits corresponding to +the raw pointer are known. Together with an ``auth`` oracle, this can make it +computationally feasible to discover the correct signature with brute force. +(The implementation should of course endeavor not to introduce ``auth`` +oracles, but this can be difficult, and attackers can be devious.) + +If the implementation can instead *encrypt* the pointer during ``sign`` and +*decrypt* it during ``auth``, this brute-force attack becomes far less +feasible, even with an ``auth`` oracle. However, there are several problems +with this idea: + +- It's unclear whether this kind of encryption is even possible without + increasing the storage size of a signed pointer. If the storage size can be + increased, brute-force atacks can be equally well mitigated by simply storing + a larger signature. + +- It would likely be impossible to implement a ``strip`` operation, which might + make debuggers and other out-of-process tools far more difficult to write, as + well as generally making primitive debugging more challenging. + +- Implementations can benefit from being able to extract the raw pointer + immediately from a signed pointer. An Armv8.3 processor executing an + ``auth``-and-load instruction can perform the load and ``auth`` in parallel; + a processor which instead encrypted the pointer would be forced to perform + these operations serially. diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index 690fc7ed271a3dba2ba9021ad1fad7fdc5a2e560..3a74c070ff9ffee7a3abc6c503495dd6cbdfc974 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -47,6 +47,12 @@ C++ Specific Potentially Breaking Changes ABI Changes in This Version --------------------------- +- Fixed Microsoft name mangling of implicitly defined variables used for thread + safe static initialization of static local variables. This change resolves + incompatibilities with code compiled by MSVC but might introduce + incompatibilities with code compiled by earlier versions of Clang when an + inline member function that contains a static local variable with a dynamic + initializer is declared with ``__declspec(dllimport)``. (#GH83616). AST Dumping Potentially Breaking Changes ---------------------------------------- @@ -100,6 +106,7 @@ C++23 Feature Support - Implemented `P2718R0: Lifetime extension in range-based for loops `_. Also materialize temporary object which is a prvalue in discarded-value expression. +- Implemented `P1774R8: Portable assumptions `_. - Implemented `P2448R2: Relaxing some constexpr restrictions `_. @@ -182,14 +189,26 @@ Deprecated Compiler Flags Modified Compiler Flags ----------------------- +- Added a new diagnostic flag ``-Wreturn-mismatch`` which is grouped under + ``-Wreturn-type``, and moved some of the diagnostics previously controlled by + ``-Wreturn-type`` under this new flag. Fixes #GH72116. Removed Compiler Flags ------------------------- - The ``-freroll-loops`` flag has been removed. It had no effect since Clang 13. +- ``-m[no-]unaligned-access`` is removed for RISC-V and LoongArch. + ``-m[no-]strict-align``, also supported by GCC, should be used instead. + (`#85350 `_.) Attribute Changes in Clang -------------------------- +- Introduced a new function attribute ``__attribute__((amdgpu_max_num_work_groups(x, y, z)))`` or + ``[[clang::amdgpu_max_num_work_groups(x, y, z)]]`` for the AMDGPU target. This attribute can be + attached to HIP or OpenCL kernel function definitions to provide an optimization hint. The parameters + ``x``, ``y``, and ``z`` specify the maximum number of workgroups for the respective dimensions, + and each must be a positive integer when provided. The parameter ``x`` is required, while ``y`` and + ``z`` are optional with default value of 1. Improvements to Clang's diagnostics ----------------------------------- @@ -227,6 +246,14 @@ Improvements to Clang's diagnostics - Clang now diagnoses lambda function expressions being implicitly cast to boolean values, under ``-Wpointer-bool-conversion``. Fixes #GH82512. +- Clang now provides improved warnings for the ``cleanup`` attribute to detect misuse scenarios, + such as attempting to call ``free`` on an unallocated object. Fixes + `#79443 `_. + +- Clang no longer warns when the ``bitand`` operator is used with boolean + operands, distinguishing it from potential typographical errors or unintended + bitwise operations. Fixes #GH77601. + Improvements to Clang's time-trace ---------------------------------- @@ -250,6 +277,9 @@ Bug Fixes in This Version for logical operators in C23. Fixes (#GH64356). +- ``__is_trivially_relocatable`` no longer returns ``false`` for volatile-qualified types. + Fixes (#GH77091). + - Clang no longer produces a false-positive `-Wunused-variable` warning for variables created through copy initialization having side-effects in C++17 and later. Fixes (#GH64356) (#GH79518). @@ -258,6 +288,19 @@ Bug Fixes in This Version operator. Fixes (#GH83267). +- Clang now correctly generates overloads for bit-precise integer types for + builtin operators in C++. Fixes #GH82998. + +- When performing mixed arithmetic between ``_Complex`` floating-point types and integers, + Clang now correctly promotes the integer to its corresponding real floating-point + type only rather than to the complex type (e.g. ``_Complex float / int`` is now evaluated + as ``_Complex float / float`` rather than ``_Complex float / _Complex float``), as mandated + by the C standard. This significantly improves codegen of `*` and `/` especially. + Fixes (`#31205 `_). + +- Fixes an assertion failure on invalid code when trying to define member + functions in lambdas. + Bug Fixes to Compiler Builtins ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -344,9 +387,21 @@ Bug Fixes to C++ Support when one of the function had more specialized templates. Fixes (`#82509 `_) and (`#74494 `_) +- Allow access to a public template alias declaration that refers to friend's + private nested type. (#GH25708). +- Fixed a crash in constant evaluation when trying to access a + captured ``this`` pointer in a lambda with an explicit object parameter. + Fixes (#GH80997) +- Fix an issue where missing set friend declaration in template class instantiation. + Fixes (#GH84368). +- Fixed a crash while checking constraints of a trailing requires-expression of a lambda, that the + expression references to an entity declared outside of the lambda. (#GH64808) +- Clang's __builtin_bit_cast will now produce a constant value for records with empty bases. See: + (#GH82383) Bug Fixes to AST Handling ^^^^^^^^^^^^^^^^^^^^^^^^^ +- Clang now properly preserves ``FoundDecls`` within a ``ConceptReference``. (#GH82628) Miscellaneous Bug Fixes ^^^^^^^^^^^^^^^^^^^^^^^ @@ -408,7 +463,7 @@ RISC-V Support CUDA/HIP Language Changes ^^^^^^^^^^^^^^^^^^^^^^^^^ -- PTX is no longer included by default when compiling for CUDA. Using +- PTX is no longer included by default when compiling for CUDA. Using ``--cuda-include-ptx=all`` will return the old behavior. CUDA Support @@ -440,6 +495,8 @@ AST Matchers - ``isInStdNamespace`` now supports Decl declared with ``extern "C++"``. - Add ``isExplicitObjectMemberFunction``. +- Fixed ``forEachArgumentWithParam`` and ``forEachArgumentWithParamType`` to + not skip the explicit object parameter for operator calls. clang-format ------------ @@ -455,6 +512,10 @@ libclang Static Analyzer --------------- +- Fixed crashing on loops if the loop variable was declared in switch blocks + but not under any case blocks if ``unroll-loops=true`` analyzer config is + set. (#GH68819) + New features ^^^^^^^^^^^^ @@ -489,6 +550,13 @@ Python Binding Changes ---------------------- - Exposed `CXRewriter` API as `class Rewriter`. +- Add some missing kinds from Index.h (CursorKind: 149-156, 272-320, 420-437. + TemplateArgumentKind: 5-9. TypeKind: 161-175 and 178). + +OpenMP Support +-------------- + +- Added support for the `[[omp::assume]]` attribute. Additional Information ====================== diff --git a/clang/docs/UsersManual.rst b/clang/docs/UsersManual.rst index 7391e4cf3a9aeb47bc949a2121db80896a903b89..7a63d720241a7a8bf81697dae6ca1fc4c217a366 100644 --- a/clang/docs/UsersManual.rst +++ b/clang/docs/UsersManual.rst @@ -4227,7 +4227,68 @@ Clang expects the GCC executable "gcc.exe" compiled for AIX ^^^ +TOC Data Transformation +""""""""""""""""""""""" +TOC data transformation is off by default (``-mno-tocdata``). +When ``-mtocdata`` is specified, the TOC data transformation will be applied to +all suitable variables with static storage duration, including static data +members of classes and block-scope static variables (if not marked as exceptions, +see further below). +Suitable variables must: + +- have complete types +- be independently generated (i.e., not placed in a pool) +- be at most as large as a pointer +- not be aligned more strictly than a pointer +- not be structs containing flexible array members +- not have internal linkage +- not have aliases +- not have section attributes +- not be thread local storage + +The TOC data transformation results in the variable, not its address, +being placed in the TOC. This eliminates the need to load the address of the +variable from the TOC. + +Note: +If the TOC data transformation is applied to a variable whose definition +is imported, the linker will generate fixup code for reading or writing to the +variable. + +When multiple toc-data options are used, the last option used has the affect. +For example: -mno-tocdata=g5,g1 -mtocdata=g1,g2 -mno-tocdata=g2 -mtocdata=g3,g4 +results in -mtocdata=g1,g3,g4 + +Names of variables not having external linkage will be ignored. + +**Options:** + +.. option:: -mno-tocdata + + This is the default behaviour. Only variables explicitly specified with + ``-mtocdata=`` will have the TOC data transformation applied. + +.. option:: -mtocdata + + Apply the TOC data transformation to all suitable variables with static + storage duration (including static data members of classes and block-scope + static variables) that are not explicitly specified with ``-mno-tocdata=``. + +.. option:: -mno-tocdata= + + Can be used in conjunction with ``-mtocdata`` to mark the comma-separated + list of external linkage variables, specified using their mangled names, as + exceptions to ``-mtocdata``. + +.. option:: -mtocdata= + + Apply the TOC data transformation to the comma-separated list of external + linkage variables, specified using their mangled names, if they are suitable. + Emit diagnostics for all unsuitable variables specified. + +Default Visibility Export Mapping +""""""""""""""""""""""""""""""""" The ``-mdefault-visibility-export-mapping=`` option can be used to control mapping of default visibility to an explicit shared object export (i.e. XCOFF exported visibility). Three values are provided for the option: diff --git a/clang/include/clang-c/Index.h b/clang/include/clang-c/Index.h index 3f3620609b6ddc08c88752c0aa744c9f083d01ff..60db3cf0966c0263083b82e1dec923ffe42bcff2 100644 --- a/clang/include/clang-c/Index.h +++ b/clang/include/clang-c/Index.h @@ -1675,7 +1675,7 @@ enum CXCursorKind { CXCursor_ConceptSpecializationExpr = 153, /** - * Expression that references a C++20 concept. + * Expression that references a C++20 requires expression. */ CXCursor_RequiresExpr = 154, diff --git a/clang/include/clang/AST/Availability.h b/clang/include/clang/AST/Availability.h index ae3acbeffe7f189f9ff3f907eb9250b870c6d273..5cfbaf0cdfbd212c94ce176fdb3fc6d3495523c9 100644 --- a/clang/include/clang/AST/Availability.h +++ b/clang/include/clang/AST/Availability.h @@ -75,6 +75,9 @@ struct AvailabilityInfo { /// Determine if this AvailabilityInfo represents the default availability. bool isDefault() const { return *this == AvailabilityInfo(); } + /// Check if the symbol has been obsoleted. + bool isObsoleted() const { return !Obsoleted.empty(); } + /// Check if the symbol is unconditionally deprecated. /// /// i.e. \code __attribute__((deprecated)) \endcode diff --git a/clang/include/clang/AST/DeclBase.h b/clang/include/clang/AST/DeclBase.h index 76810a86a78a46b20b86f9baa06022b5c1dfa4e9..47ed6d0d1db0df804f55cdfca4c5c0ddd4868bb9 100644 --- a/clang/include/clang/AST/DeclBase.h +++ b/clang/include/clang/AST/DeclBase.h @@ -673,6 +673,16 @@ public: /// fragment. See [module.global.frag]p3,4 for details. bool isDiscardedInGlobalModuleFragment() const { return false; } + /// Check if we should skip checking ODRHash for declaration \param D. + /// + /// The existing ODRHash mechanism seems to be not stable enough and + /// the false positive ODR violation reports are annoying and we rarely see + /// true ODR violation reports. Also we learned that MSVC disabled ODR checks + /// for declarations in GMF. So we try to disable ODR checks in the GMF to + /// get better user experiences before we make the ODR violation checks stable + /// enough. + bool shouldSkipCheckingODR() const; + /// Return true if this declaration has an attribute which acts as /// definition of the entity, such as 'alias' or 'ifunc'. bool hasDefiningAttr() const; diff --git a/clang/include/clang/AST/ExprCXX.h b/clang/include/clang/AST/ExprCXX.h index a0e467b35778c5c5f2b7a358ebb95c243ce9f86a..6003b866c9f564519006077b3618fc324bd09bef 100644 --- a/clang/include/clang/AST/ExprCXX.h +++ b/clang/include/clang/AST/ExprCXX.h @@ -5038,6 +5038,9 @@ class CoroutineSuspendExpr : public Expr { OpaqueValueExpr *OpaqueValue = nullptr; public: + // These types correspond to the three C++ 'await_suspend' return variants + enum class SuspendReturnType { SuspendVoid, SuspendBool, SuspendHandle }; + CoroutineSuspendExpr(StmtClass SC, SourceLocation KeywordLoc, Expr *Operand, Expr *Common, Expr *Ready, Expr *Suspend, Expr *Resume, OpaqueValueExpr *OpaqueValue) @@ -5097,6 +5100,24 @@ public: return static_cast(SubExprs[SubExpr::Operand]); } + SuspendReturnType getSuspendReturnType() const { + auto *SuspendExpr = getSuspendExpr(); + assert(SuspendExpr); + + auto SuspendType = SuspendExpr->getType(); + + if (SuspendType->isVoidType()) + return SuspendReturnType::SuspendVoid; + if (SuspendType->isBooleanType()) + return SuspendReturnType::SuspendBool; + + // Void pointer is the type of handle.address(), which is returned + // from the await suspend wrapper so that the temporary coroutine handle + // value won't go to the frame by mistake + assert(SuspendType->isVoidPointerType()); + return SuspendReturnType::SuspendHandle; + } + SourceLocation getKeywordLoc() const { return KeywordLoc; } SourceLocation getBeginLoc() const LLVM_READONLY { return KeywordLoc; } diff --git a/clang/include/clang/AST/Type.h b/clang/include/clang/AST/Type.h index 1942b0e67f65a3157a36ae1b7dbf55bf9398a10f..10916053cdfbf564d11c3c4354ba74c93b6be753 100644 --- a/clang/include/clang/AST/Type.h +++ b/clang/include/clang/AST/Type.h @@ -2244,6 +2244,7 @@ public: bool isFloatingType() const; // C99 6.2.5p11 (real floating + complex) bool isHalfType() const; // OpenCL 6.1.1.1, NEON (IEEE 754-2008 half) bool isFloat16Type() const; // C11 extension ISO/IEC TS 18661 + bool isFloat32Type() const; bool isBFloat16Type() const; bool isFloat128Type() const; bool isIbm128Type() const; @@ -7452,6 +7453,10 @@ inline bool Type::isFloat16Type() const { return isSpecificBuiltinType(BuiltinType::Float16); } +inline bool Type::isFloat32Type() const { + return isSpecificBuiltinType(BuiltinType::Float); +} + inline bool Type::isBFloat16Type() const { return isSpecificBuiltinType(BuiltinType::BFloat16); } diff --git a/clang/include/clang/ASTMatchers/ASTMatchers.h b/clang/include/clang/ASTMatchers/ASTMatchers.h index 96dbcdc344e131acadb629276434854a011d92df..2f71053d030f688f6921d15e265072a8b0cbf759 100644 --- a/clang/include/clang/ASTMatchers/ASTMatchers.h +++ b/clang/include/clang/ASTMatchers/ASTMatchers.h @@ -5032,6 +5032,25 @@ AST_POLYMORPHIC_MATCHER_P2(hasParameter, && InnerMatcher.matches(*Node.parameters()[N], Finder, Builder)); } +/// Matches if the given method declaration declares a member function with an +/// explicit object parameter. +/// +/// Given +/// \code +/// struct A { +/// int operator-(this A, int); +/// void fun(this A &&self); +/// static int operator()(int); +/// int operator+(int); +/// }; +/// \endcode +/// +/// cxxMethodDecl(isExplicitObjectMemberFunction()) matches the first two +/// methods but not the last two. +AST_MATCHER(CXXMethodDecl, isExplicitObjectMemberFunction) { + return Node.isExplicitObjectMemberFunction(); +} + /// Matches all arguments and their respective ParmVarDecl. /// /// Given @@ -5060,10 +5079,12 @@ AST_POLYMORPHIC_MATCHER_P2(forEachArgumentWithParam, // argument of the method which should not be matched against a parameter, so // we skip over it here. BoundNodesTreeBuilder Matches; - unsigned ArgIndex = cxxOperatorCallExpr(callee(cxxMethodDecl())) - .matches(Node, Finder, &Matches) - ? 1 - : 0; + unsigned ArgIndex = + cxxOperatorCallExpr( + callee(cxxMethodDecl(unless(isExplicitObjectMemberFunction())))) + .matches(Node, Finder, &Matches) + ? 1 + : 0; int ParamIndex = 0; bool Matched = false; for (; ArgIndex < Node.getNumArgs(); ++ArgIndex) { @@ -5121,11 +5142,12 @@ AST_POLYMORPHIC_MATCHER_P2(forEachArgumentWithParamType, // argument of the method which should not be matched against a parameter, so // we skip over it here. BoundNodesTreeBuilder Matches; - unsigned ArgIndex = cxxOperatorCallExpr(callee(cxxMethodDecl())) - .matches(Node, Finder, &Matches) - ? 1 - : 0; - + unsigned ArgIndex = + cxxOperatorCallExpr( + callee(cxxMethodDecl(unless(isExplicitObjectMemberFunction())))) + .matches(Node, Finder, &Matches) + ? 1 + : 0; const FunctionProtoType *FProto = nullptr; if (const auto *Call = dyn_cast(&Node)) { @@ -6366,25 +6388,6 @@ AST_MATCHER(CXXMethodDecl, isConst) { return Node.isConst(); } -/// Matches if the given method declaration declares a member function with an -/// explicit object parameter. -/// -/// Given -/// \code -/// struct A { -/// int operator-(this A, int); -/// void fun(this A &&self); -/// static int operator()(int); -/// int operator+(int); -/// }; -/// \endcode -/// -/// cxxMethodDecl(isExplicitObjectMemberFunction()) matches the first two -/// methods but not the last two. -AST_MATCHER(CXXMethodDecl, isExplicitObjectMemberFunction) { - return Node.isExplicitObjectMemberFunction(); -} - /// Matches if the given method declaration declares a copy assignment /// operator. /// diff --git a/clang/include/clang/Basic/AllDiagnostics.h b/clang/include/clang/Basic/AllDiagnostics.h index cc6aa631534a5d4ad2a3bea23de1e9c77bba1078..e64634cc138f7fd75d2d17227ee69eafa5ea2461 100644 --- a/clang/include/clang/Basic/AllDiagnostics.h +++ b/clang/include/clang/Basic/AllDiagnostics.h @@ -20,6 +20,7 @@ #include "clang/Basic/DiagnosticCrossTU.h" #include "clang/Basic/DiagnosticDriver.h" #include "clang/Basic/DiagnosticFrontend.h" +#include "clang/Basic/DiagnosticInstallAPI.h" #include "clang/Basic/DiagnosticLex.h" #include "clang/Basic/DiagnosticParse.h" #include "clang/Basic/DiagnosticSema.h" diff --git a/clang/include/clang/Basic/Attr.td b/clang/include/clang/Basic/Attr.td index ebb616fbe253fca1bb310a792d06b3df4e68b967..67d87eca16ede8a1ed28410da331105a0c1af25b 100644 --- a/clang/include/clang/Basic/Attr.td +++ b/clang/include/clang/Basic/Attr.td @@ -1580,6 +1580,13 @@ def Unlikely : StmtAttr { } def : MutualExclusions<[Likely, Unlikely]>; +def CXXAssume : StmtAttr { + let Spellings = [CXX11<"", "assume", 202207>]; + let Subjects = SubjectList<[NullStmt], ErrorDiag, "empty statements">; + let Args = [ExprArgument<"Assumption">]; + let Documentation = [CXXAssumeDocs]; +} + def NoMerge : DeclOrStmtAttr { let Spellings = [Clang<"nomerge">]; let Documentation = [NoMergeDocs]; @@ -2047,6 +2054,13 @@ def AMDGPUNumVGPR : InheritableAttr { let Subjects = SubjectList<[Function], ErrorDiag, "kernel functions">; } +def AMDGPUMaxNumWorkGroups : InheritableAttr { + let Spellings = [Clang<"amdgpu_max_num_work_groups", 0>]; + let Args = [ExprArgument<"MaxNumWorkGroupsX">, ExprArgument<"MaxNumWorkGroupsY", 1>, ExprArgument<"MaxNumWorkGroupsZ", 1>]; + let Documentation = [AMDGPUMaxNumWorkGroupsDocs]; + let Subjects = SubjectList<[Function], ErrorDiag, "kernel functions">; +} + def AMDGPUKernelCall : DeclOrTypeAttr { let Spellings = [Clang<"amdgpu_kernel">]; let Documentation = [Undocumented]; @@ -2920,7 +2934,7 @@ def Suppress : DeclOrStmtAttr { def SysVABI : DeclOrTypeAttr { let Spellings = [GCC<"sysv_abi">]; // let Subjects = [Function, ObjCMethod]; - let Documentation = [Undocumented]; + let Documentation = [SysVABIDocs]; } def ThisCall : DeclOrTypeAttr { @@ -4151,11 +4165,11 @@ def OMPDeclareVariant : InheritableAttr { }]; } -def Assumption : InheritableAttr { - let Spellings = [Clang<"assume">]; +def OMPAssume : InheritableAttr { + let Spellings = [Clang<"assume">, CXX11<"omp", "assume">]; let Subjects = SubjectList<[Function, ObjCMethod]>; let InheritEvenIfAlreadyPresent = 1; - let Documentation = [AssumptionDocs]; + let Documentation = [OMPAssumeDocs]; let Args = [StringArgument<"Assumption">]; } diff --git a/clang/include/clang/Basic/AttrDocs.td b/clang/include/clang/Basic/AttrDocs.td index b96fbddd51154ca7c7b87390a0ea27911e0df3d6..d61f96ade557d545b1b8a57453a0749535c037df 100644 --- a/clang/include/clang/Basic/AttrDocs.td +++ b/clang/include/clang/Basic/AttrDocs.td @@ -1996,6 +1996,34 @@ Here is an example: }]; } +def CXXAssumeDocs : Documentation { + let Category = DocCatStmt; + let Heading = "assume"; + let Content = [{ +The ``assume`` attribute is used to indicate to the optimizer that a +certain condition is assumed to be true at a certain point in the +program. If this condition is violated at runtime, the behavior is +undefined. ``assume`` can only be applied to a null statement. + +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++ + + int f(int x, int y) { + [[assume(x == 27)]]; + [[assume(x == y)]]; + return y + 1; // May be optimised to `return 28`. + } + }]; +} + def LikelihoodDocs : Documentation { let Category = DocCatStmt; let Heading = "likely and unlikely"; @@ -2713,6 +2741,33 @@ An error will be given if: }]; } +def AMDGPUMaxNumWorkGroupsDocs : Documentation { + let Category = DocCatAMDGPUAttributes; + let Content = [{ +This attribute specifies the max number of work groups when the kernel +is dispatched. + +Clang supports the +``__attribute__((amdgpu_max_num_work_groups(, , )))`` or +``[[clang::amdgpu_max_num_work_groups(, , )]]`` attribute for the +AMDGPU target. This attribute may be attached to HIP or OpenCL kernel function +definitions and is an optimization hint. + +The ```` parameter specifies the maximum number of work groups in the x dimension. +Similarly ```` and ```` are for the y and z dimensions respectively. +Each of the three values must be greater than 0 when provided. The ```` parameter +is required, while ```` and ```` are optional with default value of 1. + +If specified, the AMDGPU target backend might be able to produce better machine +code. + +An error will be given if: + - Specified values violate subtarget specifications; + - Specified values are not compatible with values provided through other + attributes. + }]; +} + def DocCatCallingConvs : DocumentationCategory<"Calling Conventions"> { let Content = [{ Clang supports several different calling conventions, depending on the target @@ -4629,7 +4684,7 @@ For more information see }]; } -def AssumptionDocs : Documentation { +def OMPAssumeDocs : Documentation { let Category = DocCatFunction; let Heading = "assume"; let Content = [{ diff --git a/clang/include/clang/Basic/Builtins.def b/clang/include/clang/Basic/Builtins.def new file mode 100644 index 0000000000000000000000000000000000000000..f356f881d5ef9bc2e2a13f806d40e0ab8a93c283 --- /dev/null +++ b/clang/include/clang/Basic/Builtins.def @@ -0,0 +1,102 @@ +//===--- Builtins.def - Builtin function info database ----------*- 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 +// +//===----------------------------------------------------------------------===// + +// This is only documentation for the database layout. This will be removed once +// all builtin databases are converted to tablegen files + +// The second value provided to the macro specifies the type of the function +// (result value, then each argument) as follows: +// v -> void +// b -> boolean +// c -> char +// s -> short +// i -> int +// h -> half (__fp16, OpenCL) +// x -> half (_Float16) +// y -> half (__bf16) +// f -> float +// d -> double +// z -> size_t +// w -> wchar_t +// F -> constant CFString +// G -> id +// H -> SEL +// M -> struct objc_super +// a -> __builtin_va_list +// A -> "reference" to __builtin_va_list +// V -> Vector, followed by the number of elements and the base type. +// q -> Scalable vector, followed by the number of elements and the base type. +// Q -> target builtin type, followed by a character to distinguish the builtin type +// Qa -> AArch64 svcount_t builtin type. +// E -> ext_vector, followed by the number of elements and the base type. +// X -> _Complex, followed by the base type. +// Y -> ptrdiff_t +// P -> FILE +// J -> jmp_buf +// SJ -> sigjmp_buf +// K -> ucontext_t +// p -> pid_t +// . -> "...". This may only occur at the end of the function list. +// +// Types may be prefixed with the following modifiers: +// L -> long (e.g. Li for 'long int', Ld for 'long double') +// LL -> long long (e.g. LLi for 'long long int', LLd for __float128) +// LLL -> __int128_t (e.g. LLLi) +// Z -> int32_t (require a native 32-bit integer type on the target) +// W -> int64_t (require a native 64-bit integer type on the target) +// N -> 'int' size if target is LP64, 'L' otherwise. +// O -> long for OpenCL targets, long long otherwise. +// S -> signed +// U -> unsigned +// I -> Required to constant fold to an integer constant expression. +// +// Types may be postfixed with the following modifiers: +// * -> pointer (optionally followed by an address space number, if no address +// space is specified than any address space will be accepted) +// & -> reference (optionally followed by an address space number) +// C -> const +// D -> volatile +// R -> restrict + +// The third value provided to the macro specifies information about attributes +// of the function. These must be kept in sync with the predicates in the +// Builtin::Context class. Currently we have: +// n -> nothrow +// r -> noreturn +// U -> pure +// c -> const +// t -> signature is meaningless, use custom typechecking +// T -> type is not important to semantic analysis and codegen; recognize as +// builtin even if type doesn't match signature, and don't warn if we +// can't be sure the type is right +// F -> this is a libc/libm function with a '__builtin_' prefix added. +// f -> this is a libc/libm function without a '__builtin_' prefix, or with +// 'z', a C++ standard library function in namespace std::. This builtin +// is disableable by '-fno-builtin-foo' / '-fno-builtin-std-foo'. +// h -> this function requires a specific header or an explicit declaration. +// i -> this is a runtime library implemented function without the +// '__builtin_' prefix. It will be implemented in compiler-rt or libgcc. +// p:N: -> this is a printf-like function whose Nth argument is the format +// string. +// P:N: -> similar to the p:N: attribute, but the function is like vprintf +// in that it accepts its arguments as a va_list rather than +// through an ellipsis +// s:N: -> this is a scanf-like function whose Nth argument is the format +// string. +// S:N: -> similar to the s:N: attribute, but the function is like vscanf +// in that it accepts its arguments as a va_list rather than +// through an ellipsis +// e -> const, but only when -fno-math-errno and FP exceptions are ignored +// g -> const when FP exceptions are ignored +// j -> returns_twice (like setjmp) +// u -> arguments are not evaluated for their side-effects +// V:N: -> requires vectors of at least N bits to be legal +// C -> callback behavior: argument N is called with argument +// M_0, ..., M_k as payload +// z -> this is a function in (possibly-versioned) namespace std +// E -> this function can be constant evaluated by Clang frontend diff --git a/clang/include/clang/Basic/Builtins.td b/clang/include/clang/Basic/Builtins.td index 9c703377ca8d3e8d5bf47a6dd4ee3ad7fe4e7d97..491c9d8954130f490500a6ae40a8e21e32937e11 100644 --- a/clang/include/clang/Basic/Builtins.td +++ b/clang/include/clang/Basic/Builtins.td @@ -4354,6 +4354,43 @@ def CoroSuspend : CoroLangBuiltin { let Prototype = "char(_Constant bool)"; } +// Pointer authentication builtins. +def PtrauthStrip : Builtin { + let Spellings = ["__builtin_ptrauth_strip"]; + let Attributes = [CustomTypeChecking, NoThrow, Const]; + let Prototype = "void*(void*,int)"; +} + +def PtrauthBlendDiscriminator : Builtin { + let Spellings = ["__builtin_ptrauth_blend_discriminator"]; + let Attributes = [CustomTypeChecking, NoThrow, Const]; + let Prototype = "size_t(void*,int)"; +} + +def PtrauthSignUnauthenticated : Builtin { + let Spellings = ["__builtin_ptrauth_sign_unauthenticated"]; + let Attributes = [CustomTypeChecking, NoThrow, Const]; + let Prototype = "void*(void*,int,void*)"; +} + +def PtrauthSignGenericData : Builtin { + let Spellings = ["__builtin_ptrauth_sign_generic_data"]; + let Attributes = [CustomTypeChecking, NoThrow, Const]; + let Prototype = "size_t(void*,void*)"; +} + +def PtrauthAuthAndResign : Builtin { + let Spellings = ["__builtin_ptrauth_auth_and_resign"]; + let Attributes = [CustomTypeChecking, NoThrow]; + let Prototype = "void*(void*,int,void*,int,void*)"; +} + +def PtrauthAuth : Builtin { + let Spellings = ["__builtin_ptrauth_auth"]; + let Attributes = [CustomTypeChecking, NoThrow]; + let Prototype = "void*(void*,int,void*)"; +} + // OpenCL v2.0 s6.13.16, s9.17.3.5 - Pipe functions. // We need the generic prototype, since the packet type could be anything. def ReadPipe : OCLPipeLangBuiltin { @@ -4554,6 +4591,12 @@ def HLSLWaveActiveCountBits : LangBuiltin<"HLSL_LANG"> { let Prototype = "unsigned int(bool)"; } +def HLSLClamp : LangBuiltin<"HLSL_LANG"> { + let Spellings = ["__builtin_hlsl_elementwise_clamp"]; + let Attributes = [NoThrow, Const]; + let Prototype = "void(...)"; +} + def HLSLCreateHandle : LangBuiltin<"HLSL_LANG"> { let Spellings = ["__builtin_hlsl_create_handle"]; let Attributes = [NoThrow, Const]; @@ -4572,6 +4615,12 @@ def HLSLFrac : LangBuiltin<"HLSL_LANG"> { let Prototype = "void(...)"; } +def HLSLIsinf : LangBuiltin<"HLSL_LANG"> { + let Spellings = ["__builtin_hlsl_elementwise_isinf"]; + let Attributes = [NoThrow, Const]; + let Prototype = "void(...)"; +} + def HLSLLerp : LangBuiltin<"HLSL_LANG"> { let Spellings = ["__builtin_hlsl_lerp"]; let Attributes = [NoThrow, Const]; @@ -4590,6 +4639,12 @@ def HLSLRcp : LangBuiltin<"HLSL_LANG"> { let Prototype = "void(...)"; } +def HLSLRSqrt : LangBuiltin<"HLSL_LANG"> { + let Spellings = ["__builtin_hlsl_elementwise_rsqrt"]; + let Attributes = [NoThrow, Const]; + let Prototype = "void(...)"; +} + // Builtins for XRay. def XRayCustomEvent : Builtin { let Spellings = ["__xray_customevent"]; diff --git a/clang/include/clang/Basic/BuiltinsAArch64.def b/clang/include/clang/Basic/BuiltinsAArch64.def index b5cbe90c8fd6a35186b327dd3ca8ab75e64a18c2..cf8711c6eaee37249f4a54effb379c733ab71d5e 100644 --- a/clang/include/clang/Basic/BuiltinsAArch64.def +++ b/clang/include/clang/Basic/BuiltinsAArch64.def @@ -50,6 +50,9 @@ BUILTIN(__builtin_arm_wfi, "v", "") BUILTIN(__builtin_arm_sev, "v", "") BUILTIN(__builtin_arm_sevl, "v", "") +// Like __builtin_trap but provide an 16-bit immediate reason code (which goes into `brk #N`). +BUILTIN(__builtin_arm_trap, "vUIs", "nr") + // CRC32 TARGET_BUILTIN(__builtin_arm_crc32b, "UiUiUc", "nc", "crc") TARGET_BUILTIN(__builtin_arm_crc32cb, "UiUiUc", "nc", "crc") diff --git a/clang/include/clang/Basic/BuiltinsX86.def b/clang/include/clang/Basic/BuiltinsX86.def index 207cde0414b54e41ba88a20f82c879e8bcbae315..eafcc219c10966b8789182c486fb950c426c9e1d 100644 --- a/clang/include/clang/Basic/BuiltinsX86.def +++ b/clang/include/clang/Basic/BuiltinsX86.def @@ -226,6 +226,8 @@ TARGET_BUILTIN(__builtin_ia32_minps, "V4fV4fV4f", "ncV:128:", "sse") TARGET_BUILTIN(__builtin_ia32_maxps, "V4fV4fV4f", "ncV:128:", "sse") TARGET_BUILTIN(__builtin_ia32_minss, "V4fV4fV4f", "ncV:128:", "sse") TARGET_BUILTIN(__builtin_ia32_maxss, "V4fV4fV4f", "ncV:128:", "sse") +TARGET_BUILTIN(__builtin_ia32_cmpps, "V4fV4fV4fIc", "ncV:128:", "sse") +TARGET_BUILTIN(__builtin_ia32_cmpss, "V4fV4fV4fIc", "ncV:128:", "sse") TARGET_BUILTIN(__builtin_ia32_cmpeqpd, "V2dV2dV2d", "ncV:128:", "sse2") TARGET_BUILTIN(__builtin_ia32_cmpltpd, "V2dV2dV2d", "ncV:128:", "sse2") @@ -243,6 +245,8 @@ TARGET_BUILTIN(__builtin_ia32_cmpneqsd, "V2dV2dV2d", "ncV:128:", "sse2") TARGET_BUILTIN(__builtin_ia32_cmpnltsd, "V2dV2dV2d", "ncV:128:", "sse2") TARGET_BUILTIN(__builtin_ia32_cmpnlesd, "V2dV2dV2d", "ncV:128:", "sse2") TARGET_BUILTIN(__builtin_ia32_cmpordsd, "V2dV2dV2d", "ncV:128:", "sse2") +TARGET_BUILTIN(__builtin_ia32_cmpsd, "V2dV2dV2dIc", "ncV:128:", "sse2") +TARGET_BUILTIN(__builtin_ia32_cmppd, "V2dV2dV2dIc", "ncV:128:", "sse2") TARGET_BUILTIN(__builtin_ia32_minpd, "V2dV2dV2d", "ncV:128:", "sse2") TARGET_BUILTIN(__builtin_ia32_maxpd, "V2dV2dV2d", "ncV:128:", "sse2") TARGET_BUILTIN(__builtin_ia32_minsd, "V2dV2dV2d", "ncV:128:", "sse2") @@ -462,12 +466,8 @@ TARGET_BUILTIN(__builtin_ia32_blendvps256, "V8fV8fV8fV8f", "ncV:256:", "avx") TARGET_BUILTIN(__builtin_ia32_shufpd256, "V4dV4dV4dIi", "ncV:256:", "avx") TARGET_BUILTIN(__builtin_ia32_shufps256, "V8fV8fV8fIi", "ncV:256:", "avx") TARGET_BUILTIN(__builtin_ia32_dpps256, "V8fV8fV8fIc", "ncV:256:", "avx") -TARGET_BUILTIN(__builtin_ia32_cmppd, "V2dV2dV2dIc", "ncV:128:", "avx") TARGET_BUILTIN(__builtin_ia32_cmppd256, "V4dV4dV4dIc", "ncV:256:", "avx") -TARGET_BUILTIN(__builtin_ia32_cmpps, "V4fV4fV4fIc", "ncV:128:", "avx") TARGET_BUILTIN(__builtin_ia32_cmpps256, "V8fV8fV8fIc", "ncV:256:", "avx") -TARGET_BUILTIN(__builtin_ia32_cmpsd, "V2dV2dV2dIc", "ncV:128:", "avx") -TARGET_BUILTIN(__builtin_ia32_cmpss, "V4fV4fV4fIc", "ncV:128:", "avx") TARGET_BUILTIN(__builtin_ia32_vextractf128_pd256, "V2dV4dIi", "ncV:256:", "avx") TARGET_BUILTIN(__builtin_ia32_vextractf128_ps256, "V4fV8fIi", "ncV:256:", "avx") TARGET_BUILTIN(__builtin_ia32_vextractf128_si256, "V4iV8iIi", "ncV:256:", "avx") diff --git a/clang/include/clang/Basic/CMakeLists.txt b/clang/include/clang/Basic/CMakeLists.txt index 7785fb430c069ba7d065d52ad9e9bdc1a3d0c4a4..7d53c751c13ac405d8293d912f97dd2a683e1659 100644 --- a/clang/include/clang/Basic/CMakeLists.txt +++ b/clang/include/clang/Basic/CMakeLists.txt @@ -12,6 +12,7 @@ clang_diag_gen(Common) clang_diag_gen(CrossTU) clang_diag_gen(Driver) clang_diag_gen(Frontend) +clang_diag_gen(InstallAPI) clang_diag_gen(Lex) clang_diag_gen(Parse) clang_diag_gen(Refactoring) diff --git a/clang/include/clang/Basic/CodeGenOptions.def b/clang/include/clang/Basic/CodeGenOptions.def index 6ad05031962562c205e8d63dda3049e5422e4122..340b08dd7e2a33422dfc4680ff71d2f6152a709d 100644 --- a/clang/include/clang/Basic/CodeGenOptions.def +++ b/clang/include/clang/Basic/CodeGenOptions.def @@ -59,6 +59,7 @@ CODEGENOPT(UniqueBasicBlockSectionNames, 1, 1) ///< Set for -funique-basic-block ///< basic block sections. CODEGENOPT(EnableAIXExtendedAltivecABI, 1, 0) ///< Set for -mabi=vec-extabi. Enables the extended Altivec ABI on AIX. CODEGENOPT(XCOFFReadOnlyPointers, 1, 0) ///< Set for -mxcoff-roptr. +CODEGENOPT(AllTocData, 1, 0) ///< AIX -mtocdata ENUM_CODEGENOPT(FramePointer, FramePointerKind, 2, FramePointerKind::None) /// frame-pointer: all,non-leaf,none CODEGENOPT(ClearASTBeforeBackend , 1, 0) ///< Free the AST before running backend code generation. Only works with -disable-free. diff --git a/clang/include/clang/Basic/CodeGenOptions.h b/clang/include/clang/Basic/CodeGenOptions.h index 3f8fe385fef3dff91d0ee35adabc69d5d42e4c1d..9469a424045bb0472a6cd725ebf55bfa1e0e08d8 100644 --- a/clang/include/clang/Basic/CodeGenOptions.h +++ b/clang/include/clang/Basic/CodeGenOptions.h @@ -404,6 +404,12 @@ public: /// List of pass builder callbacks. std::vector> PassBuilderCallbacks; + /// List of global variables explicitly specified by the user as toc-data. + std::vector TocDataVarsUserSpecified; + + /// List of global variables that over-ride the toc-data default. + std::vector NoTocDataVars; + /// Path to allowlist file specifying which objects /// (files, functions) should exclusively be instrumented /// by sanitizer coverage pass. diff --git a/clang/include/clang/Basic/Diagnostic.td b/clang/include/clang/Basic/Diagnostic.td index 8d66e265fbaef00db435bc2feb4c6fd1484862aa..0b8b3af939ba0e27da045ef20f0b47ec365f330b 100644 --- a/clang/include/clang/Basic/Diagnostic.td +++ b/clang/include/clang/Basic/Diagnostic.td @@ -162,6 +162,7 @@ include "DiagnosticCommonKinds.td" include "DiagnosticCrossTUKinds.td" include "DiagnosticDriverKinds.td" include "DiagnosticFrontendKinds.td" +include "DiagnosticInstallAPIKinds.td" include "DiagnosticLexKinds.td" include "DiagnosticParseKinds.td" include "DiagnosticRefactoringKinds.td" diff --git a/clang/include/clang/Basic/DiagnosticASTKinds.td b/clang/include/clang/Basic/DiagnosticASTKinds.td index c81d17ed641084a8189d5f2147354b505b40bdd5..a024f9b2a9f8c0dea9fcb0a654e5027d24508632 100644 --- a/clang/include/clang/Basic/DiagnosticASTKinds.td +++ b/clang/include/clang/Basic/DiagnosticASTKinds.td @@ -399,6 +399,8 @@ def note_constexpr_unsupported_flexible_array : Note< "flexible array initialization is not yet supported">; def note_constexpr_non_const_vectorelements : Note< "cannot determine number of elements for sizeless vectors in a constant expression">; +def note_constexpr_assumption_failed : Note< + "assumption evaluated to false">; def err_experimental_clang_interp_failed : Error< "the experimental clang interpreter failed to evaluate an expression">; diff --git a/clang/include/clang/Basic/DiagnosticDriverKinds.td b/clang/include/clang/Basic/DiagnosticDriverKinds.td index 1bc9885849d54bf2fdee50739caf48794880a8f6..e33a1f4c45b949733798ab5fb648260bcaddd7f3 100644 --- a/clang/include/clang/Basic/DiagnosticDriverKinds.td +++ b/clang/include/clang/Basic/DiagnosticDriverKinds.td @@ -587,6 +587,9 @@ 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; diff --git a/clang/include/clang/Basic/DiagnosticFrontendKinds.td b/clang/include/clang/Basic/DiagnosticFrontendKinds.td index dcd2c19fb7ee3663ba99f71c36fdeaef8e11ebfd..794a0a82be6d742013d8c83c4a57c6cdc7959c7d 100644 --- a/clang/include/clang/Basic/DiagnosticFrontendKinds.td +++ b/clang/include/clang/Basic/DiagnosticFrontendKinds.td @@ -94,6 +94,8 @@ def err_fe_backend_error_attr : def warn_fe_backend_warning_attr : Warning<"call to '%0' declared with 'warning' attribute: %1">, BackendInfo, InGroup; +def warn_toc_unsupported_type : Warning<"-mtocdata option is ignored " + "for %0 because %1">, InGroup; def err_fe_invalid_code_complete_file : Error< "cannot locate code-completion file %0">, DefaultFatal; diff --git a/clang/include/clang/Basic/DiagnosticGroups.td b/clang/include/clang/Basic/DiagnosticGroups.td index 0791a0002319de5ac3136e3cd0203661a0f07008..f5ff89111d1110b99a05167ef827e2ae72ae2000 100644 --- a/clang/include/clang/Basic/DiagnosticGroups.td +++ b/clang/include/clang/Basic/DiagnosticGroups.td @@ -617,7 +617,9 @@ def GNURedeclaredEnum : DiagGroup<"gnu-redeclared-enum">; def RedundantMove : DiagGroup<"redundant-move">; def Register : DiagGroup<"register", [DeprecatedRegister]>; def ReturnTypeCLinkage : DiagGroup<"return-type-c-linkage">; -def ReturnType : DiagGroup<"return-type", [ReturnTypeCLinkage]>; +def ReturnMismatch : DiagGroup<"return-mismatch">; +def ReturnType : DiagGroup<"return-type", [ReturnTypeCLinkage, ReturnMismatch]>; + def BindToTemporaryCopy : DiagGroup<"bind-to-temporary-copy", [CXX98CompatBindToTemporaryCopy]>; def SelfAssignmentField : DiagGroup<"self-assign-field">; @@ -873,6 +875,7 @@ def ZeroLengthArray : DiagGroup<"zero-length-array">; def GNUZeroLineDirective : DiagGroup<"gnu-zero-line-directive">; def GNUZeroVariadicMacroArguments : DiagGroup<"gnu-zero-variadic-macro-arguments">; def MisleadingIndentation : DiagGroup<"misleading-indentation">; +def PtrAuthNullPointers : DiagGroup<"ptrauth-null-pointers">; // This covers both the deprecated case (in C++98) // and the extension case (in C++11 onwards). @@ -1133,9 +1136,11 @@ def NonGCC : DiagGroup<"non-gcc", def CXX14Attrs : DiagGroup<"c++14-attribute-extensions">; def CXX17Attrs : DiagGroup<"c++17-attribute-extensions">; def CXX20Attrs : DiagGroup<"c++20-attribute-extensions">; +def CXX23Attrs : DiagGroup<"c++23-attribute-extensions">; def FutureAttrs : DiagGroup<"future-attribute-extensions", [CXX14Attrs, CXX17Attrs, - CXX20Attrs]>; + CXX20Attrs, + CXX23Attrs]>; def CXX23AttrsOnLambda : DiagGroup<"c++23-lambda-attributes">; diff --git a/clang/include/clang/Basic/DiagnosticIDs.h b/clang/include/clang/Basic/DiagnosticIDs.h index 0cdda42793f6f0a0ac08bce4ca55b2d83ea06655..95b502b1e97ab1e6a03ab2a4c778a724739a9d40 100644 --- a/clang/include/clang/Basic/DiagnosticIDs.h +++ b/clang/include/clang/Basic/DiagnosticIDs.h @@ -42,6 +42,7 @@ namespace clang { DIAG_SIZE_SEMA = 4500, DIAG_SIZE_ANALYSIS = 100, DIAG_SIZE_REFACTORING = 1000, + DIAG_SIZE_INSTALLAPI = 100, }; // Start position for diagnostics. enum { @@ -57,7 +58,8 @@ namespace clang { DIAG_START_SEMA = DIAG_START_CROSSTU + static_cast(DIAG_SIZE_CROSSTU), DIAG_START_ANALYSIS = DIAG_START_SEMA + static_cast(DIAG_SIZE_SEMA), DIAG_START_REFACTORING = DIAG_START_ANALYSIS + static_cast(DIAG_SIZE_ANALYSIS), - DIAG_UPPER_LIMIT = DIAG_START_REFACTORING + static_cast(DIAG_SIZE_REFACTORING) + DIAG_START_INSTALLAPI = DIAG_START_REFACTORING + static_cast(DIAG_SIZE_REFACTORING), + DIAG_UPPER_LIMIT = DIAG_START_INSTALLAPI + static_cast(DIAG_SIZE_INSTALLAPI) }; class CustomDiagInfo; diff --git a/clang/include/clang/Basic/DiagnosticInstallAPI.h b/clang/include/clang/Basic/DiagnosticInstallAPI.h new file mode 100644 index 0000000000000000000000000000000000000000..a76f6e087a2b0a7439082a76add6fa61950b5db7 --- /dev/null +++ b/clang/include/clang/Basic/DiagnosticInstallAPI.h @@ -0,0 +1,26 @@ +//===--- DiagnosticInstallAPI.h - Diagnostics for InstallAPI-----*- 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 +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_BASIC_DIAGNOSTICINSTALLAPI_H +#define LLVM_CLANG_BASIC_DIAGNOSTICINSTALLAPI_H + +#include "clang/Basic/Diagnostic.h" +namespace clang { +namespace diag { +enum { +#define DIAG(ENUM, FLAGS, DEFAULT_MAPPING, DESC, GROUP, SFINAE, NOWERROR, \ + SHOWINSYSHEADER, SHOWINSYSMACRO, DEFERRABLE, CATEGORY) \ + ENUM, +#define INSTALLAPISTART +#include "clang/Basic/DiagnosticInstallAPIKinds.inc" +#undef DIAG + NUM_BUILTIN_INSTALLAPI_DIAGNOSTICS +}; +} // namespace diag +} // namespace clang +#endif // LLVM_CLANG_BASIC_DIAGNOSTICINSTALLAPI_H diff --git a/clang/include/clang/Basic/DiagnosticInstallAPIKinds.td b/clang/include/clang/Basic/DiagnosticInstallAPIKinds.td new file mode 100644 index 0000000000000000000000000000000000000000..31be4f09cf3a1ce2d3afa0ab14c098e4edb7f4c3 --- /dev/null +++ b/clang/include/clang/Basic/DiagnosticInstallAPIKinds.td @@ -0,0 +1,20 @@ +//==--- DiagnosticInstallAPIKinds.td - installapi diagnostics -------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +//===----------------------------------------------------------------------===// +// InstallAPI Diagnostics +//===----------------------------------------------------------------------===// + +let Component = "InstallAPI" in { +let CategoryName = "Command line" in { +def err_cannot_write_file : Error<"cannot write file '%0': %1">; +def err_no_install_name : Error<"no install name specified: add -install_name ">; +def err_no_output_file: Error<"no output file specified">; +} // end of command line category. + +} // end of InstallAPI component diff --git a/clang/include/clang/Basic/DiagnosticParseKinds.td b/clang/include/clang/Basic/DiagnosticParseKinds.td index c0dbc25a0c3265f121f297c0a3b2e8602f1826ba..816c3ff5f8b2aa5cb6c16118f7e6522f908423e9 100644 --- a/clang/include/clang/Basic/DiagnosticParseKinds.td +++ b/clang/include/clang/Basic/DiagnosticParseKinds.td @@ -786,6 +786,9 @@ def err_ms_property_expected_comma_or_rparen : Error< def err_ms_property_initializer : Error< "property declaration cannot have a default member initializer">; +def err_assume_attr_expects_cond_expr : Error< + "use of this expression in an %0 attribute requires parentheses">; + def warn_cxx20_compat_explicit_bool : Warning< "this expression will be parsed as explicit(bool) in C++20">, InGroup, DefaultIgnore; diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index 6da49facd27ec293c4a0d172a9329155a18ca777..8e97902564af08f7d64c141ab755ba3e7f942d59 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -855,10 +855,10 @@ def note_strncat_wrong_size : Note< def warn_assume_side_effects : Warning< "the argument to %0 has side effects that will be discarded">, InGroup>; -def warn_assume_attribute_string_unknown : Warning< +def warn_omp_assume_attribute_string_unknown : Warning< "unknown assumption string '%0'; attribute is potentially ignored">, InGroup; -def warn_assume_attribute_string_unknown_suggested : Warning< +def warn_omp_assume_attribute_string_unknown_suggested : Warning< "unknown assumption string '%0' may be misspelled; attribute is potentially " "ignored, did you mean '%1'?">, InGroup; @@ -911,6 +911,22 @@ def warn_fortify_scanf_overflow : Warning< def err_function_start_invalid_type: Error< "argument must be a function">; +def err_ptrauth_disabled : + Error<"this target does not support pointer authentication">; +def err_ptrauth_invalid_key : + Error<"%0 does not identify a valid pointer authentication key for " + "the current target">; +def err_ptrauth_value_bad_type : + Error<"%select{signed value|extra discriminator|blended pointer|blended " + "integer}0 must have %select{pointer|integer|pointer or integer}1 " + "type; type here is %2">; +def warn_ptrauth_sign_null_pointer : + Warning<"signing a null pointer will yield a non-null pointer">, + InGroup; +def warn_ptrauth_auth_null_pointer : + Warning<"authenticating a null pointer will almost certainly trap">, + InGroup; + /// main() // static main() is not an error in C, just in C++. def warn_static_main : Warning<"'main' should not be declared static">, @@ -9115,6 +9131,8 @@ def ext_cxx17_attr : Extension< "use of the %0 attribute is a C++17 extension">, InGroup; def ext_cxx20_attr : Extension< "use of the %0 attribute is a C++20 extension">, InGroup; +def ext_cxx23_attr : Extension< + "use of the %0 attribute is a C++23 extension">, InGroup; def warn_unused_comparison : Warning< "%select{equality|inequality|relational|three-way}0 comparison result unused">, @@ -10169,6 +10187,9 @@ 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; @@ -10243,14 +10264,14 @@ def warn_second_parameter_to_va_arg_never_compatible : Warning< def warn_return_missing_expr : Warning< "non-void %select{function|method}1 %0 should return a value">, DefaultError, - InGroup; + InGroup; def ext_return_missing_expr : ExtWarn< "non-void %select{function|method}1 %0 should return a value">, DefaultError, - InGroup; + InGroup; def ext_return_has_expr : ExtWarn< "%select{void function|void method|constructor|destructor}1 %0 " "should not return a value">, - DefaultError, InGroup; + DefaultError, InGroup; def ext_return_has_void_expr : Extension< "void %select{function|method|block}1 %0 should not return void expression">; def err_return_init_list : Error< @@ -11511,8 +11532,6 @@ def err_module_not_defined : Error< def err_module_redeclaration : Error< "translation unit contains multiple module declarations">; def note_prev_module_declaration : Note<"previous module declaration is here">; -def err_module_declaration_missing : Error< - "missing 'export module' declaration in module interface unit">; def err_module_declaration_missing_after_global_module_introducer : Error< "missing 'module' declaration at end of global module fragment " "introduced here">; diff --git a/clang/include/clang/Basic/Features.def b/clang/include/clang/Basic/Features.def index 5fad5fc3623cb630da629ba095cf613a16d455ee..eeed5f4751f2f4e6f4ef6fa94e84c9d105bdc353 100644 --- a/clang/include/clang/Basic/Features.def +++ b/clang/include/clang/Basic/Features.def @@ -101,6 +101,7 @@ FEATURE(memory_sanitizer, FEATURE(thread_sanitizer, LangOpts.Sanitize.has(SanitizerKind::Thread)) FEATURE(dataflow_sanitizer, LangOpts.Sanitize.has(SanitizerKind::DataFlow)) FEATURE(scudo, LangOpts.Sanitize.hasOneOf(SanitizerKind::Scudo)) +FEATURE(ptrauth_intrinsics, LangOpts.PointerAuthIntrinsics) FEATURE(swiftasynccc, PP.getTargetInfo().checkCallingConvention(CC_SwiftAsync) == clang::TargetInfo::CCCR_OK) diff --git a/clang/include/clang/Basic/LangOptions.def b/clang/include/clang/Basic/LangOptions.def index 2b42b521a30363367a1620f753188bf668a1f9d9..8ef6700ecdc78eca7ec8a245d37d5d49122dd0d6 100644 --- a/clang/include/clang/Basic/LangOptions.def +++ b/clang/include/clang/Basic/LangOptions.def @@ -161,6 +161,8 @@ LANGOPT(DllExportInlines , 1, 1, "dllexported classes dllexport inline methods" LANGOPT(RelaxedTemplateTemplateArgs, 1, 0, "C++17 relaxed matching of template template arguments") LANGOPT(ExperimentalLibrary, 1, 0, "enable unstable and experimental library features") +LANGOPT(PointerAuthIntrinsics, 1, 0, "pointer authentication intrinsics") + LANGOPT(DoubleSquareBracketAttributes, 1, 0, "'[[]]' attributes extension for all language standard modes") COMPATIBLE_LANGOPT(RecoveryAST, 1, 1, "Preserve expressions in AST when encountering errors") @@ -450,6 +452,8 @@ LANGOPT(RegCall4, 1, 0, "Set __regcall4 as a default calling convention to respe LANGOPT(MatrixTypes, 1, 0, "Enable or disable the builtin matrix type") +LANGOPT(CXXAssumptions, 1, 1, "Enable or disable codegen and compile-time checks for C++23's [[assume]] attribute") + ENUM_LANGOPT(StrictFlexArraysLevel, StrictFlexArraysLevelKind, 2, StrictFlexArraysLevelKind::Default, "Rely on strict definition of flexible arrays") diff --git a/clang/include/clang/Basic/LangOptions.h b/clang/include/clang/Basic/LangOptions.h index 862952d336ef3176fb6c814de78a376baa752f3e..08fc706e3cbf744777de199fab75c9e96d72c89e 100644 --- a/clang/include/clang/Basic/LangOptions.h +++ b/clang/include/clang/Basic/LangOptions.h @@ -560,11 +560,6 @@ public: return getCompilingModule() != CMK_None; } - /// Are we compiling a standard c++ module interface? - bool isCompilingModuleInterface() const { - return getCompilingModule() == CMK_ModuleInterface; - } - /// Are we compiling a module implementation? bool isCompilingModuleImplementation() const { return !isCompilingModule() && !ModuleName.empty(); @@ -993,8 +988,8 @@ enum TranslationUnitKind { /// not complete. TU_Prefix, - /// The translation unit is a module. - TU_Module, + /// The translation unit is a clang module. + TU_ClangModule, /// The translation unit is a is a complete translation unit that we might /// incrementally extend later. diff --git a/clang/include/clang/Basic/LangStandard.h b/clang/include/clang/Basic/LangStandard.h index bc49669a82ad2db3a5718bc07fb99b578eacbc03..199e24c67316030d167f4c2b2b4e02fb44f897da 100644 --- a/clang/include/clang/Basic/LangStandard.h +++ b/clang/include/clang/Basic/LangStandard.h @@ -139,6 +139,7 @@ public: bool isOpenCL() const { return Flags & OpenCL; } static Kind getLangKind(StringRef Name); + static Kind getHLSLLangKind(StringRef Name); static const LangStandard &getLangStandardForKind(Kind K); static const LangStandard *getLangStandardForName(StringRef Name); }; diff --git a/clang/include/clang/Basic/TargetInfo.h b/clang/include/clang/Basic/TargetInfo.h index 7682f84e491c7bc15d07c2e399a80769a9740916..374595edd2ce4a2e8f92842ccce97b066291e0b8 100644 --- a/clang/include/clang/Basic/TargetInfo.h +++ b/clang/include/clang/Basic/TargetInfo.h @@ -24,6 +24,7 @@ #include "clang/Basic/TargetOptions.h" #include "llvm/ADT/APFloat.h" #include "llvm/ADT/APInt.h" +#include "llvm/ADT/APSInt.h" #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/IntrusiveRefCntPtr.h" #include "llvm/ADT/SmallSet.h" @@ -1571,6 +1572,11 @@ public: return getAddressSpaceMap()[(unsigned)AS]; } + /// Determine whether the given pointer-authentication key is valid. + /// + /// The value has been coerced to type 'int'. + virtual bool validatePointerAuthKey(const llvm::APSInt &value) const; + /// Map from the address space field in builtin description strings to the /// language address space. virtual LangAS getOpenCLBuiltinAddressSpace(unsigned AS) const { diff --git a/clang/include/clang/Driver/Driver.h b/clang/include/clang/Driver/Driver.h index c4cab360bab3bb3b31b117eb8ce2db5644b653fa..2ffc52bcb7ad3b74b6cbf54ba2d45ae1682f83f9 100644 --- a/clang/include/clang/Driver/Driver.h +++ b/clang/include/clang/Driver/Driver.h @@ -28,8 +28,8 @@ #include "llvm/Option/ArgList.h" #include "llvm/Support/StringSaver.h" -#include #include +#include #include #include @@ -615,6 +615,16 @@ public: // FIXME: This should be in CompilationInfo. std::string GetProgramPath(StringRef Name, const ToolChain &TC) const; + /// Lookup the path to the Standard library module manifest. + /// + /// \param C - The compilation. + /// \param TC - The tool chain for additional information on + /// directories to search. + // + // FIXME: This should be in CompilationInfo. + std::string GetStdModuleManifestPath(const Compilation &C, + const ToolChain &TC) const; + /// HandleAutocompletions - Handle --autocomplete by searching and printing /// possible flags, descriptions, and its arguments. void HandleAutocompletions(StringRef PassedFlags) const; @@ -839,6 +849,13 @@ llvm::Error expandResponseFiles(SmallVectorImpl &Args, bool ClangCLMode, llvm::BumpPtrAllocator &Alloc, llvm::vfs::FileSystem *FS = nullptr); +/// Apply a space separated list of edits to the input argument lists. +/// See applyOneOverrideOption. +void applyOverrideOptions(SmallVectorImpl &Args, + const char *OverrideOpts, + llvm::StringSet<> &SavedStrings, + raw_ostream *OS = nullptr); + } // end namespace driver } // end namespace clang diff --git a/clang/include/clang/Driver/OffloadBundler.h b/clang/include/clang/Driver/OffloadBundler.h index 84349abe185fa4d778585f5832930e650c1b3fb0..65d33bfbd2825f907c580b70684a36d41d1abd4e 100644 --- a/clang/include/clang/Driver/OffloadBundler.h +++ b/clang/include/clang/Driver/OffloadBundler.h @@ -17,6 +17,7 @@ #ifndef LLVM_CLANG_DRIVER_OFFLOADBUNDLER_H #define LLVM_CLANG_DRIVER_OFFLOADBUNDLER_H +#include "llvm/Support/Compression.h" #include "llvm/Support/Error.h" #include "llvm/TargetParser/Triple.h" #include @@ -36,6 +37,8 @@ public: bool HipOpenmpCompatible = false; bool Compress = false; bool Verbose = false; + llvm::compression::Format CompressionFormat; + int CompressionLevel; unsigned BundleAlignment = 1; unsigned HostInputIndex = ~0u; @@ -116,7 +119,8 @@ private: public: static llvm::Expected> - compress(const llvm::MemoryBuffer &Input, bool Verbose = false); + compress(llvm::compression::Params P, const llvm::MemoryBuffer &Input, + bool Verbose = false); static llvm::Expected> decompress(const llvm::MemoryBuffer &Input, bool Verbose = false); }; diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td index 5b3d366dbcf91be6517dfb78e68f0060b4078650..4b1fcf1db1ad0996b3cc34fa707db5c15f8f6a77 100644 --- a/clang/include/clang/Driver/Options.td +++ b/clang/include/clang/Driver/Options.td @@ -1264,6 +1264,10 @@ def fno_gpu_sanitize : Flag<["-"], "fno-gpu-sanitize">, Group; def offload_compress : Flag<["--"], "offload-compress">, HelpText<"Compress offload device binaries (HIP only)">; def no_offload_compress : Flag<["--"], "no-offload-compress">; + +def offload_compression_level_EQ : Joined<["--"], "offload-compression-level=">, + Flags<[HelpHidden]>, + HelpText<"Compression level for offload device binaries (HIP only)">; } // CUDA options @@ -3605,6 +3609,27 @@ def fpass_plugin_EQ : Joined<["-"], "fpass-plugin=">, MetaVarName<"">, HelpText<"Load pass plugin from a dynamic shared object file (only with new pass manager).">, MarshallingInfoStringVector>; +defm tocdata : BoolOption<"m","tocdata", + CodeGenOpts<"AllTocData">, DefaultFalse, + PosFlag, + NegFlag, + BothFlags<[TargetSpecific], [ClangOption, CLOption]>>, Group; +def mtocdata_EQ : CommaJoined<["-"], "mtocdata=">, + Visibility<[ClangOption, CC1Option]>, + Flags<[TargetSpecific]>, Group, + HelpText<"Specifies a list of variables to which the TOC data transformation" + "will be applied.">, + MarshallingInfoStringVector>; +def mno_tocdata_EQ : CommaJoined<["-"], "mno-tocdata=">, + Visibility<[ClangOption, CC1Option]>, + Flags<[TargetSpecific]>, Group, + HelpText<"Specifies a list of variables to be exempt from the TOC data" + "transformation.">, + MarshallingInfoStringVector>; defm preserve_as_comments : BoolFOption<"preserve-as-comments", CodeGenOpts<"PreserveAsmComments">, DefaultTrue, NegFlag, MetaVarName<"">; +defm assumptions : BoolFOption<"assumptions", + LangOpts<"CXXAssumptions">, DefaultTrue, + NegFlag, + PosFlag>; + def fvectorize : Flag<["-"], "fvectorize">, Group, HelpText<"Enable the loop vectorization passes">; def fno_vectorize : Flag<["-"], "fno-vectorize">, Group; @@ -4075,6 +4106,14 @@ defm strict_return : BoolFOption<"strict-return", " of a non-void function as unreachable">, PosFlag>; +let Group = f_Group in { + let Visibility = [ClangOption,CC1Option] in { + def fptrauth_intrinsics : Flag<["-"], "fptrauth-intrinsics">, + HelpText<"Enable pointer authentication intrinsics">; + } + def fno_ptrauth_intrinsics : Flag<["-"], "fno-ptrauth-intrinsics">; +} + def fenable_matrix : Flag<["-"], "fenable-matrix">, Group, Visibility<[ClangOption, CC1Option]>, HelpText<"Enable matrix data type and related builtin functions">, @@ -4665,21 +4704,17 @@ def mrvv_vector_bits_EQ : Joined<["-"], "mrvv-vector-bits=">, Group, " (RISC-V only)")>; def munaligned_access : Flag<["-"], "munaligned-access">, Group, - HelpText<"Allow memory accesses to be unaligned (AArch32/AArch64/LoongArch/RISC-V only)">; + HelpText<"Allow memory accesses to be unaligned (AArch32 only)">; def mno_unaligned_access : Flag<["-"], "mno-unaligned-access">, Group, - HelpText<"Force all memory accesses to be aligned (AArch32/AArch64/LoongArch/RISC-V only)">; + HelpText<"Force all memory accesses to be aligned (AArch32 only)">; def munaligned_symbols : Flag<["-"], "munaligned-symbols">, Group, HelpText<"Expect external char-aligned symbols to be without ABI alignment (SystemZ only)">; def mno_unaligned_symbols : Flag<["-"], "mno-unaligned-symbols">, Group, HelpText<"Expect external char-aligned symbols to be without ABI alignment (SystemZ only)">; -} // let Flags = [TargetSpecific] -def mstrict_align : Flag<["-"], "mstrict-align">, Alias, - Flags<[HelpHidden]>, Visibility<[ClangOption, CC1Option]>, - HelpText<"Force all memory accesses to be aligned (same as mno-unaligned-access)">; -def mno_strict_align : Flag<["-"], "mno-strict-align">, Alias, - Flags<[HelpHidden]>, Visibility<[ClangOption, CC1Option]>, - HelpText<"Allow memory accesses to be unaligned (same as munaligned-access)">; -let Flags = [TargetSpecific] in { +def mstrict_align : Flag<["-"], "mstrict-align">, + HelpText<"Force all memory accesses to be aligned (AArch64/LoongArch/RISC-V only)">; +def mno_strict_align : Flag<["-"], "mno-strict-align">, + HelpText<"Allow memory accesses to be unaligned (AArch64/LoongArch/RISC-V only)">; def mno_thumb : Flag<["-"], "mno-thumb">, Group; def mrestrict_it: Flag<["-"], "mrestrict-it">, Group, HelpText<"Disallow generation of complex IT blocks. It is off by default.">; @@ -5364,6 +5399,9 @@ def print_resource_dir : Flag<["-", "--"], "print-resource-dir">, def print_search_dirs : Flag<["-", "--"], "print-search-dirs">, HelpText<"Print the paths used for finding libraries and programs">, Visibility<[ClangOption, CLOption]>; +def print_std_module_manifest_path : Flag<["-", "--"], "print-library-module-manifest-path">, + HelpText<"Print the path for the C++ Standard library module manifest">, + Visibility<[ClangOption, CLOption]>; def print_targets : Flag<["-", "--"], "print-targets">, HelpText<"Print the registered targets">, Visibility<[ClangOption, CLOption]>; @@ -8547,6 +8585,11 @@ def dxc_entrypoint : Option<["--", "/", "-"], "E", KIND_JOINED_OR_SEPARATE>, Group, Visibility<[DXCOption]>, HelpText<"Entry point name">; +def dxc_hlsl_version : Option<["/", "-"], "HV", KIND_JOINED_OR_SEPARATE>, + Group, + Visibility<[DXCOption]>, + HelpText<"HLSL Version">, + Values<"2016, 2017, 2018, 2021, 202x">; def dxc_validator_path_EQ : Joined<["--"], "dxv-path=">, Group, HelpText<"DXIL validator installation path">; def dxc_disable_validation : DXCFlag<"Vd">, diff --git a/clang/include/clang/Driver/ToolChain.h b/clang/include/clang/Driver/ToolChain.h index fbe2e8fe8e88d850fa1bb4d3240f45f43d20a285..a4f9cad98aa8b1e40d609d001d483e29f2b00077 100644 --- a/clang/include/clang/Driver/ToolChain.h +++ b/clang/include/clang/Driver/ToolChain.h @@ -580,7 +580,7 @@ public: // Return the DWARF version to emit, in the absence of arguments // to the contrary. - virtual unsigned GetDefaultDwarfVersion() const; + virtual unsigned GetDefaultDwarfVersion() const { return 5; } // Some toolchains may have different restrictions on the DWARF version and // may need to adjust it. E.g. NVPTX may need to enforce DWARF2 even when host diff --git a/clang/include/clang/Format/.clang-format b/clang/include/clang/Format/.clang-format index f95602cab0f7fcdf5d34c485d52b65993dbb83d9..d7331b3c8cf02ef7944e83a4280476627e33b31d 100644 --- a/clang/include/clang/Format/.clang-format +++ b/clang/include/clang/Format/.clang-format @@ -1,6 +1 @@ -BasedOnStyle: LLVM -InsertBraces: true -InsertNewlineAtEOF: true -LineEnding: LF -RemoveBracesLLVM: true -RemoveParentheses: ReturnStatement +BasedOnStyle: clang-format diff --git a/clang/include/clang/Format/Format.h b/clang/include/clang/Format/Format.h index 590297fd89a398a8284f038d7a06c3c071c40ac4..54861a66889e22d45f1e4f531de31053b550061f 100644 --- a/clang/include/clang/Format/Format.h +++ b/clang/include/clang/Format/Format.h @@ -4728,6 +4728,60 @@ struct FormatStyle { /// \version 8 std::vector StatementMacros; + /// Works only when TableGenBreakInsideDAGArg is not DontBreak. + /// The string list needs to consist of identifiers in TableGen. + /// If any identifier is specified, this limits the line breaks by + /// TableGenBreakInsideDAGArg option only on DAGArg values beginning with + /// the specified identifiers. + /// + /// For example the configuration, + /// \code + /// TableGenBreakInsideDAGArg: BreakAll + /// TableGenBreakingDAGArgOperators: ['ins', 'outs'] + /// \endcode + /// + /// makes the line break only occurs inside DAGArgs beginning with the + /// specified identifiers 'ins' and 'outs'. + /// + /// \code + /// let DAGArgIns = (ins + /// i32:$src1, + /// i32:$src2 + /// ); + /// let DAGArgOtherID = (other i32:$other1, i32:$other2); + /// let DAGArgBang = (!cast("Some") i32:$src1, i32:$src2) + /// \endcode + /// \version 19 + std::vector TableGenBreakingDAGArgOperators; + + /// Different ways to control the format inside TableGen DAGArg. + enum DAGArgStyle : int8_t { + /// Never break inside DAGArg. + /// \code + /// let DAGArgIns = (ins i32:$src1, i32:$src2); + /// \endcode + DAS_DontBreak, + /// Break inside DAGArg after each list element but for the last. + /// This aligns to the first element. + /// \code + /// let DAGArgIns = (ins i32:$src1, + /// i32:$src2); + /// \endcode + DAS_BreakElements, + /// Break inside DAGArg after the operator and the all elements. + /// \code + /// let DAGArgIns = (ins + /// i32:$src1, + /// i32:$src2 + /// ); + /// \endcode + DAS_BreakAll, + }; + + /// The styles of the line break inside the DAGArg in TableGen. + /// \version 19 + DAGArgStyle TableGenBreakInsideDAGArg; + /// The number of columns used for tab stops. /// \version 3.7 unsigned TabWidth; @@ -4980,9 +5034,12 @@ struct FormatStyle { SpacesInSquareBrackets == R.SpacesInSquareBrackets && Standard == R.Standard && StatementAttributeLikeMacros == R.StatementAttributeLikeMacros && - StatementMacros == R.StatementMacros && TabWidth == R.TabWidth && - TypeNames == R.TypeNames && TypenameMacros == R.TypenameMacros && - UseTab == R.UseTab && + StatementMacros == R.StatementMacros && + TableGenBreakingDAGArgOperators == + R.TableGenBreakingDAGArgOperators && + TableGenBreakInsideDAGArg == R.TableGenBreakInsideDAGArg && + TabWidth == R.TabWidth && TypeNames == R.TypeNames && + TypenameMacros == R.TypenameMacros && UseTab == R.UseTab && VerilogBreakBetweenInstancePorts == R.VerilogBreakBetweenInstancePorts && WhitespaceSensitiveMacros == R.WhitespaceSensitiveMacros; diff --git a/clang/include/clang/Frontend/FrontendActions.h b/clang/include/clang/Frontend/FrontendActions.h index 8441af2ee3e718603ac9dd2898dcee4b14b38d01..a620ddfc40447d7795df64c407300b6ca8da5d44 100644 --- a/clang/include/clang/Frontend/FrontendActions.h +++ b/clang/include/clang/Frontend/FrontendActions.h @@ -125,7 +125,7 @@ protected: StringRef InFile) override; TranslationUnitKind getTranslationUnitKind() override { - return TU_Module; + return TU_ClangModule; } bool hasASTFileSupport() const override { return false; } @@ -138,7 +138,9 @@ protected: std::unique_ptr CreateASTConsumer(CompilerInstance &CI, StringRef InFile) override; - TranslationUnitKind getTranslationUnitKind() override { return TU_Module; } + TranslationUnitKind getTranslationUnitKind() override { + return TU_ClangModule; + } bool hasASTFileSupport() const override { return false; } }; @@ -159,6 +161,8 @@ protected: std::unique_ptr CreateASTConsumer(CompilerInstance &CI, StringRef InFile) override; + TranslationUnitKind getTranslationUnitKind() override { return TU_Complete; } + std::unique_ptr CreateOutputFile(CompilerInstance &CI, StringRef InFile) override; }; diff --git a/clang/include/clang/InstallAPI/Context.h b/clang/include/clang/InstallAPI/Context.h index 4e9e90e5d2dbec18c6f11ca3a4e64c4fd8ff30b5..54e517544b8edf526097afd66347b9e55998c0f3 100644 --- a/clang/include/clang/InstallAPI/Context.h +++ b/clang/include/clang/InstallAPI/Context.h @@ -11,9 +11,10 @@ #include "clang/Basic/Diagnostic.h" #include "clang/Basic/FileManager.h" +#include "clang/InstallAPI/DylibVerifier.h" #include "clang/InstallAPI/HeaderFile.h" +#include "clang/InstallAPI/MachO.h" #include "llvm/ADT/DenseMap.h" -#include "llvm/TextAPI/InterfaceFile.h" namespace clang { namespace installapi { @@ -25,7 +26,7 @@ class FrontendRecordsSlice; struct InstallAPIContext { /// Library attributes that are typically passed as linker inputs. - llvm::MachO::RecordsSlice::BinaryAttrs BA; + BinaryAttrs BA; /// All headers that represent a library. HeaderSeq InputHeaders; @@ -45,11 +46,14 @@ struct InstallAPIContext { /// DiagnosticsEngine for all error reporting. DiagnosticsEngine *Diags = nullptr; + /// Verifier when binary dylib is passed as input. + std::unique_ptr Verifier = nullptr; + /// File Path of output location. llvm::StringRef OutputLoc{}; /// What encoding to write output as. - llvm::MachO::FileType FT = llvm::MachO::FileType::TBD_V5; + FileType FT = FileType::TBD_V5; /// Populate entries of headers that should be included for TextAPI /// generation. diff --git a/clang/include/clang/InstallAPI/DylibVerifier.h b/clang/include/clang/InstallAPI/DylibVerifier.h new file mode 100644 index 0000000000000000000000000000000000000000..72c4743fdf65e0b9a415ae39df09fce3309a36fd --- /dev/null +++ b/clang/include/clang/InstallAPI/DylibVerifier.h @@ -0,0 +1,104 @@ +//===- InstallAPI/DylibVerifier.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 +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_INSTALLAPI_DYLIBVERIFIER_H +#define LLVM_CLANG_INSTALLAPI_DYLIBVERIFIER_H + +#include "clang/Basic/Diagnostic.h" +#include "clang/InstallAPI/MachO.h" + +namespace clang { +namespace installapi { +struct FrontendAttrs; + +/// A list of InstallAPI verification modes. +enum class VerificationMode { + Invalid, + ErrorsOnly, + ErrorsAndWarnings, + Pedantic, +}; + +/// Service responsible to tracking state of verification across the +/// lifetime of InstallAPI. +/// As declarations are collected during AST traversal, they are +/// compared as symbols against what is available in the binary dylib. +class DylibVerifier { +private: + struct SymbolContext; + +public: + enum class Result { NoVerify, Ignore, Valid, Invalid }; + struct VerifierContext { + // Current target being verified against the AST. + llvm::MachO::Target Target; + + // Query state of verification after AST has been traversed. + Result FrontendState; + + // First error for AST traversal, which is tied to the target triple. + bool DiscoveredFirstError; + }; + + DylibVerifier() = default; + + DylibVerifier(llvm::MachO::Records &&Dylib, DiagnosticsEngine *Diag, + VerificationMode Mode, bool Demangle) + : Dylib(std::move(Dylib)), Diag(Diag), Mode(Mode), Demangle(Demangle), + Exports(std::make_unique()) {} + + Result verify(GlobalRecord *R, const FrontendAttrs *FA); + Result verify(ObjCInterfaceRecord *R, const FrontendAttrs *FA); + Result verify(ObjCIVarRecord *R, const FrontendAttrs *FA, + const StringRef SuperClass); + + /// Initialize target for verification. + void setTarget(const Target &T); + + /// Release ownership over exports. + std::unique_ptr getExports() { return std::move(Exports); } + + /// Get result of verification. + Result getState() const { return Ctx.FrontendState; } + +private: + /// Determine whether to compare declaration to symbol in binary. + bool canVerify(); + + /// Shared implementation for verifying exported symbols. + Result verifyImpl(Record *R, SymbolContext &SymCtx); + + /// Update result state on each call to `verify`. + void updateState(Result State); + + /// Add verified exported symbol. + void addSymbol(const Record *R, SymbolContext &SymCtx, + TargetList &&Targets = {}); + + // Symbols in dylib. + llvm::MachO::Records Dylib; + + // Engine for reporting violations. + [[maybe_unused]] DiagnosticsEngine *Diag = nullptr; + + // Controls what class of violations to report. + [[maybe_unused]] VerificationMode Mode = VerificationMode::Invalid; + + // Attempt to demangle when reporting violations. + bool Demangle = false; + + // Valid symbols in final text file. + std::unique_ptr Exports = std::make_unique(); + + // Track current state of verification while traversing AST. + VerifierContext Ctx; +}; + +} // namespace installapi +} // namespace clang +#endif // LLVM_CLANG_INSTALLAPI_DYLIBVERIFIER_H diff --git a/clang/include/clang/InstallAPI/Frontend.h b/clang/include/clang/InstallAPI/Frontend.h index cbc2b159ebd17a3b92c27c5ea391c96120ad9f8c..660fc8cd69a59da4953d8a251ebb89942bad632a 100644 --- a/clang/include/clang/InstallAPI/Frontend.h +++ b/clang/include/clang/InstallAPI/Frontend.h @@ -14,7 +14,6 @@ #define LLVM_CLANG_INSTALLAPI_FRONTEND_H #include "clang/AST/ASTConsumer.h" -#include "clang/AST/Availability.h" #include "clang/Frontend/CompilerInstance.h" #include "clang/Frontend/FrontendActions.h" #include "clang/InstallAPI/Context.h" @@ -25,100 +24,6 @@ namespace clang { namespace installapi { -using SymbolFlags = llvm::MachO::SymbolFlags; -using RecordLinkage = llvm::MachO::RecordLinkage; -using GlobalRecord = llvm::MachO::GlobalRecord; -using ObjCContainerRecord = llvm::MachO::ObjCContainerRecord; -using ObjCInterfaceRecord = llvm::MachO::ObjCInterfaceRecord; -using ObjCCategoryRecord = llvm::MachO::ObjCCategoryRecord; -using ObjCIVarRecord = llvm::MachO::ObjCIVarRecord; - -// Represents a collection of frontend records for a library that are tied to a -// darwin target triple. -class FrontendRecordsSlice : public llvm::MachO::RecordsSlice { -public: - FrontendRecordsSlice(const llvm::Triple &T) - : llvm::MachO::RecordsSlice({T}) {} - - /// Add non-ObjC global record with attributes from AST. - /// - /// \param Name The name of symbol. - /// \param Linkage The linkage of symbol. - /// \param GV The kind of global. - /// \param Avail The availability information tied to the active target - /// triple. - /// \param D The pointer to the declaration from traversing AST. - /// \param Access The intended access level of symbol. - /// \param Flags The flags that describe attributes of the symbol. - /// \param Inlined Whether declaration is inlined, only applicable to - /// functions. - /// \return The non-owning pointer to added record in slice. - GlobalRecord *addGlobal(StringRef Name, RecordLinkage Linkage, - GlobalRecord::Kind GV, - const clang::AvailabilityInfo Avail, const Decl *D, - const HeaderType Access, - SymbolFlags Flags = SymbolFlags::None, - bool Inlined = false); - - /// Add ObjC Class record with attributes from AST. - /// - /// \param Name The name of class, not symbol. - /// \param Linkage The linkage of symbol. - /// \param Avail The availability information tied to the active target - /// triple. - /// \param D The pointer to the declaration from traversing AST. - /// \param Access The intended access level of symbol. - /// \param IsEHType Whether declaration has an exception attribute. - /// \return The non-owning pointer to added record in slice. - ObjCInterfaceRecord *addObjCInterface(StringRef Name, RecordLinkage Linkage, - const clang::AvailabilityInfo Avail, - const Decl *D, HeaderType Access, - bool IsEHType); - - /// Add ObjC Category record with attributes from AST. - /// - /// \param ClassToExtend The name of class that is extended by category, not - /// symbol. - /// \param CategoryName The name of category, not symbol. - /// \param Avail The availability information tied - /// to the active target triple. - /// \param D The pointer to the declaration from traversing AST. - /// \param Access The intended access level of symbol. - /// \return The non-owning pointer to added record in slice. - ObjCCategoryRecord *addObjCCategory(StringRef ClassToExtend, - StringRef CategoryName, - const clang::AvailabilityInfo Avail, - const Decl *D, HeaderType Access); - - /// Add ObjC IVar record with attributes from AST. - /// - /// \param Container The owning pointer for instance variable. - /// \param Name The name of ivar, not symbol. - /// \param Linkage The linkage of symbol. - /// \param Avail The availability information tied to the active target - /// triple. - /// \param D The pointer to the declaration from traversing AST. - /// \param Access The intended access level of symbol. - /// \param AC The access control tied to the ivar declaration. - /// \return The non-owning pointer to added record in slice. - ObjCIVarRecord *addObjCIVar(ObjCContainerRecord *Container, - StringRef IvarName, RecordLinkage Linkage, - const clang::AvailabilityInfo Avail, - const Decl *D, HeaderType Access, - const clang::ObjCIvarDecl::AccessControl AC); - -private: - /// Frontend information captured about records. - struct FrontendAttrs { - const AvailabilityInfo Avail; - const Decl *D; - const HeaderType Access; - }; - - /// Mapping of records stored in slice to their frontend attributes. - llvm::DenseMap FrontendRecords; -}; - /// Create a buffer that contains all headers to scan /// for global symbols with. std::unique_ptr createInputBuffer(InstallAPIContext &Ctx); diff --git a/clang/include/clang/InstallAPI/FrontendRecords.h b/clang/include/clang/InstallAPI/FrontendRecords.h new file mode 100644 index 0000000000000000000000000000000000000000..59271e81e230c2f022e1bec0894e0529e3f3a0e2 --- /dev/null +++ b/clang/include/clang/InstallAPI/FrontendRecords.h @@ -0,0 +1,112 @@ +//===- InstallAPI/FrontendRecords.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 +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_INSTALLAPI_FRONTENDRECORDS_H +#define LLVM_CLANG_INSTALLAPI_FRONTENDRECORDS_H + +#include "clang/AST/Availability.h" +#include "clang/AST/DeclObjC.h" +#include "clang/InstallAPI/HeaderFile.h" +#include "clang/InstallAPI/MachO.h" + +namespace clang { +namespace installapi { + +/// Frontend information captured about records. +struct FrontendAttrs { + const AvailabilityInfo Avail; + const Decl *D; + const HeaderType Access; +}; + +// Represents a collection of frontend records for a library that are tied to a +// darwin target triple. +class FrontendRecordsSlice : public llvm::MachO::RecordsSlice { +public: + FrontendRecordsSlice(const llvm::Triple &T) + : llvm::MachO::RecordsSlice({T}) {} + + /// Add non-ObjC global record with attributes from AST. + /// + /// \param Name The name of symbol. + /// \param Linkage The linkage of symbol. + /// \param GV The kind of global. + /// \param Avail The availability information tied to the active target + /// triple. + /// \param D The pointer to the declaration from traversing AST. + /// \param Access The intended access level of symbol. + /// \param Flags The flags that describe attributes of the symbol. + /// \param Inlined Whether declaration is inlined, only applicable to + /// functions. + /// \return The non-owning pointer to added record in slice with it's frontend + /// attributes. + std::pair + addGlobal(StringRef Name, RecordLinkage Linkage, GlobalRecord::Kind GV, + const clang::AvailabilityInfo Avail, const Decl *D, + const HeaderType Access, SymbolFlags Flags = SymbolFlags::None, + bool Inlined = false); + + /// Add ObjC Class record with attributes from AST. + /// + /// \param Name The name of class, not symbol. + /// \param Linkage The linkage of symbol. + /// \param Avail The availability information tied to the active target + /// triple. + /// \param D The pointer to the declaration from traversing AST. + /// \param Access The intended access level of symbol. + /// \param IsEHType Whether declaration has an exception attribute. + /// \return The non-owning pointer to added record in slice with it's frontend + /// attributes. + std::pair + addObjCInterface(StringRef Name, RecordLinkage Linkage, + const clang::AvailabilityInfo Avail, const Decl *D, + HeaderType Access, bool IsEHType); + + /// Add ObjC Category record with attributes from AST. + /// + /// \param ClassToExtend The name of class that is extended by category, not + /// symbol. + /// \param CategoryName The name of category, not symbol. + /// \param Avail The availability information tied + /// to the active target triple. + /// \param D The pointer to the declaration from traversing AST. + /// \param Access The intended access level of symbol. + /// \return The non-owning pointer to added record in slice with it's frontend + /// attributes. + std::pair + addObjCCategory(StringRef ClassToExtend, StringRef CategoryName, + const clang::AvailabilityInfo Avail, const Decl *D, + HeaderType Access); + + /// Add ObjC IVar record with attributes from AST. + /// + /// \param Container The owning pointer for instance variable. + /// \param Name The name of ivar, not symbol. + /// \param Linkage The linkage of symbol. + /// \param Avail The availability information tied to the active target + /// triple. + /// \param D The pointer to the declaration from traversing AST. + /// \param Access The intended access level of symbol. + /// \param AC The access control tied to the ivar declaration. + /// \return The non-owning pointer to added record in slice with it's frontend + /// attributes. + std::pair + addObjCIVar(ObjCContainerRecord *Container, StringRef IvarName, + RecordLinkage Linkage, const clang::AvailabilityInfo Avail, + const Decl *D, HeaderType Access, + const clang::ObjCIvarDecl::AccessControl AC); + +private: + /// Mapping of records stored in slice to their frontend attributes. + llvm::DenseMap FrontendRecords; +}; + +} // namespace installapi +} // namespace clang + +#endif // LLVM_CLANG_INSTALLAPI_FRONTENDRECORDS_H diff --git a/clang/include/clang/InstallAPI/InstallAPIDiagnostic.h b/clang/include/clang/InstallAPI/InstallAPIDiagnostic.h new file mode 100644 index 0000000000000000000000000000000000000000..547fb0bcf9a8936591aa156f4c566b919b5a35bf --- /dev/null +++ b/clang/include/clang/InstallAPI/InstallAPIDiagnostic.h @@ -0,0 +1,14 @@ +//===--- InstallAPIDiagnostic.h - Diagnostics for InstallAPI ----*- 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 +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_INSTALLAPI_INSTALLAPIDIAGNOSTIC_H +#define LLVM_CLANG_INSTALLAPI_INSTALLAPIDIAGNOSTIC_H + +#include "clang/Basic/DiagnosticInstallAPI.h" + +#endif diff --git a/clang/include/clang/InstallAPI/MachO.h b/clang/include/clang/InstallAPI/MachO.h new file mode 100644 index 0000000000000000000000000000000000000000..6dee6f2242038118238d853f8f6fe4b663a2ee35 --- /dev/null +++ b/clang/include/clang/InstallAPI/MachO.h @@ -0,0 +1,43 @@ +//===- InstallAPI/MachO.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 +// +//===----------------------------------------------------------------------===// +// +// Imports and forward declarations for llvm::MachO types. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_INSTALLAPI_MACHO_H +#define LLVM_CLANG_INSTALLAPI_MACHO_H + +#include "llvm/TextAPI/Architecture.h" +#include "llvm/TextAPI/InterfaceFile.h" +#include "llvm/TextAPI/PackedVersion.h" +#include "llvm/TextAPI/Platform.h" +#include "llvm/TextAPI/RecordVisitor.h" +#include "llvm/TextAPI/Symbol.h" +#include "llvm/TextAPI/Target.h" +#include "llvm/TextAPI/TextAPIWriter.h" +#include "llvm/TextAPI/Utils.h" + +using SymbolFlags = llvm::MachO::SymbolFlags; +using RecordLinkage = llvm::MachO::RecordLinkage; +using Record = llvm::MachO::Record; +using GlobalRecord = llvm::MachO::GlobalRecord; +using ObjCContainerRecord = llvm::MachO::ObjCContainerRecord; +using ObjCInterfaceRecord = llvm::MachO::ObjCInterfaceRecord; +using ObjCCategoryRecord = llvm::MachO::ObjCCategoryRecord; +using ObjCIVarRecord = llvm::MachO::ObjCIVarRecord; +using Records = llvm::MachO::Records; +using BinaryAttrs = llvm::MachO::RecordsSlice::BinaryAttrs; +using SymbolSet = llvm::MachO::SymbolSet; +using SimpleSymbol = llvm::MachO::SimpleSymbol; +using FileType = llvm::MachO::FileType; +using PackedVersion = llvm::MachO::PackedVersion; +using Target = llvm::MachO::Target; +using TargetList = llvm::MachO::TargetList; + +#endif // LLVM_CLANG_INSTALLAPI_MACHO_H diff --git a/clang/include/clang/InstallAPI/Visitor.h b/clang/include/clang/InstallAPI/Visitor.h index 71d4d9894f4205da7b6d55f6989fdba93dfecee7..9ac948ded3e332d62401132650f288c0a0805c99 100644 --- a/clang/include/clang/InstallAPI/Visitor.h +++ b/clang/include/clang/InstallAPI/Visitor.h @@ -21,6 +21,7 @@ #include "llvm/ADT/Twine.h" namespace clang { +struct AvailabilityInfo; namespace installapi { /// ASTVisitor for collecting declarations that represent global symbols. @@ -33,6 +34,7 @@ public: MC(ItaniumMangleContext::create(ASTCtx, ASTCtx.getDiagnostics())), Layout(ASTCtx.getTargetInfo().getDataLayoutString()) {} void HandleTranslationUnit(ASTContext &ASTCtx) override; + bool shouldVisitTemplateInstantiations() const { return true; } /// Collect global variables. bool VisitVarDecl(const VarDecl *D); @@ -51,9 +53,19 @@ public: /// is therefore itself not collected. bool VisitObjCCategoryDecl(const ObjCCategoryDecl *D); + /// Collect global c++ declarations. + bool VisitCXXRecordDecl(const CXXRecordDecl *D); + private: std::string getMangledName(const NamedDecl *D) const; std::string getBackendMangledName(llvm::Twine Name) const; + std::string getMangledCXXVTableName(const CXXRecordDecl *D) const; + std::string getMangledCXXThunk(const GlobalDecl &D, + const ThunkInfo &Thunk) const; + std::string getMangledCXXRTTI(const CXXRecordDecl *D) const; + std::string getMangledCXXRTTIName(const CXXRecordDecl *D) const; + std::string getMangledCtorDtor(const CXXMethodDecl *D, int Type) const; + std::optional getAccessForDecl(const NamedDecl *D) const; void recordObjCInstanceVariables( const ASTContext &ASTCtx, llvm::MachO::ObjCContainerRecord *Record, @@ -61,6 +73,8 @@ private: const llvm::iterator_range< DeclContext::specific_decl_iterator> Ivars); + void emitVTableSymbols(const CXXRecordDecl *D, const AvailabilityInfo &Avail, + const HeaderType Access, bool EmittedVTable = false); InstallAPIContext &Ctx; SourceManager &SrcMgr; diff --git a/clang/include/clang/Interpreter/Interpreter.h b/clang/include/clang/Interpreter/Interpreter.h index c8f932e95c4798393e10c6902b8561d28c003cf8..1dcba1ef967980b7aa6297316b78912b3dbdb21d 100644 --- a/clang/include/clang/Interpreter/Interpreter.h +++ b/clang/include/clang/Interpreter/Interpreter.h @@ -18,6 +18,7 @@ #include "clang/AST/GlobalDecl.h" #include "clang/Interpreter/PartialTranslationUnit.h" #include "clang/Interpreter/Value.h" +#include "clang/Sema/Ownership.h" #include "llvm/ADT/DenseMap.h" #include "llvm/ExecutionEngine/JITSymbol.h" @@ -75,18 +76,26 @@ private: llvm::StringRef CudaSDKPath; }; +/// Generate glue code between the Interpreter's built-in runtime and user code. +class RuntimeInterfaceBuilder { +public: + virtual ~RuntimeInterfaceBuilder() = default; + + using TransformExprFunction = ExprResult(RuntimeInterfaceBuilder *Builder, + Expr *, ArrayRef); + virtual TransformExprFunction *getPrintValueTransformer() = 0; +}; + /// Provides top-level interfaces for incremental compilation and execution. class Interpreter { std::unique_ptr TSCtx; std::unique_ptr IncrParser; std::unique_ptr IncrExecutor; + std::unique_ptr RuntimeIB; // An optional parser for CUDA offloading std::unique_ptr DeviceParser; - Interpreter(std::unique_ptr CI, llvm::Error &Err); - - llvm::Error CreateExecutor(); unsigned InitPTUSize = 0; // This member holds the last result of the value printing. It's a class @@ -94,8 +103,33 @@ class Interpreter { // printing happens, it's in an invalid state. Value LastValue; + // Add a call to an Expr to report its result. We query the function from + // RuntimeInterfaceBuilder once and store it as a function pointer to avoid + // frequent virtual function calls. + RuntimeInterfaceBuilder::TransformExprFunction *AddPrintValueCall = nullptr; + +protected: + // Derived classes can make use an extended interface of the Interpreter. + // That's useful for testing and out-of-tree clients. + Interpreter(std::unique_ptr CI, llvm::Error &Err); + + // Create the internal IncrementalExecutor, or re-create it after calling + // ResetExecutor(). + llvm::Error CreateExecutor(); + + // Delete the internal IncrementalExecutor. This causes a hard shutdown of the + // JIT engine. In particular, it doesn't run cleanup or destructors. + void ResetExecutor(); + + // Lazily construct the RuntimeInterfaceBuilder. The provided instance will be + // used for the entire lifetime of the interpreter. The default implementation + // targets the in-process __clang_Interpreter runtime. Override this to use a + // custom runtime. + virtual std::unique_ptr FindRuntimeInterface(); + public: - ~Interpreter(); + virtual ~Interpreter(); + static llvm::Expected> create(std::unique_ptr CI); static llvm::Expected> @@ -142,8 +176,7 @@ public: private: size_t getEffectivePTUSize() const; - - bool FindRuntimeInterface(); + void markUserCodeStart(); llvm::DenseMap Dtors; diff --git a/clang/include/clang/Parse/Parser.h b/clang/include/clang/Parse/Parser.h index 071520f535bc95742b5b9da4e27d479fb76f2f21..64e031d5094c74cd0dbef96df55e479661b033b2 100644 --- a/clang/include/clang/Parse/Parser.h +++ b/clang/include/clang/Parse/Parser.h @@ -1803,6 +1803,7 @@ public: ExprResult ParseConstraintLogicalOrExpression(bool IsTrailingRequiresClause); // Expr that doesn't include commas. ExprResult ParseAssignmentExpression(TypeCastState isTypeCast = NotTypeCast); + ExprResult ParseConditionalExpression(); ExprResult ParseMSAsmIdentifier(llvm::SmallVectorImpl &LineToks, unsigned &NumLineToksConsumed, @@ -2955,6 +2956,12 @@ private: SourceLocation ScopeLoc, CachedTokens &OpenMPTokens); + /// Parse a C++23 assume() attribute. Returns true on error. + bool ParseCXXAssumeAttributeArg(ParsedAttributes &Attrs, + IdentifierInfo *AttrName, + SourceLocation AttrNameLoc, + SourceLocation *EndLoc); + IdentifierInfo *TryParseCXX11AttributeIdentifier( SourceLocation &Loc, Sema::AttributeCompletion Completion = Sema::AttributeCompletion::None, diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h index cfc1c3b34947880502942aded76cb55ee5757364..95ea5ebc7f1ac111ef354ee766609d98ba633d59 100644 --- a/clang/include/clang/Sema/Sema.h +++ b/clang/include/clang/Sema/Sema.h @@ -2152,14 +2152,15 @@ public: bool IsLayoutCompatible(QualType T1, QualType T2) const; + bool CheckFunctionCall(FunctionDecl *FDecl, CallExpr *TheCall, + const FunctionProtoType *Proto); + private: void CheckArrayAccess(const Expr *BaseExpr, const Expr *IndexExpr, const ArraySubscriptExpr *ASE = nullptr, bool AllowOnePastEnd = true, bool IndexNegated = false); void CheckArrayAccess(const Expr *E); - bool CheckFunctionCall(FunctionDecl *FDecl, CallExpr *TheCall, - const FunctionProtoType *Proto); bool CheckObjCMethodCall(ObjCMethodDecl *Method, SourceLocation loc, ArrayRef Args); bool CheckPointerCall(NamedDecl *NDecl, CallExpr *TheCall, @@ -3059,6 +3060,8 @@ public: TemplateIdAnnotation *TemplateId, bool IsMemberSpecialization); + bool checkConstantPointerAuthKey(Expr *keyExpr, unsigned &key); + void DiagnoseFunctionSpecifiers(const DeclSpec &DS); NamedDecl *getShadowedDeclaration(const TypedefNameDecl *D, const LookupResult &R); @@ -3911,6 +3914,16 @@ public: void addAMDGPUWavesPerEUAttr(Decl *D, const AttributeCommonInfo &CI, Expr *Min, Expr *Max); + /// Create an AMDGPUMaxNumWorkGroupsAttr attribute. + AMDGPUMaxNumWorkGroupsAttr * + CreateAMDGPUMaxNumWorkGroupsAttr(const AttributeCommonInfo &CI, Expr *XExpr, + Expr *YExpr, Expr *ZExpr); + + /// addAMDGPUMaxNumWorkGroupsAttr - Adds an amdgpu_max_num_work_groups + /// attribute to a particular declaration. + void addAMDGPUMaxNumWorkGroupsAttr(Decl *D, const AttributeCommonInfo &CI, + Expr *XExpr, Expr *YExpr, Expr *ZExpr); + DLLImportAttr *mergeDLLImportAttr(Decl *D, const AttributeCommonInfo &CI); DLLExportAttr *mergeDLLExportAttr(Decl *D, const AttributeCommonInfo &CI); MSInheritanceAttr *mergeMSInheritanceAttr(Decl *D, @@ -6752,18 +6765,10 @@ public: SourceLocation RParenLoc); //// ActOnCXXThis - Parse 'this' pointer. - /// - /// \param ThisRefersToClosureObject Whether to skip the 'this' check for a - /// lambda because 'this' refers to the closure object. - ExprResult ActOnCXXThis(SourceLocation loc, - bool ThisRefersToClosureObject = false); + ExprResult ActOnCXXThis(SourceLocation loc); /// Build a CXXThisExpr and mark it referenced in the current context. - /// - /// \param ThisRefersToClosureObject Whether to skip the 'this' check for a - /// lambda because 'this' refers to the closure object. - Expr *BuildCXXThisExpr(SourceLocation Loc, QualType Type, bool IsImplicit, - bool ThisRefersToClosureObject = false); + Expr *BuildCXXThisExpr(SourceLocation Loc, QualType Type, bool IsImplicit); void MarkThisReferenced(CXXThisExpr *This); /// Try to retrieve the type of the 'this' pointer. @@ -8062,13 +8067,13 @@ public: /// The parser has processed a module import translated from a /// #include or similar preprocessing directive. - void ActOnModuleInclude(SourceLocation DirectiveLoc, Module *Mod); + void ActOnAnnotModuleInclude(SourceLocation DirectiveLoc, Module *Mod); void BuildModuleInclude(SourceLocation DirectiveLoc, Module *Mod); /// The parsed has entered a submodule. - void ActOnModuleBegin(SourceLocation DirectiveLoc, Module *Mod); + void ActOnAnnotModuleBegin(SourceLocation DirectiveLoc, Module *Mod); /// The parser has left a submodule. - void ActOnModuleEnd(SourceLocation DirectiveLoc, Module *Mod); + void ActOnAnnotModuleEnd(SourceLocation DirectiveLoc, Module *Mod); /// Create an implicit import of the given module at the given /// source location, for error recovery, if possible. @@ -9011,6 +9016,12 @@ public: void ProcessStmtAttributes(Stmt *Stmt, const ParsedAttributes &InAttrs, SmallVectorImpl &OutAttrs); + ExprResult ActOnCXXAssumeAttr(Stmt *St, const ParsedAttr &A, + SourceRange Range); + ExprResult BuildCXXAssumeExpr(Expr *Assumption, + const IdentifierInfo *AttrName, + SourceRange Range); + ///@} // @@ -9206,7 +9217,7 @@ public: bool AttachTypeConstraint(NestedNameSpecifierLoc NS, DeclarationNameInfo NameInfo, - ConceptDecl *NamedConcept, + ConceptDecl *NamedConcept, NamedDecl *FoundDecl, const TemplateArgumentListInfo *TemplateArgs, TemplateTypeParmDecl *ConstrainedParameter, SourceLocation EllipsisLoc); @@ -14716,10 +14727,10 @@ private: SmallVector OMPDeclareVariantScopes; /// The current `omp begin/end assumes` scopes. - SmallVector OMPAssumeScoped; + SmallVector OMPAssumeScoped; /// All `omp assumes` we encountered so far. - SmallVector OMPAssumeGlobal; + SmallVector OMPAssumeGlobal; /// OMPD_loop is mapped to OMPD_for, OMPD_distribute or OMPD_simd depending /// on the parameter of the bind clause. In the methods for the diff --git a/clang/include/clang/Serialization/ASTReader.h b/clang/include/clang/Serialization/ASTReader.h index 2002bf23c9595f7f21598db723f2e20506482258..370d8037a4da17933e80256f651ddfa104d78203 100644 --- a/clang/include/clang/Serialization/ASTReader.h +++ b/clang/include/clang/Serialization/ASTReader.h @@ -2456,13 +2456,6 @@ private: uint32_t Value; uint32_t CurrentBitsIndex = ~0; }; - -inline bool shouldSkipCheckingODR(const Decl *D) { - return D->getOwningModule() && - D->getASTContext().getLangOpts().SkipODRCheckInGMF && - D->getOwningModule()->isExplicitGlobalModule(); -} - } // namespace clang #endif // LLVM_CLANG_SERIALIZATION_ASTREADER_H diff --git a/clang/include/clang/Serialization/ASTWriter.h b/clang/include/clang/Serialization/ASTWriter.h index e5db486a71a490565692cb90c2ecc2055007f530..3ed9803fa3745b237b0bcb77cbd7489666722021 100644 --- a/clang/include/clang/Serialization/ASTWriter.h +++ b/clang/include/clang/Serialization/ASTWriter.h @@ -868,6 +868,8 @@ protected: return SemaPtr->getDiagnostics(); } + virtual Module *getEmittingModule(ASTContext &Ctx); + public: PCHGenerator(const Preprocessor &PP, InMemoryModuleCache &ModuleCache, StringRef OutputFile, StringRef isysroot, @@ -887,10 +889,12 @@ public: }; class ReducedBMIGenerator : public PCHGenerator { +protected: + virtual Module *getEmittingModule(ASTContext &Ctx) override; + public: ReducedBMIGenerator(const Preprocessor &PP, InMemoryModuleCache &ModuleCache, - StringRef OutputFile, std::shared_ptr Buffer, - bool IncludeTimestamps); + StringRef OutputFile); void HandleTranslationUnit(ASTContext &Ctx) override; }; diff --git a/clang/include/clang/StaticAnalyzer/Core/CheckerManager.h b/clang/include/clang/StaticAnalyzer/Core/CheckerManager.h index a45ba1bc573e1e0d7ab5b416af5595bf4615497e..ad25d18f280700033874474f7ff1efe70b51d89a 100644 --- a/clang/include/clang/StaticAnalyzer/Core/CheckerManager.h +++ b/clang/include/clang/StaticAnalyzer/Core/CheckerManager.h @@ -49,7 +49,7 @@ class ExplodedNodeSet; class ExprEngine; struct EvalCallOptions; class MemRegion; -struct NodeBuilderContext; +class NodeBuilderContext; class ObjCMethodCall; class RegionAndSymbolInvalidationTraits; class SVal; diff --git a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/CoreEngine.h b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/CoreEngine.h index 8e392421fef9bb1cb270f7816df358879bca66b7..0ef353bf9731cadd9144808526f50c94f1d32fb5 100644 --- a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/CoreEngine.h +++ b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/CoreEngine.h @@ -59,7 +59,7 @@ class CoreEngine { friend class ExprEngine; friend class IndirectGotoNodeBuilder; friend class NodeBuilder; - friend struct NodeBuilderContext; + friend class NodeBuilderContext; friend class SwitchNodeBuilder; public: @@ -193,12 +193,12 @@ public: DataTag::Factory &getDataTags() { return DataTags; } }; -// TODO: Turn into a class. -struct NodeBuilderContext { +class NodeBuilderContext { const CoreEngine &Eng; const CFGBlock *Block; const LocationContext *LC; +public: NodeBuilderContext(const CoreEngine &E, const CFGBlock *B, const LocationContext *L) : Eng(E), Block(B), LC(L) { @@ -208,9 +208,15 @@ struct NodeBuilderContext { NodeBuilderContext(const CoreEngine &E, const CFGBlock *B, ExplodedNode *N) : NodeBuilderContext(E, B, N->getLocationContext()) {} + /// Return the CoreEngine associated with this builder. + const CoreEngine &getEngine() const { return Eng; } + /// Return the CFGBlock associated with this builder. const CFGBlock *getBlock() const { return Block; } + /// Return the location context associated with this builder. + const LocationContext *getLocationContext() const { return LC; } + /// Returns the number of times the current basic block has been /// visited on the exploded graph path. unsigned blockCount() const { diff --git a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h index f7894fb83ce65cd30b165ce5aa8b73242bfa75a3..859c1497d7e6db8f0f6bd6cfda62025ecc69cc36 100644 --- a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h +++ b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h @@ -85,7 +85,7 @@ class ExplodedNodeSet; class ExplodedNode; class IndirectGotoNodeBuilder; class MemRegion; -struct NodeBuilderContext; +class NodeBuilderContext; class NodeBuilderWithSinks; class ProgramState; class ProgramStateManager; diff --git a/clang/lib/APINotes/APINotesManager.cpp b/clang/lib/APINotes/APINotesManager.cpp index d3aef09dac91056758e9b8d4abb0263bc710b71f..f60f09e2b3c23198b2cb58eea29beba8312efdb0 100644 --- a/clang/lib/APINotes/APINotesManager.cpp +++ b/clang/lib/APINotes/APINotesManager.cpp @@ -224,7 +224,7 @@ APINotesManager::getCurrentModuleAPINotes(Module *M, bool LookInModule, llvm::SmallVector APINotes; // First, look relative to the module itself. - if (LookInModule) { + if (LookInModule && M->Directory) { // Local function to try loading an API notes file in the given directory. auto tryAPINotes = [&](DirectoryEntryRef Dir, bool WantPublic) { if (auto File = findAPINotesFile(Dir, ModuleName, WantPublic)) { diff --git a/clang/lib/AST/Decl.cpp b/clang/lib/AST/Decl.cpp index d681791d3920c34700bd3af91e553924afcc7dab..95900afdd2c5d8e17e68a0fe38f9fd38a751c4da 100644 --- a/clang/lib/AST/Decl.cpp +++ b/clang/lib/AST/Decl.cpp @@ -2577,11 +2577,14 @@ APValue *VarDecl::evaluateValueImpl(SmallVectorImpl &Notes, bool Result = Init->EvaluateAsInitializer(Eval->Evaluated, Ctx, this, Notes, IsConstantInitialization); - // In C++/C23, this isn't a constant initializer if we produced notes. In that - // case, we can't keep the result, because it may only be correct under the - // assumption that the initializer is a constant context. + // In C++, or in C23 if we're initialising a 'constexpr' variable, this isn't + // a constant initializer if we produced notes. In that case, we can't keep + // the result, because it may only be correct under the assumption that the + // initializer is a constant context. if (IsConstantInitialization && - (Ctx.getLangOpts().CPlusPlus || Ctx.getLangOpts().C23) && !Notes.empty()) + (Ctx.getLangOpts().CPlusPlus || + (isConstexpr() && Ctx.getLangOpts().C23)) && + !Notes.empty()) Result = false; // Ensure the computed APValue is cleaned up later if evaluation succeeded, @@ -4496,7 +4499,7 @@ unsigned FunctionDecl::getODRHash() { } class ODRHash Hash; - Hash.AddFunctionDecl(this); + Hash.AddFunctionDecl(this, /*SkipBody=*/shouldSkipCheckingODR()); setHasODRHash(true); ODRHash = Hash.CalculateHash(); return ODRHash; diff --git a/clang/lib/AST/DeclBase.cpp b/clang/lib/AST/DeclBase.cpp index fcedb3cfd176a0de856a00d9d5ebbc1d78d54172..04bbc49ab2f3192aea29e9dd2d198c3d3fa6908c 100644 --- a/clang/lib/AST/DeclBase.cpp +++ b/clang/lib/AST/DeclBase.cpp @@ -1102,6 +1102,11 @@ bool Decl::isInAnotherModuleUnit() const { return M != getASTContext().getCurrentNamedModule(); } +bool Decl::shouldSkipCheckingODR() const { + return getASTContext().getLangOpts().SkipODRCheckInGMF && getOwningModule() && + getOwningModule()->isExplicitGlobalModule(); +} + static Decl::Kind getKind(const Decl *D) { return D->getKind(); } static Decl::Kind getKind(const DeclContext *DC) { return DC->getDeclKind(); } diff --git a/clang/lib/AST/DeclCXX.cpp b/clang/lib/AST/DeclCXX.cpp index 1c3dcf63465c68a6f3bacc3a8abba4fc97ade130..645ec2f7563bca86bee1613a2dbec89247eafc87 100644 --- a/clang/lib/AST/DeclCXX.cpp +++ b/clang/lib/AST/DeclCXX.cpp @@ -1567,10 +1567,9 @@ bool CXXRecordDecl::isGenericLambda() const { #ifndef NDEBUG static bool allLookupResultsAreTheSame(const DeclContext::lookup_result &R) { - for (auto *D : R) - if (!declaresSameEntity(D, R.front())) - return false; - return true; + return llvm::all_of(R, [&](NamedDecl *D) { + return D->isInvalidDecl() || declaresSameEntity(D, R.front()); + }); } #endif diff --git a/clang/lib/AST/DeclPrinter.cpp b/clang/lib/AST/DeclPrinter.cpp index 43d221968ea3fba214a753266cf05426db1217ed..b701581b2474a96d16cd45828eb4170076c83971 100644 --- a/clang/lib/AST/DeclPrinter.cpp +++ b/clang/lib/AST/DeclPrinter.cpp @@ -1517,6 +1517,11 @@ void DeclPrinter::VisitObjCInterfaceDecl(ObjCInterfaceDecl *OID) { return; } bool eolnOut = false; + if (OID->hasAttrs()) { + prettyPrintAttributes(OID); + Out << "\n"; + } + Out << "@interface " << I; if (auto TypeParams = OID->getTypeParamListAsWritten()) { diff --git a/clang/lib/AST/Expr.cpp b/clang/lib/AST/Expr.cpp index b4de2155adcebde8b94d2885b72fdca98766d8d9..131dace77f9c250276a087c1a6d4853ebfab211c 100644 --- a/clang/lib/AST/Expr.cpp +++ b/clang/lib/AST/Expr.cpp @@ -264,11 +264,14 @@ namespace { } QualType Expr::getEnumCoercedType(const ASTContext &Ctx) const { - if (isa(this->getType())) - return this->getType(); - else if (const auto *ECD = this->getEnumConstantDecl()) - return Ctx.getTypeDeclType(cast(ECD->getDeclContext())); - return this->getType(); + if (isa(getType())) + return getType(); + if (const auto *ECD = getEnumConstantDecl()) { + const auto *ED = cast(ECD->getDeclContext()); + if (ED->isCompleteDefinition()) + return Ctx.getTypeDeclType(ED); + } + return getType(); } SourceLocation Expr::getExprLoc() const { @@ -4601,8 +4604,17 @@ SourceRange DesignatedInitExpr::getDesignatorsSourceRange() const { SourceLocation DesignatedInitExpr::getBeginLoc() const { auto *DIE = const_cast(this); Designator &First = *DIE->getDesignator(0); - if (First.isFieldDesignator()) - return GNUSyntax ? First.getFieldLoc() : First.getDotLoc(); + if (First.isFieldDesignator()) { + // Skip past implicit designators for anonymous structs/unions, since + // these do not have valid source locations. + for (unsigned int i = 0; i < DIE->size(); i++) { + Designator &Des = *DIE->getDesignator(i); + SourceLocation retval = GNUSyntax ? Des.getFieldLoc() : Des.getDotLoc(); + if (!retval.isValid()) + continue; + return retval; + } + } return First.getLBracketLoc(); } diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp index 4a7c7755e1d6fdcf77082026c6b3691e5c98673a..592d43597dc1b45a4f325602f80bb39da5758c78 100644 --- a/clang/lib/AST/ExprConstant.cpp +++ b/clang/lib/AST/ExprConstant.cpp @@ -5582,6 +5582,32 @@ static EvalStmtResult EvaluateStmt(StmtResult &Result, EvalInfo &Info, MSConstexprContextRAII ConstexprContext( *Info.CurrentCall, hasSpecificAttr(AS->getAttrs()) && isa(SS)); + + auto LO = Info.getCtx().getLangOpts(); + if (LO.CXXAssumptions && !LO.MSVCCompat) { + for (auto *Attr : AS->getAttrs()) { + auto *AA = dyn_cast(Attr); + if (!AA) + continue; + + auto *Assumption = AA->getAssumption(); + if (Assumption->isValueDependent()) + return ESR_Failed; + + if (Assumption->HasSideEffects(Info.getCtx())) + continue; + + bool Value; + if (!EvaluateAsBooleanCondition(Assumption, Value, Info)) + return ESR_Failed; + if (!Value) { + Info.CCEDiag(Assumption->getExprLoc(), + diag::note_constexpr_assumption_failed); + return ESR_Failed; + } + } + } + return EvaluateStmt(Result, Info, SS, Case); } @@ -7321,9 +7347,6 @@ class BufferToAPValueConverter { for (size_t I = 0, E = CXXRD->getNumBases(); I != E; ++I) { const CXXBaseSpecifier &BS = CXXRD->bases_begin()[I]; CXXRecordDecl *BaseDecl = BS.getType()->getAsCXXRecordDecl(); - if (BaseDecl->isEmpty() || - Info.Ctx.getASTRecordLayout(BaseDecl).getNonVirtualSize().isZero()) - continue; std::optional SubObj = visitType( BS.getType(), Layout.getBaseClassOffset(BaseDecl) + Offset); @@ -8494,6 +8517,53 @@ public: }; } // end anonymous namespace +/// Get an lvalue to a field of a lambda's closure type. +static bool HandleLambdaCapture(EvalInfo &Info, const Expr *E, LValue &Result, + const CXXMethodDecl *MD, const FieldDecl *FD, + bool LValueToRValueConversion) { + // Static lambda function call operators can't have captures. We already + // diagnosed this, so bail out here. + if (MD->isStatic()) { + assert(Info.CurrentCall->This == nullptr && + "This should not be set for a static call operator"); + return false; + } + + // Start with 'Result' referring to the complete closure object... + if (MD->isExplicitObjectMemberFunction()) { + // Self may be passed by reference or by value. + const ParmVarDecl *Self = MD->getParamDecl(0); + if (Self->getType()->isReferenceType()) { + APValue *RefValue = Info.getParamSlot(Info.CurrentCall->Arguments, Self); + Result.setFrom(Info.Ctx, *RefValue); + } else { + const ParmVarDecl *VD = Info.CurrentCall->Arguments.getOrigParam(Self); + CallStackFrame *Frame = + Info.getCallFrameAndDepth(Info.CurrentCall->Arguments.CallIndex) + .first; + unsigned Version = Info.CurrentCall->Arguments.Version; + Result.set({VD, Frame->Index, Version}); + } + } else + Result = *Info.CurrentCall->This; + + // ... then update it to refer to the field of the closure object + // that represents the capture. + if (!HandleLValueMember(Info, E, Result, FD)) + return false; + + // And if the field is of reference type (or if we captured '*this' by + // reference), update 'Result' to refer to what + // the field refers to. + if (LValueToRValueConversion) { + APValue RVal; + if (!handleLValueToRValueConversion(Info, E, FD->getType(), Result, RVal)) + return false; + Result.setFrom(Info.Ctx, RVal); + } + return true; +} + /// Evaluate an expression as an lvalue. This can be legitimately called on /// expressions which are not glvalues, in three cases: /// * function designators in C, and @@ -8538,37 +8608,8 @@ bool LValueExprEvaluator::VisitVarDecl(const Expr *E, const VarDecl *VD) { if (auto *FD = Info.CurrentCall->LambdaCaptureFields.lookup(VD)) { const auto *MD = cast(Info.CurrentCall->Callee); - - // Static lambda function call operators can't have captures. We already - // diagnosed this, so bail out here. - if (MD->isStatic()) { - assert(Info.CurrentCall->This == nullptr && - "This should not be set for a static call operator"); - return false; - } - - // Start with 'Result' referring to the complete closure object... - if (MD->isExplicitObjectMemberFunction()) { - APValue *RefValue = - Info.getParamSlot(Info.CurrentCall->Arguments, MD->getParamDecl(0)); - Result.setFrom(Info.Ctx, *RefValue); - } else - Result = *Info.CurrentCall->This; - - // ... then update it to refer to the field of the closure object - // that represents the capture. - if (!HandleLValueMember(Info, E, Result, FD)) - return false; - // And if the field is of reference type, update 'Result' to refer to what - // the field refers to. - if (FD->getType()->isReferenceType()) { - APValue RVal; - if (!handleLValueToRValueConversion(Info, E, FD->getType(), Result, - RVal)) - return false; - Result.setFrom(Info.Ctx, RVal); - } - return true; + return HandleLambdaCapture(Info, E, Result, MD, FD, + FD->getType()->isReferenceType()); } } @@ -9046,45 +9087,46 @@ public: return Error(E); } bool VisitCXXThisExpr(const CXXThisExpr *E) { - // Can't look at 'this' when checking a potential constant expression. - if (Info.checkingPotentialConstantExpression()) - return false; - if (!Info.CurrentCall->This) { + auto DiagnoseInvalidUseOfThis = [&] { if (Info.getLangOpts().CPlusPlus11) Info.FFDiag(E, diag::note_constexpr_this) << E->isImplicit(); else Info.FFDiag(E); + }; + + // Can't look at 'this' when checking a potential constant expression. + if (Info.checkingPotentialConstantExpression()) return false; + + bool IsExplicitLambda = + isLambdaCallWithExplicitObjectParameter(Info.CurrentCall->Callee); + if (!IsExplicitLambda) { + if (!Info.CurrentCall->This) { + DiagnoseInvalidUseOfThis(); + return false; + } + + Result = *Info.CurrentCall->This; } - Result = *Info.CurrentCall->This; if (isLambdaCallOperator(Info.CurrentCall->Callee)) { // Ensure we actually have captured 'this'. If something was wrong with // 'this' capture, the error would have been previously reported. // Otherwise we can be inside of a default initialization of an object // declared by lambda's body, so no need to return false. - if (!Info.CurrentCall->LambdaThisCaptureField) - return true; - - // If we have captured 'this', the 'this' expression refers - // to the enclosing '*this' object (either by value or reference) which is - // either copied into the closure object's field that represents the - // '*this' or refers to '*this'. - // Update 'Result' to refer to the data member/field of the closure object - // that represents the '*this' capture. - if (!HandleLValueMember(Info, E, Result, - Info.CurrentCall->LambdaThisCaptureField)) - return false; - // If we captured '*this' by reference, replace the field with its referent. - if (Info.CurrentCall->LambdaThisCaptureField->getType() - ->isPointerType()) { - APValue RVal; - if (!handleLValueToRValueConversion(Info, E, E->getType(), Result, - RVal)) + if (!Info.CurrentCall->LambdaThisCaptureField) { + if (IsExplicitLambda && !Info.CurrentCall->This) { + DiagnoseInvalidUseOfThis(); return false; + } - Result.setFrom(Info.Ctx, RVal); + return true; } + + const auto *MD = cast(Info.CurrentCall->Callee); + return HandleLambdaCapture( + Info, E, Result, MD, Info.CurrentCall->LambdaThisCaptureField, + Info.CurrentCall->LambdaThisCaptureField->getType()->isPointerType()); } return true; } @@ -9211,7 +9253,8 @@ bool PointerExprEvaluator::VisitCastExpr(const CastExpr *E) { Info.getLangOpts().CPlusPlus26)) { // Permitted. } else { - if (SubExpr->getType()->isVoidPointerType()) { + if (SubExpr->getType()->isVoidPointerType() && + Info.getLangOpts().CPlusPlus) { if (HasValidResult) CCEDiag(E, diag::note_constexpr_invalid_void_star_cast) << SubExpr->getType() << Info.getLangOpts().CPlusPlus26 @@ -11816,8 +11859,8 @@ static QualType getObjectType(APValue::LValueBase B) { static const Expr *ignorePointerCastsAndParens(const Expr *E) { assert(E->isPRValue() && E->getType()->hasPointerRepresentation()); - auto *NoParens = E->IgnoreParens(); - auto *Cast = dyn_cast(NoParens); + const Expr *NoParens = E->IgnoreParens(); + const auto *Cast = dyn_cast(NoParens); if (Cast == nullptr) return NoParens; @@ -11828,7 +11871,7 @@ static const Expr *ignorePointerCastsAndParens(const Expr *E) { CastKind != CK_AddressSpaceConversion) return NoParens; - auto *SubExpr = Cast->getSubExpr(); + const auto *SubExpr = Cast->getSubExpr(); if (!SubExpr->getType()->hasPointerRepresentation() || !SubExpr->isPRValue()) return NoParens; return ignorePointerCastsAndParens(SubExpr); @@ -12900,6 +12943,10 @@ static bool isOnePastTheEndOfCompleteObject(const ASTContext &Ctx, if (Ty->isIncompleteType()) return true; + // Can't be past the end of an invalid object. + if (LV.getLValueDesignator().Invalid) + return false; + // We're a past-the-end pointer if we point to the byte after the object, // no matter what our type or path is. auto Size = Ctx.getTypeSizeInChars(Ty); diff --git a/clang/lib/AST/Interp/ByteCodeExprGen.cpp b/clang/lib/AST/Interp/ByteCodeExprGen.cpp index a384e191464feaa4a2d78a96b9d61b51a3cb33a4..af214d4a8577c6581ceb35c2cfb60c50c109b56b 100644 --- a/clang/lib/AST/Interp/ByteCodeExprGen.cpp +++ b/clang/lib/AST/Interp/ByteCodeExprGen.cpp @@ -82,15 +82,27 @@ bool ByteCodeExprGen::VisitCastExpr(const CastExpr *CE) { if (DiscardResult) return this->discard(SubExpr); - if (SubExpr->getType()->isAnyComplexType()) - return this->delegate(SubExpr); + std::optional SubExprT = classify(SubExpr->getType()); + // Prepare storage for the result. + if (!Initializing && !SubExprT) { + std::optional LocalIndex = + allocateLocal(SubExpr, /*IsExtended=*/false); + if (!LocalIndex) + return false; + if (!this->emitGetPtrLocal(*LocalIndex, CE)) + return false; + } if (!this->visit(SubExpr)) return false; - if (std::optional SubExprT = classify(SubExpr->getType())) + if (SubExprT) return this->emitLoadPop(*SubExprT, CE); - return false; + + // If the subexpr type is not primitive, we need to perform a copy here. + // This happens for example in C when dereferencing a pointer of struct + // type. + return this->emitMemcpy(CE); } case CK_UncheckedDerivedToBase: @@ -296,14 +308,11 @@ bool ByteCodeExprGen::VisitCastExpr(const CastExpr *CE) { // Location for the SubExpr. // Since SubExpr is of complex type, visiting it results in a pointer // anyway, so we just create a temporary pointer variable. - std::optional SubExprOffset = allocateLocalPrimitive( + unsigned SubExprOffset = allocateLocalPrimitive( SubExpr, PT_Ptr, /*IsConst=*/true, /*IsExtended=*/false); - if (!SubExprOffset) - return false; - if (!this->visit(SubExpr)) return false; - if (!this->emitSetLocal(PT_Ptr, *SubExprOffset, CE)) + if (!this->emitSetLocal(PT_Ptr, SubExprOffset, CE)) return false; PrimType SourceElemT = classifyComplexElementType(SubExpr->getType()); @@ -312,7 +321,7 @@ bool ByteCodeExprGen::VisitCastExpr(const CastExpr *CE) { PrimType DestElemT = classifyPrim(DestElemType); // Cast both elements individually. for (unsigned I = 0; I != 2; ++I) { - if (!this->emitGetLocal(PT_Ptr, *SubExprOffset, CE)) + if (!this->emitGetLocal(PT_Ptr, SubExprOffset, CE)) return false; if (!this->emitArrayElemPop(SourceElemT, I, CE)) return false; @@ -392,6 +401,17 @@ bool ByteCodeExprGen::VisitBinaryOperator(const BinaryOperator *BO) { const Expr *LHS = BO->getLHS(); const Expr *RHS = BO->getRHS(); + // Handle comma operators. Just discard the LHS + // and delegate to RHS. + if (BO->isCommaOp()) { + if (!this->discard(LHS)) + return false; + if (RHS->getType()->isVoidType()) + return this->discard(RHS); + + return this->delegate(RHS); + } + if (BO->getType()->isAnyComplexType()) return this->VisitComplexBinOp(BO); if ((LHS->getType()->isAnyComplexType() || @@ -407,16 +427,6 @@ bool ByteCodeExprGen::VisitBinaryOperator(const BinaryOperator *BO) { std::optional RT = classify(RHS->getType()); std::optional T = classify(BO->getType()); - // Deal with operations which have composite or void types. - if (BO->isCommaOp()) { - if (!this->discard(LHS)) - return false; - if (RHS->getType()->isVoidType()) - return this->discard(RHS); - - return this->delegate(RHS); - } - // Special case for C++'s three-way/spaceship operator <=>, which // returns a std::{strong,weak,partial}_ordering (which is a class, so doesn't // have a PrimType). @@ -676,11 +686,17 @@ bool ByteCodeExprGen::VisitComplexBinOp(const BinaryOperator *E) { if (!this->emitSetLocal(PT_Ptr, ResultOffset, E)) return false; } + QualType LHSType = LHS->getType(); + if (const auto *AT = LHSType->getAs()) + LHSType = AT->getValueType(); + QualType RHSType = RHS->getType(); + if (const auto *AT = RHSType->getAs()) + RHSType = AT->getValueType(); // Evaluate LHS and save value to LHSOffset. bool LHSIsComplex; unsigned LHSOffset; - if (LHS->getType()->isAnyComplexType()) { + if (LHSType->isAnyComplexType()) { LHSIsComplex = true; LHSOffset = this->allocateLocalPrimitive(LHS, PT_Ptr, true, false); if (!this->visit(LHS)) @@ -689,7 +705,7 @@ bool ByteCodeExprGen::VisitComplexBinOp(const BinaryOperator *E) { return false; } else { LHSIsComplex = false; - PrimType LHST = classifyPrim(LHS->getType()); + PrimType LHST = classifyPrim(LHSType); LHSOffset = this->allocateLocalPrimitive(LHS, LHST, true, false); if (!this->visit(LHS)) return false; @@ -700,7 +716,7 @@ bool ByteCodeExprGen::VisitComplexBinOp(const BinaryOperator *E) { // Same with RHS. bool RHSIsComplex; unsigned RHSOffset; - if (RHS->getType()->isAnyComplexType()) { + if (RHSType->isAnyComplexType()) { RHSIsComplex = true; RHSOffset = this->allocateLocalPrimitive(RHS, PT_Ptr, true, false); if (!this->visit(RHS)) @@ -709,7 +725,7 @@ bool ByteCodeExprGen::VisitComplexBinOp(const BinaryOperator *E) { return false; } else { RHSIsComplex = false; - PrimType RHST = classifyPrim(RHS->getType()); + PrimType RHST = classifyPrim(RHSType); RHSOffset = this->allocateLocalPrimitive(RHS, RHST, true, false); if (!this->visit(RHS)) return false; @@ -1081,9 +1097,9 @@ template bool ByteCodeExprGen::VisitUnaryExprOrTypeTraitExpr( const UnaryExprOrTypeTraitExpr *E) { UnaryExprOrTypeTrait Kind = E->getKind(); - ASTContext &ASTCtx = Ctx.getASTContext(); + const ASTContext &ASTCtx = Ctx.getASTContext(); - if (Kind == UETT_SizeOf) { + if (Kind == UETT_SizeOf || Kind == UETT_DataSizeOf) { QualType ArgType = E->getTypeOfArgument(); // C++ [expr.sizeof]p2: "When applied to a reference or a reference type, @@ -1098,7 +1114,10 @@ bool ByteCodeExprGen::VisitUnaryExprOrTypeTraitExpr( if (ArgType->isDependentType() || !ArgType->isConstantSizeType()) return false; - Size = ASTCtx.getTypeSizeInChars(ArgType); + if (Kind == UETT_SizeOf) + Size = ASTCtx.getTypeSizeInChars(ArgType); + else + Size = ASTCtx.getTypeInfoDataSizeInChars(ArgType).Width; } if (DiscardResult) @@ -1233,22 +1252,19 @@ bool ByteCodeExprGen::VisitOpaqueValueExpr(const OpaqueValueExpr *E) { // At this point we either have the evaluated source expression or a pointer // to an object on the stack. We want to create a local variable that stores // this value. - std::optional LocalIndex = - allocateLocalPrimitive(E, SubExprT, /*IsConst=*/true); - if (!LocalIndex) - return false; - if (!this->emitSetLocal(SubExprT, *LocalIndex, E)) + unsigned LocalIndex = allocateLocalPrimitive(E, SubExprT, /*IsConst=*/true); + if (!this->emitSetLocal(SubExprT, LocalIndex, E)) return false; // Here the local variable is created but the value is removed from the stack, // so we put it back if the caller needs it. if (!DiscardResult) { - if (!this->emitGetLocal(SubExprT, *LocalIndex, E)) + if (!this->emitGetLocal(SubExprT, LocalIndex, E)) return false; } // This is cleaned up when the local variable is destroyed. - OpaqueExprs.insert({E, *LocalIndex}); + OpaqueExprs.insert({E, LocalIndex}); return true; } @@ -1642,14 +1658,13 @@ bool ByteCodeExprGen::VisitMaterializeTemporaryExpr( // For everyhing else, use local variables. if (SubExprT) { - if (std::optional LocalIndex = allocateLocalPrimitive( - SubExpr, *SubExprT, /*IsConst=*/true, /*IsExtended=*/true)) { - if (!this->visit(SubExpr)) - return false; - if (!this->emitSetLocal(*SubExprT, *LocalIndex, E)) - return false; - return this->emitGetPtrLocal(*LocalIndex, E); - } + unsigned LocalIndex = allocateLocalPrimitive( + SubExpr, *SubExprT, /*IsConst=*/true, /*IsExtended=*/true); + if (!this->visit(SubExpr)) + return false; + if (!this->emitSetLocal(*SubExprT, LocalIndex, E)) + return false; + return this->emitGetPtrLocal(LocalIndex, E); } else { const Expr *Inner = E->getSubExpr()->skipRValueSubobjectAdjustments(); @@ -1744,6 +1759,14 @@ bool ByteCodeExprGen::VisitTypeTraitExpr(const TypeTraitExpr *E) { return this->emitConst(E->getValue(), E); } +template +bool ByteCodeExprGen::VisitArrayTypeTraitExpr( + const ArrayTypeTraitExpr *E) { + if (DiscardResult) + return true; + return this->emitConst(E->getValue(), E); +} + template bool ByteCodeExprGen::VisitLambdaExpr(const LambdaExpr *E) { if (DiscardResult) @@ -2215,6 +2238,12 @@ bool ByteCodeExprGen::VisitPseudoObjectExpr( return true; } +template +bool ByteCodeExprGen::VisitPackIndexingExpr( + const PackIndexingExpr *E) { + return this->delegate(E->getSelectedExpr()); +} + template bool ByteCodeExprGen::discard(const Expr *E) { if (E->containsErrors()) return false; @@ -2227,7 +2256,7 @@ template bool ByteCodeExprGen::discard(const Expr *E) { template bool ByteCodeExprGen::delegate(const Expr *E) { if (E->containsErrors()) - return false; + return this->emitError(E); // We're basically doing: // OptionScope Scope(this, DicardResult, Initializing); @@ -2237,7 +2266,7 @@ bool ByteCodeExprGen::delegate(const Expr *E) { template bool ByteCodeExprGen::visit(const Expr *E) { if (E->containsErrors()) - return false; + return this->emitError(E); if (E->getType()->isVoidType()) return this->discard(E); @@ -2266,7 +2295,7 @@ bool ByteCodeExprGen::visitInitializer(const Expr *E) { assert(!classify(E->getType())); if (E->containsErrors()) - return false; + return this->emitError(E); OptionScope Scope(this, /*NewDiscardResult=*/false, /*NewInitializing=*/true); @@ -2660,18 +2689,12 @@ bool ByteCodeExprGen::visitVarDecl(const VarDecl *VD) { if (P.getGlobal(VD)) return true; - // Ignore external declarations. We will instead emit a dummy - // pointer when we see a DeclRefExpr for them. - if (VD->hasExternalStorage()) - return true; - std::optional GlobalIndex = P.createGlobal(VD, Init); if (!GlobalIndex) return false; - assert(Init); - { + if (Init) { DeclScope LocalScope(this, VD); if (VarT) { @@ -2681,6 +2704,7 @@ bool ByteCodeExprGen::visitVarDecl(const VarDecl *VD) { } return this->visitGlobalInitializer(Init, *GlobalIndex); } + return true; } else { VariableScope LocalScope(this); if (VarT) { @@ -2893,11 +2917,7 @@ template bool ByteCodeExprGen::VisitCXXDefaultInitExpr( const CXXDefaultInitExpr *E) { SourceLocScope SLS(this, E); - if (Initializing) - return this->visitInitializer(E->getExpr()); - - assert(classify(E->getType())); - return this->visit(E->getExpr()); + return this->delegate(E->getExpr()); } template @@ -2959,6 +2979,8 @@ bool ByteCodeExprGen::VisitCXXThisExpr(const CXXThisExpr *E) { template bool ByteCodeExprGen::VisitUnaryOperator(const UnaryOperator *E) { const Expr *SubExpr = E->getSubExpr(); + if (SubExpr->getType()->isAnyComplexType()) + return this->VisitComplexUnaryOperator(E); std::optional T = classify(SubExpr->getType()); switch (E->getOpcode()) { @@ -3109,16 +3131,97 @@ bool ByteCodeExprGen::VisitUnaryOperator(const UnaryOperator *E) { return false; return DiscardResult ? this->emitPop(*T, E) : this->emitComp(*T, E); case UO_Real: // __real x - if (T) - return this->delegate(SubExpr); - return this->emitComplexReal(SubExpr); + assert(T); + return this->delegate(SubExpr); case UO_Imag: { // __imag x - if (T) { - if (!this->discard(SubExpr)) + assert(T); + if (!this->discard(SubExpr)) + return false; + return this->visitZeroInitializer(*T, SubExpr->getType(), SubExpr); + } + case UO_Extension: + return this->delegate(SubExpr); + case UO_Coawait: + assert(false && "Unhandled opcode"); + } + + return false; +} + +template +bool ByteCodeExprGen::VisitComplexUnaryOperator( + const UnaryOperator *E) { + const Expr *SubExpr = E->getSubExpr(); + assert(SubExpr->getType()->isAnyComplexType()); + + if (DiscardResult) + return this->discard(SubExpr); + + std::optional ResT = classify(E); + auto prepareResult = [=]() -> bool { + if (!ResT && !Initializing) { + std::optional LocalIndex = + allocateLocal(SubExpr, /*IsExtended=*/false); + if (!LocalIndex) return false; - return this->visitZeroInitializer(*T, SubExpr->getType(), SubExpr); + return this->emitGetPtrLocal(*LocalIndex, E); } + return true; + }; + + // The offset of the temporary, if we created one. + unsigned SubExprOffset = ~0u; + auto createTemp = [=, &SubExprOffset]() -> bool { + SubExprOffset = this->allocateLocalPrimitive(SubExpr, PT_Ptr, true, false); + if (!this->visit(SubExpr)) + return false; + return this->emitSetLocal(PT_Ptr, SubExprOffset, E); + }; + + PrimType ElemT = classifyComplexElementType(SubExpr->getType()); + auto getElem = [=](unsigned Offset, unsigned Index) -> bool { + if (!this->emitGetLocal(PT_Ptr, Offset, E)) + return false; + return this->emitArrayElemPop(ElemT, Index, E); + }; + + switch (E->getOpcode()) { + case UO_Minus: + if (!prepareResult()) + return false; + if (!createTemp()) + return false; + for (unsigned I = 0; I != 2; ++I) { + if (!getElem(SubExprOffset, I)) + return false; + if (!this->emitNeg(ElemT, E)) + return false; + if (!this->emitInitElem(ElemT, I, E)) + return false; + } + break; + + case UO_Plus: // +x + case UO_AddrOf: // &x + case UO_Deref: // *x + return this->delegate(SubExpr); + + case UO_LNot: + if (!this->visit(SubExpr)) + return false; + if (!this->emitComplexBoolCast(SubExpr)) + return false; + if (!this->emitInvBool(E)) + return false; + if (PrimType ET = classifyPrim(E->getType()); ET != PT_Bool) + return this->emitCast(PT_Bool, ET, E); + return true; + + case UO_Real: + return this->emitComplexReal(SubExpr); + + case UO_Imag: if (!this->visit(SubExpr)) return false; @@ -3131,14 +3234,12 @@ bool ByteCodeExprGen::VisitUnaryOperator(const UnaryOperator *E) { // Since our _Complex implementation does not map to a primitive type, // we sometimes have to do the lvalue-to-rvalue conversion here manually. return this->emitArrayElemPop(classifyPrim(E->getType()), 1, E); - } - case UO_Extension: - return this->delegate(SubExpr); - case UO_Coawait: - assert(false && "Unhandled opcode"); + + default: + return this->emitInvalid(E); } - return false; + return true; } template @@ -3166,53 +3267,20 @@ bool ByteCodeExprGen::VisitDeclRefExpr(const DeclRefExpr *E) { // pointer to the actual value) instead of a pointer to the pointer to the // value. bool IsReference = D->getType()->isReferenceType(); - // Complex values are copied in the AST via a simply assignment or - // ltor cast. But we represent them as two-element arrays, which means - // we pass them around as pointers. So, to assignm from them, we will - // have to copy both (primitive) elements instead. - bool IsComplex = D->getType()->isAnyComplexType(); // Check for local/global variables and parameters. if (auto It = Locals.find(D); It != Locals.end()) { const unsigned Offset = It->second.Offset; - // FIXME: Fix the code duplication here with the code in the global case. - if (Initializing && IsComplex) { - PrimType ElemT = classifyComplexElementType(D->getType()); - for (unsigned I = 0; I != 2; ++I) { - if (!this->emitGetPtrLocal(Offset, E)) - return false; - if (!this->emitArrayElemPop(ElemT, I, E)) - return false; - if (!this->emitInitElem(ElemT, I, E)) - return false; - } - return true; - } - if (IsReference) return this->emitGetLocal(PT_Ptr, Offset, E); return this->emitGetPtrLocal(Offset, E); } else if (auto GlobalIndex = P.getGlobal(D)) { - if (Initializing && IsComplex) { - PrimType ElemT = classifyComplexElementType(D->getType()); - for (unsigned I = 0; I != 2; ++I) { - if (!this->emitGetPtrGlobal(*GlobalIndex, E)) - return false; - if (!this->emitArrayElemPop(ElemT, I, E)) - return false; - if (!this->emitInitElem(ElemT, I, E)) - return false; - } - return true; - } - if (IsReference) return this->emitGetGlobalPtr(*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()) { - // FIXME: _Complex initializing case? if (IsReference || !It->second.IsPtr) return this->emitGetParamPtr(It->second.Offset, E); @@ -3235,15 +3303,13 @@ bool ByteCodeExprGen::VisitDeclRefExpr(const DeclRefExpr *E) { if (Ctx.getLangOpts().CPlusPlus) { if (const auto *VD = dyn_cast(D)) { // Visit local const variables like normal. - if (VD->isLocalVarDecl() && VD->getType().isConstQualified()) { + if ((VD->isLocalVarDecl() || VD->isStaticDataMember()) && + VD->getType().isConstQualified()) { if (!this->visitVarDecl(VD)) return false; // Retry. return this->VisitDeclRefExpr(E); } - - if (VD->hasExternalStorage()) - return this->emitInvalidDeclRef(E, E); } } else { if (const auto *VD = dyn_cast(D); diff --git a/clang/lib/AST/Interp/ByteCodeExprGen.h b/clang/lib/AST/Interp/ByteCodeExprGen.h index 5977bb5e6ff25daaf30508cc44d9d71d029ecd74..db0d73ce23f7c450dc0eab43575056b4659c2d9f 100644 --- a/clang/lib/AST/Interp/ByteCodeExprGen.h +++ b/clang/lib/AST/Interp/ByteCodeExprGen.h @@ -75,6 +75,7 @@ public: bool VisitGNUNullExpr(const GNUNullExpr *E); bool VisitCXXThisExpr(const CXXThisExpr *E); bool VisitUnaryOperator(const UnaryOperator *E); + bool VisitComplexUnaryOperator(const UnaryOperator *E); bool VisitDeclRefExpr(const DeclRefExpr *E); bool VisitImplicitValueInitExpr(const ImplicitValueInitExpr *E); bool VisitSubstNonTypeTemplateParmExpr(const SubstNonTypeTemplateParmExpr *E); @@ -98,6 +99,7 @@ public: bool VisitCXXBindTemporaryExpr(const CXXBindTemporaryExpr *E); bool VisitCompoundLiteralExpr(const CompoundLiteralExpr *E); bool VisitTypeTraitExpr(const TypeTraitExpr *E); + bool VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *E); bool VisitLambdaExpr(const LambdaExpr *E); bool VisitPredefinedExpr(const PredefinedExpr *E); bool VisitCXXThrowExpr(const CXXThrowExpr *E); @@ -118,6 +120,7 @@ public: bool VisitConceptSpecializationExpr(const ConceptSpecializationExpr *E); bool VisitCXXRewrittenBinaryOperator(const CXXRewrittenBinaryOperator *E); bool VisitPseudoObjectExpr(const PseudoObjectExpr *E); + bool VisitPackIndexingExpr(const PackIndexingExpr *E); protected: bool visitExpr(const Expr *E) override; diff --git a/clang/lib/AST/Interp/ByteCodeStmtGen.cpp b/clang/lib/AST/Interp/ByteCodeStmtGen.cpp index 6da3860f98d8c022d53781eaba72b5167295b086..675063e74898867e0edc7875a252c8510a701a87 100644 --- a/clang/lib/AST/Interp/ByteCodeStmtGen.cpp +++ b/clang/lib/AST/Interp/ByteCodeStmtGen.cpp @@ -273,15 +273,18 @@ bool ByteCodeStmtGen::visitStmt(const Stmt *S) { return visitCaseStmt(cast(S)); case Stmt::DefaultStmtClass: return visitDefaultStmt(cast(S)); - case Stmt::GCCAsmStmtClass: - case Stmt::MSAsmStmtClass: - return visitAsmStmt(cast(S)); case Stmt::AttributedStmtClass: return visitAttributedStmt(cast(S)); case Stmt::CXXTryStmtClass: return visitCXXTryStmt(cast(S)); case Stmt::NullStmtClass: return true; + // Always invalid statements. + case Stmt::GCCAsmStmtClass: + case Stmt::MSAsmStmtClass: + case Stmt::GotoStmtClass: + case Stmt::LabelStmtClass: + return this->emitInvalid(S); default: { if (auto *Exp = dyn_cast(S)) return this->discard(Exp); @@ -420,6 +423,11 @@ bool ByteCodeStmtGen::visitWhileStmt(const WhileStmt *S) { LoopScope LS(this, EndLabel, CondLabel); this->emitLabel(CondLabel); + + if (const DeclStmt *CondDecl = S->getConditionVariableDeclStmt()) + if (!visitDeclStmt(CondDecl)) + return false; + if (!this->visitBool(Cond)) return false; if (!this->jumpFalse(EndLabel)) @@ -484,6 +492,10 @@ bool ByteCodeStmtGen::visitForStmt(const ForStmt *S) { if (Init && !this->visitStmt(Init)) return false; this->emitLabel(CondLabel); + + if (const DeclStmt *CondDecl = S->getConditionVariableDeclStmt()) + if (!visitDeclStmt(CondDecl)) + return false; if (Cond) { if (!this->visitBool(Cond)) return false; @@ -582,17 +594,21 @@ bool ByteCodeStmtGen::visitContinueStmt(const ContinueStmt *S) { template bool ByteCodeStmtGen::visitSwitchStmt(const SwitchStmt *S) { const Expr *Cond = S->getCond(); - PrimType CondT = this->classifyPrim(Cond->getType()); LabelTy EndLabel = this->getLabel(); OptLabelTy DefaultLabel = std::nullopt; - unsigned CondVar = this->allocateLocalPrimitive(Cond, CondT, true, false); if (const auto *CondInit = S->getInit()) if (!visitStmt(CondInit)) return false; + if (const DeclStmt *CondDecl = S->getConditionVariableDeclStmt()) + if (!visitDeclStmt(CondDecl)) + return false; + // Initialize condition variable. + PrimType CondT = this->classifyPrim(Cond->getType()); + unsigned CondVar = this->allocateLocalPrimitive(Cond, CondT, true, false); if (!this->visit(Cond)) return false; if (!this->emitSetLocal(CondT, CondVar, S)) @@ -657,11 +673,6 @@ bool ByteCodeStmtGen::visitDefaultStmt(const DefaultStmt *S) { return this->visitStmt(S->getSubStmt()); } -template -bool ByteCodeStmtGen::visitAsmStmt(const AsmStmt *S) { - return this->emitInvalid(S); -} - template bool ByteCodeStmtGen::visitAttributedStmt(const AttributedStmt *S) { // Ignore all attributes. diff --git a/clang/lib/AST/Interp/ByteCodeStmtGen.h b/clang/lib/AST/Interp/ByteCodeStmtGen.h index 64e03587ab2112dad4fb29609ebf8bad61770d81..ab7a591fb798ee6fb8e1d97c12d7a491fe84c536 100644 --- a/clang/lib/AST/Interp/ByteCodeStmtGen.h +++ b/clang/lib/AST/Interp/ByteCodeStmtGen.h @@ -63,7 +63,6 @@ private: bool visitSwitchStmt(const SwitchStmt *S); bool visitCaseStmt(const CaseStmt *S); bool visitDefaultStmt(const DefaultStmt *S); - bool visitAsmStmt(const AsmStmt *S); bool visitAttributedStmt(const AttributedStmt *S); bool visitCXXTryStmt(const CXXTryStmt *S); diff --git a/clang/lib/AST/Interp/Descriptor.cpp b/clang/lib/AST/Interp/Descriptor.cpp index ce7ed9cec3db3f073825ca6e763a2d5a05867732..a4ccc0236d292ce40665aaf2d37138e1e9831b86 100644 --- a/clang/lib/AST/Interp/Descriptor.cpp +++ b/clang/lib/AST/Interp/Descriptor.cpp @@ -233,9 +233,10 @@ static BlockMoveFn getMoveArrayPrim(PrimType Type) { Descriptor::Descriptor(const DeclTy &D, PrimType Type, MetadataSize MD, bool IsConst, bool IsTemporary, bool IsMutable) : Source(D), ElemSize(primSize(Type)), Size(ElemSize), - MDSize(MD.value_or(0)), AllocSize(align(Size + MDSize)), IsConst(IsConst), - IsMutable(IsMutable), IsTemporary(IsTemporary), CtorFn(getCtorPrim(Type)), - DtorFn(getDtorPrim(Type)), MoveFn(getMovePrim(Type)) { + MDSize(MD.value_or(0)), AllocSize(align(Size + MDSize)), PrimT(Type), + IsConst(IsConst), IsMutable(IsMutable), IsTemporary(IsTemporary), + CtorFn(getCtorPrim(Type)), DtorFn(getDtorPrim(Type)), + MoveFn(getMovePrim(Type)) { assert(AllocSize >= Size); assert(Source && "Missing source"); } @@ -246,7 +247,7 @@ Descriptor::Descriptor(const DeclTy &D, PrimType Type, MetadataSize MD, bool IsMutable) : Source(D), ElemSize(primSize(Type)), Size(ElemSize * NumElems), MDSize(MD.value_or(0)), - AllocSize(align(MDSize) + align(Size) + sizeof(InitMapPtr)), + AllocSize(align(MDSize) + align(Size) + sizeof(InitMapPtr)), PrimT(Type), IsConst(IsConst), IsMutable(IsMutable), IsTemporary(IsTemporary), IsArray(true), CtorFn(getCtorArrayPrim(Type)), DtorFn(getDtorArrayPrim(Type)), MoveFn(getMoveArrayPrim(Type)) { @@ -300,10 +301,19 @@ Descriptor::Descriptor(const DeclTy &D, const Record *R, MetadataSize MD, assert(Source && "Missing source"); } -Descriptor::Descriptor(const DeclTy &D, MetadataSize MD) - : Source(D), ElemSize(1), Size(ElemSize), MDSize(MD.value_or(0)), - AllocSize(Size + MDSize), ElemRecord(nullptr), IsConst(true), - IsMutable(false), IsTemporary(false), IsDummy(true) { +/// Dummy. +Descriptor::Descriptor(const DeclTy &D) + : Source(D), ElemSize(1), Size(1), MDSize(0), AllocSize(MDSize), + ElemRecord(nullptr), IsConst(true), IsMutable(false), IsTemporary(false), + IsDummy(true) { + assert(Source && "Missing source"); +} + +/// Dummy array. +Descriptor::Descriptor(const DeclTy &D, UnknownSize) + : Source(D), ElemSize(1), Size(UnknownSizeMark), MDSize(0), + AllocSize(MDSize), ElemRecord(nullptr), IsConst(true), IsMutable(false), + IsTemporary(false), IsArray(true), IsDummy(true) { assert(Source && "Missing source"); } diff --git a/clang/lib/AST/Interp/Descriptor.h b/clang/lib/AST/Interp/Descriptor.h index 0f64d678f3ef6b9415d37f04eb9a87c40151371f..4e257361ad146bfaa14c78873cb1f08bf1bbf162 100644 --- a/clang/lib/AST/Interp/Descriptor.h +++ b/clang/lib/AST/Interp/Descriptor.h @@ -112,6 +112,10 @@ public: const Record *const ElemRecord = nullptr; /// Descriptor of the array element. const Descriptor *const ElemDesc = nullptr; + /// The primitive type this descriptor was created for, + /// or the primitive element type in case this is + /// a primitive array. + const std::optional PrimT = std::nullopt; /// Flag indicating if the block is mutable. const bool IsConst = false; /// Flag indicating if a field is mutable. @@ -152,7 +156,11 @@ public: Descriptor(const DeclTy &D, const Record *R, MetadataSize MD, bool IsConst, bool IsTemporary, bool IsMutable); - Descriptor(const DeclTy &D, MetadataSize MD); + /// Allocates a dummy descriptor. + Descriptor(const DeclTy &D); + + /// Allocates a dummy array descriptor. + Descriptor(const DeclTy &D, UnknownSize); QualType getType() const; QualType getElemQualType() const; @@ -183,6 +191,11 @@ public: return Size; } + PrimType getPrimType() const { + assert(isPrimitiveArray() || isPrimitive()); + return *PrimT; + } + /// Returns the allocated size, including metadata. unsigned getAllocSize() const { return AllocSize; } /// returns the size of an element when the structure is viewed as an array. diff --git a/clang/lib/AST/Interp/Disasm.cpp b/clang/lib/AST/Interp/Disasm.cpp index 315ddb293044b78e792e0c285b8c9148cabd4799..390d79d44b0a743d60a5ab769f7ea2289bcaaec3 100644 --- a/clang/lib/AST/Interp/Disasm.cpp +++ b/clang/lib/AST/Interp/Disasm.cpp @@ -10,8 +10,11 @@ // //===----------------------------------------------------------------------===// +#include "Boolean.h" #include "Floating.h" #include "Function.h" +#include "FunctionPointer.h" +#include "Integral.h" #include "IntegralAP.h" #include "Opcode.h" #include "PrimType.h" @@ -86,6 +89,40 @@ LLVM_DUMP_METHOD void Function::dump(llvm::raw_ostream &OS) const { LLVM_DUMP_METHOD void Program::dump() const { dump(llvm::errs()); } +static const char *primTypeToString(PrimType T) { + switch (T) { + case PT_Sint8: + return "Sint8"; + case PT_Uint8: + return "Uint8"; + case PT_Sint16: + return "Sint16"; + case PT_Uint16: + return "Uint16"; + case PT_Sint32: + return "Sint32"; + case PT_Uint32: + return "Uint32"; + case PT_Sint64: + return "Sint64"; + case PT_Uint64: + return "Uint64"; + case PT_IntAP: + return "IntAP"; + case PT_IntAPS: + return "IntAPS"; + case PT_Bool: + return "Bool"; + case PT_Float: + return "Float"; + case PT_Ptr: + return "Ptr"; + case PT_FnPtr: + return "FnPtr"; + } + llvm_unreachable("Unhandled PrimType"); +} + LLVM_DUMP_METHOD void Program::dump(llvm::raw_ostream &OS) const { { ColorScope SC(OS, true, {llvm::raw_ostream::BRIGHT_RED, true}); @@ -100,9 +137,10 @@ LLVM_DUMP_METHOD void Program::dump(llvm::raw_ostream &OS) const { unsigned GI = 0; for (const Global *G : Globals) { const Descriptor *Desc = G->block()->getDescriptor(); + Pointer GP = getPtrGlobal(GI); + OS << GI << ": " << (void *)G->block() << " "; { - Pointer GP = getPtrGlobal(GI); ColorScope SC(OS, true, GP.isInitialized() ? TerminalColor{llvm::raw_ostream::GREEN, false} @@ -111,6 +149,15 @@ LLVM_DUMP_METHOD void Program::dump(llvm::raw_ostream &OS) const { } Desc->dump(OS); OS << "\n"; + if (Desc->isPrimitive() && !Desc->isDummy()) { + OS << " "; + { + ColorScope SC(OS, true, {llvm::raw_ostream::BRIGHT_CYAN, false}); + OS << primTypeToString(Desc->getPrimType()) << " "; + } + TYPE_SWITCH(Desc->getPrimType(), { GP.deref().print(OS); }); + OS << "\n"; + } ++GI; } @@ -136,7 +183,7 @@ LLVM_DUMP_METHOD void Descriptor::dump(llvm::raw_ostream &OS) const { { ColorScope SC(OS, true, {llvm::raw_ostream::BLUE, true}); if (const auto *ND = dyn_cast_if_present(asDecl())) - OS << ND->getName(); + ND->printQualifiedName(OS); else if (asExpr()) OS << "expr (TODO)"; } diff --git a/clang/lib/AST/Interp/Interp.cpp b/clang/lib/AST/Interp/Interp.cpp index 4f3cd6cd21a15184f56de3df592da5fc70941944..0ce64a572c263f3daa07d3de4385037e24fa6496 100644 --- a/clang/lib/AST/Interp/Interp.cpp +++ b/clang/lib/AST/Interp/Interp.cpp @@ -254,10 +254,10 @@ bool CheckConstant(InterpState &S, CodePtr OpPC, const Descriptor *Desc) { if (VD->isConstexpr()) return true; + QualType T = VD->getType(); if (S.getLangOpts().CPlusPlus && !S.getLangOpts().CPlusPlus11) - return false; + return T->isSignedIntegerOrEnumerationType() || T->isUnsignedIntegerOrEnumerationType(); - QualType T = VD->getType(); if (T.isConstQualified()) return true; @@ -485,7 +485,9 @@ bool CheckCallable(InterpState &S, CodePtr OpPC, const Function *F) { // Don't emit anything if the function isn't defined and we're checking // for a constant expression. It might be defined at the point we're // actually calling it. - if (!DiagDecl->isDefined() && S.checkingPotentialConstantExpression()) + bool IsExtern = DiagDecl->getStorageClass() == SC_Extern; + if (!DiagDecl->isDefined() && !IsExtern && + S.checkingPotentialConstantExpression()) return false; // If the declaration is defined _and_ declared 'constexpr', the below diff --git a/clang/lib/AST/Interp/Interp.h b/clang/lib/AST/Interp/Interp.h index bb220657c2dadc18628a27078d691c6ab898d8bc..405993eb827036f620ec62e119ddb33667697682 100644 --- a/clang/lib/AST/Interp/Interp.h +++ b/clang/lib/AST/Interp/Interp.h @@ -122,6 +122,9 @@ bool CheckNonNullArgs(InterpState &S, CodePtr OpPC, const Function *F, bool SetThreeWayComparisonField(InterpState &S, CodePtr OpPC, const Pointer &Ptr, const APSInt &IntValue); +/// Copy the contents of Src into Dest. +bool DoMemcpy(InterpState &S, CodePtr OpPC, const Pointer &Src, Pointer &Dest); + /// Checks if the shift operation is legal. template bool CheckShift(InterpState &S, CodePtr OpPC, const LT &LHS, const RT &RHS, @@ -165,7 +168,8 @@ bool CheckDivRem(InterpState &S, CodePtr OpPC, const T &LHS, const T &RHS) { const auto *Op = cast(S.Current->getExpr(OpPC)); S.FFDiag(Op, diag::note_expr_divide_by_zero) << Op->getRHS()->getSourceRange(); - return false; + if constexpr (!std::is_same_v) + return false; } if (LHS.isSigned() && LHS.isMin() && RHS.isNegative() && RHS.isMinusOne()) { @@ -846,8 +850,7 @@ bool CMP3(InterpState &S, CodePtr OpPC, const ComparisonCategoryInfo *CmpInfo) { CmpInfo->getValueInfo(CmpInfo->makeWeakResult(CmpResult)); assert(CmpValueInfo); assert(CmpValueInfo->hasValidIntValue()); - const APSInt &IntValue = CmpValueInfo->getIntValue(); - return SetThreeWayComparisonField(S, OpPC, P, IntValue); + return SetThreeWayComparisonField(S, OpPC, P, CmpValueInfo->getIntValue()); } template ::T> @@ -1488,6 +1491,16 @@ bool InitElemPop(InterpState &S, CodePtr OpPC, uint32_t Idx) { return true; } +inline bool Memcpy(InterpState &S, CodePtr OpPC) { + const Pointer &Src = S.Stk.pop(); + Pointer &Dest = S.Stk.peek(); + + if (!CheckLoad(S, OpPC, Src)) + return false; + + return DoMemcpy(S, OpPC, Src, Dest); +} + //===----------------------------------------------------------------------===// // AddOffset, SubOffset //===----------------------------------------------------------------------===// @@ -1934,8 +1947,15 @@ inline bool ArrayElemPtr(InterpState &S, CodePtr OpPC) { const T &Offset = S.Stk.pop(); const Pointer &Ptr = S.Stk.peek(); - if (Ptr.isDummy()) - return true; + if (!Ptr.isZero()) { + if (!CheckArray(S, OpPC, Ptr)) + return false; + + if (Ptr.isDummy()) { + S.Stk.push(Ptr); + return true; + } + } if (!OffsetHelper(S, OpPC, Offset, Ptr)) return false; @@ -1948,9 +1968,14 @@ inline bool ArrayElemPtrPop(InterpState &S, CodePtr OpPC) { const T &Offset = S.Stk.pop(); const Pointer &Ptr = S.Stk.pop(); - if (Ptr.isDummy()) { - S.Stk.push(Ptr); - return true; + if (!Ptr.isZero()) { + if (!CheckArray(S, OpPC, Ptr)) + return false; + + if (Ptr.isDummy()) { + S.Stk.push(Ptr); + return true; + } } if (!OffsetHelper(S, OpPC, Offset, Ptr)) @@ -2202,6 +2227,9 @@ inline bool Invalid(InterpState &S, CodePtr OpPC) { return false; } +/// Do nothing and just abort execution. +inline bool Error(InterpState &S, CodePtr OpPC) { return false; } + /// Same here, but only for casts. inline bool InvalidCast(InterpState &S, CodePtr OpPC, CastKind Kind) { const SourceLocation &Loc = S.Current->getLocation(OpPC); diff --git a/clang/lib/AST/Interp/InterpBuiltin.cpp b/clang/lib/AST/Interp/InterpBuiltin.cpp index 5250d02be85a61efffa6d91ddeb672a47235b054..1bf5d55314f1f2ac2a059defc40903cb2dec3e85 100644 --- a/clang/lib/AST/Interp/InterpBuiltin.cpp +++ b/clang/lib/AST/Interp/InterpBuiltin.cpp @@ -53,11 +53,7 @@ static APSInt peekToAPSInt(InterpStack &Stk, PrimType T, size_t Offset = 0) { Offset = align(primSize(T)); APSInt R; - INT_TYPE_SWITCH(T, { - T Val = Stk.peek(Offset); - R = APSInt(APInt(Val.bitWidth(), static_cast(Val), T::isSigned()), - !T::isSigned()); - }); + INT_TYPE_SWITCH(T, R = Stk.peek(Offset).toAPSInt()); return R; } @@ -123,6 +119,36 @@ static bool retPrimValue(InterpState &S, CodePtr OpPC, APValue &Result, #undef RET_CASE } +static bool interp__builtin_is_constant_evaluated(InterpState &S, CodePtr OpPC, + const InterpFrame *Frame, + const CallExpr *Call) { + // The current frame is the one for __builtin_is_constant_evaluated. + // The one above that, potentially the one for std::is_constant_evaluated(). + if (S.inConstantContext() && !S.checkingPotentialConstantExpression() && + Frame->Caller && S.getEvalStatus().Diag) { + auto isStdCall = [](const FunctionDecl *F) -> bool { + return F && F->isInStdNamespace() && F->getIdentifier() && + F->getIdentifier()->isStr("is_constant_evaluated"); + }; + const InterpFrame *Caller = Frame->Caller; + + if (Caller->Caller && isStdCall(Caller->getCallee())) { + const Expr *E = Caller->Caller->getExpr(Caller->getRetPC()); + S.report(E->getExprLoc(), + diag::warn_is_constant_evaluated_always_true_constexpr) + << "std::is_constant_evaluated"; + } else { + const Expr *E = Frame->Caller->getExpr(Frame->getRetPC()); + S.report(E->getExprLoc(), + diag::warn_is_constant_evaluated_always_true_constexpr) + << "__builtin_is_constant_evaluated"; + } + } + + S.Stk.push(Boolean::from(S.inConstantContext())); + return true; +} + static bool interp__builtin_strcmp(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const CallExpr *Call) { @@ -537,11 +563,12 @@ static bool interp__builtin_rotate(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const Function *Func, const CallExpr *Call, bool Right) { - PrimType ArgT = *S.getContext().classify(Call->getArg(0)->getType()); - assert(ArgT == *S.getContext().classify(Call->getArg(1)->getType())); + PrimType AmountT = *S.getContext().classify(Call->getArg(1)->getType()); + PrimType ValueT = *S.getContext().classify(Call->getArg(0)->getType()); - APSInt Amount = peekToAPSInt(S.Stk, ArgT); - APSInt Value = peekToAPSInt(S.Stk, ArgT, align(primSize(ArgT)) * 2); + APSInt Amount = peekToAPSInt(S.Stk, AmountT); + APSInt Value = peekToAPSInt( + S.Stk, ValueT, align(primSize(AmountT)) + align(primSize(ValueT))); APSInt Result; if (Right) @@ -609,10 +636,9 @@ static bool interp__builtin_eh_return_data_regno(InterpState &S, CodePtr OpPC, return true; } -static bool interp__builtin_launder(InterpState &S, CodePtr OpPC, - const InterpFrame *Frame, - const Function *Func, - const CallExpr *Call) { +/// Just takes the first Argument to the call and puts it on the stack. +static bool noopPointer(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, + const Function *Func, const CallExpr *Call) { const Pointer &Arg = S.Stk.peek(); S.Stk.push(Arg); return true; @@ -921,14 +947,15 @@ static bool interp__builtin_complex(InterpState &S, CodePtr OpPC, bool InterpretBuiltin(InterpState &S, CodePtr OpPC, const Function *F, const CallExpr *Call) { - InterpFrame *Frame = S.Current; + const InterpFrame *Frame = S.Current; APValue Dummy; std::optional ReturnT = S.getContext().classify(Call); switch (F->getBuiltinID()) { case Builtin::BI__builtin_is_constant_evaluated: - S.Stk.push(Boolean::from(S.inConstantContext())); + if (!interp__builtin_is_constant_evaluated(S, OpPC, Frame, Call)) + return false; break; case Builtin::BI__builtin_assume: case Builtin::BI__assume: @@ -1052,6 +1079,7 @@ bool InterpretBuiltin(InterpState &S, CodePtr OpPC, const Function *F, case Builtin::BI__builtin_popcount: case Builtin::BI__builtin_popcountl: case Builtin::BI__builtin_popcountll: + case Builtin::BI__builtin_popcountg: case Builtin::BI__popcnt16: // Microsoft variants of popcount case Builtin::BI__popcnt: case Builtin::BI__popcnt64: @@ -1146,7 +1174,9 @@ bool InterpretBuiltin(InterpState &S, CodePtr OpPC, const Function *F, break; case Builtin::BI__builtin_launder: - if (!interp__builtin_launder(S, OpPC, Frame, F, Call)) + case Builtin::BI__builtin___CFStringMakeConstantString: + case Builtin::BI__builtin___NSStringMakeConstantString: + if (!noopPointer(S, OpPC, Frame, F, Call)) return false; break; @@ -1329,5 +1359,50 @@ bool SetThreeWayComparisonField(InterpState &S, CodePtr OpPC, return true; } +bool DoMemcpy(InterpState &S, CodePtr OpPC, const Pointer &Src, Pointer &Dest) { + assert(Src.isLive() && Dest.isLive()); + + [[maybe_unused]] const Descriptor *SrcDesc = Src.getFieldDesc(); + const Descriptor *DestDesc = Dest.getFieldDesc(); + + assert(!DestDesc->isPrimitive() && !SrcDesc->isPrimitive()); + + if (DestDesc->isPrimitiveArray()) { + assert(SrcDesc->isPrimitiveArray()); + assert(SrcDesc->getNumElems() == DestDesc->getNumElems()); + PrimType ET = DestDesc->getPrimType(); + for (unsigned I = 0, N = DestDesc->getNumElems(); I != N; ++I) { + Pointer DestElem = Dest.atIndex(I); + TYPE_SWITCH(ET, { + DestElem.deref() = Src.atIndex(I).deref(); + DestElem.initialize(); + }); + } + return true; + } + + if (DestDesc->isRecord()) { + assert(SrcDesc->isRecord()); + assert(SrcDesc->ElemRecord == DestDesc->ElemRecord); + const Record *R = DestDesc->ElemRecord; + for (const Record::Field &F : R->fields()) { + Pointer DestField = Dest.atField(F.Offset); + if (std::optional FT = S.Ctx.classify(F.Decl->getType())) { + TYPE_SWITCH(*FT, { + DestField.deref() = Src.atField(F.Offset).deref(); + DestField.initialize(); + }); + } else { + return Invalid(S, OpPC); + } + } + return true; + } + + // FIXME: Composite types. + + return Invalid(S, OpPC); +} + } // namespace interp } // namespace clang diff --git a/clang/lib/AST/Interp/InterpFrame.cpp b/clang/lib/AST/Interp/InterpFrame.cpp index f69ff06b5e81b5f2d593eade300b851e48cd7462..12e2e6ff9155b9a0ca5a2a5d1142e56903ef329e 100644 --- a/clang/lib/AST/Interp/InterpFrame.cpp +++ b/clang/lib/AST/Interp/InterpFrame.cpp @@ -190,6 +190,8 @@ SourceRange InterpFrame::getCallRange() const { } const FunctionDecl *InterpFrame::getCallee() const { + if (!Func) + return nullptr; return Func->getDecl(); } diff --git a/clang/lib/AST/Interp/Opcodes.td b/clang/lib/AST/Interp/Opcodes.td index 9b99aa0ccb558a92b4913124c3ca9c72b7701b8b..cc1310f4c0d52aeb0b00ac8fd39acafdcce43fac 100644 --- a/clang/lib/AST/Interp/Opcodes.td +++ b/clang/lib/AST/Interp/Opcodes.td @@ -706,6 +706,7 @@ def Dup : Opcode { // [] -> [] def Invalid : Opcode {} +def Error : Opcode {} def InvalidCast : Opcode { let Args = [ArgCastKind]; } @@ -720,3 +721,5 @@ def CheckNonNullArg : Opcode { let Types = [PtrTypeClass]; let HasGroup = 1; } + +def Memcpy : Opcode; diff --git a/clang/lib/AST/Interp/Pointer.cpp b/clang/lib/AST/Interp/Pointer.cpp index 3f85635f43674d1e964f441418d8e77c3d6fc23b..af60ced0e10e9ea2a6e4231a6bf34a3c841976d6 100644 --- a/clang/lib/AST/Interp/Pointer.cpp +++ b/clang/lib/AST/Interp/Pointer.cpp @@ -320,10 +320,10 @@ std::optional Pointer::toRValue(const Context &Ctx) const { // Complex types. if (const auto *CT = Ty->getAs()) { QualType ElemTy = CT->getElementType(); - std::optional ElemT = Ctx.classify(ElemTy); - assert(ElemT); if (ElemTy->isIntegerType()) { + std::optional ElemT = Ctx.classify(ElemTy); + assert(ElemT); INT_TYPE_SWITCH(*ElemT, { auto V1 = Ptr.atIndex(0).deref(); auto V2 = Ptr.atIndex(1).deref(); diff --git a/clang/lib/AST/Interp/Pointer.h b/clang/lib/AST/Interp/Pointer.h index 34ecdb967960d534370e9dc3b2f32394454eee49..fffb4aba492fc83c8a3082342e324959bd10c151 100644 --- a/clang/lib/AST/Interp/Pointer.h +++ b/clang/lib/AST/Interp/Pointer.h @@ -285,6 +285,11 @@ public: bool inPrimitiveArray() const { return getFieldDesc()->isPrimitiveArray(); } /// Checks if the structure is an array of unknown size. bool isUnknownSizeArray() const { + // If this points inside a dummy block, return true. + // FIXME: This might change in the future. If it does, we need + // to set the proper Ctor/Dtor functions for dummy Descriptors. + if (Base != 0 && Base != sizeof(InlineDescriptor) && isDummy()) + return true; return getFieldDesc()->isUnknownSizeArray(); } /// Checks if the pointer points to an array. diff --git a/clang/lib/AST/Interp/Program.cpp b/clang/lib/AST/Interp/Program.cpp index 86e18ede6381147287a5dd349cbe88eb52c8323b..da6f72c62115dd94a3c216ce9cbbc2351aaadf3e 100644 --- a/clang/lib/AST/Interp/Program.cpp +++ b/clang/lib/AST/Interp/Program.cpp @@ -145,11 +145,20 @@ std::optional Program::getOrCreateGlobal(const ValueDecl *VD, std::optional Program::getOrCreateDummy(const ValueDecl *VD) { // Dedup blocks since they are immutable and pointers cannot be compared. - if (auto It = DummyParams.find(VD); It != DummyParams.end()) + if (auto It = DummyVariables.find(VD); It != DummyVariables.end()) return It->second; // Create dummy descriptor. - Descriptor *Desc = allocateDescriptor(VD, std::nullopt); + // We create desriptors of 'array of unknown size' if the type is an array + // type _and_ the size isn't known (it's not a ConstantArrayType). If the size + // is known however, we create a regular dummy pointer. + Descriptor *Desc; + if (const auto *AT = VD->getType()->getAsArrayTypeUnsafe(); + AT && !isa(AT)) + Desc = allocateDescriptor(VD, Descriptor::UnknownSize{}); + else + Desc = allocateDescriptor(VD); + // Allocate a block for storage. unsigned I = Globals.size(); @@ -158,7 +167,7 @@ std::optional Program::getOrCreateDummy(const ValueDecl *VD) { G->block()->invokeCtor(); Globals.push_back(G); - DummyParams[VD] = I; + DummyVariables[VD] = I; return I; } diff --git a/clang/lib/AST/Interp/Program.h b/clang/lib/AST/Interp/Program.h index 50bdb575e805cf61bf1589bacf7489285bbbf666..36b5a1faa513a913e7908a457778ffb204b97eb2 100644 --- a/clang/lib/AST/Interp/Program.h +++ b/clang/lib/AST/Interp/Program.h @@ -208,7 +208,7 @@ private: llvm::DenseMap Records; /// Dummy parameter to generate pointers from. - llvm::DenseMap DummyParams; + llvm::DenseMap DummyVariables; /// Creates a new descriptor. template diff --git a/clang/lib/AST/MicrosoftMangle.cpp b/clang/lib/AST/MicrosoftMangle.cpp index b272a546573a31bb3bfeee2afd9411779988966d..aa26bb7ed46f482cfa4b7e02dee65c0f69a303b0 100644 --- a/clang/lib/AST/MicrosoftMangle.cpp +++ b/clang/lib/AST/MicrosoftMangle.cpp @@ -390,6 +390,7 @@ public: const FunctionDecl *D = nullptr, bool ForceThisQuals = false, bool MangleExceptionSpec = true); + void mangleSourceName(StringRef Name); void mangleNestedName(GlobalDecl GD); private: @@ -408,7 +409,6 @@ private: mangleUnqualifiedName(GD, cast(GD.getDecl())->getDeclName()); } void mangleUnqualifiedName(GlobalDecl GD, DeclarationName Name); - void mangleSourceName(StringRef Name); void mangleOperatorName(OverloadedOperatorKind OO, SourceLocation Loc); void mangleCXXDtorType(CXXDtorType T); void mangleQualifiers(Qualifiers Quals, bool IsMember); @@ -3920,7 +3920,8 @@ void MicrosoftMangleContextImpl::mangleThreadSafeStaticGuardVariable( msvc_hashing_ostream MHO(Out); MicrosoftCXXNameMangler Mangler(*this, MHO); - Mangler.getStream() << "?$TSS" << GuardNum << '@'; + Mangler.getStream() << "?"; + Mangler.mangleSourceName("$TSS" + llvm::utostr(GuardNum)); Mangler.mangleNestedName(VD); Mangler.getStream() << "@4HA"; } diff --git a/clang/lib/AST/Type.cpp b/clang/lib/AST/Type.cpp index 78dcd3f4007a5ad169931a5359b3d6b08c782209..22666184c56ccfc9579fb2b6d28eb49c165e667d 100644 --- a/clang/lib/AST/Type.cpp +++ b/clang/lib/AST/Type.cpp @@ -2682,6 +2682,8 @@ bool QualType::isTriviallyRelocatableType(const ASTContext &Context) const { return false; } else if (const auto *RD = BaseElementType->getAsRecordDecl()) { return RD->canPassInRegisters(); + } else if (BaseElementType.isTriviallyCopyableType(Context)) { + return true; } else { switch (isNonTrivialToPrimitiveDestructiveMove()) { case PCK_Trivial: diff --git a/clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp b/clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp index 1d2bd9a9b08af363c0db33bc1523c40878f08fae..cc1ebd511191a93d76a0528ee95ba6dd1907044c 100644 --- a/clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp +++ b/clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp @@ -771,6 +771,7 @@ static bool isOriginalRecordConstructor(const Expr &RecordPRValue) { return !Init->isSemanticForm() || !Init->isTransparent(); return isa(RecordPRValue) || isa(RecordPRValue) || isa(RecordPRValue) || + isa(RecordPRValue) || isa(RecordPRValue) || // The framework currently does not propagate the objects created in // the two branches of a `ConditionalOperator` because there is no way diff --git a/clang/lib/Analysis/FlowSensitive/Transfer.cpp b/clang/lib/Analysis/FlowSensitive/Transfer.cpp index 04aa2831df05580e0dd3e8c64bf3900ce0377847..8b44bcb4e3caeb0f44e1a1e8408634ce8c5b4207 100644 --- a/clang/lib/Analysis/FlowSensitive/Transfer.cpp +++ b/clang/lib/Analysis/FlowSensitive/Transfer.cpp @@ -450,6 +450,25 @@ public: Env.setStorageLocation(*S, *MemberLoc); } + void VisitCXXDefaultArgExpr(const CXXDefaultArgExpr *S) { + const Expr *ArgExpr = S->getExpr(); + assert(ArgExpr != nullptr); + propagateValueOrStorageLocation(*ArgExpr, *S, Env); + + // If this is a prvalue of record type, we consider it to be an "original + // record constructor", which we always require to have a `RecordValue`. + // So make sure we have a value if we didn't propagate one above. + if (S->isPRValue() && S->getType()->isRecordType()) { + if (Env.getValue(*S) == nullptr) { + Value *Val = Env.createValue(S->getType()); + // We're guaranteed to always be able to create a value for record + // types. + assert(Val != nullptr); + Env.setValue(*S, *Val); + } + } + } + void VisitCXXDefaultInitExpr(const CXXDefaultInitExpr *S) { const Expr *InitExpr = S->getExpr(); assert(InitExpr != nullptr); diff --git a/clang/lib/Basic/Attributes.cpp b/clang/lib/Basic/Attributes.cpp index 44a4f1890d39e11bc70678b7cbc1cbe514b367f9..867d241a2cf8479363a3e683a458027a2117f4f7 100644 --- a/clang/lib/Basic/Attributes.cpp +++ b/clang/lib/Basic/Attributes.cpp @@ -47,8 +47,12 @@ int clang::hasAttribute(AttributeCommonInfo::Syntax Syntax, // attributes. We support those, but not through the typical attribute // machinery that goes through TableGen. We support this in all OpenMP modes // so long as double square brackets are enabled. - if (LangOpts.OpenMP && ScopeName == "omp") - return (Name == "directive" || Name == "sequence") ? 1 : 0; + // + // Other OpenMP attributes (e.g. [[omp::assume]]) are handled via the + // regular attribute parsing machinery. + if (LangOpts.OpenMP && ScopeName == "omp" && + (Name == "directive" || Name == "sequence")) + return 1; int res = hasAttributeImpl(Syntax, Name, ScopeName, Target, LangOpts); if (res) diff --git a/clang/lib/Basic/DiagnosticIDs.cpp b/clang/lib/Basic/DiagnosticIDs.cpp index b353a6627f298bae566e27b2b8edfccca2449d76..4138b4ee4b0e5d7d31c1319110d4d00805ddd859 100644 --- a/clang/lib/Basic/DiagnosticIDs.cpp +++ b/clang/lib/Basic/DiagnosticIDs.cpp @@ -49,6 +49,7 @@ struct StaticDiagInfoDescriptionStringTable { #include "clang/Basic/DiagnosticSemaKinds.inc" #include "clang/Basic/DiagnosticAnalysisKinds.inc" #include "clang/Basic/DiagnosticRefactoringKinds.inc" +#include "clang/Basic/DiagnosticInstallAPIKinds.inc" // clang-format on #undef DIAG }; @@ -70,7 +71,8 @@ const StaticDiagInfoDescriptionStringTable StaticDiagInfoDescriptions = { #include "clang/Basic/DiagnosticSemaKinds.inc" #include "clang/Basic/DiagnosticAnalysisKinds.inc" #include "clang/Basic/DiagnosticRefactoringKinds.inc" - // clang-format on +#include "clang/Basic/DiagnosticInstallAPIKinds.inc" +// clang-format on #undef DIAG }; @@ -95,7 +97,8 @@ const uint32_t StaticDiagInfoDescriptionOffsets[] = { #include "clang/Basic/DiagnosticSemaKinds.inc" #include "clang/Basic/DiagnosticAnalysisKinds.inc" #include "clang/Basic/DiagnosticRefactoringKinds.inc" - // clang-format on +#include "clang/Basic/DiagnosticInstallAPIKinds.inc" +// clang-format on #undef DIAG }; @@ -173,6 +176,7 @@ VALIDATE_DIAG_SIZE(CROSSTU) VALIDATE_DIAG_SIZE(SEMA) VALIDATE_DIAG_SIZE(ANALYSIS) VALIDATE_DIAG_SIZE(REFACTORING) +VALIDATE_DIAG_SIZE(INSTALLAPI) #undef VALIDATE_DIAG_SIZE #undef STRINGIFY_NAME @@ -204,6 +208,7 @@ const StaticDiagInfoRec StaticDiagInfo[] = { #include "clang/Basic/DiagnosticSemaKinds.inc" #include "clang/Basic/DiagnosticAnalysisKinds.inc" #include "clang/Basic/DiagnosticRefactoringKinds.inc" +#include "clang/Basic/DiagnosticInstallAPIKinds.inc" // clang-format on #undef DIAG }; @@ -246,6 +251,7 @@ CATEGORY(CROSSTU, COMMENT) CATEGORY(SEMA, CROSSTU) CATEGORY(ANALYSIS, SEMA) CATEGORY(REFACTORING, ANALYSIS) +CATEGORY(INSTALLAPI, REFACTORING) #undef CATEGORY // Avoid out of bounds reads. diff --git a/clang/lib/Basic/LangStandards.cpp b/clang/lib/Basic/LangStandards.cpp index ab09c7221dda92f0a690e4544dc7624818f27bbc..cb2c07723499827ca256a16e44c042c34cfe4bff 100644 --- a/clang/lib/Basic/LangStandards.cpp +++ b/clang/lib/Basic/LangStandards.cpp @@ -69,6 +69,16 @@ LangStandard::Kind LangStandard::getLangKind(StringRef Name) { .Default(lang_unspecified); } +LangStandard::Kind LangStandard::getHLSLLangKind(StringRef Name) { + return llvm::StringSwitch(Name) + .Case("2016", LangStandard::lang_hlsl2016) + .Case("2017", LangStandard::lang_hlsl2017) + .Case("2018", LangStandard::lang_hlsl2018) + .Case("2021", LangStandard::lang_hlsl2021) + .Case("202x", LangStandard::lang_hlsl202x) + .Default(LangStandard::lang_unspecified); +} + const LangStandard *LangStandard::getLangStandardForName(StringRef Name) { Kind K = getLangKind(Name); if (K == lang_unspecified) diff --git a/clang/lib/Basic/Module.cpp b/clang/lib/Basic/Module.cpp index 9f597dcf8b0f5a59f347d888f6d7856ecc097e36..256365d66bb9074128d65c481a83165ff48a8b3a 100644 --- a/clang/lib/Basic/Module.cpp +++ b/clang/lib/Basic/Module.cpp @@ -301,10 +301,9 @@ bool Module::directlyUses(const Module *Requested) { if (Requested->isSubModuleOf(Use)) return true; - // Anyone is allowed to use our builtin stdarg.h and stddef.h and their - // accompanying modules. - if (Requested->getTopLevelModuleName() == "_Builtin_stdarg" || - Requested->getTopLevelModuleName() == "_Builtin_stddef") + // Anyone is allowed to use our builtin stddef.h and its accompanying modules. + if (Requested->fullModuleNameIs({"_Builtin_stddef", "max_align_t"}) || + Requested->fullModuleNameIs({"_Builtin_stddef_wint_t"})) return true; if (NoUndeclaredIncludes) diff --git a/clang/lib/Basic/TargetInfo.cpp b/clang/lib/Basic/TargetInfo.cpp index 96b3ad9ba2f2731b1bd3a5443a0b6d1a5ceae6f5..5d9055174c089ad8d11bdf32e0eb46b952527d82 100644 --- a/clang/lib/Basic/TargetInfo.cpp +++ b/clang/lib/Basic/TargetInfo.cpp @@ -925,6 +925,10 @@ bool TargetInfo::validateInputConstraint( return true; } +bool TargetInfo::validatePointerAuthKey(const llvm::APSInt &value) const { + return false; +} + void TargetInfo::CheckFixedPointBits() const { // Check that the number of fractional and integral bits (and maybe sign) can // fit into the bits given for a fixed point type. diff --git a/clang/lib/Basic/Targets/AArch64.cpp b/clang/lib/Basic/Targets/AArch64.cpp index 5abb060073c517eed192d8cf08dc4918893e9d2c..fa8b5a869594b3a239f0d50cafa2496110ec8df1 100644 --- a/clang/lib/Basic/Targets/AArch64.cpp +++ b/clang/lib/Basic/Targets/AArch64.cpp @@ -14,6 +14,7 @@ #include "clang/Basic/LangOptions.h" #include "clang/Basic/TargetBuiltins.h" #include "clang/Basic/TargetInfo.h" +#include "llvm/ADT/APSInt.h" #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/StringExtras.h" #include "llvm/ADT/StringSwitch.h" @@ -1450,6 +1451,11 @@ int AArch64TargetInfo::getEHDataRegisterNumber(unsigned RegNo) const { return -1; } +bool AArch64TargetInfo::validatePointerAuthKey( + const llvm::APSInt &value) const { + return 0 <= value && value <= 3; +} + bool AArch64TargetInfo::hasInt128Type() const { return true; } AArch64leTargetInfo::AArch64leTargetInfo(const llvm::Triple &Triple, diff --git a/clang/lib/Basic/Targets/AArch64.h b/clang/lib/Basic/Targets/AArch64.h index c1ba156860a1220d72109a2abaeea5753c6a8f2b..2dd6b2181e87df66e8493144c3e9f2040c1c1aa5 100644 --- a/clang/lib/Basic/Targets/AArch64.h +++ b/clang/lib/Basic/Targets/AArch64.h @@ -195,6 +195,8 @@ public: int getEHDataRegisterNumber(unsigned RegNo) const override; + bool validatePointerAuthKey(const llvm::APSInt &value) const override; + const char *getBFloat16Mangling() const override { return "u6__bf16"; }; bool hasInt128Type() const override; diff --git a/clang/lib/Basic/Targets/BPF.cpp b/clang/lib/Basic/Targets/BPF.cpp index e3fbbb720d0694c48f3f731232dc71ba5fa2998f..b5ba11a3bdca9d709eef35c5ce531923c425aa01 100644 --- a/clang/lib/Basic/Targets/BPF.cpp +++ b/clang/lib/Basic/Targets/BPF.cpp @@ -35,6 +35,9 @@ void BPFTargetInfo::getTargetDefines(const LangOptions &Opts, Builder.defineMacro("__BPF_CPU_VERSION__", "0"); return; } + + Builder.defineMacro("__BPF_FEATURE_ADDR_SPACE_CAST"); + if (CPU.empty() || CPU == "generic" || CPU == "v1") { Builder.defineMacro("__BPF_CPU_VERSION__", "1"); return; @@ -42,6 +45,7 @@ void BPFTargetInfo::getTargetDefines(const LangOptions &Opts, std::string CpuVerNumStr = CPU.substr(1); Builder.defineMacro("__BPF_CPU_VERSION__", CpuVerNumStr); + Builder.defineMacro("__BPF_FEATURE_MAY_GOTO"); int CpuVerNum = std::stoi(CpuVerNumStr); if (CpuVerNum >= 2) diff --git a/clang/lib/CodeGen/BackendUtil.cpp b/clang/lib/CodeGen/BackendUtil.cpp index 7310e3817c79a19a5f51ed898a7f9d963b0f1820..82b30b8d815629d367a9282abf1b4b3be99cce63 100644 --- a/clang/lib/CodeGen/BackendUtil.cpp +++ b/clang/lib/CodeGen/BackendUtil.cpp @@ -76,6 +76,7 @@ #include "llvm/Transforms/Instrumentation/MemProfiler.h" #include "llvm/Transforms/Instrumentation/MemorySanitizer.h" #include "llvm/Transforms/Instrumentation/PGOInstrumentation.h" +#include "llvm/Transforms/Instrumentation/RemoveTrapsPass.h" #include "llvm/Transforms/Instrumentation/SanitizerBinaryMetadata.h" #include "llvm/Transforms/Instrumentation/SanitizerCoverage.h" #include "llvm/Transforms/Instrumentation/ThreadSanitizer.h" @@ -83,6 +84,7 @@ #include "llvm/Transforms/Scalar/EarlyCSE.h" #include "llvm/Transforms/Scalar/GVN.h" #include "llvm/Transforms/Scalar/JumpThreading.h" +#include "llvm/Transforms/Scalar/SimplifyCFG.h" #include "llvm/Transforms/Utils/Debugify.h" #include "llvm/Transforms/Utils/EntryExitInstrumenter.h" #include "llvm/Transforms/Utils/ModuleUtils.h" @@ -98,6 +100,10 @@ using namespace llvm; namespace llvm { extern cl::opt PrintPipelinePasses; +cl::opt ClRemoveTraps("clang-remove-traps", cl::Optional, + cl::desc("Insert remove-traps pass."), + cl::init(false)); + // Experiment to move sanitizers earlier. static cl::opt ClSanitizeOnOptimizerEarlyEP( "sanitizer-early-opt-ep", cl::Optional, @@ -744,6 +750,21 @@ static void addSanitizers(const Triple &TargetTriple, // LastEP does not need GlobalsAA. PB.registerOptimizerLastEPCallback(SanitizersCallback); } + + if (ClRemoveTraps) { + // We can optimize after inliner, and PGO profile matching. The hook below + // is called at the end `buildFunctionSimplificationPipeline`, which called + // from `buildInlinerPipeline`, which called after profile matching. + PB.registerScalarOptimizerLateEPCallback( + [](FunctionPassManager &FPM, OptimizationLevel Level) { + // RemoveTrapsPass expects trap blocks preceded by conditional + // branches, which usually is not the case without SimplifyCFG. + // TODO: Remove `SimplifyCFGPass` after switching to dedicated + // intrinsic. + FPM.addPass(SimplifyCFGPass()); + FPM.addPass(RemoveTrapsPass()); + }); + } } void EmitAssemblyHelper::RunOptimizationPipeline( diff --git a/clang/lib/CodeGen/CGAtomic.cpp b/clang/lib/CodeGen/CGAtomic.cpp index a8d846b4f6a592b05cb5551fad6e36aa473273ba..fb03d013e8afc7ba7c9e952eadabd44ae9e005a9 100644 --- a/clang/lib/CodeGen/CGAtomic.cpp +++ b/clang/lib/CodeGen/CGAtomic.cpp @@ -194,12 +194,14 @@ namespace { RValue convertAtomicTempToRValue(Address addr, AggValueSlot resultSlot, SourceLocation loc, bool AsValue) const; - /// Converts a rvalue to integer value. - llvm::Value *convertRValueToInt(RValue RVal) const; + llvm::Value *getScalarRValValueOrNull(RValue RVal) const; - RValue ConvertIntToValueOrAtomic(llvm::Value *IntVal, - AggValueSlot ResultSlot, - SourceLocation Loc, bool AsValue) const; + /// Converts an rvalue to integer value if needed. + llvm::Value *convertRValueToInt(RValue RVal, bool CastFP = true) const; + + RValue ConvertToValueOrAtomic(llvm::Value *IntVal, AggValueSlot ResultSlot, + SourceLocation Loc, bool AsValue, + bool CastFP = true) const; /// Copy an atomic r-value into atomic-layout memory. void emitCopyIntoMemory(RValue rvalue) const; @@ -261,7 +263,8 @@ namespace { void EmitAtomicLoadLibcall(llvm::Value *AddForLoaded, llvm::AtomicOrdering AO, bool IsVolatile); /// Emits atomic load as LLVM instruction. - llvm::Value *EmitAtomicLoadOp(llvm::AtomicOrdering AO, bool IsVolatile); + llvm::Value *EmitAtomicLoadOp(llvm::AtomicOrdering AO, bool IsVolatile, + bool CastFP = true); /// Emits atomic compare-and-exchange op as a libcall. llvm::Value *EmitAtomicCompareExchangeLibcall( llvm::Value *ExpectedAddr, llvm::Value *DesiredAddr, @@ -1396,12 +1399,13 @@ RValue AtomicInfo::convertAtomicTempToRValue(Address addr, LVal.getBaseInfo(), TBAAAccessInfo())); } -RValue AtomicInfo::ConvertIntToValueOrAtomic(llvm::Value *IntVal, - AggValueSlot ResultSlot, - SourceLocation Loc, - bool AsValue) const { +RValue AtomicInfo::ConvertToValueOrAtomic(llvm::Value *Val, + AggValueSlot ResultSlot, + SourceLocation Loc, bool AsValue, + bool CastFP) const { // Try not to in some easy cases. - assert(IntVal->getType()->isIntegerTy() && "Expected integer value"); + assert((Val->getType()->isIntegerTy() || Val->getType()->isIEEELikeFPTy()) && + "Expected integer or floating point value"); if (getEvaluationKind() == TEK_Scalar && (((!LVal.isBitField() || LVal.getBitFieldInfo().Size == ValueSizeInBits) && @@ -1410,13 +1414,14 @@ RValue AtomicInfo::ConvertIntToValueOrAtomic(llvm::Value *IntVal, auto *ValTy = AsValue ? CGF.ConvertTypeForMem(ValueTy) : getAtomicAddress().getElementType(); - if (ValTy->isIntegerTy()) { - assert(IntVal->getType() == ValTy && "Different integer types."); - return RValue::get(CGF.EmitFromMemory(IntVal, ValueTy)); + if (ValTy->isIntegerTy() || (!CastFP && ValTy->isIEEELikeFPTy())) { + assert((!ValTy->isIntegerTy() || Val->getType() == ValTy) && + "Different integer types."); + return RValue::get(CGF.EmitFromMemory(Val, ValueTy)); } else if (ValTy->isPointerTy()) - return RValue::get(CGF.Builder.CreateIntToPtr(IntVal, ValTy)); - else if (llvm::CastInst::isBitCastable(IntVal->getType(), ValTy)) - return RValue::get(CGF.Builder.CreateBitCast(IntVal, ValTy)); + return RValue::get(CGF.Builder.CreateIntToPtr(Val, ValTy)); + else if (llvm::CastInst::isBitCastable(Val->getType(), ValTy)) + return RValue::get(CGF.Builder.CreateBitCast(Val, ValTy)); } // Create a temporary. This needs to be big enough to hold the @@ -1433,8 +1438,7 @@ RValue AtomicInfo::ConvertIntToValueOrAtomic(llvm::Value *IntVal, // Slam the integer into the temporary. Address CastTemp = castToAtomicIntPointer(Temp); - CGF.Builder.CreateStore(IntVal, CastTemp) - ->setVolatile(TempIsVolatile); + CGF.Builder.CreateStore(Val, CastTemp)->setVolatile(TempIsVolatile); return convertAtomicTempToRValue(Temp, ResultSlot, Loc, AsValue); } @@ -1453,9 +1457,11 @@ void AtomicInfo::EmitAtomicLoadLibcall(llvm::Value *AddForLoaded, } llvm::Value *AtomicInfo::EmitAtomicLoadOp(llvm::AtomicOrdering AO, - bool IsVolatile) { + bool IsVolatile, bool CastFP) { // Okay, we're doing this natively. - Address Addr = getAtomicAddressAsAtomicIntPointer(); + Address Addr = getAtomicAddress(); + if (!(Addr.getElementType()->isIEEELikeFPTy() && !CastFP)) + Addr = castToAtomicIntPointer(Addr); llvm::LoadInst *Load = CGF.Builder.CreateLoad(Addr, "atomic-load"); Load->setAtomic(AO); @@ -1515,7 +1521,7 @@ RValue AtomicInfo::EmitAtomicLoad(AggValueSlot ResultSlot, SourceLocation Loc, } // Okay, we're doing this natively. - auto *Load = EmitAtomicLoadOp(AO, IsVolatile); + auto *Load = EmitAtomicLoadOp(AO, IsVolatile, /*CastFP=*/false); // If we're ignoring an aggregate return, don't do anything. if (getEvaluationKind() == TEK_Aggregate && ResultSlot.isIgnored()) @@ -1523,7 +1529,8 @@ RValue AtomicInfo::EmitAtomicLoad(AggValueSlot ResultSlot, SourceLocation Loc, // Okay, turn that back into the original value or atomic (for non-simple // lvalues) type. - return ConvertIntToValueOrAtomic(Load, ResultSlot, Loc, AsValue); + return ConvertToValueOrAtomic(Load, ResultSlot, Loc, AsValue, + /*CastFP=*/false); } /// Emit a load from an l-value of atomic type. Note that the r-value @@ -1586,12 +1593,18 @@ Address AtomicInfo::materializeRValue(RValue rvalue) const { return TempLV.getAddress(CGF); } -llvm::Value *AtomicInfo::convertRValueToInt(RValue RVal) const { +llvm::Value *AtomicInfo::getScalarRValValueOrNull(RValue RVal) const { + if (RVal.isScalar() && (!hasPadding() || !LVal.isSimple())) + return RVal.getScalarVal(); + return nullptr; +} + +llvm::Value *AtomicInfo::convertRValueToInt(RValue RVal, bool CastFP) const { // If we've got a scalar value of the right size, try to avoid going - // through memory. - if (RVal.isScalar() && (!hasPadding() || !LVal.isSimple())) { - llvm::Value *Value = RVal.getScalarVal(); - if (isa(Value->getType())) + // through memory. Floats get casted if needed by AtomicExpandPass. + if (llvm::Value *Value = getScalarRValValueOrNull(RVal)) { + if (isa(Value->getType()) || + (!CastFP && Value->getType()->isIEEELikeFPTy())) return CGF.EmitToMemory(Value, ValueTy); else { llvm::IntegerType *InputIntTy = llvm::IntegerType::get( @@ -1677,8 +1690,8 @@ std::pair AtomicInfo::EmitAtomicCompareExchange( auto Res = EmitAtomicCompareExchangeOp(ExpectedVal, DesiredVal, Success, Failure, IsWeak); return std::make_pair( - ConvertIntToValueOrAtomic(Res.first, AggValueSlot::ignored(), - SourceLocation(), /*AsValue=*/false), + ConvertToValueOrAtomic(Res.first, AggValueSlot::ignored(), + SourceLocation(), /*AsValue=*/false), Res.second); } @@ -1787,8 +1800,8 @@ void AtomicInfo::EmitAtomicUpdateOp( requiresMemSetZero(getAtomicAddress().getElementType())) { CGF.Builder.CreateStore(PHI, NewAtomicIntAddr); } - auto OldRVal = ConvertIntToValueOrAtomic(PHI, AggValueSlot::ignored(), - SourceLocation(), /*AsValue=*/false); + auto OldRVal = ConvertToValueOrAtomic(PHI, AggValueSlot::ignored(), + SourceLocation(), /*AsValue=*/false); EmitAtomicUpdateValue(CGF, *this, OldRVal, UpdateOp, NewAtomicAddr); auto *DesiredVal = CGF.Builder.CreateLoad(NewAtomicIntAddr); // Try to write new value using cmpxchg operation. @@ -1953,13 +1966,22 @@ void CodeGenFunction::EmitAtomicStore(RValue rvalue, LValue dest, } // Okay, we're doing this natively. - llvm::Value *intValue = atomics.convertRValueToInt(rvalue); + llvm::Value *ValToStore = + atomics.convertRValueToInt(rvalue, /*CastFP=*/false); // Do the atomic store. - Address addr = atomics.castToAtomicIntPointer(atomics.getAtomicAddress()); - intValue = Builder.CreateIntCast( - intValue, addr.getElementType(), /*isSigned=*/false); - llvm::StoreInst *store = Builder.CreateStore(intValue, addr); + Address Addr = atomics.getAtomicAddress(); + bool ShouldCastToInt = true; + if (llvm::Value *Value = atomics.getScalarRValValueOrNull(rvalue)) + if (isa(Value->getType()) || + Value->getType()->isIEEELikeFPTy()) + ShouldCastToInt = false; + if (ShouldCastToInt) { + Addr = atomics.castToAtomicIntPointer(Addr); + ValToStore = Builder.CreateIntCast(ValToStore, Addr.getElementType(), + /*isSigned=*/false); + } + llvm::StoreInst *store = Builder.CreateStore(ValToStore, Addr); if (AO == llvm::AtomicOrdering::Acquire) AO = llvm::AtomicOrdering::Monotonic; diff --git a/clang/lib/CodeGen/CGBlocks.cpp b/clang/lib/CodeGen/CGBlocks.cpp index 0cbace7b7f7bbd5068c4cfe9c7b639e0100d7aea..ad0b50d799618ed7ec7ecb581dd1bec84538a40c 100644 --- a/clang/lib/CodeGen/CGBlocks.cpp +++ b/clang/lib/CodeGen/CGBlocks.cpp @@ -1540,7 +1540,10 @@ llvm::Function *CodeGenFunction::GenerateBlockFunction( llvm::BasicBlock *resume = Builder.GetInsertBlock(); // Go back to the entry. - ++entry_ptr; + if (entry_ptr->getNextNonDebugInstruction()) + entry_ptr = entry_ptr->getNextNonDebugInstruction()->getIterator(); + else + entry_ptr = entry->end(); Builder.SetInsertPoint(entry, entry_ptr); // Emit debug information for all the DeclRefExprs. diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp index 20c35757939152650af451c7bfa728d9ec50f593..e965df810add549d431368ea4729d62e4f8a5246 100644 --- a/clang/lib/CodeGen/CGBuiltin.cpp +++ b/clang/lib/CodeGen/CGBuiltin.cpp @@ -5208,6 +5208,73 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID, case Builtin::BI__iso_volatile_store64: return RValue::get(EmitISOVolatileStore(*this, E)); + case Builtin::BI__builtin_ptrauth_auth: + case Builtin::BI__builtin_ptrauth_auth_and_resign: + case Builtin::BI__builtin_ptrauth_blend_discriminator: + case Builtin::BI__builtin_ptrauth_sign_generic_data: + case Builtin::BI__builtin_ptrauth_sign_unauthenticated: + case Builtin::BI__builtin_ptrauth_strip: { + // Emit the arguments. + SmallVector Args; + for (auto argExpr : E->arguments()) + Args.push_back(EmitScalarExpr(argExpr)); + + // Cast the value to intptr_t, saving its original type. + llvm::Type *OrigValueType = Args[0]->getType(); + if (OrigValueType->isPointerTy()) + Args[0] = Builder.CreatePtrToInt(Args[0], IntPtrTy); + + switch (BuiltinID) { + case Builtin::BI__builtin_ptrauth_auth_and_resign: + if (Args[4]->getType()->isPointerTy()) + Args[4] = Builder.CreatePtrToInt(Args[4], IntPtrTy); + LLVM_FALLTHROUGH; + + case Builtin::BI__builtin_ptrauth_auth: + case Builtin::BI__builtin_ptrauth_sign_unauthenticated: + if (Args[2]->getType()->isPointerTy()) + Args[2] = Builder.CreatePtrToInt(Args[2], IntPtrTy); + break; + + case Builtin::BI__builtin_ptrauth_sign_generic_data: + if (Args[1]->getType()->isPointerTy()) + Args[1] = Builder.CreatePtrToInt(Args[1], IntPtrTy); + break; + + case Builtin::BI__builtin_ptrauth_blend_discriminator: + case Builtin::BI__builtin_ptrauth_strip: + break; + } + + // Call the intrinsic. + auto IntrinsicID = [&]() -> unsigned { + switch (BuiltinID) { + case Builtin::BI__builtin_ptrauth_auth: + return llvm::Intrinsic::ptrauth_auth; + case Builtin::BI__builtin_ptrauth_auth_and_resign: + return llvm::Intrinsic::ptrauth_resign; + case Builtin::BI__builtin_ptrauth_blend_discriminator: + return llvm::Intrinsic::ptrauth_blend; + case Builtin::BI__builtin_ptrauth_sign_generic_data: + return llvm::Intrinsic::ptrauth_sign_generic; + case Builtin::BI__builtin_ptrauth_sign_unauthenticated: + return llvm::Intrinsic::ptrauth_sign; + case Builtin::BI__builtin_ptrauth_strip: + return llvm::Intrinsic::ptrauth_strip; + } + llvm_unreachable("bad ptrauth intrinsic"); + }(); + auto Intrinsic = CGM.getIntrinsic(IntrinsicID); + llvm::Value *Result = EmitRuntimeCall(Intrinsic, Args); + + if (BuiltinID != Builtin::BI__builtin_ptrauth_sign_generic_data && + BuiltinID != Builtin::BI__builtin_ptrauth_blend_discriminator && + OrigValueType->isPointerTy()) { + Result = Builder.CreateIntToPtr(Result, OrigValueType); + } + return RValue::get(Result); + } + case Builtin::BI__exception_code: case Builtin::BI_exception_code: return RValue::get(EmitSEHExceptionCode()); @@ -5460,7 +5527,13 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID, } // OpenCL v2.0, s6.13.17 - Enqueue kernel function. - // It contains four different overload formats specified in Table 6.13.17.1. + // Table 6.13.17.1 specifies four overload forms of enqueue_kernel. + // The code below expands the builtin call to a call to one of the following + // functions that an OpenCL runtime library will have to provide: + // __enqueue_kernel_basic + // __enqueue_kernel_varargs + // __enqueue_kernel_basic_events + // __enqueue_kernel_events_varargs case Builtin::BIenqueue_kernel: { StringRef Name; // Generated function call name unsigned NumArgs = E->getNumArgs(); @@ -10680,6 +10753,12 @@ Value *CodeGenFunction::EmitAArch64BuiltinExpr(unsigned BuiltinID, return Builder.CreateCall(F, llvm::ConstantInt::get(Int32Ty, HintID)); } + if (BuiltinID == clang::AArch64::BI__builtin_arm_trap) { + Function *F = CGM.getIntrinsic(Intrinsic::aarch64_break); + llvm::Value *Arg = EmitScalarExpr(E->getArg(0)); + return Builder.CreateCall(F, Builder.CreateZExt(Arg, CGM.Int32Ty)); + } + if (BuiltinID == clang::AArch64::BI__builtin_arm_get_sme_state) { // Create call to __arm_sme_state and store the results to the two pointers. CallInst *CI = EmitRuntimeCall(CGM.CreateRuntimeFunction( @@ -17969,6 +18048,21 @@ Value *CodeGenFunction::EmitHLSLBuiltinExpr(unsigned BuiltinID, /*ReturnType=*/llvm::Type::getInt1Ty(getLLVMContext()), Intrinsic::dx_any, ArrayRef{Op0}, nullptr, "dx.any"); } + case Builtin::BI__builtin_hlsl_elementwise_clamp: { + Value *OpX = EmitScalarExpr(E->getArg(0)); + Value *OpMin = EmitScalarExpr(E->getArg(1)); + Value *OpMax = EmitScalarExpr(E->getArg(2)); + + QualType Ty = E->getArg(0)->getType(); + bool IsUnsigned = false; + if (auto *VecTy = Ty->getAs()) + Ty = VecTy->getElementType(); + IsUnsigned = Ty->isUnsignedIntegerType(); + return Builder.CreateIntrinsic( + /*ReturnType=*/OpX->getType(), + IsUnsigned ? Intrinsic::dx_uclamp : Intrinsic::dx_clamp, + ArrayRef{OpX, OpMin, OpMax}, nullptr, "dx.clamp"); + } case Builtin::BI__builtin_hlsl_dot: { Value *Op0 = EmitScalarExpr(E->getArg(0)); Value *Op1 = EmitScalarExpr(E->getArg(1)); @@ -18009,38 +18103,11 @@ Value *CodeGenFunction::EmitHLSLBuiltinExpr(unsigned BuiltinID, Value *X = EmitScalarExpr(E->getArg(0)); Value *Y = EmitScalarExpr(E->getArg(1)); Value *S = EmitScalarExpr(E->getArg(2)); - llvm::Type *Xty = X->getType(); - llvm::Type *Yty = Y->getType(); - llvm::Type *Sty = S->getType(); - if (!Xty->isVectorTy() && !Yty->isVectorTy() && !Sty->isVectorTy()) { - if (Xty->isFloatingPointTy()) { - auto V = Builder.CreateFSub(Y, X); - V = Builder.CreateFMul(S, V); - return Builder.CreateFAdd(X, V, "dx.lerp"); - } - llvm_unreachable("Scalar Lerp is only supported on floats."); - } - // A VectorSplat should have happened - assert(Xty->isVectorTy() && Yty->isVectorTy() && Sty->isVectorTy() && - "Lerp of vector and scalar is not supported."); - - [[maybe_unused]] auto *XVecTy = - E->getArg(0)->getType()->getAs(); - [[maybe_unused]] auto *YVecTy = - E->getArg(1)->getType()->getAs(); - [[maybe_unused]] auto *SVecTy = - E->getArg(2)->getType()->getAs(); - // A HLSLVectorTruncation should have happend - assert(XVecTy->getNumElements() == YVecTy->getNumElements() && - XVecTy->getNumElements() == SVecTy->getNumElements() && - "Lerp requires vectors to be of the same size."); - assert(XVecTy->getElementType()->isRealFloatingType() && - XVecTy->getElementType() == YVecTy->getElementType() && - XVecTy->getElementType() == SVecTy->getElementType() && - "Lerp requires float vectors to be of the same type."); + if (!E->getArg(0)->getType()->hasFloatingRepresentation()) + llvm_unreachable("lerp operand must have a float representation"); return Builder.CreateIntrinsic( - /*ReturnType=*/Xty, Intrinsic::dx_lerp, ArrayRef{X, Y, S}, - nullptr, "dx.lerp"); + /*ReturnType=*/X->getType(), Intrinsic::dx_lerp, + ArrayRef{X, Y, S}, nullptr, "dx.lerp"); } case Builtin::BI__builtin_hlsl_elementwise_frac: { Value *Op0 = EmitScalarExpr(E->getArg(0)); @@ -18050,6 +18117,20 @@ Value *CodeGenFunction::EmitHLSLBuiltinExpr(unsigned BuiltinID, /*ReturnType=*/Op0->getType(), Intrinsic::dx_frac, ArrayRef{Op0}, nullptr, "dx.frac"); } + case Builtin::BI__builtin_hlsl_elementwise_isinf: { + Value *Op0 = EmitScalarExpr(E->getArg(0)); + llvm::Type *Xty = Op0->getType(); + llvm::Type *retType = llvm::Type::getInt1Ty(this->getLLVMContext()); + if (Xty->isVectorTy()) { + auto *XVecTy = E->getArg(0)->getType()->getAs(); + retType = llvm::VectorType::get( + retType, ElementCount::getFixed(XVecTy->getNumElements())); + } + if (!E->getArg(0)->getType()->hasFloatingRepresentation()) + llvm_unreachable("isinf operand must have a float representation"); + return Builder.CreateIntrinsic(retType, Intrinsic::dx_isinf, + ArrayRef{Op0}, nullptr, "dx.isinf"); + } case Builtin::BI__builtin_hlsl_mad: { Value *M = EmitScalarExpr(E->getArg(0)); Value *A = EmitScalarExpr(E->getArg(1)); @@ -18077,6 +18158,14 @@ Value *CodeGenFunction::EmitHLSLBuiltinExpr(unsigned BuiltinID, /*ReturnType=*/Op0->getType(), Intrinsic::dx_rcp, ArrayRef{Op0}, nullptr, "dx.rcp"); } + case Builtin::BI__builtin_hlsl_elementwise_rsqrt: { + Value *Op0 = EmitScalarExpr(E->getArg(0)); + if (!E->getArg(0)->getType()->hasFloatingRepresentation()) + llvm_unreachable("rsqrt operand must have a float representation"); + return Builder.CreateIntrinsic( + /*ReturnType=*/Op0->getType(), Intrinsic::dx_rsqrt, + ArrayRef{Op0}, nullptr, "dx.rsqrt"); + } } return nullptr; } diff --git a/clang/lib/CodeGen/CGCall.cpp b/clang/lib/CodeGen/CGCall.cpp index 13f68237b464d60e48c232feab1d02beb07aeb91..a28d7888715d858430ff9893a80a4d86c23f9dfd 100644 --- a/clang/lib/CodeGen/CGCall.cpp +++ b/clang/lib/CodeGen/CGCall.cpp @@ -1796,14 +1796,14 @@ static void AddAttributesFromFunctionProtoType(ASTContext &Ctx, FuncAttrs.addAttribute("aarch64_inout_zt0"); } -static void AddAttributesFromAssumes(llvm::AttrBuilder &FuncAttrs, - const Decl *Callee) { +static void AddAttributesFromOMPAssumes(llvm::AttrBuilder &FuncAttrs, + const Decl *Callee) { if (!Callee) return; SmallVector Attrs; - for (const AssumptionAttr *AA : Callee->specific_attrs()) + for (const OMPAssumeAttr *AA : Callee->specific_attrs()) AA->getAssumption().split(Attrs, ","); if (!Attrs.empty()) @@ -2344,7 +2344,7 @@ void CodeGenModule::ConstructAttributeList(StringRef Name, // Attach assumption attributes to the declaration. If this is a call // site, attach assumptions from the caller to the call as well. - AddAttributesFromAssumes(FuncAttrs, TargetDecl); + AddAttributesFromOMPAssumes(FuncAttrs, TargetDecl); bool HasOptnone = false; // The NoBuiltinAttr attached to the target FunctionDecl. diff --git a/clang/lib/CodeGen/CGCoroutine.cpp b/clang/lib/CodeGen/CGCoroutine.cpp index 888d30bfb3e1d6a45f1d9e57ba84257dd7f16cfd..b7142ec08af986d16656fdb7e10aed35b98912d1 100644 --- a/clang/lib/CodeGen/CGCoroutine.cpp +++ b/clang/lib/CodeGen/CGCoroutine.cpp @@ -141,7 +141,7 @@ static bool FunctionCanThrow(const FunctionDecl *D) { Proto->canThrow() != CT_Cannot; } -static bool ResumeStmtCanThrow(const Stmt *S) { +static bool StmtCanThrow(const Stmt *S) { if (const auto *CE = dyn_cast(S)) { const auto *Callee = CE->getDirectCallee(); if (!Callee) @@ -167,7 +167,7 @@ static bool ResumeStmtCanThrow(const Stmt *S) { } for (const auto *child : S->children()) - if (ResumeStmtCanThrow(child)) + if (StmtCanThrow(child)) return true; return false; @@ -178,18 +178,31 @@ static bool ResumeStmtCanThrow(const Stmt *S) { // auto && x = CommonExpr(); // if (!x.await_ready()) { // llvm_coro_save(); -// x.await_suspend(...); (*) -// llvm_coro_suspend(); (**) +// llvm_coro_await_suspend(&x, frame, wrapper) (*) (**) +// llvm_coro_suspend(); (***) // } // x.await_resume(); // // where the result of the entire expression is the result of x.await_resume() // -// (*) If x.await_suspend return type is bool, it allows to veto a suspend: +// (*) llvm_coro_await_suspend_{void, bool, handle} is lowered to +// wrapper(&x, frame) when it's certain not to interfere with +// coroutine transform. await_suspend expression is +// asynchronous to the coroutine body and not all analyses +// and transformations can handle it correctly at the moment. +// +// Wrapper function encapsulates x.await_suspend(...) call and looks like: +// +// auto __await_suspend_wrapper(auto& awaiter, void* frame) { +// std::coroutine_handle<> handle(frame); +// return awaiter.await_suspend(handle); +// } +// +// (**) If x.await_suspend return type is bool, it allows to veto a suspend: // if (x.await_suspend(...)) // llvm_coro_suspend(); // -// (**) llvm_coro_suspend() encodes three possible continuations as +// (***) llvm_coro_suspend() encodes three possible continuations as // a switch instruction: // // %where-to = call i8 @llvm.coro.suspend(...) @@ -212,9 +225,10 @@ static LValueOrRValue emitSuspendExpression(CodeGenFunction &CGF, CGCoroData &Co bool ignoreResult, bool forLValue) { auto *E = S.getCommonExpr(); - auto Binder = + auto CommonBinder = CodeGenFunction::OpaqueValueMappingData::bind(CGF, S.getOpaqueValue(), E); - auto UnbindOnExit = llvm::make_scope_exit([&] { Binder.unbind(CGF); }); + auto UnbindCommonOnExit = + llvm::make_scope_exit([&] { CommonBinder.unbind(CGF); }); auto Prefix = buildSuspendPrefixStr(Coro, Kind); BasicBlock *ReadyBlock = CGF.createBasicBlock(Prefix + Twine(".ready")); @@ -232,16 +246,73 @@ static LValueOrRValue emitSuspendExpression(CodeGenFunction &CGF, CGCoroData &Co auto *NullPtr = llvm::ConstantPointerNull::get(CGF.CGM.Int8PtrTy); auto *SaveCall = Builder.CreateCall(CoroSave, {NullPtr}); + auto SuspendWrapper = CodeGenFunction(CGF.CGM).generateAwaitSuspendWrapper( + CGF.CurFn->getName(), Prefix, S); + CGF.CurCoro.InSuspendBlock = true; - auto *SuspendRet = CGF.EmitScalarExpr(S.getSuspendExpr()); + + assert(CGF.CurCoro.Data && CGF.CurCoro.Data->CoroBegin && + "expected to be called in coroutine context"); + + SmallVector SuspendIntrinsicCallArgs; + SuspendIntrinsicCallArgs.push_back( + CGF.getOrCreateOpaqueLValueMapping(S.getOpaqueValue()).getPointer(CGF)); + + SuspendIntrinsicCallArgs.push_back(CGF.CurCoro.Data->CoroBegin); + SuspendIntrinsicCallArgs.push_back(SuspendWrapper); + + const auto SuspendReturnType = S.getSuspendReturnType(); + llvm::Intrinsic::ID AwaitSuspendIID; + + switch (SuspendReturnType) { + case CoroutineSuspendExpr::SuspendReturnType::SuspendVoid: + AwaitSuspendIID = llvm::Intrinsic::coro_await_suspend_void; + break; + case CoroutineSuspendExpr::SuspendReturnType::SuspendBool: + AwaitSuspendIID = llvm::Intrinsic::coro_await_suspend_bool; + break; + case CoroutineSuspendExpr::SuspendReturnType::SuspendHandle: + AwaitSuspendIID = llvm::Intrinsic::coro_await_suspend_handle; + break; + } + + llvm::Function *AwaitSuspendIntrinsic = CGF.CGM.getIntrinsic(AwaitSuspendIID); + + const auto AwaitSuspendCanThrow = StmtCanThrow(S.getSuspendExpr()); + + llvm::CallBase *SuspendRet = nullptr; + // FIXME: add call attributes? + if (AwaitSuspendCanThrow) + SuspendRet = + CGF.EmitCallOrInvoke(AwaitSuspendIntrinsic, SuspendIntrinsicCallArgs); + else + SuspendRet = CGF.EmitNounwindRuntimeCall(AwaitSuspendIntrinsic, + SuspendIntrinsicCallArgs); + + assert(SuspendRet); CGF.CurCoro.InSuspendBlock = false; - if (SuspendRet != nullptr && SuspendRet->getType()->isIntegerTy(1)) { + switch (SuspendReturnType) { + case CoroutineSuspendExpr::SuspendReturnType::SuspendVoid: + assert(SuspendRet->getType()->isVoidTy()); + break; + case CoroutineSuspendExpr::SuspendReturnType::SuspendBool: { + assert(SuspendRet->getType()->isIntegerTy()); + // Veto suspension if requested by bool returning await_suspend. BasicBlock *RealSuspendBlock = CGF.createBasicBlock(Prefix + Twine(".suspend.bool")); CGF.Builder.CreateCondBr(SuspendRet, RealSuspendBlock, ReadyBlock); CGF.EmitBlock(RealSuspendBlock); + break; + } + case CoroutineSuspendExpr::SuspendReturnType::SuspendHandle: { + assert(SuspendRet->getType()->isPointerTy()); + + auto ResumeIntrinsic = CGF.CGM.getIntrinsic(llvm::Intrinsic::coro_resume); + Builder.CreateCall(ResumeIntrinsic, SuspendRet); + break; + } } // Emit the suspend point. @@ -267,7 +338,7 @@ static LValueOrRValue emitSuspendExpression(CodeGenFunction &CGF, CGCoroData &Co // is marked as 'noexcept', we avoid generating this additional IR. CXXTryStmt *TryStmt = nullptr; if (Coro.ExceptionHandler && Kind == AwaitKind::Init && - ResumeStmtCanThrow(S.getResumeExpr())) { + StmtCanThrow(S.getResumeExpr())) { Coro.ResumeEHVar = CGF.CreateTempAlloca(Builder.getInt1Ty(), Prefix + Twine("resume.eh")); Builder.CreateFlagStore(true, Coro.ResumeEHVar); @@ -338,6 +409,69 @@ static QualType getCoroutineSuspendExprReturnType(const ASTContext &Ctx, } #endif +llvm::Function * +CodeGenFunction::generateAwaitSuspendWrapper(Twine const &CoroName, + Twine const &SuspendPointName, + CoroutineSuspendExpr const &S) { + std::string FuncName = "__await_suspend_wrapper_"; + FuncName += CoroName.str(); + FuncName += '_'; + FuncName += SuspendPointName.str(); + + ASTContext &C = getContext(); + + FunctionArgList args; + + ImplicitParamDecl AwaiterDecl(C, C.VoidPtrTy, ImplicitParamKind::Other); + ImplicitParamDecl FrameDecl(C, C.VoidPtrTy, ImplicitParamKind::Other); + QualType ReturnTy = S.getSuspendExpr()->getType(); + + args.push_back(&AwaiterDecl); + args.push_back(&FrameDecl); + + const CGFunctionInfo &FI = + CGM.getTypes().arrangeBuiltinFunctionDeclaration(ReturnTy, args); + + llvm::FunctionType *LTy = CGM.getTypes().GetFunctionType(FI); + + llvm::Function *Fn = llvm::Function::Create( + LTy, llvm::GlobalValue::PrivateLinkage, FuncName, &CGM.getModule()); + + Fn->addParamAttr(0, llvm::Attribute::AttrKind::NonNull); + Fn->addParamAttr(0, llvm::Attribute::AttrKind::NoUndef); + + Fn->addParamAttr(1, llvm::Attribute::AttrKind::NoUndef); + + Fn->setMustProgress(); + Fn->addFnAttr(llvm::Attribute::AttrKind::AlwaysInline); + + StartFunction(GlobalDecl(), ReturnTy, Fn, FI, args); + + // FIXME: add TBAA metadata to the loads + llvm::Value *AwaiterPtr = Builder.CreateLoad(GetAddrOfLocalVar(&AwaiterDecl)); + auto AwaiterLValue = + MakeNaturalAlignAddrLValue(AwaiterPtr, AwaiterDecl.getType()); + + CurAwaitSuspendWrapper.FramePtr = + Builder.CreateLoad(GetAddrOfLocalVar(&FrameDecl)); + + auto AwaiterBinder = CodeGenFunction::OpaqueValueMappingData::bind( + *this, S.getOpaqueValue(), AwaiterLValue); + + auto *SuspendRet = EmitScalarExpr(S.getSuspendExpr()); + + auto UnbindCommonOnExit = + llvm::make_scope_exit([&] { AwaiterBinder.unbind(*this); }); + if (SuspendRet != nullptr) { + Fn->addRetAttr(llvm::Attribute::AttrKind::NoUndef); + Builder.CreateStore(SuspendRet, ReturnValue); + } + + CurAwaitSuspendWrapper.FramePtr = nullptr; + FinishFunction(); + return Fn; +} + LValue CodeGenFunction::EmitCoawaitLValue(const CoawaitExpr *E) { assert(getCoroutineSuspendExprReturnType(getContext(), E)->isReferenceType() && @@ -834,6 +968,11 @@ RValue CodeGenFunction::EmitCoroutineIntrinsic(const CallExpr *E, if (CurCoro.Data && CurCoro.Data->CoroBegin) { return RValue::get(CurCoro.Data->CoroBegin); } + + if (CurAwaitSuspendWrapper.FramePtr) { + return RValue::get(CurAwaitSuspendWrapper.FramePtr); + } + CGM.Error(E->getBeginLoc(), "this builtin expect that __builtin_coro_begin " "has been used earlier in this function"); auto *NullPtr = llvm::ConstantPointerNull::get(Builder.getPtrTy()); diff --git a/clang/lib/CodeGen/CGDecl.cpp b/clang/lib/CodeGen/CGDecl.cpp index bbe14ef4c17244f75ecd6866d0e86e8e3ec36685..dc42faf8dbb9fda10203dae710ca3b201a7a58ab 100644 --- a/clang/lib/CodeGen/CGDecl.cpp +++ b/clang/lib/CodeGen/CGDecl.cpp @@ -284,6 +284,7 @@ llvm::Constant *CodeGenModule::getOrCreateStaticVarDecl( setTLSMode(GV, D); setGVProperties(GV, &D); + getTargetCodeGenInfo().setTargetAttributes(cast(&D), GV, *this); // Make sure the result is of the correct type. LangAS ExpectedAS = Ty.getAddressSpace(); diff --git a/clang/lib/CodeGen/CGOpenMPRuntime.cpp b/clang/lib/CodeGen/CGOpenMPRuntime.cpp index a7b72df6d9f897964e5c6e4f7d01ecb4b67f3af2..e8a68dbcc68709c7afd7249032674409dd711e9f 100644 --- a/clang/lib/CodeGen/CGOpenMPRuntime.cpp +++ b/clang/lib/CodeGen/CGOpenMPRuntime.cpp @@ -2647,6 +2647,9 @@ void CGOpenMPRuntime::emitDistributeStaticInit( void CGOpenMPRuntime::emitForStaticFinish(CodeGenFunction &CGF, SourceLocation Loc, OpenMPDirectiveKind DKind) { + assert(DKind == OMPD_distribute || DKind == OMPD_for || + DKind == OMPD_sections && + "Expected distribute, for, or sections directive kind"); if (!CGF.HaveInsertPoint()) return; // Call __kmpc_for_static_fini(ident_t *loc, kmp_int32 tid); diff --git a/clang/lib/CodeGen/CGStmt.cpp b/clang/lib/CodeGen/CGStmt.cpp index d0a3a716ad75e1f39f581b0e1404a714a47695db..8898e3f22a7df6d6ff8cd69b5255279d3ed8005a 100644 --- a/clang/lib/CodeGen/CGStmt.cpp +++ b/clang/lib/CodeGen/CGStmt.cpp @@ -728,11 +728,19 @@ void CodeGenFunction::EmitAttributedStmt(const AttributedStmt &S) { case attr::AlwaysInline: alwaysinline = true; break; - case attr::MustTail: + case attr::MustTail: { const Stmt *Sub = S.getSubStmt(); const ReturnStmt *R = cast(Sub); musttail = cast(R->getRetValue()->IgnoreParens()); - break; + } break; + case attr::CXXAssume: { + const Expr *Assumption = cast(A)->getAssumption(); + if (getLangOpts().CXXAssumptions && + !Assumption->HasSideEffects(getContext())) { + llvm::Value *AssumptionVal = EvaluateExprAsBool(Assumption); + Builder.CreateAssumption(AssumptionVal); + } + } break; } } SaveAndRestore save_nomerge(InNoMergeAttributedStmt, nomerge); diff --git a/clang/lib/CodeGen/CGStmtOpenMP.cpp b/clang/lib/CodeGen/CGStmtOpenMP.cpp index 3fbd2e03eb61df89440d821821a9baf06084b320..8edcc4ceea94369d13b683cf47295500e8218377 100644 --- a/clang/lib/CodeGen/CGStmtOpenMP.cpp +++ b/clang/lib/CodeGen/CGStmtOpenMP.cpp @@ -2910,10 +2910,10 @@ void CodeGenFunction::EmitOMPOuterLoop( EmitBlock(LoopExit.getBlock()); // Tell the runtime we are done. - auto &&CodeGen = [DynamicOrOrdered, &S](CodeGenFunction &CGF) { + auto &&CodeGen = [DynamicOrOrdered, &S, &LoopArgs](CodeGenFunction &CGF) { if (!DynamicOrOrdered) CGF.CGM.getOpenMPRuntime().emitForStaticFinish(CGF, S.getEndLoc(), - S.getDirectiveKind()); + LoopArgs.DKind); }; OMPCancelStack.emitExit(*this, S.getDirectiveKind(), CodeGen); } @@ -3019,6 +3019,7 @@ void CodeGenFunction::EmitOMPForOuterLoop( OuterLoopArgs.Cond = S.getCond(); OuterLoopArgs.NextLB = S.getNextLowerBound(); OuterLoopArgs.NextUB = S.getNextUpperBound(); + OuterLoopArgs.DKind = LoopArgs.DKind; EmitOMPOuterLoop(DynamicOrOrdered, IsMonotonic, S, LoopScope, OuterLoopArgs, emitOMPLoopBodyWithStopPoint, CodeGenOrdered); } @@ -3080,6 +3081,7 @@ void CodeGenFunction::EmitOMPDistributeOuterLoop( OuterLoopArgs.NextUB = isOpenMPLoopBoundSharingDirective(S.getDirectiveKind()) ? S.getCombinedNextUpperBound() : S.getNextUpperBound(); + OuterLoopArgs.DKind = OMPD_distribute; EmitOMPOuterLoop(/* DynamicOrOrdered = */ false, /* IsMonotonic = */ false, S, LoopScope, OuterLoopArgs, CodeGenLoopContent, @@ -3452,15 +3454,16 @@ bool CodeGenFunction::EmitOMPWorksharingLoop( // Tell the runtime we are done. auto &&CodeGen = [&S](CodeGenFunction &CGF) { CGF.CGM.getOpenMPRuntime().emitForStaticFinish(CGF, S.getEndLoc(), - S.getDirectiveKind()); + OMPD_for); }; OMPCancelStack.emitExit(*this, S.getDirectiveKind(), CodeGen); } else { // Emit the outer loop, which requests its work chunk [LB..UB] from // runtime and runs the inner loop to process it. - const OMPLoopArguments LoopArguments( + OMPLoopArguments LoopArguments( LB.getAddress(*this), UB.getAddress(*this), ST.getAddress(*this), IL.getAddress(*this), Chunk, EUB); + LoopArguments.DKind = OMPD_for; EmitOMPForOuterLoop(ScheduleKind, IsMonotonic, S, LoopScope, Ordered, LoopArguments, CGDispatchBounds); } @@ -4082,7 +4085,7 @@ void CodeGenFunction::EmitSections(const OMPExecutableDirective &S) { // Tell the runtime we are done. auto &&CodeGen = [&S](CodeGenFunction &CGF) { CGF.CGM.getOpenMPRuntime().emitForStaticFinish(CGF, S.getEndLoc(), - S.getDirectiveKind()); + OMPD_sections); }; CGF.OMPCancelStack.emitExit(CGF, S.getDirectiveKind(), CodeGen); CGF.EmitOMPReductionClauseFinal(S, /*ReductionKind=*/OMPD_parallel); @@ -4746,10 +4749,10 @@ void CodeGenFunction::EmitOMPTaskBasedDirective( if (CGF.CGM.getCodeGenOpts().hasReducedDebugInfo()) (void)DI->EmitDeclareOfAutoVariable(SharedVar, ContextValue, CGF.Builder, false); - llvm::Instruction &Last = CGF.Builder.GetInsertBlock()->back(); // Get the call dbg.declare instruction we just created and update // its DIExpression to add offset to base address. - if (auto DDI = dyn_cast(&Last)) { + auto UpdateExpr = [](llvm::LLVMContext &Ctx, auto *Declare, + unsigned Offset) { SmallVector Ops; // Add offset to the base address if non zero. if (Offset) { @@ -4757,9 +4760,21 @@ void CodeGenFunction::EmitOMPTaskBasedDirective( Ops.push_back(Offset); } Ops.push_back(llvm::dwarf::DW_OP_deref); - auto &Ctx = DDI->getContext(); - llvm::DIExpression *DIExpr = llvm::DIExpression::get(Ctx, Ops); - Last.setOperand(2, llvm::MetadataAsValue::get(Ctx, DIExpr)); + Declare->setExpression(llvm::DIExpression::get(Ctx, Ops)); + }; + llvm::Instruction &Last = CGF.Builder.GetInsertBlock()->back(); + if (auto DDI = dyn_cast(&Last)) + UpdateExpr(DDI->getContext(), DDI, Offset); + // If we're emitting using the new debug info format into a block + // without a terminator, the record will be "trailing". + assert(!Last.isTerminator() && "unexpected terminator"); + if (auto *Marker = + CGF.Builder.GetInsertBlock()->getTrailingDbgRecords()) { + for (llvm::DPValue &DPV : llvm::reverse( + llvm::filterDbgVars(Marker->getDbgRecordRange()))) { + UpdateExpr(Last.getContext(), &DPV, Offset); + break; + } } } } @@ -5782,7 +5797,7 @@ void CodeGenFunction::EmitOMPDistributeLoop(const OMPLoopDirective &S, }); EmitBlock(LoopExit.getBlock()); // Tell the runtime we are done. - RT.emitForStaticFinish(*this, S.getEndLoc(), S.getDirectiveKind()); + RT.emitForStaticFinish(*this, S.getEndLoc(), OMPD_distribute); } else { // Emit the outer loop, which requests its work chunk [LB..UB] from // runtime and runs the inner loop to process it. diff --git a/clang/lib/CodeGen/CodeGenFunction.cpp b/clang/lib/CodeGen/CodeGenFunction.cpp index b87fc86f4e635f344ad947858f4436936b6395aa..4a3ff49b0007a3c6d70d9ef8974a1d7e00cc73ff 100644 --- a/clang/lib/CodeGen/CodeGenFunction.cpp +++ b/clang/lib/CodeGen/CodeGenFunction.cpp @@ -31,6 +31,7 @@ #include "clang/AST/StmtObjC.h" #include "clang/Basic/Builtins.h" #include "clang/Basic/CodeGenOptions.h" +#include "clang/Basic/TargetBuiltins.h" #include "clang/Basic/TargetInfo.h" #include "clang/CodeGen/CGFunctionInfo.h" #include "clang/Frontend/FrontendDiagnostic.h" @@ -2613,6 +2614,24 @@ void CGBuilderInserter::InsertHelper( // called function. void CodeGenFunction::checkTargetFeatures(const CallExpr *E, const FunctionDecl *TargetDecl) { + // SemaChecking cannot handle below x86 builtins because they have different + // parameter ranges with different TargetAttribute of caller. + if (CGM.getContext().getTargetInfo().getTriple().isX86()) { + unsigned BuiltinID = TargetDecl->getBuiltinID(); + if (BuiltinID == X86::BI__builtin_ia32_cmpps || + BuiltinID == X86::BI__builtin_ia32_cmpss || + BuiltinID == X86::BI__builtin_ia32_cmppd || + BuiltinID == X86::BI__builtin_ia32_cmpsd) { + const FunctionDecl *FD = dyn_cast_or_null(CurCodeDecl); + llvm::StringMap TargetFetureMap; + CGM.getContext().getFunctionFeatureMap(TargetFetureMap, FD); + llvm::APSInt Result = + *(E->getArg(2)->getIntegerConstantExpr(CGM.getContext())); + if (Result.getSExtValue() > 7 && !TargetFetureMap.lookup("avx")) + CGM.getDiags().Report(E->getBeginLoc(), diag::err_builtin_needs_feature) + << TargetDecl->getDeclName() << "avx"; + } + } return checkTargetFeatures(E->getBeginLoc(), TargetDecl); } diff --git a/clang/lib/CodeGen/CodeGenFunction.h b/clang/lib/CodeGen/CodeGenFunction.h index 06327a1847177882943f24fabd1018e2641c0210..e8f8aa601ed017b559d2b87548110423e5c78107 100644 --- a/clang/lib/CodeGen/CodeGenFunction.h +++ b/clang/lib/CodeGen/CodeGenFunction.h @@ -352,6 +352,25 @@ public: return isCoroutine() && CurCoro.InSuspendBlock; } + // Holds FramePtr for await_suspend wrapper generation, + // so that __builtin_coro_frame call can be lowered + // directly to value of its second argument + struct AwaitSuspendWrapperInfo { + llvm::Value *FramePtr = nullptr; + }; + AwaitSuspendWrapperInfo CurAwaitSuspendWrapper; + + // Generates wrapper function for `llvm.coro.await.suspend.*` intrinisics. + // It encapsulates SuspendExpr in a function, to separate it's body + // from the main coroutine to avoid miscompilations. Intrinisic + // is lowered to this function call in CoroSplit pass + // Function signature is: + // __await_suspend_wrapper_(ptr %awaiter, ptr %hdl) + // where type is one of (void, i1, ptr) + llvm::Function *generateAwaitSuspendWrapper(Twine const &CoroName, + Twine const &SuspendPointName, + CoroutineSuspendExpr const &S); + /// CurGD - The GlobalDecl for the current function being compiled. GlobalDecl CurGD; @@ -3812,6 +3831,8 @@ private: Expr *NextLB = nullptr; /// Update of UB after a whole chunk has been executed Expr *NextUB = nullptr; + /// Distinguish between the for distribute and sections + OpenMPDirectiveKind DKind = llvm::omp::OMPD_unknown; OMPLoopArguments() = default; OMPLoopArguments(Address LB, Address UB, Address ST, Address IL, llvm::Value *Chunk = nullptr, Expr *EUB = nullptr, diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp index 967319bdfc4571168f370c42b3b6ad26d21b8c6c..8ceecff28cbc63929834f524ccb7e85d2b23cb58 100644 --- a/clang/lib/CodeGen/CodeGenModule.cpp +++ b/clang/lib/CodeGen/CodeGenModule.cpp @@ -626,6 +626,26 @@ static bool checkAliasedGlobal( return true; } +// Emit a warning if toc-data attribute is requested for global variables that +// have aliases and remove the toc-data attribute. +static void checkAliasForTocData(llvm::GlobalVariable *GVar, + const CodeGenOptions &CodeGenOpts, + DiagnosticsEngine &Diags, + SourceLocation Location) { + if (GVar->hasAttribute("toc-data")) { + auto GVId = GVar->getName(); + // Is this a global variable specified by the user as local? + if ((llvm::binary_search(CodeGenOpts.TocDataVarsUserSpecified, GVId))) { + Diags.Report(Location, diag::warn_toc_unsupported_type) + << GVId << "the variable has an alias"; + } + llvm::AttributeSet CurrAttributes = GVar->getAttributes(); + llvm::AttributeSet NewAttributes = + CurrAttributes.removeAttribute(GVar->getContext(), "toc-data"); + GVar->setAttributes(NewAttributes); + } +} + void CodeGenModule::checkAliases() { // Check if the constructed aliases are well formed. It is really unfortunate // that we have to do this in CodeGen, but we only construct mangled names @@ -652,6 +672,12 @@ void CodeGenModule::checkAliases() { continue; } + if (getContext().getTargetInfo().getTriple().isOSAIX()) + if (const llvm::GlobalVariable *GVar = + dyn_cast(GV)) + checkAliasForTocData(const_cast(GVar), + getCodeGenOpts(), Diags, Location); + llvm::Constant *Aliasee = IsIFunc ? cast(Alias)->getResolver() : cast(Alias)->getAliasee(); diff --git a/clang/lib/CodeGen/CodeGenTBAA.cpp b/clang/lib/CodeGen/CodeGenTBAA.cpp index 1f07205a5af2251c773dbe34f06b2d008dd678e6..a1e14c5f0a8c784e58154c2c85cce1bd0b77e749 100644 --- a/clang/lib/CodeGen/CodeGenTBAA.cpp +++ b/clang/lib/CodeGen/CodeGenTBAA.cpp @@ -286,6 +286,14 @@ CodeGenTBAA::CollectFields(uint64_t BaseOffset, /* Things not handled yet include: C++ base classes, bitfields, */ if (const RecordType *TTy = QTy->getAs()) { + if (TTy->isUnionType()) { + uint64_t Size = Context.getTypeSizeInChars(QTy).getQuantity(); + llvm::MDNode *TBAAType = getChar(); + llvm::MDNode *TBAATag = getAccessTagInfo(TBAAAccessInfo(TBAAType, Size)); + Fields.push_back( + llvm::MDBuilder::TBAAStructField(BaseOffset, Size, TBAATag)); + return true; + } const RecordDecl *RD = TTy->getDecl()->getDefinition(); if (RD->hasFlexibleArrayMember()) return false; diff --git a/clang/lib/CodeGen/Targets/AMDGPU.cpp b/clang/lib/CodeGen/Targets/AMDGPU.cpp index 03ac6b78598fc8477e6756b4c64f5936fd0daedb..44e86c0b40f6864e00893968e420a5127b2add63 100644 --- a/clang/lib/CodeGen/Targets/AMDGPU.cpp +++ b/clang/lib/CodeGen/Targets/AMDGPU.cpp @@ -356,6 +356,29 @@ void AMDGPUTargetCodeGenInfo::setFunctionDeclAttributes( if (NumVGPR != 0) F->addFnAttr("amdgpu-num-vgpr", llvm::utostr(NumVGPR)); } + + if (const auto *Attr = FD->getAttr()) { + uint32_t X = Attr->getMaxNumWorkGroupsX() + ->EvaluateKnownConstInt(M.getContext()) + .getExtValue(); + // Y and Z dimensions default to 1 if not specified + uint32_t Y = Attr->getMaxNumWorkGroupsY() + ? Attr->getMaxNumWorkGroupsY() + ->EvaluateKnownConstInt(M.getContext()) + .getExtValue() + : 1; + uint32_t Z = Attr->getMaxNumWorkGroupsZ() + ? Attr->getMaxNumWorkGroupsZ() + ->EvaluateKnownConstInt(M.getContext()) + .getExtValue() + : 1; + + llvm::SmallString<32> AttrVal; + llvm::raw_svector_ostream OS(AttrVal); + OS << X << ',' << Y << ',' << Z; + + F->addFnAttr("amdgpu-max-num-workgroups", AttrVal.str()); + } } /// Emits control constants used to change per-architecture behaviour in the diff --git a/clang/lib/CodeGen/Targets/PPC.cpp b/clang/lib/CodeGen/Targets/PPC.cpp index 40dddde508c1772da1fcf0475af07b5977b26490..00b04723f17dd2e0a2ed392b57aab43300379c1e 100644 --- a/clang/lib/CodeGen/Targets/PPC.cpp +++ b/clang/lib/CodeGen/Targets/PPC.cpp @@ -8,6 +8,7 @@ #include "ABIInfoImpl.h" #include "TargetInfo.h" +#include "clang/Basic/DiagnosticFrontend.h" using namespace clang; using namespace clang::CodeGen; @@ -145,6 +146,9 @@ public: bool initDwarfEHRegSizeTable(CodeGen::CodeGenFunction &CGF, llvm::Value *Address) const override; + + void setTargetAttributes(const Decl *D, llvm::GlobalValue *GV, + CodeGen::CodeGenModule &M) const override; }; } // namespace @@ -265,6 +269,61 @@ bool AIXTargetCodeGenInfo::initDwarfEHRegSizeTable( return PPC_initDwarfEHRegSizeTable(CGF, Address, Is64Bit, /*IsAIX*/ true); } +void AIXTargetCodeGenInfo::setTargetAttributes( + const Decl *D, llvm::GlobalValue *GV, CodeGen::CodeGenModule &M) const { + if (!isa(GV)) + return; + + auto *GVar = dyn_cast(GV); + auto GVId = GV->getName(); + + // Is this a global variable specified by the user as toc-data? + bool UserSpecifiedTOC = + llvm::binary_search(M.getCodeGenOpts().TocDataVarsUserSpecified, GVId); + // Assumes the same variable cannot be in both TocVarsUserSpecified and + // NoTocVars. + if (UserSpecifiedTOC || + ((M.getCodeGenOpts().AllTocData) && + !llvm::binary_search(M.getCodeGenOpts().NoTocDataVars, GVId))) { + const unsigned long PointerSize = + GV->getParent()->getDataLayout().getPointerSizeInBits() / 8; + auto *VarD = dyn_cast(D); + assert(VarD && "Invalid declaration of global variable."); + + ASTContext &Context = D->getASTContext(); + unsigned Alignment = Context.toBits(Context.getDeclAlign(D)) / 8; + const auto *Ty = VarD->getType().getTypePtr(); + const RecordDecl *RDecl = + Ty->isRecordType() ? Ty->getAs()->getDecl() : nullptr; + + bool EmitDiagnostic = UserSpecifiedTOC && GV->hasExternalLinkage(); + auto reportUnsupportedWarning = [&](bool ShouldEmitWarning, StringRef Msg) { + if (ShouldEmitWarning) + M.getDiags().Report(D->getLocation(), diag::warn_toc_unsupported_type) + << GVId << Msg; + }; + if (!Ty || Ty->isIncompleteType()) + reportUnsupportedWarning(EmitDiagnostic, "of incomplete type"); + else if (RDecl && RDecl->hasFlexibleArrayMember()) + reportUnsupportedWarning(EmitDiagnostic, + "it contains a flexible array member"); + else if (VarD->getTLSKind() != VarDecl::TLS_None) + reportUnsupportedWarning(EmitDiagnostic, "of thread local storage"); + else if (PointerSize < Context.getTypeInfo(VarD->getType()).Width / 8) + reportUnsupportedWarning(EmitDiagnostic, + "variable is larger than a pointer"); + else if (PointerSize < Alignment) + reportUnsupportedWarning(EmitDiagnostic, + "variable is aligned wider than a pointer"); + else if (D->hasAttr()) + reportUnsupportedWarning(EmitDiagnostic, + "variable has a section attribute"); + else if (GV->hasExternalLinkage() || + (M.getCodeGenOpts().AllTocData && !GV->hasLocalLinkage())) + GVar->addAttribute("toc-data"); + } +} + // PowerPC-32 namespace { /// PPC32_SVR4_ABIInfo - The 32-bit PowerPC ELF (SVR4) ABI information. diff --git a/clang/lib/CodeGen/Targets/RISCV.cpp b/clang/lib/CodeGen/Targets/RISCV.cpp index dec6540230a60fb4d29a0aee42b0111c33e3fe18..9a79424c4612ceb45c2f386c28d878d6b66ea655 100644 --- a/clang/lib/CodeGen/Targets/RISCV.cpp +++ b/clang/lib/CodeGen/Targets/RISCV.cpp @@ -529,7 +529,10 @@ public: RISCVTargetCodeGenInfo(CodeGen::CodeGenTypes &CGT, unsigned XLen, unsigned FLen, bool EABI) : TargetCodeGenInfo( - std::make_unique(CGT, XLen, FLen, EABI)) {} + std::make_unique(CGT, XLen, FLen, EABI)) { + SwiftInfo = + std::make_unique(CGT, /*SwiftErrorInRegister=*/false); + } void setTargetAttributes(const Decl *D, llvm::GlobalValue *GV, CodeGen::CodeGenModule &CGM) const override { diff --git a/clang/lib/DirectoryWatcher/linux/DirectoryWatcher-linux.cpp b/clang/lib/DirectoryWatcher/linux/DirectoryWatcher-linux.cpp index beca9586988b526876c0787ae9d0e62345268c4f..2ffbc1a226958a0a8ecf6cca1965cdb9235e9ef6 100644 --- a/clang/lib/DirectoryWatcher/linux/DirectoryWatcher-linux.cpp +++ b/clang/lib/DirectoryWatcher/linux/DirectoryWatcher-linux.cpp @@ -333,8 +333,7 @@ llvm::Expected> clang::DirectoryWatcher::creat const int InotifyFD = inotify_init1(IN_CLOEXEC); if (InotifyFD == -1) return llvm::make_error( - std::string("inotify_init1() error: ") + strerror(errno), - llvm::inconvertibleErrorCode()); + llvm::errnoAsErrorCode(), std::string(": inotify_init1()")); const int InotifyWD = inotify_add_watch( InotifyFD, Path.str().c_str(), @@ -346,15 +345,13 @@ llvm::Expected> clang::DirectoryWatcher::creat ); if (InotifyWD == -1) return llvm::make_error( - std::string("inotify_add_watch() error: ") + strerror(errno), - llvm::inconvertibleErrorCode()); + llvm::errnoAsErrorCode(), std::string(": inotify_add_watch()")); auto InotifyPollingStopper = SemaphorePipe::create(); if (!InotifyPollingStopper) return llvm::make_error( - std::string("SemaphorePipe::create() error: ") + strerror(errno), - llvm::inconvertibleErrorCode()); + llvm::errnoAsErrorCode(), std::string(": SemaphorePipe::create()")); return std::make_unique( Path, Receiver, WaitForInitialSync, InotifyFD, InotifyWD, diff --git a/clang/lib/Driver/Driver.cpp b/clang/lib/Driver/Driver.cpp index fce43430a913740ddde1c361b9457f8315730576..1daf588142b3b47c390c8d095183225d3e96c430 100644 --- a/clang/lib/Driver/Driver.cpp +++ b/clang/lib/Driver/Driver.cpp @@ -87,6 +87,7 @@ #include "llvm/Support/Process.h" #include "llvm/Support/Program.h" #include "llvm/Support/RISCVISAInfo.h" +#include "llvm/Support/Regex.h" #include "llvm/Support/StringSaver.h" #include "llvm/Support/VirtualFileSystem.h" #include "llvm/Support/raw_ostream.h" @@ -2196,6 +2197,12 @@ bool Driver::HandleImmediateArgs(const Compilation &C) { return false; } + if (C.getArgs().hasArg(options::OPT_print_std_module_manifest_path)) { + llvm::outs() << GetStdModuleManifestPath(C, C.getDefaultToolChain()) + << '\n'; + return false; + } + if (C.getArgs().hasArg(options::OPT_print_runtime_dir)) { if (std::optional RuntimePath = TC.getRuntimePath()) llvm::outs() << *RuntimePath << '\n'; @@ -4638,7 +4645,13 @@ Action *Driver::BuildOffloadingActions(Compilation &C, } } - if (offloadDeviceOnly()) + // All kinds exit now in device-only mode except for non-RDC mode HIP. + if (offloadDeviceOnly() && + (getFinalPhase(Args) == phases::Preprocess || + !C.isOffloadingHostKind(Action::OFK_HIP) || + !Args.hasFlag(options::OPT_gpu_bundle_output, + options::OPT_no_gpu_bundle_output, true) || + Args.hasFlag(options::OPT_fgpu_rdc, options::OPT_fno_gpu_rdc, false))) return C.MakeAction(DDeps, types::TY_Nothing); if (OffloadActions.empty()) @@ -4671,6 +4684,10 @@ Action *Driver::BuildOffloadingActions(Compilation &C, nullptr, C.getActiveOffloadKinds()); } + // HIP wants '--offload-device-only' to create a fatbinary by default. + if (offloadDeviceOnly()) + return C.MakeAction(DDep, types::TY_Nothing); + // If we are unable to embed a single device output into the host, we need to // add each device output as a host dependency to ensure they are still built. bool SingleDeviceOutput = !llvm::any_of(OffloadActions, [](Action *A) { @@ -6176,6 +6193,44 @@ std::string Driver::GetProgramPath(StringRef Name, const ToolChain &TC) const { return std::string(Name); } +std::string Driver::GetStdModuleManifestPath(const Compilation &C, + const ToolChain &TC) const { + std::string error = ""; + + switch (TC.GetCXXStdlibType(C.getArgs())) { + case ToolChain::CST_Libcxx: { + std::string lib = GetFilePath("libc++.so", TC); + + // Note when there are multiple flavours of libc++ the module json needs to + // look at the command-line arguments for the proper json. + // These flavours do not exist at the moment, but there are plans to + // provide a variant that is built with sanitizer instrumentation enabled. + + // For example + // StringRef modules = [&] { + // const SanitizerArgs &Sanitize = TC.getSanitizerArgs(C.getArgs()); + // if (Sanitize.needsAsanRt()) + // return "modules-asan.json"; + // return "modules.json"; + // }(); + + SmallString<128> path(lib.begin(), lib.end()); + llvm::sys::path::remove_filename(path); + llvm::sys::path::append(path, "modules.json"); + if (TC.getVFS().exists(path)) + return static_cast(path); + + return error; + } + + case ToolChain::CST_Libstdcxx: + // libstdc++ does not provide Standard library modules yet. + return error; + } + + return error; +} + std::string Driver::GetTemporaryPath(StringRef Prefix, StringRef Suffix) const { SmallString<128> Path; std::error_code EC = llvm::sys::fs::createTemporaryFile(Prefix, Suffix, Path); @@ -6668,3 +6723,131 @@ llvm::Error driver::expandResponseFiles(SmallVectorImpl &Args, return llvm::Error::success(); } + +static const char *GetStableCStr(llvm::StringSet<> &SavedStrings, StringRef S) { + return SavedStrings.insert(S).first->getKeyData(); +} + +/// Apply a list of edits to the input argument lists. +/// +/// The input string is a space separated list of edits to perform, +/// they are applied in order to the input argument lists. Edits +/// should be one of the following forms: +/// +/// '#': Silence information about the changes to the command line arguments. +/// +/// '^': Add FOO as a new argument at the beginning of the command line. +/// +/// '+': Add FOO as a new argument at the end of the command line. +/// +/// 's/XXX/YYY/': Substitute the regular expression XXX with YYY in the command +/// line. +/// +/// 'xOPTION': Removes all instances of the literal argument OPTION. +/// +/// 'XOPTION': Removes all instances of the literal argument OPTION, +/// and the following argument. +/// +/// 'Ox': Removes all flags matching 'O' or 'O[sz0-9]' and adds 'Ox' +/// at the end of the command line. +/// +/// \param OS - The stream to write edit information to. +/// \param Args - The vector of command line arguments. +/// \param Edit - The override command to perform. +/// \param SavedStrings - Set to use for storing string representations. +static void applyOneOverrideOption(raw_ostream &OS, + SmallVectorImpl &Args, + StringRef Edit, + llvm::StringSet<> &SavedStrings) { + // This does not need to be efficient. + + if (Edit[0] == '^') { + const char *Str = GetStableCStr(SavedStrings, Edit.substr(1)); + OS << "### Adding argument " << Str << " at beginning\n"; + Args.insert(Args.begin() + 1, Str); + } else if (Edit[0] == '+') { + const char *Str = GetStableCStr(SavedStrings, Edit.substr(1)); + OS << "### Adding argument " << Str << " at end\n"; + Args.push_back(Str); + } else if (Edit[0] == 's' && Edit[1] == '/' && Edit.ends_with("/") && + Edit.slice(2, Edit.size() - 1).contains('/')) { + StringRef MatchPattern = Edit.substr(2).split('/').first; + StringRef ReplPattern = Edit.substr(2).split('/').second; + ReplPattern = ReplPattern.slice(0, ReplPattern.size() - 1); + + for (unsigned i = 1, e = Args.size(); i != e; ++i) { + // Ignore end-of-line response file markers + if (Args[i] == nullptr) + continue; + std::string Repl = llvm::Regex(MatchPattern).sub(ReplPattern, Args[i]); + + if (Repl != Args[i]) { + OS << "### Replacing '" << Args[i] << "' with '" << Repl << "'\n"; + Args[i] = GetStableCStr(SavedStrings, Repl); + } + } + } else if (Edit[0] == 'x' || Edit[0] == 'X') { + auto Option = Edit.substr(1); + for (unsigned i = 1; i < Args.size();) { + if (Option == Args[i]) { + OS << "### Deleting argument " << Args[i] << '\n'; + Args.erase(Args.begin() + i); + if (Edit[0] == 'X') { + if (i < Args.size()) { + OS << "### Deleting argument " << Args[i] << '\n'; + Args.erase(Args.begin() + i); + } else + OS << "### Invalid X edit, end of command line!\n"; + } + } else + ++i; + } + } else if (Edit[0] == 'O') { + for (unsigned i = 1; i < Args.size();) { + const char *A = Args[i]; + // Ignore end-of-line response file markers + if (A == nullptr) + continue; + if (A[0] == '-' && A[1] == 'O' && + (A[2] == '\0' || (A[3] == '\0' && (A[2] == 's' || A[2] == 'z' || + ('0' <= A[2] && A[2] <= '9'))))) { + OS << "### Deleting argument " << Args[i] << '\n'; + Args.erase(Args.begin() + i); + } else + ++i; + } + OS << "### Adding argument " << Edit << " at end\n"; + Args.push_back(GetStableCStr(SavedStrings, '-' + Edit.str())); + } else { + OS << "### Unrecognized edit: " << Edit << "\n"; + } +} + +void driver::applyOverrideOptions(SmallVectorImpl &Args, + const char *OverrideStr, + llvm::StringSet<> &SavedStrings, + raw_ostream *OS) { + if (!OS) + OS = &llvm::nulls(); + + if (OverrideStr[0] == '#') { + ++OverrideStr; + OS = &llvm::nulls(); + } + + *OS << "### CCC_OVERRIDE_OPTIONS: " << OverrideStr << "\n"; + + // This does not need to be efficient. + + const char *S = OverrideStr; + while (*S) { + const char *End = ::strchr(S, ' '); + if (!End) + End = S + strlen(S); + if (End != S) + applyOneOverrideOption(*OS, Args, std::string(S, End), SavedStrings); + S = End; + if (*S != '\0') + ++S; + } +} diff --git a/clang/lib/Driver/OffloadBundler.cpp b/clang/lib/Driver/OffloadBundler.cpp index f9eadfaec88dec41f9d239014aa9c7a1e81769ab..77c89356bc76bb38a4b0771b739b281a92bb709f 100644 --- a/clang/lib/Driver/OffloadBundler.cpp +++ b/clang/lib/Driver/OffloadBundler.cpp @@ -924,6 +924,17 @@ CreateFileHandler(MemoryBuffer &FirstInput, } OffloadBundlerConfig::OffloadBundlerConfig() { + if (llvm::compression::zstd::isAvailable()) { + CompressionFormat = llvm::compression::Format::Zstd; + // Compression level 3 is usually sufficient for zstd since long distance + // matching is enabled. + CompressionLevel = 3; + } else if (llvm::compression::zlib::isAvailable()) { + CompressionFormat = llvm::compression::Format::Zlib; + // Use default level for zlib since higher level does not have significant + // improvement. + CompressionLevel = llvm::compression::zlib::DefaultCompression; + } auto IgnoreEnvVarOpt = llvm::sys::Process::GetEnv("OFFLOAD_BUNDLER_IGNORE_ENV_VAR"); if (IgnoreEnvVarOpt.has_value() && IgnoreEnvVarOpt.value() == "1") @@ -937,11 +948,41 @@ OffloadBundlerConfig::OffloadBundlerConfig() { llvm::sys::Process::GetEnv("OFFLOAD_BUNDLER_COMPRESS"); if (CompressEnvVarOpt.has_value()) Compress = CompressEnvVarOpt.value() == "1"; + + auto CompressionLevelEnvVarOpt = + llvm::sys::Process::GetEnv("OFFLOAD_BUNDLER_COMPRESSION_LEVEL"); + if (CompressionLevelEnvVarOpt.has_value()) { + llvm::StringRef CompressionLevelStr = CompressionLevelEnvVarOpt.value(); + int Level; + if (!CompressionLevelStr.getAsInteger(10, Level)) + CompressionLevel = Level; + else + llvm::errs() + << "Warning: Invalid value for OFFLOAD_BUNDLER_COMPRESSION_LEVEL: " + << CompressionLevelStr.str() << ". Ignoring it.\n"; + } +} + +// Utility function to format numbers with commas +static std::string formatWithCommas(unsigned long long Value) { + std::string Num = std::to_string(Value); + int InsertPosition = Num.length() - 3; + while (InsertPosition > 0) { + Num.insert(InsertPosition, ","); + InsertPosition -= 3; + } + return Num; } llvm::Expected> -CompressedOffloadBundle::compress(const llvm::MemoryBuffer &Input, +CompressedOffloadBundle::compress(llvm::compression::Params P, + const llvm::MemoryBuffer &Input, bool Verbose) { + if (!llvm::compression::zstd::isAvailable() && + !llvm::compression::zlib::isAvailable()) + return createStringError(llvm::inconvertibleErrorCode(), + "Compression not supported"); + llvm::Timer HashTimer("Hash Calculation Timer", "Hash calculation time", ClangOffloadBundlerTimerGroup); if (Verbose) @@ -959,25 +1000,15 @@ CompressedOffloadBundle::compress(const llvm::MemoryBuffer &Input, reinterpret_cast(Input.getBuffer().data()), Input.getBuffer().size()); - llvm::compression::Format CompressionFormat; - - if (llvm::compression::zstd::isAvailable()) - CompressionFormat = llvm::compression::Format::Zstd; - else if (llvm::compression::zlib::isAvailable()) - CompressionFormat = llvm::compression::Format::Zlib; - else - return createStringError(llvm::inconvertibleErrorCode(), - "Compression not supported"); - llvm::Timer CompressTimer("Compression Timer", "Compression time", ClangOffloadBundlerTimerGroup); if (Verbose) CompressTimer.startTimer(); - llvm::compression::compress(CompressionFormat, BufferUint8, CompressedBuffer); + llvm::compression::compress(P, BufferUint8, CompressedBuffer); if (Verbose) CompressTimer.stopTimer(); - uint16_t CompressionMethod = static_cast(CompressionFormat); + uint16_t CompressionMethod = static_cast(P.format); uint32_t UncompressedSize = Input.getBuffer().size(); SmallVector FinalBuffer; @@ -995,17 +1026,29 @@ CompressedOffloadBundle::compress(const llvm::MemoryBuffer &Input, if (Verbose) { auto MethodUsed = - CompressionFormat == llvm::compression::Format::Zstd ? "zstd" : "zlib"; + P.format == llvm::compression::Format::Zstd ? "zstd" : "zlib"; + double CompressionRate = + static_cast(UncompressedSize) / CompressedBuffer.size(); + double CompressionTimeSeconds = CompressTimer.getTotalTime().getWallTime(); + double CompressionSpeedMBs = + (UncompressedSize / (1024.0 * 1024.0)) / CompressionTimeSeconds; + llvm::errs() << "Compressed bundle format version: " << Version << "\n" << "Compression method used: " << MethodUsed << "\n" - << "Binary size before compression: " << UncompressedSize - << " bytes\n" - << "Binary size after compression: " << CompressedBuffer.size() - << " bytes\n" + << "Compression level: " << P.level << "\n" + << "Binary size before compression: " + << formatWithCommas(UncompressedSize) << " bytes\n" + << "Binary size after compression: " + << formatWithCommas(CompressedBuffer.size()) << " bytes\n" + << "Compression rate: " + << llvm::format("%.2lf", CompressionRate) << "\n" + << "Compression ratio: " + << llvm::format("%.2lf%%", 100.0 / CompressionRate) << "\n" + << "Compression speed: " + << llvm::format("%.2lf MB/s", CompressionSpeedMBs) << "\n" << "Truncated MD5 hash: " << llvm::format_hex(TruncatedHash, 16) << "\n"; } - return llvm::MemoryBuffer::getMemBufferCopy( llvm::StringRef(FinalBuffer.data(), FinalBuffer.size())); } @@ -1070,7 +1113,10 @@ CompressedOffloadBundle::decompress(const llvm::MemoryBuffer &Input, if (Verbose) { DecompressTimer.stopTimer(); - // Recalculate MD5 hash + double DecompressionTimeSeconds = + DecompressTimer.getTotalTime().getWallTime(); + + // Recalculate MD5 hash for integrity check llvm::Timer HashRecalcTimer("Hash Recalculation Timer", "Hash recalculation time", ClangOffloadBundlerTimerGroup); @@ -1084,16 +1130,27 @@ CompressedOffloadBundle::decompress(const llvm::MemoryBuffer &Input, HashRecalcTimer.stopTimer(); bool HashMatch = (StoredHash == RecalculatedHash); + double CompressionRate = + static_cast(UncompressedSize) / CompressedData.size(); + double DecompressionSpeedMBs = + (UncompressedSize / (1024.0 * 1024.0)) / DecompressionTimeSeconds; + llvm::errs() << "Compressed bundle format version: " << ThisVersion << "\n" << "Decompression method: " << (CompressionFormat == llvm::compression::Format::Zlib ? "zlib" : "zstd") << "\n" - << "Size before decompression: " << CompressedData.size() - << " bytes\n" - << "Size after decompression: " << UncompressedSize - << " bytes\n" + << "Size before decompression: " + << formatWithCommas(CompressedData.size()) << " bytes\n" + << "Size after decompression: " + << formatWithCommas(UncompressedSize) << " bytes\n" + << "Compression rate: " + << llvm::format("%.2lf", CompressionRate) << "\n" + << "Compression ratio: " + << llvm::format("%.2lf%%", 100.0 / CompressionRate) << "\n" + << "Decompression speed: " + << llvm::format("%.2lf MB/s", DecompressionSpeedMBs) << "\n" << "Stored hash: " << llvm::format_hex(StoredHash, 16) << "\n" << "Recalculated hash: " << llvm::format_hex(RecalculatedHash, 16) << "\n" @@ -1287,8 +1344,10 @@ Error OffloadBundler::BundleFiles() { std::unique_ptr BufferMemory = llvm::MemoryBuffer::getMemBufferCopy( llvm::StringRef(Buffer.data(), Buffer.size())); - auto CompressionResult = - CompressedOffloadBundle::compress(*BufferMemory, BundlerConfig.Verbose); + auto CompressionResult = CompressedOffloadBundle::compress( + {BundlerConfig.CompressionFormat, BundlerConfig.CompressionLevel, + /*zstdEnableLdm=*/true}, + *BufferMemory, BundlerConfig.Verbose); if (auto Error = CompressionResult.takeError()) return Error; diff --git a/clang/lib/Driver/ToolChain.cpp b/clang/lib/Driver/ToolChain.cpp index 08b1fd01b3c0ac1a6f3b6542268a6f3c3a7524e6..03450fc0f57b93e9acb16f1ece913f68d88f6a58 100644 --- a/clang/lib/Driver/ToolChain.cpp +++ b/clang/lib/Driver/ToolChain.cpp @@ -453,12 +453,6 @@ ToolChain::getDefaultUnwindTableLevel(const ArgList &Args) const { return UnwindTableLevel::None; } -unsigned ToolChain::GetDefaultDwarfVersion() const { - // TODO: Remove the RISC-V special case when R_RISCV_SET_ULEB128 linker - // support becomes more widely available. - return getTriple().isRISCV() ? 4 : 5; -} - Tool *ToolChain::getClang() const { if (!Clang) Clang.reset(new tools::Clang(*this, useIntegratedBackend())); diff --git a/clang/lib/Driver/ToolChains/AIX.cpp b/clang/lib/Driver/ToolChains/AIX.cpp index 3c7049a99982d0d2f22bf4c972a300e621610664..6e089903a3158a4e79e4cd4f516be2df19d4e6dd 100644 --- a/clang/lib/Driver/ToolChains/AIX.cpp +++ b/clang/lib/Driver/ToolChains/AIX.cpp @@ -433,6 +433,88 @@ void AIX::AddCXXStdlibLibArgs(const llvm::opt::ArgList &Args, llvm_unreachable("Unexpected C++ library type; only libc++ is supported."); } +// This function processes all the mtocdata options to build the final +// simplified toc data options to pass to CC1. +static void addTocDataOptions(const llvm::opt::ArgList &Args, + llvm::opt::ArgStringList &CC1Args, + const Driver &D) { + + // Check the global toc-data setting. The default is -mno-tocdata. + // To enable toc-data globally, -mtocdata must be specified. + // Additionally, it must be last to take effect. + const bool TOCDataGloballyinEffect = [&Args]() { + if (const Arg *LastArg = + Args.getLastArg(options::OPT_mtocdata, options::OPT_mno_tocdata)) + return LastArg->getOption().matches(options::OPT_mtocdata); + else + return false; + }(); + + // Currently only supported for small code model. + if (TOCDataGloballyinEffect && + (Args.getLastArgValue(options::OPT_mcmodel_EQ).equals("large") || + Args.getLastArgValue(options::OPT_mcmodel_EQ).equals("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. + }; + + const TOCDataSetting DefaultTocDataSetting = + TOCDataGloballyinEffect ? DataInTOC : AddressInTOC; + + // Process the list of variables in the explicitly specified options + // -mtocdata= and -mno-tocdata= to see which variables are opposite to + // the global setting of tocdata in TOCDataGloballyinEffect. + // Those that have the opposite setting to TOCDataGloballyinEffect, are added + // to ExplicitlySpecifiedGlobals. + llvm::StringSet<> ExplicitlySpecifiedGlobals; + for (const auto Arg : + Args.filtered(options::OPT_mtocdata_EQ, options::OPT_mno_tocdata_EQ)) { + TOCDataSetting ArgTocDataSetting = + Arg->getOption().matches(options::OPT_mtocdata_EQ) ? DataInTOC + : AddressInTOC; + + if (ArgTocDataSetting != DefaultTocDataSetting) + for (const char *Val : Arg->getValues()) + ExplicitlySpecifiedGlobals.insert(Val); + else + for (const char *Val : Arg->getValues()) + ExplicitlySpecifiedGlobals.erase(Val); + } + + auto buildExceptionList = [](const llvm::StringSet<> &ExplicitValues, + const char *OptionSpelling) { + std::string Option(OptionSpelling); + bool IsFirst = true; + for (const auto &E : ExplicitValues) { + if (!IsFirst) + Option += ","; + + IsFirst = false; + Option += E.first(); + } + return Option; + }; + + // Pass the final tocdata options to CC1 consisting of the default + // tocdata option (-mtocdata/-mno-tocdata) along with the list + // option (-mno-tocdata=/-mtocdata=) if there are any explicitly specified + // variables which would be exceptions to the default setting. + const char *TocDataGlobalOption = + TOCDataGloballyinEffect ? "-mtocdata" : "-mno-tocdata"; + CC1Args.push_back(TocDataGlobalOption); + + const char *TocDataListOption = + TOCDataGloballyinEffect ? "-mno-tocdata=" : "-mtocdata="; + if (!ExplicitlySpecifiedGlobals.empty()) + CC1Args.push_back(Args.MakeArgString(llvm::Twine( + buildExceptionList(ExplicitlySpecifiedGlobals, TocDataListOption)))); +} + void AIX::addClangTargetOptions( const llvm::opt::ArgList &Args, llvm::opt::ArgStringList &CC1Args, Action::OffloadKind DeviceOffloadingKind) const { @@ -440,6 +522,11 @@ void AIX::addClangTargetOptions( Args.AddLastArg(CC1Args, options::OPT_mdefault_visibility_export_mapping_EQ); Args.addOptInFlag(CC1Args, options::OPT_mxcoff_roptr, options::OPT_mno_xcoff_roptr); + // Forward last mtocdata/mno_tocdata options to -cc1. + if (Args.hasArg(options::OPT_mtocdata_EQ, options::OPT_mno_tocdata_EQ, + options::OPT_mtocdata)) + addTocDataOptions(Args, CC1Args, getDriver()); + if (Args.hasFlag(options::OPT_fxl_pragma_pack, options::OPT_fno_xl_pragma_pack, true)) CC1Args.push_back("-fxl-pragma-pack"); diff --git a/clang/lib/Driver/ToolChains/Arch/AArch64.cpp b/clang/lib/Driver/ToolChains/Arch/AArch64.cpp index aa3b80cb16e55ab3496dbc1da27b33a480398a42..3e6e29584df3ac719a340293419fb2c0a11e6fb5 100644 --- a/clang/lib/Driver/ToolChains/Arch/AArch64.cpp +++ b/clang/lib/Driver/ToolChains/Arch/AArch64.cpp @@ -321,9 +321,11 @@ void aarch64::getAArch64TargetFeatures(const Driver &D, } } - if (Arg *A = Args.getLastArg(options::OPT_mno_unaligned_access, - options::OPT_munaligned_access)) { - if (A->getOption().matches(options::OPT_mno_unaligned_access)) + if (Arg *A = Args.getLastArg( + options::OPT_mstrict_align, options::OPT_mno_strict_align, + options::OPT_mno_unaligned_access, options::OPT_munaligned_access)) { + if (A->getOption().matches(options::OPT_mstrict_align) || + A->getOption().matches(options::OPT_mno_unaligned_access)) Features.push_back("+strict-align"); } else if (Triple.isOSOpenBSD()) Features.push_back("+strict-align"); diff --git a/clang/lib/Driver/ToolChains/Arch/ARM.cpp b/clang/lib/Driver/ToolChains/Arch/ARM.cpp index ba158b92bb44bacee3566072c00ca3773fedf0d6..a68368c4758651ab9fb60863df294b63285d5582 100644 --- a/clang/lib/Driver/ToolChains/Arch/ARM.cpp +++ b/clang/lib/Driver/ToolChains/Arch/ARM.cpp @@ -868,12 +868,16 @@ fp16_fml_fallthrough: } } - // Kernel code has more strict alignment requirements. - if (KernelOrKext) { - Features.push_back("+strict-align"); - } else if (Arg *A = Args.getLastArg(options::OPT_mno_unaligned_access, - options::OPT_munaligned_access)) { - if (A->getOption().matches(options::OPT_munaligned_access)) { + if (Arg *A = Args.getLastArg(options::OPT_mno_unaligned_access, + options::OPT_munaligned_access, + options::OPT_mstrict_align, + options::OPT_mno_strict_align)) { + // Kernel code has more strict alignment requirements. + if (KernelOrKext || + A->getOption().matches(options::OPT_mno_unaligned_access) || + A->getOption().matches(options::OPT_mstrict_align)) { + Features.push_back("+strict-align"); + } else { // No v6M core supports unaligned memory access (v6M ARM ARM A3.2). if (Triple.getSubArch() == llvm::Triple::SubArchType::ARMSubArch_v6m) D.Diag(diag::err_target_unsupported_unaligned) << "v6m"; @@ -881,8 +885,7 @@ fp16_fml_fallthrough: // access either. else if (Triple.getSubArch() == llvm::Triple::SubArchType::ARMSubArch_v8m_baseline) D.Diag(diag::err_target_unsupported_unaligned) << "v8m.base"; - } else - Features.push_back("+strict-align"); + } } else { // Assume pre-ARMv6 doesn't support unaligned accesses. // diff --git a/clang/lib/Driver/ToolChains/Arch/LoongArch.cpp b/clang/lib/Driver/ToolChains/Arch/LoongArch.cpp index 31153a67ad284033d7a63282d093a849d8ec176a..d23f9b36efb9acf0591afe18b133de4a762260b9 100644 --- a/clang/lib/Driver/ToolChains/Arch/LoongArch.cpp +++ b/clang/lib/Driver/ToolChains/Arch/LoongArch.cpp @@ -165,10 +165,9 @@ void loongarch::getLoongArchTargetFeatures(const Driver &D, } } - // Select the `ual` feature determined by -m[no-]unaligned-access - // or the alias -m[no-]strict-align. - AddTargetFeature(Args, Features, options::OPT_munaligned_access, - options::OPT_mno_unaligned_access, "ual"); + // Select the `ual` feature determined by -m[no-]strict-align. + AddTargetFeature(Args, Features, options::OPT_mno_strict_align, + options::OPT_mstrict_align, "ual"); // Accept but warn about these TargetSpecific options. if (Arg *A = Args.getLastArgNoClaim(options::OPT_mabi_EQ)) diff --git a/clang/lib/Driver/ToolChains/Arch/RISCV.cpp b/clang/lib/Driver/ToolChains/Arch/RISCV.cpp index a46b44f9ad2b2ddc84cbcb6d1b27ad61dd8935c3..5165bccc6d7e3069d56baa5faa03e910757bedf4 100644 --- a/clang/lib/Driver/ToolChains/Arch/RISCV.cpp +++ b/clang/lib/Driver/ToolChains/Arch/RISCV.cpp @@ -167,9 +167,9 @@ void riscv::getRISCVTargetFeatures(const Driver &D, const llvm::Triple &Triple, Features.push_back("-relax"); } - // -mno-unaligned-access is default, unless -munaligned-access is specified. - AddTargetFeature(Args, Features, options::OPT_munaligned_access, - options::OPT_mno_unaligned_access, "fast-unaligned-access"); + // -mstrict-align is default, unless -mno-strict-align is specified. + AddTargetFeature(Args, Features, options::OPT_mno_strict_align, + options::OPT_mstrict_align, "fast-unaligned-access"); // Now add any that the user explicitly requested on the command line, // which may override the defaults. diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp index fa17f6295d6ea7da671a32f8b1bbaebfbfec8276..055884d275ce1b380cea91eee15237fd3a7b0acb 100644 --- a/clang/lib/Driver/ToolChains/Clang.cpp +++ b/clang/lib/Driver/ToolChains/Clang.cpp @@ -2687,8 +2687,8 @@ static void CollectArgsForIntegratedAssembler(Compilation &C, } } -static StringRef EnumComplexRangeToStr(LangOptions::ComplexRangeKind Range) { - StringRef RangeStr = ""; +static StringRef EnumComplexRangeToStr(LangOptions::ComplexRangeKind Range, + StringRef Option) { switch (Range) { case LangOptions::ComplexRangeKind::CX_Limited: return "-fcx-limited-range"; @@ -2697,17 +2697,32 @@ static StringRef EnumComplexRangeToStr(LangOptions::ComplexRangeKind Range) { return "-fcx-fortran-rules"; break; default: - return RangeStr; + return Option; break; } } static void EmitComplexRangeDiag(const Driver &D, LangOptions::ComplexRangeKind Range1, - LangOptions::ComplexRangeKind Range2) { - if (Range1 != Range2 && Range1 != LangOptions::ComplexRangeKind::CX_None) - D.Diag(clang::diag::warn_drv_overriding_option) - << EnumComplexRangeToStr(Range1) << EnumComplexRangeToStr(Range2); + LangOptions::ComplexRangeKind Range2, + StringRef Option = StringRef()) { + if (Range1 != Range2 && Range1 != LangOptions::ComplexRangeKind::CX_None) { + bool NegateFortranOption = false; + bool NegateLimitedOption = false; + if (!Option.empty()) { + NegateFortranOption = + Range1 == LangOptions::ComplexRangeKind::CX_Fortran && + Option == "-fno-cx-fortran-rules"; + NegateLimitedOption = + Range1 == LangOptions::ComplexRangeKind::CX_Limited && + Option == "-fno-cx-limited-range"; + } + if (Option.empty() || + (!Option.empty() && !NegateFortranOption && !NegateLimitedOption)) + D.Diag(clang::diag::warn_drv_overriding_option) + << EnumComplexRangeToStr(Range1, Option) + << EnumComplexRangeToStr(Range2, Option); + } } static std::string @@ -2815,7 +2830,8 @@ static void RenderFloatingPointOptions(const ToolChain &TC, const Driver &D, break; } case options::OPT_fno_cx_limited_range: - EmitComplexRangeDiag(D, Range, LangOptions::ComplexRangeKind::CX_Full); + EmitComplexRangeDiag(D, Range, LangOptions::ComplexRangeKind::CX_Full, + "-fno-cx-limited-range"); Range = LangOptions::ComplexRangeKind::CX_Full; break; case options::OPT_fcx_fortran_rules: { @@ -2824,7 +2840,8 @@ static void RenderFloatingPointOptions(const ToolChain &TC, const Driver &D, break; } case options::OPT_fno_cx_fortran_rules: - EmitComplexRangeDiag(D, Range, LangOptions::ComplexRangeKind::CX_Full); + EmitComplexRangeDiag(D, Range, LangOptions::ComplexRangeKind::CX_Full, + "-fno-cx-fortran-rules"); Range = LangOptions::ComplexRangeKind::CX_Full; break; case options::OPT_ffp_model_EQ: { @@ -6982,6 +6999,11 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, (!IsWindowsMSVC || IsMSVC2015Compatible))) CmdArgs.push_back("-fno-threadsafe-statics"); + // Add -fno-assumptions, if it was specified. + if (!Args.hasFlag(options::OPT_fassumptions, options::OPT_fno_assumptions, + true)) + CmdArgs.push_back("-fno-assumptions"); + // -fgnu-keywords default varies depending on language; only pass if // specified. Args.AddLastArg(CmdArgs, options::OPT_fgnu_keywords, @@ -7177,6 +7199,10 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, // -fno-common is the default, set -fcommon only when that flag is set. Args.addOptInFlag(CmdArgs, options::OPT_fcommon, options::OPT_fno_common); + if (Args.hasFlag(options::OPT_fptrauth_intrinsics, + options::OPT_fno_ptrauth_intrinsics, false)) + CmdArgs.push_back("-fptrauth-intrinsics"); + // -fsigned-bitfields is default, and clang doesn't yet support // -funsigned-bitfields. if (!Args.hasFlag(options::OPT_fsigned_bitfields, @@ -8524,7 +8550,6 @@ void ClangAs::ConstructJob(Compilation &C, const JobAction &JA, } // Begin OffloadBundler - void OffloadBundler::ConstructJob(Compilation &C, const JobAction &JA, const InputInfo &Output, const InputInfoList &Inputs, @@ -8622,11 +8647,7 @@ void OffloadBundler::ConstructJob(Compilation &C, const JobAction &JA, } CmdArgs.push_back(TCArgs.MakeArgString(UB)); } - if (TCArgs.hasFlag(options::OPT_offload_compress, - options::OPT_no_offload_compress, false)) - CmdArgs.push_back("-compress"); - if (TCArgs.hasArg(options::OPT_v)) - CmdArgs.push_back("-verbose"); + addOffloadCompressArgs(TCArgs, CmdArgs); // All the inputs are encoded as commands. C.addCommand(std::make_unique( JA, *this, ResponseFileSupport::None(), @@ -8895,9 +8916,7 @@ void LinkerWrapper::ConstructJob(Compilation &C, const JobAction &JA, for (const char *LinkArg : LinkCommand->getArguments()) CmdArgs.push_back(LinkArg); - if (Args.hasFlag(options::OPT_offload_compress, - options::OPT_no_offload_compress, false)) - CmdArgs.push_back("--compress"); + addOffloadCompressArgs(Args, CmdArgs); const char *Exec = Args.MakeArgString(getToolChain().GetProgramPath("clang-linker-wrapper")); diff --git a/clang/lib/Driver/ToolChains/CommonArgs.cpp b/clang/lib/Driver/ToolChains/CommonArgs.cpp index 7f0f78b41e79ed358922b2bcc68ccefe58ad066f..83015b0cb81a6ef3e940974e89f1398f1db314c6 100644 --- a/clang/lib/Driver/ToolChains/CommonArgs.cpp +++ b/clang/lib/Driver/ToolChains/CommonArgs.cpp @@ -740,7 +740,8 @@ bool tools::isTLSDESCEnabled(const ToolChain &TC, SupportedArgument = V == "desc" || V == "trad"; EnableTLSDESC = V == "desc"; } else if (Triple.isX86()) { - SupportedArgument = V == "gnu"; + SupportedArgument = V == "gnu" || V == "gnu2"; + EnableTLSDESC = V == "gnu2"; } else { Unsupported = true; } @@ -2863,3 +2864,15 @@ void tools::addOutlineAtomicsArgs(const Driver &D, const ToolChain &TC, CmdArgs.push_back("+outline-atomics"); } } + +void tools::addOffloadCompressArgs(const llvm::opt::ArgList &TCArgs, + llvm::opt::ArgStringList &CmdArgs) { + if (TCArgs.hasFlag(options::OPT_offload_compress, + options::OPT_no_offload_compress, false)) + CmdArgs.push_back("-compress"); + if (TCArgs.hasArg(options::OPT_v)) + CmdArgs.push_back("-verbose"); + if (auto *Arg = TCArgs.getLastArg(options::OPT_offload_compression_level_EQ)) + CmdArgs.push_back( + TCArgs.MakeArgString(Twine("-compression-level=") + Arg->getValue())); +} diff --git a/clang/lib/Driver/ToolChains/CommonArgs.h b/clang/lib/Driver/ToolChains/CommonArgs.h index b8f649aab4bdd2124984eca2531c1eade995e9b1..bb37be4bd6ea05f04d08f3abad37ec256a59850f 100644 --- a/clang/lib/Driver/ToolChains/CommonArgs.h +++ b/clang/lib/Driver/ToolChains/CommonArgs.h @@ -221,6 +221,8 @@ void addOutlineAtomicsArgs(const Driver &D, const ToolChain &TC, const llvm::opt::ArgList &Args, llvm::opt::ArgStringList &CmdArgs, const llvm::Triple &Triple); +void addOffloadCompressArgs(const llvm::opt::ArgList &TCArgs, + llvm::opt::ArgStringList &CmdArgs); } // end namespace tools } // end namespace driver diff --git a/clang/lib/Driver/ToolChains/Cuda.cpp b/clang/lib/Driver/ToolChains/Cuda.cpp index c6007d3cfab8643ec7bb1510e1fde1dc4f7967cb..5f0b516e1a1a08f0d40bec2c8f66ba42a277c1b2 100644 --- a/clang/lib/Driver/ToolChains/Cuda.cpp +++ b/clang/lib/Driver/ToolChains/Cuda.cpp @@ -750,10 +750,12 @@ NVPTXToolChain::TranslateArgs(const llvm::opt::DerivedArgList &Args, if (!llvm::is_contained(*DAL, A)) DAL->append(A); - // TODO: We should accept 'generic' as a valid architecture. if (!DAL->hasArg(options::OPT_march_EQ) && OffloadKind != Action::OFK_None) { DAL->AddJoinedArg(nullptr, Opts.getOption(options::OPT_march_EQ), CudaArchToString(CudaArch::CudaDefault)); + } else if (DAL->getLastArgValue(options::OPT_march_EQ) == "generic" && + OffloadKind == Action::OFK_None) { + DAL->eraseArg(options::OPT_march_EQ); } else if (DAL->getLastArgValue(options::OPT_march_EQ) == "native") { auto GPUsOrErr = getSystemGPUArchs(Args); if (!GPUsOrErr) { diff --git a/clang/lib/Driver/ToolChains/HIPUtility.cpp b/clang/lib/Driver/ToolChains/HIPUtility.cpp index fcecf2e1313bb5e106dac7f2780e678c47284d17..08c647dfcb6f728f52ff9f2e4dcb662c0860ad0b 100644 --- a/clang/lib/Driver/ToolChains/HIPUtility.cpp +++ b/clang/lib/Driver/ToolChains/HIPUtility.cpp @@ -7,6 +7,7 @@ //===----------------------------------------------------------------------===// #include "HIPUtility.h" +#include "Clang.h" #include "CommonArgs.h" #include "clang/Driver/Compilation.h" #include "clang/Driver/Options.h" @@ -258,11 +259,7 @@ void HIP::constructHIPFatbinCommand(Compilation &C, const JobAction &JA, Args.MakeArgString(std::string("-output=").append(Output)); BundlerArgs.push_back(BundlerOutputArg); - if (Args.hasFlag(options::OPT_offload_compress, - options::OPT_no_offload_compress, false)) - BundlerArgs.push_back("-compress"); - if (Args.hasArg(options::OPT_v)) - BundlerArgs.push_back("-verbose"); + addOffloadCompressArgs(Args, BundlerArgs); const char *Bundler = Args.MakeArgString( T.getToolChain().GetProgramPath("clang-offload-bundler")); diff --git a/clang/lib/Driver/ToolChains/HLSL.cpp b/clang/lib/Driver/ToolChains/HLSL.cpp index c6ad862b229420b79a852660104d74bf0fe7c349..05aac9caa7fb296f893318e2f59d9706ab151f6d 100644 --- a/clang/lib/Driver/ToolChains/HLSL.cpp +++ b/clang/lib/Driver/ToolChains/HLSL.cpp @@ -226,6 +226,21 @@ HLSLToolChain::TranslateArgs(const DerivedArgList &Args, StringRef BoundArch, A->claim(); continue; } + if (A->getOption().getID() == options::OPT_dxc_hlsl_version) { + // Translate -HV into -std for llvm + // depending on the value given + LangStandard::Kind LangStd = LangStandard::getHLSLLangKind(A->getValue()); + if (LangStd != LangStandard::lang_unspecified) { + LangStandard l = LangStandard::getLangStandardForKind(LangStd); + DAL->AddSeparateArg(nullptr, Opts.getOption(options::OPT_std_EQ), + l.getName()); + } else { + getDriver().Diag(diag::err_drv_invalid_value) << "HV" << A->getValue(); + } + + A->claim(); + continue; + } DAL->append(A); } diff --git a/clang/lib/Format/.clang-format b/clang/lib/Format/.clang-format index f95602cab0f7fcdf5d34c485d52b65993dbb83d9..d7331b3c8cf02ef7944e83a4280476627e33b31d 100644 --- a/clang/lib/Format/.clang-format +++ b/clang/lib/Format/.clang-format @@ -1,6 +1 @@ -BasedOnStyle: LLVM -InsertBraces: true -InsertNewlineAtEOF: true -LineEnding: LF -RemoveBracesLLVM: true -RemoveParentheses: ReturnStatement +BasedOnStyle: clang-format diff --git a/clang/lib/Format/AffectedRangeManager.cpp b/clang/lib/Format/AffectedRangeManager.cpp index bf124d73e89e71a7d369049a9ccd1ac97c674a06..ae08965714b1b760335fd6b4a593a945bf0aaddf 100644 --- a/clang/lib/Format/AffectedRangeManager.cpp +++ b/clang/lib/Format/AffectedRangeManager.cpp @@ -13,7 +13,6 @@ #include "AffectedRangeManager.h" -#include "FormatToken.h" #include "TokenAnnotator.h" namespace clang { diff --git a/clang/lib/Format/BreakableToken.cpp b/clang/lib/Format/BreakableToken.cpp index 75304908dc65066b2017327f71544f99350819bf..c33b74eeb80b4aa139385149e88df41262bdc3dd 100644 --- a/clang/lib/Format/BreakableToken.cpp +++ b/clang/lib/Format/BreakableToken.cpp @@ -15,10 +15,6 @@ #include "BreakableToken.h" #include "ContinuationIndenter.h" #include "clang/Basic/CharInfo.h" -#include "clang/Format/Format.h" -#include "llvm/ADT/STLExtras.h" -#include "llvm/Support/Debug.h" -#include #define DEBUG_TYPE "format-token-breaker" diff --git a/clang/lib/Format/BreakableToken.h b/clang/lib/Format/BreakableToken.h index e7c0680641e294e940332887e5e1e9fe370e1916..8b9360a3335ef41965d5448793a358417d85f4df 100644 --- a/clang/lib/Format/BreakableToken.h +++ b/clang/lib/Format/BreakableToken.h @@ -18,11 +18,8 @@ #define LLVM_CLANG_LIB_FORMAT_BREAKABLETOKEN_H #include "Encoding.h" -#include "TokenAnnotator.h" #include "WhitespaceManager.h" #include "llvm/ADT/StringSet.h" -#include "llvm/Support/Regex.h" -#include namespace clang { namespace format { diff --git a/clang/lib/Format/ContinuationIndenter.cpp b/clang/lib/Format/ContinuationIndenter.cpp index df44e6994c478440f183ab06b366ec439f2a43f7..b3de317f16336c68e3633184a01dd25bfe0a42f4 100644 --- a/clang/lib/Format/ContinuationIndenter.cpp +++ b/clang/lib/Format/ContinuationIndenter.cpp @@ -14,15 +14,6 @@ #include "ContinuationIndenter.h" #include "BreakableToken.h" #include "FormatInternal.h" -#include "FormatToken.h" -#include "WhitespaceManager.h" -#include "clang/Basic/OperatorPrecedence.h" -#include "clang/Basic/SourceManager.h" -#include "clang/Basic/TokenKinds.h" -#include "clang/Format/Format.h" -#include "llvm/ADT/StringSet.h" -#include "llvm/Support/Debug.h" -#include #define DEBUG_TYPE "format-indenter" @@ -241,7 +232,9 @@ ContinuationIndenter::ContinuationIndenter(const FormatStyle &Style, : Style(Style), Keywords(Keywords), SourceMgr(SourceMgr), Whitespaces(Whitespaces), Encoding(Encoding), BinPackInconclusiveFunctions(BinPackInconclusiveFunctions), - CommentPragmasRegex(Style.CommentPragmas), RawStringFormats(Style) {} + CommentPragmasRegex(Style.CommentPragmas), RawStringFormats(Style) { + assert(IsCpp == Style.isCpp()); +} LineState ContinuationIndenter::getInitialState(unsigned FirstIndent, unsigned FirstStartColumn, @@ -406,7 +399,7 @@ bool ContinuationIndenter::mustBreak(const LineState &State) { } if ((startsNextParameter(Current, Style) || Previous.is(tok::semi) || (Previous.is(TT_TemplateCloser) && Current.is(TT_StartOfName) && - State.Line->First->isNot(TT_AttributeSquare) && Style.isCpp() && + State.Line->First->isNot(TT_AttributeSquare) && IsCpp && // FIXME: This is a temporary workaround for the case where clang-format // sets BreakBeforeParameter to avoid bin packing and this creates a // completely unnecessary line break after a template type that isn't @@ -677,8 +670,8 @@ void ContinuationIndenter::addTokenOnCurrentLine(LineState &State, bool DryRun, auto &CurrentState = State.Stack.back(); bool DisallowLineBreaksOnThisLine = - Style.LambdaBodyIndentation == FormatStyle::LBI_Signature && - Style.isCpp() && [&Current] { + Style.LambdaBodyIndentation == FormatStyle::LBI_Signature && IsCpp && + [&Current] { // Deal with lambda arguments in C++. The aim here is to ensure that we // don't over-indent lambda function bodies when lambdas are passed as // arguments to function calls. We do this by ensuring that either all @@ -822,6 +815,7 @@ void ContinuationIndenter::addTokenOnCurrentLine(LineState &State, bool DryRun, !CurrentState.IsCSharpGenericTypeConstraint && Previous.opensScope() && Previous.isNot(TT_ObjCMethodExpr) && Previous.isNot(TT_RequiresClause) && Previous.isNot(TT_TableGenDAGArgOpener) && + Previous.isNot(TT_TableGenDAGArgOpenerToBreak) && !(Current.MacroParent && Previous.MacroParent) && (Current.isNot(TT_LineComment) || Previous.isOneOf(BK_BracedInit, TT_VerilogMultiLineListLParen))) { @@ -1091,7 +1085,7 @@ unsigned ContinuationIndenter::addTokenOnNewLine(LineState &State, // Any break on this level means that the parent level has been broken // and we need to avoid bin packing there. bool NestedBlockSpecialCase = - (!Style.isCpp() && Current.is(tok::r_brace) && State.Stack.size() > 1 && + (!IsCpp && Current.is(tok::r_brace) && State.Stack.size() > 1 && State.Stack[State.Stack.size() - 2].NestedBlockInlined) || (Style.Language == FormatStyle::LK_ObjC && Current.is(tok::r_brace) && State.Stack.size() > 1 && !Style.ObjCBreakBeforeNestedBlockParam); @@ -1444,7 +1438,9 @@ unsigned ContinuationIndenter::getNewLineColumn(const LineState &State) { Style.BreakInheritanceList == FormatStyle::BILS_AfterColon) { return CurrentState.Indent; } - if (Previous.is(tok::r_paren) && !Current.isBinaryOperator() && + if (Previous.is(tok::r_paren) && + Previous.isNot(TT_TableGenDAGArgOperatorToBreak) && + !Current.isBinaryOperator() && !Current.isOneOf(tok::colon, tok::comment)) { return ContinuationIndent; } @@ -1705,7 +1701,8 @@ void ContinuationIndenter::moveStatePastFakeLParens(LineState &State, (Style.AlignAfterOpenBracket != FormatStyle::BAS_DontAlign || PrecedenceLevel != prec::Comma || Current.NestingLevel == 0) && (!Style.isTableGen() || - (Previous && Previous->is(TT_TableGenDAGArgListComma)))) { + (Previous && Previous->isOneOf(TT_TableGenDAGArgListComma, + TT_TableGenDAGArgListCommaToBreak)))) { NewParenState.Indent = std::max( std::max(State.Column, NewParenState.Indent), CurrentState.LastSpace); } @@ -1842,6 +1839,17 @@ void ContinuationIndenter::moveStatePastScopeOpener(LineState &State, Style.ContinuationIndentWidth + std::max(CurrentState.LastSpace, CurrentState.StartOfFunctionCall); + if (Style.isTableGen() && Current.is(TT_TableGenDAGArgOpenerToBreak) && + Style.TableGenBreakInsideDAGArg == FormatStyle::DAS_BreakElements) { + // For the case the next token is a TableGen DAGArg operator identifier + // that is not marked to have a line break after it. + // In this case the option DAS_BreakElements requires to align the + // DAGArg elements to the operator. + const FormatToken *Next = Current.Next; + if (Next && Next->is(TT_TableGenDAGArgOperatorID)) + NewIndent = State.Column + Next->TokenText.size() + 2; + } + // Ensure that different different brackets force relative alignment, e.g.: // void SomeFunction(vector< // break // int> v); diff --git a/clang/lib/Format/ContinuationIndenter.h b/clang/lib/Format/ContinuationIndenter.h index 2598947bb624c52b5bbb78a1c6946212004fd10c..18441e10a124924c111e7bb68954e6c12ffc4f9b 100644 --- a/clang/lib/Format/ContinuationIndenter.h +++ b/clang/lib/Format/ContinuationIndenter.h @@ -17,11 +17,6 @@ #include "Encoding.h" #include "FormatToken.h" -#include "clang/Format/Format.h" -#include "llvm/Support/Regex.h" -#include -#include -#include namespace clang { class SourceManager; diff --git a/clang/lib/Format/DefinitionBlockSeparator.cpp b/clang/lib/Format/DefinitionBlockSeparator.cpp index 319236d3bd618ca2b16586c219f42ad63f5fdc26..32fc77de4407cc5083b464d310238203917aaeac 100644 --- a/clang/lib/Format/DefinitionBlockSeparator.cpp +++ b/clang/lib/Format/DefinitionBlockSeparator.cpp @@ -14,7 +14,6 @@ //===----------------------------------------------------------------------===// #include "DefinitionBlockSeparator.h" -#include "llvm/Support/Debug.h" #define DEBUG_TYPE "definition-block-separator" namespace clang { diff --git a/clang/lib/Format/Encoding.h b/clang/lib/Format/Encoding.h index a0d664121b2bba6a7fa492446696c7600aac04f9..12f9043bb95ad89106b8fc6dcc4c185833fa3641 100644 --- a/clang/lib/Format/Encoding.h +++ b/clang/lib/Format/Encoding.h @@ -16,7 +16,6 @@ #define LLVM_CLANG_LIB_FORMAT_ENCODING_H #include "clang/Basic/LLVM.h" -#include "llvm/ADT/StringRef.h" #include "llvm/Support/ConvertUTF.h" #include "llvm/Support/Unicode.h" diff --git a/clang/lib/Format/Format.cpp b/clang/lib/Format/Format.cpp index e64ba7eebc1ce81f48197a5bf3fb1b3e89c200b8..89813badc8ec20c00dff9d64ae0098eafe26c855 100644 --- a/clang/lib/Format/Format.cpp +++ b/clang/lib/Format/Format.cpp @@ -13,44 +13,16 @@ //===----------------------------------------------------------------------===// #include "clang/Format/Format.h" -#include "AffectedRangeManager.h" -#include "BreakableToken.h" -#include "ContinuationIndenter.h" #include "DefinitionBlockSeparator.h" -#include "FormatInternal.h" -#include "FormatToken.h" -#include "FormatTokenLexer.h" #include "IntegerLiteralSeparatorFixer.h" #include "NamespaceEndCommentsFixer.h" #include "ObjCPropertyAttributeOrderFixer.h" #include "QualifierAlignmentFixer.h" #include "SortJavaScriptImports.h" -#include "TokenAnalyzer.h" -#include "TokenAnnotator.h" #include "UnwrappedLineFormatter.h" -#include "UnwrappedLineParser.h" #include "UsingDeclarationsSorter.h" -#include "WhitespaceManager.h" -#include "clang/Basic/Diagnostic.h" -#include "clang/Basic/DiagnosticOptions.h" -#include "clang/Basic/SourceManager.h" -#include "clang/Lex/Lexer.h" #include "clang/Tooling/Inclusions/HeaderIncludes.h" -#include "llvm/ADT/STLExtras.h" #include "llvm/ADT/Sequence.h" -#include "llvm/ADT/StringRef.h" -#include "llvm/Support/Allocator.h" -#include "llvm/Support/Debug.h" -#include "llvm/Support/Path.h" -#include "llvm/Support/Regex.h" -#include "llvm/Support/VirtualFileSystem.h" -#include "llvm/Support/YAMLTraits.h" -#include -#include -#include -#include -#include -#include #define DEBUG_TYPE "format-formatter" @@ -307,6 +279,14 @@ struct ScalarEnumerationTraits { } }; +template <> struct ScalarEnumerationTraits { + static void enumeration(IO &IO, FormatStyle::DAGArgStyle &Value) { + IO.enumCase(Value, "DontBreak", FormatStyle::DAS_DontBreak); + IO.enumCase(Value, "BreakElements", FormatStyle::DAS_BreakElements); + IO.enumCase(Value, "BreakAll", FormatStyle::DAS_BreakAll); + } +}; + template <> struct ScalarEnumerationTraits { static void @@ -1120,6 +1100,10 @@ template <> struct MappingTraits { IO.mapOptional("StatementAttributeLikeMacros", Style.StatementAttributeLikeMacros); IO.mapOptional("StatementMacros", Style.StatementMacros); + IO.mapOptional("TableGenBreakingDAGArgOperators", + Style.TableGenBreakingDAGArgOperators); + IO.mapOptional("TableGenBreakInsideDAGArg", + Style.TableGenBreakInsideDAGArg); IO.mapOptional("TabWidth", Style.TabWidth); IO.mapOptional("TypeNames", Style.TypeNames); IO.mapOptional("TypenameMacros", Style.TypenameMacros); @@ -1580,6 +1564,8 @@ FormatStyle getLLVMStyle(FormatStyle::LanguageKind Language) { LLVMStyle.StatementAttributeLikeMacros.push_back("Q_EMIT"); LLVMStyle.StatementMacros.push_back("Q_UNUSED"); LLVMStyle.StatementMacros.push_back("QT_REQUIRE_VERSION"); + LLVMStyle.TableGenBreakingDAGArgOperators = {}; + LLVMStyle.TableGenBreakInsideDAGArg = FormatStyle::DAS_DontBreak; LLVMStyle.TabWidth = 8; LLVMStyle.UseTab = FormatStyle::UT_Never; LLVMStyle.VerilogBreakBetweenInstancePorts = true; @@ -3841,13 +3827,15 @@ tooling::Replacements sortUsingDeclarations(const FormatStyle &Style, } LangOptions getFormattingLangOpts(const FormatStyle &Style) { - LangOptions LangOpts; + IsCpp = Style.isCpp(); FormatStyle::LanguageStandard LexingStd = Style.Standard; if (LexingStd == FormatStyle::LS_Auto) LexingStd = FormatStyle::LS_Latest; if (LexingStd == FormatStyle::LS_Latest) LexingStd = FormatStyle::LS_Cpp20; + + LangOptions LangOpts; LangOpts.CPlusPlus = 1; LangOpts.CPlusPlus11 = LexingStd >= FormatStyle::LS_Cpp11; LangOpts.CPlusPlus14 = LexingStd >= FormatStyle::LS_Cpp14; @@ -3858,10 +3846,8 @@ LangOptions getFormattingLangOpts(const FormatStyle &Style) { // the sequence "<::" will be unconditionally treated as "[:". // Cf. Lexer::LexTokenInternal. LangOpts.Digraphs = LexingStd >= FormatStyle::LS_Cpp11; - LangOpts.LineComment = 1; - bool AlternativeOperators = Style.isCpp(); - LangOpts.CXXOperatorNames = AlternativeOperators ? 1 : 0; + LangOpts.CXXOperatorNames = IsCpp; LangOpts.Bool = 1; LangOpts.ObjC = 1; LangOpts.MicrosoftExt = 1; // To get kw___try, kw___finally. diff --git a/clang/lib/Format/FormatInternal.h b/clang/lib/Format/FormatInternal.h index 9043ce32e9e32aa157ee90acd691a5138d71bc25..60c5bf6b786b04f49238fd43ec15771a73d871a7 100644 --- a/clang/lib/Format/FormatInternal.h +++ b/clang/lib/Format/FormatInternal.h @@ -15,7 +15,9 @@ #ifndef LLVM_CLANG_LIB_FORMAT_FORMATINTERNAL_H #define LLVM_CLANG_LIB_FORMAT_FORMATINTERNAL_H -#include "BreakableToken.h" +#include "clang/Basic/LLVM.h" +#include "clang/Format/Format.h" +#include "clang/Tooling/Core/Replacement.h" #include namespace clang { diff --git a/clang/lib/Format/FormatToken.cpp b/clang/lib/Format/FormatToken.cpp index 56a7b2d63877652a89330ce72e090d1cad64a325..cd94a9df6cff79ebb46917711ca00139d4056af9 100644 --- a/clang/lib/Format/FormatToken.cpp +++ b/clang/lib/Format/FormatToken.cpp @@ -14,13 +14,12 @@ #include "FormatToken.h" #include "ContinuationIndenter.h" -#include "llvm/ADT/SmallVector.h" -#include "llvm/Support/Debug.h" -#include namespace clang { namespace format { +bool IsCpp = false; + const char *getTokenTypeName(TokenType Type) { static const char *const TokNames[] = { #define TYPE(X) #X, @@ -71,8 +70,22 @@ bool FormatToken::isSimpleTypeSpecifier() const { } } +// Sorted common C++ non-keyword types. +static SmallVector CppNonKeywordTypes = { + "clock_t", "int16_t", "int32_t", "int64_t", "int8_t", + "intptr_t", "ptrdiff_t", "size_t", "time_t", "uint16_t", + "uint32_t", "uint64_t", "uint8_t", "uintptr_t", +}; + +bool FormatToken::isTypeName() const { + return is(TT_TypeName) || isSimpleTypeSpecifier() || + (IsCpp && is(tok::identifier) && + std::binary_search(CppNonKeywordTypes.begin(), + CppNonKeywordTypes.end(), TokenText)); +} + bool FormatToken::isTypeOrIdentifier() const { - return isSimpleTypeSpecifier() || Tok.isOneOf(tok::kw_auto, tok::identifier); + return isTypeName() || isOneOf(tok::kw_auto, tok::identifier); } bool FormatToken::isBlockIndentedInitRBrace(const FormatStyle &Style) const { diff --git a/clang/lib/Format/FormatToken.h b/clang/lib/Format/FormatToken.h index 312454950419600b15775f4c703c262fab148126..a141db3d41d7b9b8c9cbec53e5f4c499809b511d 100644 --- a/clang/lib/Format/FormatToken.h +++ b/clang/lib/Format/FormatToken.h @@ -19,13 +19,14 @@ #include "clang/Basic/OperatorPrecedence.h" #include "clang/Format/Format.h" #include "clang/Lex/Lexer.h" -#include -#include #include namespace clang { namespace format { +/// Whether the language is C/C++/Objective-C/Objective-C++. +extern bool IsCpp; + #define LIST_TOKEN_TYPES \ TYPE(ArrayInitializerLSquare) \ TYPE(ArraySubscriptLSquare) \ @@ -155,7 +156,11 @@ namespace format { TYPE(TableGenDAGArgCloser) \ TYPE(TableGenDAGArgListColon) \ TYPE(TableGenDAGArgListComma) \ + TYPE(TableGenDAGArgListCommaToBreak) \ TYPE(TableGenDAGArgOpener) \ + TYPE(TableGenDAGArgOpenerToBreak) \ + TYPE(TableGenDAGArgOperatorID) \ + TYPE(TableGenDAGArgOperatorToBreak) \ TYPE(TableGenListCloser) \ TYPE(TableGenListOpener) \ TYPE(TableGenMultiLineString) \ @@ -676,6 +681,8 @@ public: /// Determine whether the token is a simple-type-specifier. [[nodiscard]] bool isSimpleTypeSpecifier() const; + [[nodiscard]] bool isTypeName() const; + [[nodiscard]] bool isTypeOrIdentifier() const; bool isObjCAccessSpecifier() const { @@ -821,7 +828,7 @@ public: /// Returns whether the token is the left square bracket of a C++ /// structured binding declaration. - bool isCppStructuredBinding(bool IsCpp) const { + bool isCppStructuredBinding() const { if (!IsCpp || isNot(tok::l_square)) return false; const FormatToken *T = this; diff --git a/clang/lib/Format/FormatTokenLexer.cpp b/clang/lib/Format/FormatTokenLexer.cpp index 036f7e6a4efc1ea9f12689b6accaec700d527595..a1c8df80e6a9f55ba1350a3555bd0e09640360ac 100644 --- a/clang/lib/Format/FormatTokenLexer.cpp +++ b/clang/lib/Format/FormatTokenLexer.cpp @@ -13,11 +13,7 @@ //===----------------------------------------------------------------------===// #include "FormatTokenLexer.h" -#include "FormatToken.h" -#include "clang/Basic/SourceLocation.h" #include "clang/Basic/SourceManager.h" -#include "clang/Format/Format.h" -#include "llvm/Support/Regex.h" namespace clang { namespace format { @@ -34,6 +30,7 @@ FormatTokenLexer::FormatTokenLexer( Encoding(Encoding), Allocator(Allocator), FirstInLineIndex(0), FormattingDisabled(false), MacroBlockBeginRegex(Style.MacroBlockBegin), MacroBlockEndRegex(Style.MacroBlockEnd) { + assert(IsCpp == Style.isCpp()); Lex.reset(new Lexer(ID, SourceMgr.getBufferOrFake(ID), SourceMgr, LangOpts)); Lex->SetKeepWhitespaceMode(true); @@ -114,7 +111,7 @@ void FormatTokenLexer::tryMergePreviousTokens() { return; if (tryMergeForEach()) return; - if (Style.isCpp() && tryTransformTryUsageForC()) + if (IsCpp && tryTransformTryUsageForC()) return; if (Style.isJavaScript() || Style.isCSharp()) { @@ -1341,7 +1338,7 @@ FormatToken *FormatTokenLexer::getNextToken() { Column = FormatTok->LastLineColumnWidth; } - if (Style.isCpp()) { + if (IsCpp) { auto *Identifier = FormatTok->Tok.getIdentifierInfo(); auto it = Macros.find(Identifier); if (!(Tokens.size() > 0 && Tokens.back()->Tok.getIdentifierInfo() && diff --git a/clang/lib/Format/FormatTokenLexer.h b/clang/lib/Format/FormatTokenLexer.h index 65dd733bd53352a4b1be96b360090fde180fba50..277cc0a2dfde6663e84fe6d14716db98f8d874fd 100644 --- a/clang/lib/Format/FormatTokenLexer.h +++ b/clang/lib/Format/FormatTokenLexer.h @@ -17,14 +17,9 @@ #include "Encoding.h" #include "FormatToken.h" -#include "clang/Basic/LangOptions.h" -#include "clang/Basic/SourceLocation.h" -#include "clang/Basic/SourceManager.h" -#include "clang/Format/Format.h" #include "llvm/ADT/MapVector.h" #include "llvm/ADT/SmallPtrSet.h" #include "llvm/ADT/StringSet.h" -#include "llvm/Support/Regex.h" #include diff --git a/clang/lib/Format/FormatTokenSource.h b/clang/lib/Format/FormatTokenSource.h index 7819244eb7d19a489e11556c1253cbc5c9f297e1..cce19f527a9236df8dc8df12cdcfbe09cf87bd6e 100644 --- a/clang/lib/Format/FormatTokenSource.h +++ b/clang/lib/Format/FormatTokenSource.h @@ -15,10 +15,7 @@ #ifndef LLVM_CLANG_LIB_FORMAT_FORMATTOKENSOURCE_H #define LLVM_CLANG_LIB_FORMAT_FORMATTOKENSOURCE_H -#include "FormatToken.h" #include "UnwrappedLineParser.h" -#include "llvm/ADT/DenseMap.h" -#include #define DEBUG_TYPE "format-token-source" diff --git a/clang/lib/Format/MacroCallReconstructor.cpp b/clang/lib/Format/MacroCallReconstructor.cpp index 101acefdfe7a31525336d13db76d992aba43e4fb..5ba4f2c99a6afa287ad45b2e2ba113ca4671c296 100644 --- a/clang/lib/Format/MacroCallReconstructor.cpp +++ b/clang/lib/Format/MacroCallReconstructor.cpp @@ -16,10 +16,7 @@ #include "Macros.h" #include "UnwrappedLineParser.h" -#include "clang/Basic/TokenKinds.h" #include "llvm/ADT/DenseSet.h" -#include "llvm/Support/Debug.h" -#include #define DEBUG_TYPE "format-reconstruct" diff --git a/clang/lib/Format/MacroExpander.cpp b/clang/lib/Format/MacroExpander.cpp index 5a1cdd884c5e69b9eb04d3109a44ee289085e304..7668765764e8d7973f5eafb33e83bf2d8e8f3365 100644 --- a/clang/lib/Format/MacroExpander.cpp +++ b/clang/lib/Format/MacroExpander.cpp @@ -14,19 +14,8 @@ #include "Macros.h" -#include "Encoding.h" -#include "FormatToken.h" #include "FormatTokenLexer.h" -#include "clang/Basic/TokenKinds.h" -#include "clang/Format/Format.h" -#include "clang/Lex/HeaderSearch.h" -#include "clang/Lex/HeaderSearchOptions.h" -#include "clang/Lex/Lexer.h" -#include "clang/Lex/ModuleLoader.h" #include "clang/Lex/Preprocessor.h" -#include "clang/Lex/PreprocessorOptions.h" -#include "llvm/ADT/StringSet.h" -#include "llvm/Support/ErrorHandling.h" namespace clang { namespace format { diff --git a/clang/lib/Format/Macros.h b/clang/lib/Format/Macros.h index d2f7fe502364cd5550756ea1292f8d17affeba25..fb12d22299dead2a8037595a3d351f7773bea59d 100644 --- a/clang/lib/Format/Macros.h +++ b/clang/lib/Format/Macros.h @@ -39,15 +39,9 @@ #define CLANG_LIB_FORMAT_MACROS_H #include -#include -#include -#include #include "FormatToken.h" -#include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/DenseMap.h" -#include "llvm/ADT/SmallVector.h" -#include "llvm/ADT/StringRef.h" namespace clang { namespace format { diff --git a/clang/lib/Format/NamespaceEndCommentsFixer.cpp b/clang/lib/Format/NamespaceEndCommentsFixer.cpp index 08f8d6840fe00a874031e7ba32ba4599ca66071d..010cc41f176836105345d181d3b6bc7022adb69e 100644 --- a/clang/lib/Format/NamespaceEndCommentsFixer.cpp +++ b/clang/lib/Format/NamespaceEndCommentsFixer.cpp @@ -13,9 +13,6 @@ //===----------------------------------------------------------------------===// #include "NamespaceEndCommentsFixer.h" -#include "clang/Basic/TokenKinds.h" -#include "llvm/Support/Debug.h" -#include "llvm/Support/Regex.h" #define DEBUG_TYPE "namespace-end-comments-fixer" diff --git a/clang/lib/Format/ObjCPropertyAttributeOrderFixer.cpp b/clang/lib/Format/ObjCPropertyAttributeOrderFixer.cpp index c91d6251425eab508c3c196c66ba77774f9fabdb..6339d346fd9c7d4cf829e92491dd4ff66a0524fe 100644 --- a/clang/lib/Format/ObjCPropertyAttributeOrderFixer.cpp +++ b/clang/lib/Format/ObjCPropertyAttributeOrderFixer.cpp @@ -15,8 +15,6 @@ #include "ObjCPropertyAttributeOrderFixer.h" -#include - namespace clang { namespace format { diff --git a/clang/lib/Format/QualifierAlignmentFixer.cpp b/clang/lib/Format/QualifierAlignmentFixer.cpp index 0c63d330b5aed47906d9e333c15b745a2fd4a6e9..32d5153fc8151ddab02f85cf62516a91817ba72e 100644 --- a/clang/lib/Format/QualifierAlignmentFixer.cpp +++ b/clang/lib/Format/QualifierAlignmentFixer.cpp @@ -13,12 +13,6 @@ //===----------------------------------------------------------------------===// #include "QualifierAlignmentFixer.h" -#include "FormatToken.h" -#include "llvm/Support/Debug.h" -#include "llvm/Support/Regex.h" - -#include -#include #define DEBUG_TYPE "format-qualifier-alignment-fixer" @@ -272,7 +266,7 @@ const FormatToken *LeftRightQualifierAlignmentFixer::analyzeRight( // The case `long const long int volatile` -> `long long int const volatile` // The case `long long volatile int const` -> `long long int const volatile` // The case `const long long volatile int` -> `long long int const volatile` - if (TypeToken->isSimpleTypeSpecifier()) { + if (TypeToken->isTypeName()) { // The case `const decltype(foo)` -> `const decltype(foo)` // The case `const typeof(foo)` -> `const typeof(foo)` // The case `const _Atomic(foo)` -> `const _Atomic(foo)` @@ -291,7 +285,7 @@ const FormatToken *LeftRightQualifierAlignmentFixer::analyzeRight( // The case `unsigned short const` -> `unsigned short const` // The case: // `unsigned short volatile const` -> `unsigned short const volatile` - if (PreviousCheck && PreviousCheck->isSimpleTypeSpecifier()) { + if (PreviousCheck && PreviousCheck->isTypeName()) { if (LastQual != Tok) rotateTokens(SourceMgr, Fixes, Tok, LastQual, /*Left=*/false); return Tok; @@ -408,7 +402,7 @@ const FormatToken *LeftRightQualifierAlignmentFixer::analyzeLeft( // The case `volatile long long const int` -> `const volatile long long int` // The case `const long long volatile int` -> `const volatile long long int` // The case `long volatile long int const` -> `const volatile long long int` - if (TypeToken->isSimpleTypeSpecifier()) { + if (TypeToken->isTypeName()) { const FormatToken *LastSimpleTypeSpecifier = TypeToken; while (isConfiguredQualifierOrType( LastSimpleTypeSpecifier->getPreviousNonComment(), @@ -527,7 +521,9 @@ LeftRightQualifierAlignmentFixer::LeftRightQualifierAlignmentFixer( const std::string &Qualifier, const std::vector &QualifierTokens, bool RightAlign) : TokenAnalyzer(Env, Style), Qualifier(Qualifier), RightAlign(RightAlign), - ConfiguredQualifierTokens(QualifierTokens) {} + ConfiguredQualifierTokens(QualifierTokens) { + IsCpp = Style.isCpp(); +} std::pair LeftRightQualifierAlignmentFixer::analyze( @@ -611,15 +607,14 @@ void prepareLeftRightOrderingForQualifierAlignmentFixer( } bool LeftRightQualifierAlignmentFixer::isQualifierOrType( - const FormatToken *const Tok) { - return Tok && (Tok->isSimpleTypeSpecifier() || Tok->is(tok::kw_auto) || - isQualifier(Tok)); + const FormatToken *Tok) { + return Tok && + (Tok->isTypeName() || Tok->is(tok::kw_auto) || isQualifier(Tok)); } bool LeftRightQualifierAlignmentFixer::isConfiguredQualifierOrType( - const FormatToken *const Tok, - const std::vector &Qualifiers) { - return Tok && (Tok->isSimpleTypeSpecifier() || Tok->is(tok::kw_auto) || + const FormatToken *Tok, const std::vector &Qualifiers) { + return Tok && (Tok->isTypeName() || Tok->is(tok::kw_auto) || isConfiguredQualifier(Tok, Qualifiers)); } diff --git a/clang/lib/Format/SortJavaScriptImports.cpp b/clang/lib/Format/SortJavaScriptImports.cpp index 1a6a1b19e7022a080460b1dfd0a0cd152673a4bf..fda2ad8c311bfb7154a41fb8c20dd5f89ccb8f50 100644 --- a/clang/lib/Format/SortJavaScriptImports.cpp +++ b/clang/lib/Format/SortJavaScriptImports.cpp @@ -13,19 +13,6 @@ #include "SortJavaScriptImports.h" #include "TokenAnalyzer.h" -#include "TokenAnnotator.h" -#include "clang/Basic/Diagnostic.h" -#include "clang/Basic/DiagnosticOptions.h" -#include "clang/Basic/LLVM.h" -#include "clang/Basic/SourceLocation.h" -#include "clang/Basic/SourceManager.h" -#include "clang/Basic/TokenKinds.h" -#include "clang/Format/Format.h" -#include "llvm/ADT/STLExtras.h" -#include "llvm/ADT/SmallVector.h" -#include "llvm/Support/Debug.h" -#include -#include #define DEBUG_TYPE "format-formatter" diff --git a/clang/lib/Format/SortJavaScriptImports.h b/clang/lib/Format/SortJavaScriptImports.h index 7336db9537b0d5512e0132fca0c81513572c6371..b55b149aab4cd25881e9b6e2209f956d19e0f47c 100644 --- a/clang/lib/Format/SortJavaScriptImports.h +++ b/clang/lib/Format/SortJavaScriptImports.h @@ -14,10 +14,7 @@ #ifndef LLVM_CLANG_LIB_FORMAT_SORTJAVASCRIPTIMPORTS_H #define LLVM_CLANG_LIB_FORMAT_SORTJAVASCRIPTIMPORTS_H -#include "clang/Basic/LLVM.h" #include "clang/Format/Format.h" -#include "llvm/ADT/ArrayRef.h" -#include "llvm/ADT/StringRef.h" namespace clang { namespace format { diff --git a/clang/lib/Format/TokenAnalyzer.cpp b/clang/lib/Format/TokenAnalyzer.cpp index bd648c430f9b0a460b9901018efaf341e02e848e..2fdc2460bf67c8af6d495a2b790ff54e3291f2ba 100644 --- a/clang/lib/Format/TokenAnalyzer.cpp +++ b/clang/lib/Format/TokenAnalyzer.cpp @@ -14,21 +14,6 @@ //===----------------------------------------------------------------------===// #include "TokenAnalyzer.h" -#include "AffectedRangeManager.h" -#include "Encoding.h" -#include "FormatToken.h" -#include "FormatTokenLexer.h" -#include "TokenAnnotator.h" -#include "UnwrappedLineParser.h" -#include "clang/Basic/Diagnostic.h" -#include "clang/Basic/DiagnosticOptions.h" -#include "clang/Basic/FileManager.h" -#include "clang/Basic/SourceManager.h" -#include "clang/Format/Format.h" -#include "llvm/ADT/STLExtras.h" -#include "llvm/ADT/SmallVector.h" -#include "llvm/Support/Debug.h" -#include #define DEBUG_TYPE "format-formatter" diff --git a/clang/lib/Format/TokenAnalyzer.h b/clang/lib/Format/TokenAnalyzer.h index 4086dab1c94c3ad6a11fba34ad271e196392829d..b7494c395c8a29b36c8654ea2b2849b8437f8033 100644 --- a/clang/lib/Format/TokenAnalyzer.h +++ b/clang/lib/Format/TokenAnalyzer.h @@ -17,19 +17,8 @@ #define LLVM_CLANG_LIB_FORMAT_TOKENANALYZER_H #include "AffectedRangeManager.h" -#include "Encoding.h" -#include "FormatToken.h" #include "FormatTokenLexer.h" #include "TokenAnnotator.h" -#include "UnwrappedLineParser.h" -#include "clang/Basic/Diagnostic.h" -#include "clang/Basic/DiagnosticOptions.h" -#include "clang/Basic/FileManager.h" -#include "clang/Basic/SourceManager.h" -#include "clang/Format/Format.h" -#include "llvm/ADT/STLExtras.h" -#include "llvm/Support/Debug.h" -#include namespace clang { namespace format { diff --git a/clang/lib/Format/TokenAnnotator.cpp b/clang/lib/Format/TokenAnnotator.cpp index 04f0374b674e53ad71e538ce4a90b2dd14a0868e..911f7cca470a32dd4b8de924cb9d8a98ebbcb7c1 100644 --- a/clang/lib/Format/TokenAnnotator.cpp +++ b/clang/lib/Format/TokenAnnotator.cpp @@ -13,11 +13,7 @@ //===----------------------------------------------------------------------===// #include "TokenAnnotator.h" -#include "FormatToken.h" -#include "clang/Basic/SourceManager.h" -#include "clang/Basic/TokenKinds.h" #include "llvm/ADT/SmallPtrSet.h" -#include "llvm/Support/Debug.h" #define DEBUG_TYPE "format-token-annotator" @@ -84,7 +80,7 @@ static bool isKeywordWithCondition(const FormatToken &Tok) { } /// Returns \c true if the token starts a C++ attribute, \c false otherwise. -static bool isCppAttribute(bool IsCpp, const FormatToken &Tok) { +static bool isCppAttribute(const FormatToken &Tok) { if (!IsCpp || !Tok.startsSequence(tok::l_square, tok::l_square)) return false; // The first square bracket is part of an ObjC array literal @@ -126,7 +122,8 @@ public: const AdditionalKeywords &Keywords, SmallVector &Scopes) : Style(Style), Line(Line), CurrentToken(Line.First), AutoFound(false), - IsCpp(Style.isCpp()), Keywords(Keywords), Scopes(Scopes) { + Keywords(Keywords), Scopes(Scopes) { + assert(IsCpp == Style.isCpp()); Contexts.push_back(Context(tok::unknown, 1, /*IsExpression=*/false)); resetTokenMetadata(); } @@ -562,7 +559,7 @@ private: (CurrentToken->is(tok::l_paren) && CurrentToken->Next && CurrentToken->Next->isOneOf(tok::star, tok::amp, tok::caret)); if ((CurrentToken->Previous->isOneOf(tok::kw_const, tok::kw_auto) || - CurrentToken->Previous->isSimpleTypeSpecifier()) && + CurrentToken->Previous->isTypeName()) && !(CurrentToken->is(tok::l_brace) || (CurrentToken->is(tok::l_paren) && !ProbablyFunctionTypeLParen))) { Contexts.back().IsExpression = false; @@ -682,7 +679,7 @@ private: const bool IsInnerSquare = Contexts.back().InCpp11AttributeSpecifier; const bool IsCpp11AttributeSpecifier = - isCppAttribute(IsCpp, *Left) || IsInnerSquare; + isCppAttribute(*Left) || IsInnerSquare; // Treat C# Attributes [STAThread] much like C++ attributes [[...]]. bool IsCSharpAttributeSpecifier = @@ -690,7 +687,7 @@ private: Contexts.back().InCSharpAttributeSpecifier; bool InsideInlineASM = Line.startsWith(tok::kw_asm); - bool IsCppStructuredBinding = Left->isCppStructuredBinding(IsCpp); + bool IsCppStructuredBinding = Left->isCppStructuredBinding(); bool StartsObjCMethodExpr = !IsCppStructuredBinding && !InsideInlineASM && !CppArrayTemplates && IsCpp && !IsCpp11AttributeSpecifier && !IsCSharpAttributeSpecifier && @@ -989,16 +986,59 @@ private: return false; } + // Judge if the token is a operator ID to insert line break in DAGArg. + // That is, TableGenBreakingDAGArgOperators is empty (by the definition of the + // option) or the token is in the list. + bool isTableGenDAGArgBreakingOperator(const FormatToken &Tok) { + auto &Opes = Style.TableGenBreakingDAGArgOperators; + // If the list is empty, all operators are breaking operators. + if (Opes.empty()) + return true; + // Otherwise, the operator is limited to normal identifiers. + if (Tok.isNot(tok::identifier) || + Tok.isOneOf(TT_TableGenBangOperator, TT_TableGenCondOperator)) { + return false; + } + // The case next is colon, it is not a operator of identifier. + if (!Tok.Next || Tok.Next->is(tok::colon)) + return false; + return std::find(Opes.begin(), Opes.end(), Tok.TokenText.str()) != + Opes.end(); + } + // SimpleValue6 ::= "(" DagArg [DagArgList] ")" // This parses SimpleValue 6's inside part of "(" ")" bool parseTableGenDAGArgAndList(FormatToken *Opener) { + FormatToken *FirstTok = CurrentToken; if (!parseTableGenDAGArg()) return false; + bool BreakInside = false; + if (Style.TableGenBreakInsideDAGArg != FormatStyle::DAS_DontBreak) { + // Specialized detection for DAGArgOperator, that determines the way of + // line break for this DAGArg elements. + if (isTableGenDAGArgBreakingOperator(*FirstTok)) { + // Special case for identifier DAGArg operator. + BreakInside = true; + Opener->setType(TT_TableGenDAGArgOpenerToBreak); + if (FirstTok->isOneOf(TT_TableGenBangOperator, + TT_TableGenCondOperator)) { + // Special case for bang/cond operators. Set the whole operator as + // the DAGArg operator. Always break after it. + CurrentToken->Previous->setType(TT_TableGenDAGArgOperatorToBreak); + } else if (FirstTok->is(tok::identifier)) { + if (Style.TableGenBreakInsideDAGArg == FormatStyle::DAS_BreakAll) + FirstTok->setType(TT_TableGenDAGArgOperatorToBreak); + else + FirstTok->setType(TT_TableGenDAGArgOperatorID); + } + } + } // Parse the [DagArgList] part bool FirstDAGArgListElm = true; while (CurrentToken) { if (!FirstDAGArgListElm && CurrentToken->is(tok::comma)) { - CurrentToken->setType(TT_TableGenDAGArgListComma); + CurrentToken->setType(BreakInside ? TT_TableGenDAGArgListCommaToBreak + : TT_TableGenDAGArgListComma); skipToNextNonComment(); } if (CurrentToken && CurrentToken->is(tok::r_paren)) { @@ -2573,7 +2613,7 @@ private: return true; // MyClass a; - if (PreviousNotConst->isSimpleTypeSpecifier()) + if (PreviousNotConst->isTypeName()) return true; // type[] a in Java @@ -2688,7 +2728,7 @@ private: if (Tok.Next->isOneOf(tok::kw_noexcept, tok::kw_volatile, tok::kw_const, tok::kw_requires, tok::kw_throw, tok::arrow, Keywords.kw_override, Keywords.kw_final) || - isCppAttribute(IsCpp, *Tok.Next)) { + isCppAttribute(*Tok.Next)) { return false; } @@ -2706,7 +2746,7 @@ private: // Heuristically try to determine whether the parentheses contain a type. auto IsQualifiedPointerOrReference = [](FormatToken *T) { // This is used to handle cases such as x = (foo *const)&y; - assert(!T->isSimpleTypeSpecifier() && "Should have already been checked"); + assert(!T->isTypeName() && "Should have already been checked"); // Strip trailing qualifiers such as const or volatile when checking // whether the parens could be a cast to a pointer/reference type. while (T) { @@ -2738,7 +2778,7 @@ private: bool ParensAreType = !Tok.Previous || Tok.Previous->isOneOf(TT_TemplateCloser, TT_TypeDeclarationParen) || - Tok.Previous->isSimpleTypeSpecifier() || + Tok.Previous->isTypeName() || IsQualifiedPointerOrReference(Tok.Previous); bool ParensCouldEndDecl = Tok.Next->isOneOf(tok::equal, tok::semi, tok::l_brace, tok::greater); @@ -3009,7 +3049,6 @@ private: AnnotatedLine &Line; FormatToken *CurrentToken; bool AutoFound; - bool IsCpp; const AdditionalKeywords &Keywords; SmallVector &Scopes; @@ -3584,7 +3623,7 @@ void TokenAnnotator::annotate(AnnotatedLine &Line) { // This function heuristically determines whether 'Current' starts the name of a // function declaration. -static bool isFunctionDeclarationName(bool IsCpp, const FormatToken &Current, +static bool isFunctionDeclarationName(const FormatToken &Current, const AnnotatedLine &Line, FormatToken *&ClosingParen) { assert(Current.Previous); @@ -3595,6 +3634,13 @@ static bool isFunctionDeclarationName(bool IsCpp, const FormatToken &Current, if (!Current.Tok.getIdentifierInfo()) return false; + const auto &Previous = *Current.Previous; + + if (const auto *PrevPrev = Previous.Previous; + PrevPrev && PrevPrev->is(TT_ObjCDecl)) { + return false; + } + auto skipOperatorName = [](const FormatToken *Next) -> const FormatToken * { for (; Next; Next = Next->Next) { if (Next->is(TT_OverloadedOperatorLParen)) @@ -3614,8 +3660,8 @@ static bool isFunctionDeclarationName(bool IsCpp, const FormatToken &Current, Next = Next->Next; continue; } - if ((Next->isSimpleTypeSpecifier() || Next->is(tok::identifier)) && - Next->Next && Next->Next->isPointerOrReference()) { + if ((Next->isTypeName() || Next->is(tok::identifier)) && Next->Next && + Next->Next->isPointerOrReference()) { // For operator void*(), operator char*(), operator Foo*(). Next = Next->Next; continue; @@ -3633,18 +3679,17 @@ static bool isFunctionDeclarationName(bool IsCpp, const FormatToken &Current, // Find parentheses of parameter list. const FormatToken *Next = Current.Next; if (Current.is(tok::kw_operator)) { - const auto *Previous = Current.Previous; - if (Previous->Tok.getIdentifierInfo() && - !Previous->isOneOf(tok::kw_return, tok::kw_co_return)) { + if (Previous.Tok.getIdentifierInfo() && + !Previous.isOneOf(tok::kw_return, tok::kw_co_return)) { return true; } - if (Previous->is(tok::r_paren) && Previous->is(TT_TypeDeclarationParen)) { - assert(Previous->MatchingParen); - assert(Previous->MatchingParen->is(tok::l_paren)); - assert(Previous->MatchingParen->is(TT_TypeDeclarationParen)); + if (Previous.is(tok::r_paren) && Previous.is(TT_TypeDeclarationParen)) { + assert(Previous.MatchingParen); + assert(Previous.MatchingParen->is(tok::l_paren)); + assert(Previous.MatchingParen->is(TT_TypeDeclarationParen)); return true; } - if (!Previous->isPointerOrReference() && Previous->isNot(TT_TemplateCloser)) + if (!Previous.isPointerOrReference() && Previous.isNot(TT_TemplateCloser)) return false; Next = skipOperatorName(Next); } else { @@ -3663,7 +3708,7 @@ static bool isFunctionDeclarationName(bool IsCpp, const FormatToken &Current, } if (Next->isNot(tok::identifier)) return false; - } else if (isCppAttribute(IsCpp, *Next)) { + } else if (isCppAttribute(*Next)) { Next = Next->MatchingParen; if (!Next) return false; @@ -3712,9 +3757,8 @@ static bool isFunctionDeclarationName(bool IsCpp, const FormatToken &Current, Tok = Tok->MatchingParen; continue; } - if (Tok->is(tok::kw_const) || Tok->isSimpleTypeSpecifier() || - Tok->isOneOf(TT_PointerOrReference, TT_StartOfName, tok::ellipsis, - TT_TypeName)) { + if (Tok->is(tok::kw_const) || Tok->isTypeName() || + Tok->isOneOf(TT_PointerOrReference, TT_StartOfName, tok::ellipsis)) { return true; } if (Tok->isOneOf(tok::l_brace, TT_ObjCMethodExpr) || Tok->Tok.isLiteral()) @@ -3775,8 +3819,7 @@ void TokenAnnotator::calculateFormattingInformation(AnnotatedLine &Line) const { if (Tok->Previous->EndsCppAttributeGroup) AfterLastAttribute = Tok; if (const bool IsCtorOrDtor = Tok->is(TT_CtorDtorDeclName); - IsCtorOrDtor || - isFunctionDeclarationName(IsCpp, *Tok, Line, ClosingParen)) { + IsCtorOrDtor || isFunctionDeclarationName(*Tok, Line, ClosingParen)) { if (!IsCtorOrDtor) Tok->setFinalizedType(TT_FunctionDeclarationName); LineIsFunctionDeclaration = true; @@ -4267,6 +4310,10 @@ bool TokenAnnotator::spaceRequiredBetween(const AnnotatedLine &Line, return Left.is(tok::hash); if (Left.isOneOf(tok::hashhash, tok::hash)) return Right.is(tok::hash); + if (Left.is(BK_Block) && Right.is(tok::r_brace) && + Right.MatchingParen == &Left && Line.Children.empty()) { + return Style.SpaceInEmptyBlock; + } if ((Left.is(tok::l_paren) && Right.is(tok::r_paren)) || (Left.is(tok::l_brace) && Left.isNot(BK_Block) && Right.is(tok::r_brace) && Right.isNot(BK_Block))) { @@ -4458,7 +4505,7 @@ bool TokenAnnotator::spaceRequiredBetween(const AnnotatedLine &Line, if (Right.isPointerOrReference()) { const FormatToken *Previous = &Left; while (Previous && Previous->isNot(tok::kw_operator)) { - if (Previous->is(tok::identifier) || Previous->isSimpleTypeSpecifier()) { + if (Previous->is(tok::identifier) || Previous->isTypeName()) { Previous = Previous->getPreviousNonComment(); continue; } @@ -4609,7 +4656,7 @@ bool TokenAnnotator::spaceRequiredBetween(const AnnotatedLine &Line, return Style.SpaceBeforeParensOptions.AfterFunctionDefinitionName || spaceRequiredBeforeParens(Right); } - if (!Left.Previous || Left.Previous->isNot(tok::period)) { + if (!Left.Previous || !Left.Previous->isOneOf(tok::period, tok::arrow)) { if (Left.isOneOf(tok::kw_try, Keywords.kw___except, tok::kw_catch)) { return Style.SpaceBeforeParensOptions.AfterControlStatements || spaceRequiredBeforeParens(Right); @@ -4647,7 +4694,7 @@ bool TokenAnnotator::spaceRequiredBetween(const AnnotatedLine &Line, if (!Style.isVerilog() && (Left.isOneOf(tok::identifier, tok::greater, tok::r_square, tok::r_paren) || - Left.isSimpleTypeSpecifier()) && + Left.isTypeName()) && Right.is(tok::l_brace) && Right.getNextNonComment() && Right.isNot(BK_Block)) { return false; @@ -5082,6 +5129,11 @@ bool TokenAnnotator::spaceRequiredBefore(const AnnotatedLine &Line, } if (Right.is(TT_TableGenCondOperatorColon)) return false; + if (Left.isOneOf(TT_TableGenDAGArgOperatorID, + TT_TableGenDAGArgOperatorToBreak) && + Right.isNot(TT_TableGenDAGArgCloser)) { + return true; + } // Do not insert bang operators and consequent openers. if (Right.isOneOf(tok::l_paren, tok::less) && Left.isOneOf(TT_TableGenBangOperator, TT_TableGenCondOperator)) { @@ -5458,6 +5510,18 @@ bool TokenAnnotator::mustBreakBefore(const AnnotatedLine &Line, // case2:0); if (Left.is(TT_TableGenCondOperatorComma)) return true; + if (Left.is(TT_TableGenDAGArgOperatorToBreak) && + Right.isNot(TT_TableGenDAGArgCloser)) { + return true; + } + if (Left.is(TT_TableGenDAGArgListCommaToBreak)) + return true; + if (Right.is(TT_TableGenDAGArgCloser) && Right.MatchingParen && + Right.MatchingParen->is(TT_TableGenDAGArgOpenerToBreak) && + &Left != Right.MatchingParen->Next) { + // Check to avoid empty DAGArg such as (ins). + return Style.TableGenBreakInsideDAGArg == FormatStyle::DAS_BreakAll; + } } if (Line.startsWith(tok::kw_asm) && Right.is(TT_InlineASMColon) && @@ -5872,6 +5936,8 @@ bool TokenAnnotator::canBreakBefore(const AnnotatedLine &Line, // Avoid to break around paste operator. if (Left.is(tok::hash) || Right.is(tok::hash)) return false; + if (Left.isOneOf(TT_TableGenBangOperator, TT_TableGenCondOperator)) + return false; } if (Left.is(tok::at)) diff --git a/clang/lib/Format/TokenAnnotator.h b/clang/lib/Format/TokenAnnotator.h index a631e5f52bc60a3bc1ab167fa15a15e0e83e7af0..aa44b31e0fce9ecc137fdfc26f6b762ef28701c5 100644 --- a/clang/lib/Format/TokenAnnotator.h +++ b/clang/lib/Format/TokenAnnotator.h @@ -16,7 +16,6 @@ #define LLVM_CLANG_LIB_FORMAT_TOKENANNOTATOR_H #include "UnwrappedLineParser.h" -#include "clang/Format/Format.h" namespace clang { namespace format { @@ -212,7 +211,9 @@ private: class TokenAnnotator { public: TokenAnnotator(const FormatStyle &Style, const AdditionalKeywords &Keywords) - : Style(Style), IsCpp(Style.isCpp()), Keywords(Keywords) {} + : Style(Style), Keywords(Keywords) { + assert(IsCpp == Style.isCpp()); + } /// Adapts the indent levels of comment lines to the indent of the /// subsequent line. @@ -260,8 +261,6 @@ private: const FormatStyle &Style; - bool IsCpp; - const AdditionalKeywords &Keywords; SmallVector Scopes; diff --git a/clang/lib/Format/UnwrappedLineFormatter.cpp b/clang/lib/Format/UnwrappedLineFormatter.cpp index fb31980ab9f491bedddcfb93de529af20e7145f1..bb5841f4e926310650b601619b0283142f0ad3db 100644 --- a/clang/lib/Format/UnwrappedLineFormatter.cpp +++ b/clang/lib/Format/UnwrappedLineFormatter.cpp @@ -7,10 +7,8 @@ //===----------------------------------------------------------------------===// #include "UnwrappedLineFormatter.h" -#include "FormatToken.h" #include "NamespaceEndCommentsFixer.h" #include "WhitespaceManager.h" -#include "llvm/Support/Debug.h" #include #define DEBUG_TYPE "format-formatter" diff --git a/clang/lib/Format/UnwrappedLineFormatter.h b/clang/lib/Format/UnwrappedLineFormatter.h index ee6d31de8c42232e065518a08d9ed9d39169234e..9b8acf427a2a000cb835a2d058dd4ba943b71808 100644 --- a/clang/lib/Format/UnwrappedLineFormatter.h +++ b/clang/lib/Format/UnwrappedLineFormatter.h @@ -16,8 +16,6 @@ #define LLVM_CLANG_LIB_FORMAT_UNWRAPPEDLINEFORMATTER_H #include "ContinuationIndenter.h" -#include "clang/Format/Format.h" -#include namespace clang { namespace format { diff --git a/clang/lib/Format/UnwrappedLineParser.cpp b/clang/lib/Format/UnwrappedLineParser.cpp index 2ce291da11b86ae822b610685694927cb1678cdc..6ac4c7dc1a187bfb2bbb0def2060d8867193769c 100644 --- a/clang/lib/Format/UnwrappedLineParser.cpp +++ b/clang/lib/Format/UnwrappedLineParser.cpp @@ -13,20 +13,9 @@ //===----------------------------------------------------------------------===// #include "UnwrappedLineParser.h" -#include "FormatToken.h" -#include "FormatTokenLexer.h" #include "FormatTokenSource.h" -#include "Macros.h" #include "TokenAnnotator.h" -#include "clang/Basic/TokenKinds.h" -#include "llvm/ADT/STLExtras.h" -#include "llvm/ADT/StringRef.h" -#include "llvm/Support/Debug.h" #include "llvm/Support/raw_os_ostream.h" -#include "llvm/Support/raw_ostream.h" - -#include -#include #define DEBUG_TYPE "format-parser" @@ -159,14 +148,16 @@ UnwrappedLineParser::UnwrappedLineParser( llvm::SpecificBumpPtrAllocator &Allocator, IdentifierTable &IdentTable) : Line(new UnwrappedLine), MustBreakBeforeNextToken(false), - CurrentLines(&Lines), Style(Style), IsCpp(Style.isCpp()), - Keywords(Keywords), CommentPragmasRegex(Style.CommentPragmas), - Tokens(nullptr), Callback(Callback), AllTokens(Tokens), PPBranchLevel(-1), + CurrentLines(&Lines), Style(Style), Keywords(Keywords), + CommentPragmasRegex(Style.CommentPragmas), Tokens(nullptr), + Callback(Callback), AllTokens(Tokens), PPBranchLevel(-1), IncludeGuard(Style.IndentPPDirectives == FormatStyle::PPDIS_None ? IG_Rejected : IG_Inited), IncludeGuardToken(nullptr), FirstStartColumn(FirstStartColumn), - Macros(Style.Macros, SourceMgr, Style, Allocator, IdentTable) {} + Macros(Style.Macros, SourceMgr, Style, Allocator, IdentTable) { + assert(IsCpp == Style.isCpp()); +} void UnwrappedLineParser::reset() { PPBranchLevel = -1; @@ -1222,7 +1213,6 @@ void UnwrappedLineParser::parsePPUnknown() { static bool tokenCanStartNewLine(const FormatToken &Tok) { // Semicolon can be a null-statement, l_square can be a start of a macro or // a C++11 attribute, but this doesn't seem to be common. - assert(Tok.isNot(TT_AttributeSquare)); return !Tok.isOneOf(tok::semi, tok::l_brace, // Tokens that can only be used as binary operators and a // part of overloaded operator names. @@ -1865,8 +1855,7 @@ void UnwrappedLineParser::parseStructuralElement( case tok::caret: nextToken(); // Block return type. - if (FormatTok->Tok.isAnyIdentifier() || - FormatTok->isSimpleTypeSpecifier()) { + if (FormatTok->Tok.isAnyIdentifier() || FormatTok->isTypeName()) { nextToken(); // Return types: pointers are ok too. while (FormatTok->is(tok::star)) @@ -2222,7 +2211,7 @@ bool UnwrappedLineParser::tryToParseLambda() { bool InTemplateParameterList = false; while (FormatTok->isNot(tok::l_brace)) { - if (FormatTok->isSimpleTypeSpecifier()) { + if (FormatTok->isTypeName()) { nextToken(); continue; } @@ -2339,7 +2328,7 @@ bool UnwrappedLineParser::tryToParseLambdaIntroducer() { !Previous->isOneOf(tok::kw_return, tok::kw_co_await, tok::kw_co_yield, tok::kw_co_return)) || Previous->closesScope())) || - LeftSquare->isCppStructuredBinding(IsCpp)) { + LeftSquare->isCppStructuredBinding()) { return false; } if (FormatTok->is(tok::l_square) || tok::isLiteral(FormatTok->Tok.getKind())) @@ -3478,7 +3467,7 @@ bool clang::format::UnwrappedLineParser::parseRequires() { --OpenAngles; break; default: - if (NextToken->isSimpleTypeSpecifier()) { + if (NextToken->isTypeName()) { FormatTok = Tokens->setPosition(StoredPosition); parseRequiresExpression(RequiresToken); return false; @@ -3711,14 +3700,19 @@ bool UnwrappedLineParser::parseEnum() { if (Style.Language == FormatStyle::LK_Proto && FormatTok->is(tok::equal)) return false; - // Eat up enum class ... - if (FormatTok->isOneOf(tok::kw_class, tok::kw_struct)) - nextToken(); + if (IsCpp) { + // Eat up enum class ... + if (FormatTok->isOneOf(tok::kw_class, tok::kw_struct)) + nextToken(); + while (FormatTok->is(tok::l_square)) + if (!handleCppAttributes()) + return false; + } while (FormatTok->Tok.getIdentifierInfo() || FormatTok->isOneOf(tok::colon, tok::coloncolon, tok::less, tok::greater, tok::comma, tok::question, - tok::l_square, tok::r_square)) { + tok::l_square)) { if (Style.isVerilog()) { FormatTok->setFinalizedType(TT_VerilogDimensionedTypeName); nextToken(); @@ -3731,7 +3725,6 @@ bool UnwrappedLineParser::parseEnum() { // We can have macros or attributes in between 'enum' and the enum name. if (FormatTok->is(tok::l_paren)) parseParens(); - assert(FormatTok->isNot(TT_AttributeSquare)); if (FormatTok->is(tok::identifier)) { nextToken(); // If there are two identifiers in a row, this is likely an elaborate @@ -3962,8 +3955,8 @@ void UnwrappedLineParser::parseRecord(bool ParseAsExpr) { } if (FormatTok->is(tok::l_square)) { FormatToken *Previous = FormatTok->Previous; - if (!Previous || - !(Previous->is(tok::r_paren) || Previous->isTypeOrIdentifier())) { + if (!Previous || (Previous->isNot(tok::r_paren) && + !Previous->isTypeOrIdentifier())) { // Don't try parsing a lambda if we had a closing parenthesis before, // it was probably a pointer to an array: int (*)[]. if (!tryToParseLambda()) diff --git a/clang/lib/Format/UnwrappedLineParser.h b/clang/lib/Format/UnwrappedLineParser.h index 619fbb217882b3399a92c829199f7ab00ba57519..da3188ed240c93249e891e04cebf8540d66fb7ce 100644 --- a/clang/lib/Format/UnwrappedLineParser.h +++ b/clang/lib/Format/UnwrappedLineParser.h @@ -15,17 +15,8 @@ #ifndef LLVM_CLANG_LIB_FORMAT_UNWRAPPEDLINEPARSER_H #define LLVM_CLANG_LIB_FORMAT_UNWRAPPEDLINEPARSER_H -#include "Encoding.h" -#include "FormatToken.h" #include "Macros.h" -#include "clang/Basic/IdentifierTable.h" -#include "clang/Format/Format.h" -#include "llvm/ADT/ArrayRef.h" -#include "llvm/ADT/BitVector.h" -#include "llvm/Support/Regex.h" -#include #include -#include namespace clang { namespace format { @@ -324,7 +315,6 @@ private: llvm::BitVector DeclarationScopeStack; const FormatStyle &Style; - bool IsCpp; const AdditionalKeywords &Keywords; llvm::Regex CommentPragmasRegex; diff --git a/clang/lib/Format/UsingDeclarationsSorter.cpp b/clang/lib/Format/UsingDeclarationsSorter.cpp index 2f4b1e0e4627085c5ca3705964a96ac64cb275d8..3543f86b1a65a5c1d852d2fa1d287b7f30670f7e 100644 --- a/clang/lib/Format/UsingDeclarationsSorter.cpp +++ b/clang/lib/Format/UsingDeclarationsSorter.cpp @@ -13,11 +13,6 @@ //===----------------------------------------------------------------------===// #include "UsingDeclarationsSorter.h" -#include "clang/Format/Format.h" -#include "llvm/Support/Debug.h" -#include "llvm/Support/Regex.h" - -#include #define DEBUG_TYPE "using-declarations-sorter" diff --git a/clang/lib/Format/WhitespaceManager.cpp b/clang/lib/Format/WhitespaceManager.cpp index 753be25bfd67585380ad61be9c00fa7167ca9764..6577c19cdf7978ce756987f39ae1af0eb39f89c4 100644 --- a/clang/lib/Format/WhitespaceManager.cpp +++ b/clang/lib/Format/WhitespaceManager.cpp @@ -12,9 +12,6 @@ //===----------------------------------------------------------------------===// #include "WhitespaceManager.h" -#include "llvm/ADT/STLExtras.h" -#include "llvm/ADT/SmallVector.h" -#include namespace clang { namespace format { diff --git a/clang/lib/Format/WhitespaceManager.h b/clang/lib/Format/WhitespaceManager.h index 9942e0f35738fca054aebbc2106356fbce956dc6..0ebc6cf8377cdb293a6895a851c25e117001ae93 100644 --- a/clang/lib/Format/WhitespaceManager.h +++ b/clang/lib/Format/WhitespaceManager.h @@ -17,11 +17,6 @@ #include "TokenAnnotator.h" #include "clang/Basic/SourceManager.h" -#include "clang/Format/Format.h" -#include "llvm/ADT/SmallVector.h" -#include -#include -#include namespace clang { namespace format { diff --git a/clang/lib/Frontend/CompilerInstance.cpp b/clang/lib/Frontend/CompilerInstance.cpp index ec4e68209d657d93398f3d845562c8bb30d3de33..019f847ccbaad0278e1ec9b010ea22beb9a7d22d 100644 --- a/clang/lib/Frontend/CompilerInstance.cpp +++ b/clang/lib/Frontend/CompilerInstance.cpp @@ -1047,6 +1047,11 @@ bool CompilerInstance::ExecuteAction(FrontendAction &Act) { if (getFrontendOpts().ShowStats || !getFrontendOpts().StatsFile.empty()) llvm::EnableStatistics(false); + // Sort vectors containing toc data and no toc data variables to facilitate + // binary search later. + llvm::sort(getCodeGenOpts().TocDataVarsUserSpecified); + llvm::sort(getCodeGenOpts().NoTocDataVars); + for (const FrontendInputFile &FIF : getFrontendOpts().Inputs) { // Reset the ID tables if we are reusing the SourceManager and parsing // regular files. diff --git a/clang/lib/Frontend/CompilerInvocation.cpp b/clang/lib/Frontend/CompilerInvocation.cpp index 451bdb9386f58779ef0c6ab4e6e3b96bece176a7..2a21a9d619dc0b1855e113e5e7481d5c14a400d4 100644 --- a/clang/lib/Frontend/CompilerInvocation.cpp +++ b/clang/lib/Frontend/CompilerInvocation.cpp @@ -3293,6 +3293,17 @@ static void ParseAPINotesArgs(APINotesOptions &Opts, ArgList &Args, Opts.ModuleSearchPaths.push_back(A->getValue()); } +static void GeneratePointerAuthArgs(const LangOptions &Opts, + ArgumentConsumer Consumer) { + if (Opts.PointerAuthIntrinsics) + GenerateArg(Consumer, OPT_fptrauth_intrinsics); +} + +static void ParsePointerAuthArgs(LangOptions &Opts, ArgList &Args, + DiagnosticsEngine &Diags) { + Opts.PointerAuthIntrinsics = Args.hasArg(OPT_fptrauth_intrinsics); +} + /// Check if input file kind and language standard are compatible. static bool IsInputCompatibleWithStandard(InputKind IK, const LangStandard &S) { @@ -4014,6 +4025,7 @@ bool CompilerInvocation::ParseLangArgs(LangOptions &Opts, ArgList &Args, if (TT.getArch() == llvm::Triple::UnknownArch || !(TT.getArch() == llvm::Triple::aarch64 || TT.isPPC() || + TT.getArch() == llvm::Triple::systemz || TT.getArch() == llvm::Triple::nvptx || TT.getArch() == llvm::Triple::nvptx64 || TT.getArch() == llvm::Triple::amdgcn || @@ -4612,6 +4624,8 @@ bool CompilerInvocation::CreateFromArgsImpl( Res.getFileSystemOpts().WorkingDir); ParseAPINotesArgs(Res.getAPINotesOpts(), Args, Diags); + ParsePointerAuthArgs(LangOpts, Args, Diags); + ParseLangArgs(LangOpts, Args, DashX, T, Res.getPreprocessorOpts().Includes, Diags); if (Res.getFrontendOpts().ProgramAction == frontend::RewriteObjC) @@ -4842,6 +4856,7 @@ void CompilerInvocationBase::generateCC1CommandLine( GenerateTargetArgs(getTargetOpts(), Consumer); GenerateHeaderSearchArgs(getHeaderSearchOpts(), Consumer); GenerateAPINotesArgs(getAPINotesOpts(), Consumer); + GeneratePointerAuthArgs(getLangOpts(), Consumer); GenerateLangArgs(getLangOpts(), Consumer, T, getFrontendOpts().DashX); GenerateCodeGenArgs(getCodeGenOpts(), Consumer, T, getFrontendOpts().OutputFile, &getLangOpts()); diff --git a/clang/lib/Frontend/FrontendActions.cpp b/clang/lib/Frontend/FrontendActions.cpp index 50338bfa670f8302e529c614d85eb2f82446e858..81fcd8d5ae9bd30d9605a9cb6d37d87b4b7c35ec 100644 --- a/clang/lib/Frontend/FrontendActions.cpp +++ b/clang/lib/Frontend/FrontendActions.cpp @@ -293,11 +293,9 @@ GenerateModuleInterfaceAction::CreateOutputFile(CompilerInstance &CI, std::unique_ptr GenerateReducedModuleInterfaceAction::CreateASTConsumer(CompilerInstance &CI, StringRef InFile) { - auto Buffer = std::make_shared(); - return std::make_unique( - CI.getPreprocessor(), CI.getModuleCache(), - CI.getFrontendOpts().OutputFile, Buffer, - /*IncludeTimestamps=*/+CI.getFrontendOpts().IncludeTimestamps); + return std::make_unique(CI.getPreprocessor(), + CI.getModuleCache(), + CI.getFrontendOpts().OutputFile); } bool GenerateHeaderUnitAction::BeginSourceFileAction(CompilerInstance &CI) { diff --git a/clang/lib/Headers/CMakeLists.txt b/clang/lib/Headers/CMakeLists.txt index b9a966be73ee97b2ef569e99d3634abfc28148bc..902e33bb95897cf46531ffe1db9360a9ab7a07e7 100644 --- a/clang/lib/Headers/CMakeLists.txt +++ b/clang/lib/Headers/CMakeLists.txt @@ -214,6 +214,7 @@ set(x86_files popcntintrin.h prfchiintrin.h prfchwintrin.h + ptrauth.h ptwriteintrin.h raointintrin.h rdpruintrin.h diff --git a/clang/lib/Headers/__stddef_null.h b/clang/lib/Headers/__stddef_null.h index 7336fdab389723d0277acc4f11d30253ab96fd8a..c10bd2d7d9887c65c3c67c7b10ba485be9dd605f 100644 --- a/clang/lib/Headers/__stddef_null.h +++ b/clang/lib/Headers/__stddef_null.h @@ -7,7 +7,7 @@ *===-----------------------------------------------------------------------=== */ -#if !defined(NULL) || !__has_feature(modules) +#if !defined(NULL) || !__building_module(_Builtin_stddef) /* linux/stddef.h will define NULL to 0. glibc (and other) headers then define * __need_NULL and rely on stddef.h to redefine NULL to the correct value again. diff --git a/clang/lib/Headers/__stddef_nullptr_t.h b/clang/lib/Headers/__stddef_nullptr_t.h index 183d394d56c1b70fd1c02f964837d415e2ab5918..7f3fbe6fe0d3a8ebc353d89833a43800fd61d478 100644 --- a/clang/lib/Headers/__stddef_nullptr_t.h +++ b/clang/lib/Headers/__stddef_nullptr_t.h @@ -7,7 +7,12 @@ *===-----------------------------------------------------------------------=== */ -#ifndef _NULLPTR_T +/* + * When -fbuiltin-headers-in-system-modules is set this is a non-modular header + * and needs to behave as if it was textual. + */ +#if !defined(_NULLPTR_T) || \ + (__has_feature(modules) && !__building_module(_Builtin_stddef)) #define _NULLPTR_T #ifdef __cplusplus diff --git a/clang/lib/Headers/__stddef_offsetof.h b/clang/lib/Headers/__stddef_offsetof.h index 3b347b3b92f62cec7baa85a7de83e3bf676ac209..84172c6cd27352222e7cb89af8933a2e6000c24e 100644 --- a/clang/lib/Headers/__stddef_offsetof.h +++ b/clang/lib/Headers/__stddef_offsetof.h @@ -7,6 +7,11 @@ *===-----------------------------------------------------------------------=== */ -#ifndef offsetof +/* + * When -fbuiltin-headers-in-system-modules is set this is a non-modular header + * and needs to behave as if it was textual. + */ +#if !defined(offsetof) || \ + (__has_feature(modules) && !__building_module(_Builtin_stddef)) #define offsetof(t, d) __builtin_offsetof(t, d) #endif diff --git a/clang/lib/Headers/__stddef_ptrdiff_t.h b/clang/lib/Headers/__stddef_ptrdiff_t.h index 3ea6d7d2852e1cca7ca1ddbe10daf69f896f292d..fd3c893c66c97940c7197d05286b34aaaac1ecd7 100644 --- a/clang/lib/Headers/__stddef_ptrdiff_t.h +++ b/clang/lib/Headers/__stddef_ptrdiff_t.h @@ -7,7 +7,12 @@ *===-----------------------------------------------------------------------=== */ -#ifndef _PTRDIFF_T +/* + * When -fbuiltin-headers-in-system-modules is set this is a non-modular header + * and needs to behave as if it was textual. + */ +#if !defined(_PTRDIFF_T) || \ + (__has_feature(modules) && !__building_module(_Builtin_stddef)) #define _PTRDIFF_T typedef __PTRDIFF_TYPE__ ptrdiff_t; diff --git a/clang/lib/Headers/__stddef_rsize_t.h b/clang/lib/Headers/__stddef_rsize_t.h index b6428d0c12b62aec8589488155da32ea1b5ac1ca..dd433d40d9733a7257fe7632771276b082dac469 100644 --- a/clang/lib/Headers/__stddef_rsize_t.h +++ b/clang/lib/Headers/__stddef_rsize_t.h @@ -7,7 +7,12 @@ *===-----------------------------------------------------------------------=== */ -#ifndef _RSIZE_T +/* + * When -fbuiltin-headers-in-system-modules is set this is a non-modular header + * and needs to behave as if it was textual. + */ +#if !defined(_RSIZE_T) || \ + (__has_feature(modules) && !__building_module(_Builtin_stddef)) #define _RSIZE_T typedef __SIZE_TYPE__ rsize_t; diff --git a/clang/lib/Headers/__stddef_size_t.h b/clang/lib/Headers/__stddef_size_t.h index e4a389510bcdbf330c6d39376cc593eed83c7941..3dd7b1f37929498cf574b72d62966c448a47c7c4 100644 --- a/clang/lib/Headers/__stddef_size_t.h +++ b/clang/lib/Headers/__stddef_size_t.h @@ -7,7 +7,12 @@ *===-----------------------------------------------------------------------=== */ -#ifndef _SIZE_T +/* + * When -fbuiltin-headers-in-system-modules is set this is a non-modular header + * and needs to behave as if it was textual. + */ +#if !defined(_SIZE_T) || \ + (__has_feature(modules) && !__building_module(_Builtin_stddef)) #define _SIZE_T typedef __SIZE_TYPE__ size_t; diff --git a/clang/lib/Headers/__stddef_unreachable.h b/clang/lib/Headers/__stddef_unreachable.h index 3e7fe01979662afc53985594c74e259810e277a7..518580c92d3f5d01ae73e45be3e6e2b2e0b3075b 100644 --- a/clang/lib/Headers/__stddef_unreachable.h +++ b/clang/lib/Headers/__stddef_unreachable.h @@ -7,6 +7,11 @@ *===-----------------------------------------------------------------------=== */ -#ifndef unreachable +/* + * When -fbuiltin-headers-in-system-modules is set this is a non-modular header + * and needs to behave as if it was textual. + */ +#if !defined(unreachable) || \ + (__has_feature(modules) && !__building_module(_Builtin_stddef)) #define unreachable() __builtin_unreachable() #endif diff --git a/clang/lib/Headers/__stddef_wchar_t.h b/clang/lib/Headers/__stddef_wchar_t.h index 16a6186512c0c35367b3949189ce8080e7b5f714..bd69f6322541637ab3cfbfbb9d09dca5393c5c5c 100644 --- a/clang/lib/Headers/__stddef_wchar_t.h +++ b/clang/lib/Headers/__stddef_wchar_t.h @@ -9,7 +9,12 @@ #if !defined(__cplusplus) || (defined(_MSC_VER) && !_NATIVE_WCHAR_T_DEFINED) -#ifndef _WCHAR_T +/* + * When -fbuiltin-headers-in-system-modules is set this is a non-modular header + * and needs to behave as if it was textual. + */ +#if !defined(_WCHAR_T) || \ + (__has_feature(modules) && !__building_module(_Builtin_stddef)) #define _WCHAR_T #ifdef _MSC_EXTENSIONS diff --git a/clang/lib/Headers/avxintrin.h b/clang/lib/Headers/avxintrin.h index f116d8bc3a94c726fcae3aa9dc44087fd58f842d..ecd9bf18a41ca0d9ceb5bbf73d402c3cdbeff778 100644 --- a/clang/lib/Headers/avxintrin.h +++ b/clang/lib/Headers/avxintrin.h @@ -1574,14 +1574,6 @@ _mm256_blendv_ps(__m256 __a, __m256 __b, __m256 __c) (__v4df)(__m256d)(b), (int)(mask))) /* Compare */ -#define _CMP_EQ_OQ 0x00 /* Equal (ordered, non-signaling) */ -#define _CMP_LT_OS 0x01 /* Less-than (ordered, signaling) */ -#define _CMP_LE_OS 0x02 /* Less-than-or-equal (ordered, signaling) */ -#define _CMP_UNORD_Q 0x03 /* Unordered (non-signaling) */ -#define _CMP_NEQ_UQ 0x04 /* Not-equal (unordered, non-signaling) */ -#define _CMP_NLT_US 0x05 /* Not-less-than (unordered, signaling) */ -#define _CMP_NLE_US 0x06 /* Not-less-than-or-equal (unordered, signaling) */ -#define _CMP_ORD_Q 0x07 /* Ordered (non-signaling) */ #define _CMP_EQ_UQ 0x08 /* Equal (unordered, non-signaling) */ #define _CMP_NGE_US 0x09 /* Not-greater-than-or-equal (unordered, signaling) */ #define _CMP_NGT_US 0x0a /* Not-greater-than (unordered, signaling) */ @@ -1607,6 +1599,7 @@ _mm256_blendv_ps(__m256 __a, __m256 __b, __m256 __c) #define _CMP_GT_OQ 0x1e /* Greater-than (ordered, non-signaling) */ #define _CMP_TRUE_US 0x1f /* True (unordered, signaling) */ +/* Below intrinsic defined in emmintrin.h can be used for AVX */ /// Compares each of the corresponding double-precision values of two /// 128-bit vectors of [2 x double], using the operation specified by the /// immediate integer operand. @@ -1663,10 +1656,9 @@ _mm256_blendv_ps(__m256 __a, __m256 __b, __m256 __c) /// 0x1E: Greater-than (ordered, non-signaling) \n /// 0x1F: True (unordered, signaling) /// \returns A 128-bit vector of [2 x double] containing the comparison results. -#define _mm_cmp_pd(a, b, c) \ - ((__m128d)__builtin_ia32_cmppd((__v2df)(__m128d)(a), \ - (__v2df)(__m128d)(b), (c))) +/// \fn __m128d _mm_cmp_pd(__m128d a, __m128d b, const int c) +/* Below intrinsic defined in xmmintrin.h can be used for AVX */ /// Compares each of the corresponding values of two 128-bit vectors of /// [4 x float], using the operation specified by the immediate integer /// operand. @@ -1723,9 +1715,7 @@ _mm256_blendv_ps(__m256 __a, __m256 __b, __m256 __c) /// 0x1E: Greater-than (ordered, non-signaling) \n /// 0x1F: True (unordered, signaling) /// \returns A 128-bit vector of [4 x float] containing the comparison results. -#define _mm_cmp_ps(a, b, c) \ - ((__m128)__builtin_ia32_cmpps((__v4sf)(__m128)(a), \ - (__v4sf)(__m128)(b), (c))) +/// \fn __m128 _mm_cmp_ps(__m128 a, __m128 b, const int c) /// Compares each of the corresponding double-precision values of two /// 256-bit vectors of [4 x double], using the operation specified by the @@ -1847,6 +1837,7 @@ _mm256_blendv_ps(__m256 __a, __m256 __b, __m256 __c) ((__m256)__builtin_ia32_cmpps256((__v8sf)(__m256)(a), \ (__v8sf)(__m256)(b), (c))) +/* Below intrinsic defined in emmintrin.h can be used for AVX */ /// Compares each of the corresponding scalar double-precision values of /// two 128-bit vectors of [2 x double], using the operation specified by the /// immediate integer operand. @@ -1902,10 +1893,9 @@ _mm256_blendv_ps(__m256 __a, __m256 __b, __m256 __c) /// 0x1E: Greater-than (ordered, non-signaling) \n /// 0x1F: True (unordered, signaling) /// \returns A 128-bit vector of [2 x double] containing the comparison results. -#define _mm_cmp_sd(a, b, c) \ - ((__m128d)__builtin_ia32_cmpsd((__v2df)(__m128d)(a), \ - (__v2df)(__m128d)(b), (c))) +/// \fn __m128d _mm_cmp_sd(__m128d a, __m128d b, const int c) +/* Below intrinsic defined in xmmintrin.h can be used for AVX */ /// Compares each of the corresponding scalar values of two 128-bit /// vectors of [4 x float], using the operation specified by the immediate /// integer operand. @@ -1961,9 +1951,7 @@ _mm256_blendv_ps(__m256 __a, __m256 __b, __m256 __c) /// 0x1E: Greater-than (ordered, non-signaling) \n /// 0x1F: True (unordered, signaling) /// \returns A 128-bit vector of [4 x float] containing the comparison results. -#define _mm_cmp_ss(a, b, c) \ - ((__m128)__builtin_ia32_cmpss((__v4sf)(__m128)(a), \ - (__v4sf)(__m128)(b), (c))) +/// \fn __m128 _mm_cmp_ss(__m128 a, __m128 b, const int c) /// Takes a [8 x i32] vector and returns the vector element value /// indexed by the immediate constant operand. diff --git a/clang/lib/Headers/emmintrin.h b/clang/lib/Headers/emmintrin.h index 1d451b5f5b25de4afe105ef7ea8e9212d26826d4..984f0cf917e99bf576b4ab82c80a07106be86c65 100644 --- a/clang/lib/Headers/emmintrin.h +++ b/clang/lib/Headers/emmintrin.h @@ -410,8 +410,9 @@ static __inline__ __m128d __DEFAULT_FN_ATTRS _mm_xor_pd(__m128d __a, } /// Compares each of the corresponding double-precision values of the -/// 128-bit vectors of [2 x double] for equality. Each comparison yields 0x0 -/// for false, 0xFFFFFFFFFFFFFFFF for true. +/// 128-bit vectors of [2 x double] for equality. +/// +/// Each comparison yields 0x0 for false, 0xFFFFFFFFFFFFFFFF for true. /// /// \headerfile /// @@ -429,8 +430,9 @@ static __inline__ __m128d __DEFAULT_FN_ATTRS _mm_cmpeq_pd(__m128d __a, /// Compares each of the corresponding double-precision values of the /// 128-bit vectors of [2 x double] to determine if the values in the first -/// operand are less than those in the second operand. Each comparison -/// yields 0x0 for false, 0xFFFFFFFFFFFFFFFF for true. +/// operand are less than those in the second operand. +/// +/// Each comparison yields 0x0 for false, 0xFFFFFFFFFFFFFFFF for true. /// /// \headerfile /// @@ -949,8 +951,8 @@ static __inline__ __m128d __DEFAULT_FN_ATTRS _mm_cmpnge_sd(__m128d __a, /// Compares the lower double-precision floating-point values in each of /// the two 128-bit floating-point vectors of [2 x double] for equality. /// -/// The comparison yields 0 for false, 1 for true. If either of the two -/// lower double-precision values is NaN, 0 is returned. +/// The comparison returns 0 for false, 1 for true. If either of the two +/// lower double-precision values is NaN, returns 0. /// /// \headerfile /// @@ -962,8 +964,7 @@ static __inline__ __m128d __DEFAULT_FN_ATTRS _mm_cmpnge_sd(__m128d __a, /// \param __b /// A 128-bit vector of [2 x double]. The lower double-precision value is /// compared to the lower double-precision value of \a __a. -/// \returns An integer containing the comparison results. If either of the two -/// lower double-precision values is NaN, 0 is returned. +/// \returns An integer containing the comparison results. static __inline__ int __DEFAULT_FN_ATTRS _mm_comieq_sd(__m128d __a, __m128d __b) { return __builtin_ia32_comisdeq((__v2df)__a, (__v2df)__b); @@ -974,8 +975,8 @@ static __inline__ int __DEFAULT_FN_ATTRS _mm_comieq_sd(__m128d __a, /// the value in the first parameter is less than the corresponding value in /// the second parameter. /// -/// The comparison yields 0 for false, 1 for true. If either of the two -/// lower double-precision values is NaN, 0 is returned. +/// The comparison returns 0 for false, 1 for true. If either of the two +/// lower double-precision values is NaN, returns 0. /// /// \headerfile /// @@ -987,8 +988,7 @@ static __inline__ int __DEFAULT_FN_ATTRS _mm_comieq_sd(__m128d __a, /// \param __b /// A 128-bit vector of [2 x double]. The lower double-precision value is /// compared to the lower double-precision value of \a __a. -/// \returns An integer containing the comparison results. If either of the two -/// lower double-precision values is NaN, 0 is returned. +/// \returns An integer containing the comparison results. static __inline__ int __DEFAULT_FN_ATTRS _mm_comilt_sd(__m128d __a, __m128d __b) { return __builtin_ia32_comisdlt((__v2df)__a, (__v2df)__b); @@ -999,8 +999,8 @@ static __inline__ int __DEFAULT_FN_ATTRS _mm_comilt_sd(__m128d __a, /// the value in the first parameter is less than or equal to the /// corresponding value in the second parameter. /// -/// The comparison yields 0 for false, 1 for true. If either of the two -/// lower double-precision values is NaN, 0 is returned. +/// The comparison returns 0 for false, 1 for true. If either of the two +/// lower double-precision values is NaN, returns 0. /// /// \headerfile /// @@ -1012,8 +1012,7 @@ static __inline__ int __DEFAULT_FN_ATTRS _mm_comilt_sd(__m128d __a, /// \param __b /// A 128-bit vector of [2 x double]. The lower double-precision value is /// compared to the lower double-precision value of \a __a. -/// \returns An integer containing the comparison results. If either of the two -/// lower double-precision values is NaN, 0 is returned. +/// \returns An integer containing the comparison results. static __inline__ int __DEFAULT_FN_ATTRS _mm_comile_sd(__m128d __a, __m128d __b) { return __builtin_ia32_comisdle((__v2df)__a, (__v2df)__b); @@ -1024,8 +1023,8 @@ static __inline__ int __DEFAULT_FN_ATTRS _mm_comile_sd(__m128d __a, /// the value in the first parameter is greater than the corresponding value /// in the second parameter. /// -/// The comparison yields 0 for false, 1 for true. If either of the two -/// lower double-precision values is NaN, 0 is returned. +/// The comparison returns 0 for false, 1 for true. If either of the two +/// lower double-precision values is NaN, returns 0. /// /// \headerfile /// @@ -1037,8 +1036,7 @@ static __inline__ int __DEFAULT_FN_ATTRS _mm_comile_sd(__m128d __a, /// \param __b /// A 128-bit vector of [2 x double]. The lower double-precision value is /// compared to the lower double-precision value of \a __a. -/// \returns An integer containing the comparison results. If either of the two -/// lower double-precision values is NaN, 0 is returned. +/// \returns An integer containing the comparison results. static __inline__ int __DEFAULT_FN_ATTRS _mm_comigt_sd(__m128d __a, __m128d __b) { return __builtin_ia32_comisdgt((__v2df)__a, (__v2df)__b); @@ -1049,8 +1047,8 @@ static __inline__ int __DEFAULT_FN_ATTRS _mm_comigt_sd(__m128d __a, /// the value in the first parameter is greater than or equal to the /// corresponding value in the second parameter. /// -/// The comparison yields 0 for false, 1 for true. If either of the two -/// lower double-precision values is NaN, 0 is returned. +/// The comparison returns 0 for false, 1 for true. If either of the two +/// lower double-precision values is NaN, returns 0. /// /// \headerfile /// @@ -1062,8 +1060,7 @@ static __inline__ int __DEFAULT_FN_ATTRS _mm_comigt_sd(__m128d __a, /// \param __b /// A 128-bit vector of [2 x double]. The lower double-precision value is /// compared to the lower double-precision value of \a __a. -/// \returns An integer containing the comparison results. If either of the two -/// lower double-precision values is NaN, 0 is returned. +/// \returns An integer containing the comparison results. static __inline__ int __DEFAULT_FN_ATTRS _mm_comige_sd(__m128d __a, __m128d __b) { return __builtin_ia32_comisdge((__v2df)__a, (__v2df)__b); @@ -1074,7 +1071,7 @@ static __inline__ int __DEFAULT_FN_ATTRS _mm_comige_sd(__m128d __a, /// the value in the first parameter is unequal to the corresponding value in /// the second parameter. /// -/// The comparison yields 0 for false, 1 for true. If either of the two +/// The comparison returns 0 for false, 1 for true. If either of the two /// lower double-precision values is NaN, 1 is returned. /// /// \headerfile @@ -1087,18 +1084,17 @@ static __inline__ int __DEFAULT_FN_ATTRS _mm_comige_sd(__m128d __a, /// \param __b /// A 128-bit vector of [2 x double]. The lower double-precision value is /// compared to the lower double-precision value of \a __a. -/// \returns An integer containing the comparison results. If either of the two -/// lower double-precision values is NaN, 1 is returned. +/// \returns An integer containing the comparison results. static __inline__ int __DEFAULT_FN_ATTRS _mm_comineq_sd(__m128d __a, __m128d __b) { return __builtin_ia32_comisdneq((__v2df)__a, (__v2df)__b); } /// Compares the lower double-precision floating-point values in each of -/// the two 128-bit floating-point vectors of [2 x double] for equality. The -/// comparison yields 0 for false, 1 for true. +/// the two 128-bit floating-point vectors of [2 x double] for equality. /// -/// If either of the two lower double-precision values is NaN, 0 is returned. +/// The comparison returns 0 for false, 1 for true. If either of the two +/// lower double-precision values is NaN, returns 0. /// /// \headerfile /// @@ -1110,8 +1106,7 @@ static __inline__ int __DEFAULT_FN_ATTRS _mm_comineq_sd(__m128d __a, /// \param __b /// A 128-bit vector of [2 x double]. The lower double-precision value is /// compared to the lower double-precision value of \a __a. -/// \returns An integer containing the comparison results. If either of the two -/// lower double-precision values is NaN, 0 is returned. +/// \returns An integer containing the comparison results. static __inline__ int __DEFAULT_FN_ATTRS _mm_ucomieq_sd(__m128d __a, __m128d __b) { return __builtin_ia32_ucomisdeq((__v2df)__a, (__v2df)__b); @@ -1122,8 +1117,8 @@ static __inline__ int __DEFAULT_FN_ATTRS _mm_ucomieq_sd(__m128d __a, /// the value in the first parameter is less than the corresponding value in /// the second parameter. /// -/// The comparison yields 0 for false, 1 for true. If either of the two lower -/// double-precision values is NaN, 0 is returned. +/// The comparison returns 0 for false, 1 for true. If either of the two +/// lower double-precision values is NaN, returns 0. /// /// \headerfile /// @@ -1135,8 +1130,7 @@ static __inline__ int __DEFAULT_FN_ATTRS _mm_ucomieq_sd(__m128d __a, /// \param __b /// A 128-bit vector of [2 x double]. The lower double-precision value is /// compared to the lower double-precision value of \a __a. -/// \returns An integer containing the comparison results. If either of the two -/// lower double-precision values is NaN, 0 is returned. +/// \returns An integer containing the comparison results. static __inline__ int __DEFAULT_FN_ATTRS _mm_ucomilt_sd(__m128d __a, __m128d __b) { return __builtin_ia32_ucomisdlt((__v2df)__a, (__v2df)__b); @@ -1147,8 +1141,8 @@ static __inline__ int __DEFAULT_FN_ATTRS _mm_ucomilt_sd(__m128d __a, /// the value in the first parameter is less than or equal to the /// corresponding value in the second parameter. /// -/// The comparison yields 0 for false, 1 for true. If either of the two lower -/// double-precision values is NaN, 0 is returned. +/// The comparison returns 0 for false, 1 for true. If either of the two +/// lower double-precision values is NaN, returns 0. /// /// \headerfile /// @@ -1160,8 +1154,7 @@ static __inline__ int __DEFAULT_FN_ATTRS _mm_ucomilt_sd(__m128d __a, /// \param __b /// A 128-bit vector of [2 x double]. The lower double-precision value is /// compared to the lower double-precision value of \a __a. -/// \returns An integer containing the comparison results. If either of the two -/// lower double-precision values is NaN, 0 is returned. +/// \returns An integer containing the comparison results. static __inline__ int __DEFAULT_FN_ATTRS _mm_ucomile_sd(__m128d __a, __m128d __b) { return __builtin_ia32_ucomisdle((__v2df)__a, (__v2df)__b); @@ -1172,8 +1165,8 @@ static __inline__ int __DEFAULT_FN_ATTRS _mm_ucomile_sd(__m128d __a, /// the value in the first parameter is greater than the corresponding value /// in the second parameter. /// -/// The comparison yields 0 for false, 1 for true. If either of the two lower -/// double-precision values is NaN, 0 is returned. +/// The comparison returns 0 for false, 1 for true. If either of the two +/// lower double-precision values is NaN, returns 0. /// /// \headerfile /// @@ -1185,8 +1178,7 @@ static __inline__ int __DEFAULT_FN_ATTRS _mm_ucomile_sd(__m128d __a, /// \param __b /// A 128-bit vector of [2 x double]. The lower double-precision value is /// compared to the lower double-precision value of \a __a. -/// \returns An integer containing the comparison results. If either of the two -/// lower double-precision values is NaN, 0 is returned. +/// \returns An integer containing the comparison results. static __inline__ int __DEFAULT_FN_ATTRS _mm_ucomigt_sd(__m128d __a, __m128d __b) { return __builtin_ia32_ucomisdgt((__v2df)__a, (__v2df)__b); @@ -1197,8 +1189,8 @@ static __inline__ int __DEFAULT_FN_ATTRS _mm_ucomigt_sd(__m128d __a, /// the value in the first parameter is greater than or equal to the /// corresponding value in the second parameter. /// -/// The comparison yields 0 for false, 1 for true. If either of the two -/// lower double-precision values is NaN, 0 is returned. +/// The comparison returns 0 for false, 1 for true. If either of the two +/// lower double-precision values is NaN, returns 0. /// /// \headerfile /// @@ -1210,8 +1202,7 @@ static __inline__ int __DEFAULT_FN_ATTRS _mm_ucomigt_sd(__m128d __a, /// \param __b /// A 128-bit vector of [2 x double]. The lower double-precision value is /// compared to the lower double-precision value of \a __a. -/// \returns An integer containing the comparison results. If either of the two -/// lower double-precision values is NaN, 0 is returned. +/// \returns An integer containing the comparison results. static __inline__ int __DEFAULT_FN_ATTRS _mm_ucomige_sd(__m128d __a, __m128d __b) { return __builtin_ia32_ucomisdge((__v2df)__a, (__v2df)__b); @@ -1222,8 +1213,8 @@ static __inline__ int __DEFAULT_FN_ATTRS _mm_ucomige_sd(__m128d __a, /// the value in the first parameter is unequal to the corresponding value in /// the second parameter. /// -/// The comparison yields 0 for false, 1 for true. If either of the two lower -/// double-precision values is NaN, 1 is returned. +/// The comparison returns 0 for false, 1 for true. If either of the two +/// lower double-precision values is NaN, 1 is returned. /// /// \headerfile /// @@ -1235,8 +1226,7 @@ static __inline__ int __DEFAULT_FN_ATTRS _mm_ucomige_sd(__m128d __a, /// \param __b /// A 128-bit vector of [2 x double]. The lower double-precision value is /// compared to the lower double-precision value of \a __a. -/// \returns An integer containing the comparison result. If either of the two -/// lower double-precision values is NaN, 1 is returned. +/// \returns An integer containing the comparison result. static __inline__ int __DEFAULT_FN_ATTRS _mm_ucomineq_sd(__m128d __a, __m128d __b) { return __builtin_ia32_ucomisdneq((__v2df)__a, (__v2df)__b); @@ -3023,8 +3013,9 @@ static __inline__ __m128i __DEFAULT_FN_ATTRS _mm_srl_epi64(__m128i __a, } /// Compares each of the corresponding 8-bit values of the 128-bit -/// integer vectors for equality. Each comparison yields 0x0 for false, 0xFF -/// for true. +/// integer vectors for equality. +/// +/// Each comparison yields 0x0 for false, 0xFF for true. /// /// \headerfile /// @@ -3041,8 +3032,9 @@ static __inline__ __m128i __DEFAULT_FN_ATTRS _mm_cmpeq_epi8(__m128i __a, } /// Compares each of the corresponding 16-bit values of the 128-bit -/// integer vectors for equality. Each comparison yields 0x0 for false, -/// 0xFFFF for true. +/// integer vectors for equality. +/// +/// Each comparison yields 0x0 for false, 0xFFFF for true. /// /// \headerfile /// @@ -3059,8 +3051,9 @@ static __inline__ __m128i __DEFAULT_FN_ATTRS _mm_cmpeq_epi16(__m128i __a, } /// Compares each of the corresponding 32-bit values of the 128-bit -/// integer vectors for equality. Each comparison yields 0x0 for false, -/// 0xFFFFFFFF for true. +/// integer vectors for equality. +/// +/// Each comparison yields 0x0 for false, 0xFFFFFFFF for true. /// /// \headerfile /// @@ -3078,8 +3071,9 @@ static __inline__ __m128i __DEFAULT_FN_ATTRS _mm_cmpeq_epi32(__m128i __a, /// Compares each of the corresponding signed 8-bit values of the 128-bit /// integer vectors to determine if the values in the first operand are -/// greater than those in the second operand. Each comparison yields 0x0 for -/// false, 0xFF for true. +/// greater than those in the second operand. +/// +/// Each comparison yields 0x0 for false, 0xFF for true. /// /// \headerfile /// @@ -4745,6 +4739,74 @@ static __inline__ __m128d __DEFAULT_FN_ATTRS _mm_castsi128_pd(__m128i __a) { return (__m128d)__a; } +/// Compares each of the corresponding double-precision values of two +/// 128-bit vectors of [2 x double], using the operation specified by the +/// immediate integer operand. +/// +/// Each comparison yields 0x0 for false, 0xFFFFFFFFFFFFFFFF for true. +/// +/// \headerfile +/// +/// \code +/// __m128d _mm_cmp_pd(__m128d a, __m128d b, const int c); +/// \endcode +/// +/// This intrinsic corresponds to the (V)CMPPD instruction. +/// +/// \param a +/// A 128-bit vector of [2 x double]. +/// \param b +/// A 128-bit vector of [2 x double]. +/// \param c +/// An immediate integer operand, with bits [4:0] specifying which comparison +/// operation to use: \n +/// 0x00: Equal (ordered, non-signaling) \n +/// 0x01: Less-than (ordered, signaling) \n +/// 0x02: Less-than-or-equal (ordered, signaling) \n +/// 0x03: Unordered (non-signaling) \n +/// 0x04: Not-equal (unordered, non-signaling) \n +/// 0x05: Not-less-than (unordered, signaling) \n +/// 0x06: Not-less-than-or-equal (unordered, signaling) \n +/// 0x07: Ordered (non-signaling) \n +/// \returns A 128-bit vector of [2 x double] containing the comparison results. +#define _mm_cmp_pd(a, b, c) \ + ((__m128d)__builtin_ia32_cmppd((__v2df)(__m128d)(a), (__v2df)(__m128d)(b), \ + (c))) + +/// Compares each of the corresponding scalar double-precision values of +/// two 128-bit vectors of [2 x double], using the operation specified by the +/// immediate integer operand. +/// +/// Each comparison yields 0x0 for false, 0xFFFFFFFFFFFFFFFF for true. +/// +/// \headerfile +/// +/// \code +/// __m128d _mm_cmp_sd(__m128d a, __m128d b, const int c); +/// \endcode +/// +/// This intrinsic corresponds to the (V)CMPSD instruction. +/// +/// \param a +/// A 128-bit vector of [2 x double]. +/// \param b +/// A 128-bit vector of [2 x double]. +/// \param c +/// An immediate integer operand, with bits [4:0] specifying which comparison +/// operation to use: \n +/// 0x00: Equal (ordered, non-signaling) \n +/// 0x01: Less-than (ordered, signaling) \n +/// 0x02: Less-than-or-equal (ordered, signaling) \n +/// 0x03: Unordered (non-signaling) \n +/// 0x04: Not-equal (unordered, non-signaling) \n +/// 0x05: Not-less-than (unordered, signaling) \n +/// 0x06: Not-less-than-or-equal (unordered, signaling) \n +/// 0x07: Ordered (non-signaling) \n +/// \returns A 128-bit vector of [2 x double] containing the comparison results. +#define _mm_cmp_sd(a, b, c) \ + ((__m128d)__builtin_ia32_cmpsd((__v2df)(__m128d)(a), (__v2df)(__m128d)(b), \ + (c))) + #if defined(__cplusplus) extern "C" { #endif diff --git a/clang/lib/Headers/hlsl/hlsl_intrinsics.h b/clang/lib/Headers/hlsl/hlsl_intrinsics.h index 45f8544392584e49d3c5708b2be329f6d2e7b7e8..5e703772b7ee4f539d21efba95ece7b3737af31f 100644 --- a/clang/lib/Headers/hlsl/hlsl_intrinsics.h +++ b/clang/lib/Headers/hlsl/hlsl_intrinsics.h @@ -252,6 +252,116 @@ double3 ceil(double3); _HLSL_BUILTIN_ALIAS(__builtin_elementwise_ceil) double4 ceil(double4); +//===----------------------------------------------------------------------===// +// clamp builtins +//===----------------------------------------------------------------------===// + +/// \fn T clamp(T X, T Min, T Max) +/// \brief Clamps the specified value \a X to the specified +/// minimum ( \a Min) and maximum ( \a Max) range. +/// \param X A value to clamp. +/// \param Min The specified minimum range. +/// \param Max The specified maximum range. +/// +/// Returns The clamped value for the \a X parameter. +/// For values of -INF or INF, clamp will behave as expected. +/// However for values of NaN, the results are undefined. + +_HLSL_16BIT_AVAILABILITY(shadermodel, 6.2) +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_clamp) +half clamp(half, half, half); +_HLSL_16BIT_AVAILABILITY(shadermodel, 6.2) +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_clamp) +half2 clamp(half2, half2, half2); +_HLSL_16BIT_AVAILABILITY(shadermodel, 6.2) +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_clamp) +half3 clamp(half3, half3, half3); +_HLSL_16BIT_AVAILABILITY(shadermodel, 6.2) +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_clamp) +half4 clamp(half4, half4, half4); + +#ifdef __HLSL_ENABLE_16_BIT +_HLSL_AVAILABILITY(shadermodel, 6.2) +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_clamp) +int16_t clamp(int16_t, int16_t, int16_t); +_HLSL_AVAILABILITY(shadermodel, 6.2) +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_clamp) +int16_t2 clamp(int16_t2, int16_t2, int16_t2); +_HLSL_AVAILABILITY(shadermodel, 6.2) +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_clamp) +int16_t3 clamp(int16_t3, int16_t3, int16_t3); +_HLSL_AVAILABILITY(shadermodel, 6.2) +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_clamp) +int16_t4 clamp(int16_t4, int16_t4, int16_t4); + +_HLSL_AVAILABILITY(shadermodel, 6.2) +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_clamp) +uint16_t clamp(uint16_t, uint16_t, uint16_t); +_HLSL_AVAILABILITY(shadermodel, 6.2) +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_clamp) +uint16_t2 clamp(uint16_t2, uint16_t2, uint16_t2); +_HLSL_AVAILABILITY(shadermodel, 6.2) +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_clamp) +uint16_t3 clamp(uint16_t3, uint16_t3, uint16_t3); +_HLSL_AVAILABILITY(shadermodel, 6.2) +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_clamp) +uint16_t4 clamp(uint16_t4, uint16_t4, uint16_t4); +#endif + +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_clamp) +int clamp(int, int, int); +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_clamp) +int2 clamp(int2, int2, int2); +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_clamp) +int3 clamp(int3, int3, int3); +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_clamp) +int4 clamp(int4, int4, int4); + +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_clamp) +uint clamp(uint, uint, uint); +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_clamp) +uint2 clamp(uint2, uint2, uint2); +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_clamp) +uint3 clamp(uint3, uint3, uint3); +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_clamp) +uint4 clamp(uint4, uint4, uint4); + +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_clamp) +int64_t clamp(int64_t, int64_t, int64_t); +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_clamp) +int64_t2 clamp(int64_t2, int64_t2, int64_t2); +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_clamp) +int64_t3 clamp(int64_t3, int64_t3, int64_t3); +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_clamp) +int64_t4 clamp(int64_t4, int64_t4, int64_t4); + +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_clamp) +uint64_t clamp(uint64_t, uint64_t, uint64_t); +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_clamp) +uint64_t2 clamp(uint64_t2, uint64_t2, uint64_t2); +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_clamp) +uint64_t3 clamp(uint64_t3, uint64_t3, uint64_t3); +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_clamp) +uint64_t4 clamp(uint64_t4, uint64_t4, uint64_t4); + +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_clamp) +float clamp(float, float, float); +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_clamp) +float2 clamp(float2, float2, float2); +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_clamp) +float3 clamp(float3, float3, float3); +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_clamp) +float4 clamp(float4, float4, float4); + +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_clamp) +double clamp(double, double, double); +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_clamp) +double2 clamp(double2, double2, double2); +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_clamp) +double3 clamp(double3, double3, double3); +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_clamp) +double4 clamp(double4, double4, double4); + //===----------------------------------------------------------------------===// // cos builtins //===----------------------------------------------------------------------===// @@ -525,6 +635,39 @@ float3 frac(float3); _HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_frac) float4 frac(float4); +//===----------------------------------------------------------------------===// +// isinf builtins +//===----------------------------------------------------------------------===// + +/// \fn T isinf(T x) +/// \brief Determines if the specified value \a x is infinite. +/// \param x The specified input value. +/// +/// Returns a value of the same size as the input, with a value set +/// to True if the x parameter is +INF or -INF. Otherwise, False. + +_HLSL_16BIT_AVAILABILITY(shadermodel, 6.2) +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_isinf) +bool isinf(half); +_HLSL_16BIT_AVAILABILITY(shadermodel, 6.2) +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_isinf) +bool2 isinf(half2); +_HLSL_16BIT_AVAILABILITY(shadermodel, 6.2) +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_isinf) +bool3 isinf(half3); +_HLSL_16BIT_AVAILABILITY(shadermodel, 6.2) +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_isinf) +bool4 isinf(half4); + +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_isinf) +bool isinf(float); +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_isinf) +bool2 isinf(float2); +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_isinf) +bool3 isinf(float3); +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_isinf) +bool4 isinf(float4); + //===----------------------------------------------------------------------===// // lerp builtins //===----------------------------------------------------------------------===// @@ -1153,6 +1296,39 @@ double3 rcp(double3); _HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_rcp) double4 rcp(double4); +//===----------------------------------------------------------------------===// +// rsqrt builtins +//===----------------------------------------------------------------------===// + +/// \fn T rsqrt(T x) +/// \brief Returns the reciprocal of the square root of the specified value. +/// ie 1 / sqrt( \a x). +/// \param x The specified input value. +/// +/// This function uses the following formula: 1 / sqrt(x). + +_HLSL_16BIT_AVAILABILITY(shadermodel, 6.2) +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_rsqrt) +half rsqrt(half); +_HLSL_16BIT_AVAILABILITY(shadermodel, 6.2) +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_rsqrt) +half2 rsqrt(half2); +_HLSL_16BIT_AVAILABILITY(shadermodel, 6.2) +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_rsqrt) +half3 rsqrt(half3); +_HLSL_16BIT_AVAILABILITY(shadermodel, 6.2) +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_rsqrt) +half4 rsqrt(half4); + +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_rsqrt) +float rsqrt(float); +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_rsqrt) +float2 rsqrt(float2); +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_rsqrt) +float3 rsqrt(float3); +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_rsqrt) +float4 rsqrt(float4); + //===----------------------------------------------------------------------===// // round builtins //===----------------------------------------------------------------------===// diff --git a/clang/lib/Headers/module.modulemap b/clang/lib/Headers/module.modulemap index a786689d391773c2b1bf61f04a947d15309b7bfa..8741968fa7f364b64394e3e985ce0e6d755b6a84 100644 --- a/clang/lib/Headers/module.modulemap +++ b/clang/lib/Headers/module.modulemap @@ -155,9 +155,9 @@ module _Builtin_intrinsics [system] [extern_c] { // Start -fbuiltin-headers-in-system-modules affected modules -// The following modules all ignore their top level headers -// when -fbuiltin-headers-in-system-modules is passed, and -// most of those headers join system modules when present. +// The following modules all ignore their headers when +// -fbuiltin-headers-in-system-modules is passed, and many of +// those headers join system modules when present. // e.g. if -fbuiltin-headers-in-system-modules is passed, then // float.h will not be in the _Builtin_float module (that module @@ -190,11 +190,6 @@ module _Builtin_stdalign [system] { export * } -// When -fbuiltin-headers-in-system-modules is passed, only -// the top level headers are removed, the implementation headers -// will always be in their submodules. That means when stdarg.h -// is included, it will still import this module and make the -// appropriate submodules visible. module _Builtin_stdarg [system] { textual header "stdarg.h" @@ -237,6 +232,8 @@ module _Builtin_stdbool [system] { module _Builtin_stddef [system] { textual header "stddef.h" + // __stddef_max_align_t.h is always in this module, even if + // -fbuiltin-headers-in-system-modules is passed. explicit module max_align_t { header "__stddef_max_align_t.h" export * @@ -283,9 +280,10 @@ module _Builtin_stddef [system] { } } -/* wint_t is provided by and not . It's here - * for compatibility, but must be explicitly requested. Therefore - * __stddef_wint_t.h is not part of _Builtin_stddef. */ +// wint_t is provided by and not . It's here +// for compatibility, but must be explicitly requested. Therefore +// __stddef_wint_t.h is not part of _Builtin_stddef. It is always in +// this module even if -fbuiltin-headers-in-system-modules is passed. module _Builtin_stddef_wint_t [system] { header "__stddef_wint_t.h" export * @@ -317,3 +315,8 @@ module opencl_c { header "opencl-c.h" header "opencl-c-base.h" } + +module ptrauth { + header "ptrauth.h" + export * +} diff --git a/clang/lib/Headers/ptrauth.h b/clang/lib/Headers/ptrauth.h new file mode 100644 index 0000000000000000000000000000000000000000..56c3c3636c9bcd9f76819ef9fb62777a79889b71 --- /dev/null +++ b/clang/lib/Headers/ptrauth.h @@ -0,0 +1,185 @@ +/*===---- ptrauth.h - Pointer authentication -------------------------------=== + * + * 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 __PTRAUTH_H +#define __PTRAUTH_H + +typedef enum { + ptrauth_key_asia = 0, + ptrauth_key_asib = 1, + ptrauth_key_asda = 2, + ptrauth_key_asdb = 3, +} ptrauth_key; + +/* An integer type of the appropriate size for a discriminator argument. */ +typedef __UINTPTR_TYPE__ ptrauth_extra_data_t; + +/* An integer type of the appropriate size for a generic signature. */ +typedef __UINTPTR_TYPE__ ptrauth_generic_signature_t; + +/* A signed pointer value embeds the original pointer together with + a signature that attests to the validity of that pointer. Because + this signature must use only "spare" bits of the pointer, a + signature's validity is probabilistic in practice: it is unlikely + but still plausible that an invalidly-derived signature will + somehow equal the correct signature and therefore successfully + authenticate. Nonetheless, this scheme provides a strong degree + of protection against certain kinds of attacks. */ + +/* Authenticating a pointer that was not signed with the given key + and extra-data value will (likely) fail by trapping. */ + +#if __has_feature(ptrauth_intrinsics) + +/* Strip the signature from a value without authenticating it. + + If the value is a function pointer, the result will not be a + legal function pointer because of the missing signature, and + attempting to call it will result in an authentication failure. + + The value must be an expression of pointer type. + The key must be a constant expression of type ptrauth_key. + The result will have the same type as the original value. */ +#define ptrauth_strip(__value, __key) __builtin_ptrauth_strip(__value, __key) + +/* Blend a constant discriminator into the given pointer-like value + to form a new discriminator. Not all bits of the inputs are + guaranteed to contribute to the result. + + On arm64e, the integer must fall within the range of a uint16_t; + other bits may be ignored. + + The first argument must be an expression of pointer type. + The second argument must be an expression of integer type. + The result will have type uintptr_t. */ +#define ptrauth_blend_discriminator(__pointer, __integer) \ + __builtin_ptrauth_blend_discriminator(__pointer, __integer) + +/* Add a signature to the given pointer value using a specific key, + using the given extra data as a salt to the signing process. + + This operation does not authenticate the original value and is + therefore potentially insecure if an attacker could possibly + control that value. + + The value must be an expression of pointer type. + The key must be a constant expression of type ptrauth_key. + The extra data must be an expression of pointer or integer type; + if an integer, it will be coerced to ptrauth_extra_data_t. + The result will have the same type as the original value. */ +#define ptrauth_sign_unauthenticated(__value, __key, __data) \ + __builtin_ptrauth_sign_unauthenticated(__value, __key, __data) + +/* Authenticate a pointer using one scheme and resign it using another. + + If the result is subsequently authenticated using the new scheme, that + authentication is guaranteed to fail if and only if the initial + authentication failed. + + The value must be an expression of pointer type. + The key must be a constant expression of type ptrauth_key. + The extra data must be an expression of pointer or integer type; + if an integer, it will be coerced to ptrauth_extra_data_t. + The result will have the same type as the original value. + + This operation is guaranteed to not leave the intermediate value + available for attack before it is re-signed. + + Do not pass a null pointer to this function. A null pointer + will not successfully authenticate. + + This operation traps if the authentication fails. */ +#define ptrauth_auth_and_resign(__value, __old_key, __old_data, __new_key, \ + __new_data) \ + __builtin_ptrauth_auth_and_resign(__value, __old_key, __old_data, __new_key, \ + __new_data) + +/* Authenticate a data pointer. + + The value must be an expression of non-function pointer type. + The key must be a constant expression of type ptrauth_key. + The extra data must be an expression of pointer or integer type; + if an integer, it will be coerced to ptrauth_extra_data_t. + The result will have the same type as the original value. + + This operation traps if the authentication fails. */ +#define ptrauth_auth_data(__value, __old_key, __old_data) \ + __builtin_ptrauth_auth(__value, __old_key, __old_data) + +/* Compute a signature for the given pair of pointer-sized values. + The order of the arguments is significant. + + Like a pointer signature, the resulting signature depends on + private key data and therefore should not be reliably reproducible + by attackers. That means that this can be used to validate the + integrity of arbitrary data by storing a signature for that data + alongside it, then checking that the signature is still valid later. + Data which exceeds two pointers in size can be signed by either + computing a tree of generic signatures or just signing an ordinary + cryptographic hash of the data. + + The result has type ptrauth_generic_signature_t. However, it may + not have as many bits of entropy as that type's width would suggest; + some implementations are known to compute a compressed signature as + if the arguments were a pointer and a discriminator. + + The arguments must be either pointers or integers; if integers, they + will be coerce to uintptr_t. */ +#define ptrauth_sign_generic_data(__value, __data) \ + __builtin_ptrauth_sign_generic_data(__value, __data) + +#else + +#define ptrauth_strip(__value, __key) \ + ({ \ + (void)__key; \ + __value; \ + }) + +#define ptrauth_blend_discriminator(__pointer, __integer) \ + ({ \ + (void)__pointer; \ + (void)__integer; \ + ((ptrauth_extra_data_t)0); \ + }) + +#define ptrauth_sign_unauthenticated(__value, __key, __data) \ + ({ \ + (void)__key; \ + (void)__data; \ + __value; \ + }) + +#define ptrauth_auth_and_resign(__value, __old_key, __old_data, __new_key, \ + __new_data) \ + ({ \ + (void)__old_key; \ + (void)__old_data; \ + (void)__new_key; \ + (void)__new_data; \ + __value; \ + }) + +#define ptrauth_auth_data(__value, __old_key, __old_data) \ + ({ \ + (void)__old_key; \ + (void)__old_data; \ + __value; \ + }) + +#define ptrauth_sign_generic_data(__value, __data) \ + ({ \ + (void)__value; \ + (void)__data; \ + ((ptrauth_generic_signature_t)0); \ + }) + +#endif /* __has_feature(ptrauth_intrinsics) */ + +#endif /* __PTRAUTH_H */ diff --git a/clang/lib/Headers/smmintrin.h b/clang/lib/Headers/smmintrin.h index c52ffb77e33d5c4e986bab30f42d0553312257b9..9fb9cc9b01348cae2302249e55020fc0c36a58fb 100644 --- a/clang/lib/Headers/smmintrin.h +++ b/clang/lib/Headers/smmintrin.h @@ -1188,6 +1188,8 @@ static __inline__ int __DEFAULT_FN_ATTRS _mm_testnzc_si128(__m128i __M, /// Compares each of the corresponding 64-bit values of the 128-bit /// integer vectors for equality. /// +/// Each comparison yields 0x0 for false, 0xFFFFFFFFFFFFFFFF for true. +/// /// \headerfile /// /// This intrinsic corresponds to the VPCMPEQQ / PCMPEQQ instruction. @@ -2301,6 +2303,8 @@ static __inline__ __m128i __DEFAULT_FN_ATTRS _mm_minpos_epu16(__m128i __V) { /// integer vectors to determine if the values in the first operand are /// greater than those in the second operand. /// +/// Each comparison yields 0x0 for false, 0xFFFFFFFFFFFFFFFF for true. +/// /// \headerfile /// /// This intrinsic corresponds to the VPCMPGTQ / PCMPGTQ instruction. diff --git a/clang/lib/Headers/xmmintrin.h b/clang/lib/Headers/xmmintrin.h index 47368f3c23d2d6224d1a2855f0f48bd2de95a36d..8e386a72cde78989cbb0324aaf011ef46bbe11d9 100644 --- a/clang/lib/Headers/xmmintrin.h +++ b/clang/lib/Headers/xmmintrin.h @@ -474,7 +474,9 @@ _mm_xor_ps(__m128 __a, __m128 __b) } /// Compares two 32-bit float values in the low-order bits of both -/// operands for equality and returns the result of the comparison in the +/// operands for equality. +/// +/// The comparison yields 0x0 for false, 0xFFFFFFFF for true, in the /// low-order bits of a vector [4 x float]. /// /// \headerfile @@ -498,6 +500,8 @@ _mm_cmpeq_ss(__m128 __a, __m128 __b) /// Compares each of the corresponding 32-bit float values of the /// 128-bit vectors of [4 x float] for equality. /// +/// Each comparison yields 0x0 for false, 0xFFFFFFFF for true. +/// /// \headerfile /// /// This intrinsic corresponds to the VCMPEQPS / CMPEQPS instructions. @@ -515,8 +519,10 @@ _mm_cmpeq_ps(__m128 __a, __m128 __b) /// Compares two 32-bit float values in the low-order bits of both /// operands to determine if the value in the first operand is less than the -/// corresponding value in the second operand and returns the result of the -/// comparison in the low-order bits of a vector of [4 x float]. +/// corresponding value in the second operand. +/// +/// The comparison yields 0x0 for false, 0xFFFFFFFF for true, in the +/// low-order bits of a vector of [4 x float]. /// /// \headerfile /// @@ -540,6 +546,8 @@ _mm_cmplt_ss(__m128 __a, __m128 __b) /// 128-bit vectors of [4 x float] to determine if the values in the first /// operand are less than those in the second operand. /// +/// Each comparison yields 0x0 for false, 0xFFFFFFFFFFFFFFFF for true. +/// /// \headerfile /// /// This intrinsic corresponds to the VCMPLTPS / CMPLTPS instructions. @@ -557,9 +565,10 @@ _mm_cmplt_ps(__m128 __a, __m128 __b) /// Compares two 32-bit float values in the low-order bits of both /// operands to determine if the value in the first operand is less than or -/// equal to the corresponding value in the second operand and returns the -/// result of the comparison in the low-order bits of a vector of -/// [4 x float]. +/// equal to the corresponding value in the second operand. +/// +/// The comparison yields 0x0 for false, 0xFFFFFFFFFFFFFFFF for true, in +/// the low-order bits of a vector of [4 x float]. /// /// \headerfile /// @@ -583,6 +592,8 @@ _mm_cmple_ss(__m128 __a, __m128 __b) /// 128-bit vectors of [4 x float] to determine if the values in the first /// operand are less than or equal to those in the second operand. /// +/// Each comparison yields 0x0 for false, 0xFFFFFFFF for true. +/// /// \headerfile /// /// This intrinsic corresponds to the VCMPLEPS / CMPLEPS instructions. @@ -600,8 +611,10 @@ _mm_cmple_ps(__m128 __a, __m128 __b) /// Compares two 32-bit float values in the low-order bits of both /// operands to determine if the value in the first operand is greater than -/// the corresponding value in the second operand and returns the result of -/// the comparison in the low-order bits of a vector of [4 x float]. +/// the corresponding value in the second operand. +/// +/// The comparison yields 0x0 for false, 0xFFFFFFFF for true, in the +/// low-order bits of a vector of [4 x float]. /// /// \headerfile /// @@ -627,6 +640,8 @@ _mm_cmpgt_ss(__m128 __a, __m128 __b) /// 128-bit vectors of [4 x float] to determine if the values in the first /// operand are greater than those in the second operand. /// +/// Each comparison yields 0x0 for false, 0xFFFFFFFF for true. +/// /// \headerfile /// /// This intrinsic corresponds to the VCMPLTPS / CMPLTPS instructions. @@ -644,9 +659,10 @@ _mm_cmpgt_ps(__m128 __a, __m128 __b) /// Compares two 32-bit float values in the low-order bits of both /// operands to determine if the value in the first operand is greater than -/// or equal to the corresponding value in the second operand and returns -/// the result of the comparison in the low-order bits of a vector of -/// [4 x float]. +/// or equal to the corresponding value in the second operand. +/// +/// Each comparison yields 0x0 for false, 0xFFFFFFFF for true, in the +/// low-order bits of a vector of [4 x float]. /// /// \headerfile /// @@ -672,6 +688,8 @@ _mm_cmpge_ss(__m128 __a, __m128 __b) /// 128-bit vectors of [4 x float] to determine if the values in the first /// operand are greater than or equal to those in the second operand. /// +/// Each comparison yields 0x0 for false, 0xFFFFFFFFFFFFFFFF for true. +/// /// \headerfile /// /// This intrinsic corresponds to the VCMPLEPS / CMPLEPS instructions. @@ -687,8 +705,10 @@ _mm_cmpge_ps(__m128 __a, __m128 __b) return (__m128)__builtin_ia32_cmpleps((__v4sf)__b, (__v4sf)__a); } -/// Compares two 32-bit float values in the low-order bits of both -/// operands for inequality and returns the result of the comparison in the +/// Compares two 32-bit float values in the low-order bits of both operands +/// for inequality. +/// +/// The comparison yields 0x0 for false, 0xFFFFFFFF for true, in the /// low-order bits of a vector of [4 x float]. /// /// \headerfile @@ -713,6 +733,8 @@ _mm_cmpneq_ss(__m128 __a, __m128 __b) /// Compares each of the corresponding 32-bit float values of the /// 128-bit vectors of [4 x float] for inequality. /// +/// Each comparison yields 0x0 for false, 0xFFFFFFFF for true. +/// /// \headerfile /// /// This intrinsic corresponds to the VCMPNEQPS / CMPNEQPS @@ -731,8 +753,10 @@ _mm_cmpneq_ps(__m128 __a, __m128 __b) /// Compares two 32-bit float values in the low-order bits of both /// operands to determine if the value in the first operand is not less than -/// the corresponding value in the second operand and returns the result of -/// the comparison in the low-order bits of a vector of [4 x float]. +/// the corresponding value in the second operand. +/// +/// Each comparison yields 0x0 for false, 0xFFFFFFFF for true, in the +/// low-order bits of a vector of [4 x float]. /// /// \headerfile /// @@ -757,6 +781,8 @@ _mm_cmpnlt_ss(__m128 __a, __m128 __b) /// 128-bit vectors of [4 x float] to determine if the values in the first /// operand are not less than those in the second operand. /// +/// Each comparison yields 0x0 for false, 0xFFFFFFFF for true. +/// /// \headerfile /// /// This intrinsic corresponds to the VCMPNLTPS / CMPNLTPS @@ -775,9 +801,10 @@ _mm_cmpnlt_ps(__m128 __a, __m128 __b) /// Compares two 32-bit float values in the low-order bits of both /// operands to determine if the value in the first operand is not less than -/// or equal to the corresponding value in the second operand and returns -/// the result of the comparison in the low-order bits of a vector of -/// [4 x float]. +/// or equal to the corresponding value in the second operand. +/// +/// Each comparison yields 0x0 for false, 0xFFFFFFFF for true, in the +/// low-order bits of a vector of [4 x float]. /// /// \headerfile /// @@ -802,6 +829,8 @@ _mm_cmpnle_ss(__m128 __a, __m128 __b) /// 128-bit vectors of [4 x float] to determine if the values in the first /// operand are not less than or equal to those in the second operand. /// +/// Each comparison yields 0x0 for false, 0xFFFFFFFF for true. +/// /// \headerfile /// /// This intrinsic corresponds to the VCMPNLEPS / CMPNLEPS @@ -820,9 +849,10 @@ _mm_cmpnle_ps(__m128 __a, __m128 __b) /// Compares two 32-bit float values in the low-order bits of both /// operands to determine if the value in the first operand is not greater -/// than the corresponding value in the second operand and returns the -/// result of the comparison in the low-order bits of a vector of -/// [4 x float]. +/// than the corresponding value in the second operand. +/// +/// Each comparison yields 0x0 for false, 0xFFFFFFFF for true, in the +/// low-order bits of a vector of [4 x float]. /// /// \headerfile /// @@ -849,6 +879,8 @@ _mm_cmpngt_ss(__m128 __a, __m128 __b) /// 128-bit vectors of [4 x float] to determine if the values in the first /// operand are not greater than those in the second operand. /// +/// Each comparison yields 0x0 for false, 0xFFFFFFFF for true. +/// /// \headerfile /// /// This intrinsic corresponds to the VCMPNLTPS / CMPNLTPS @@ -867,9 +899,10 @@ _mm_cmpngt_ps(__m128 __a, __m128 __b) /// Compares two 32-bit float values in the low-order bits of both /// operands to determine if the value in the first operand is not greater -/// than or equal to the corresponding value in the second operand and -/// returns the result of the comparison in the low-order bits of a vector -/// of [4 x float]. +/// than or equal to the corresponding value in the second operand. +/// +/// Each comparison yields 0x0 for false, 0xFFFFFFFF for true, in the +/// low-order bits of a vector of [4 x float]. /// /// \headerfile /// @@ -896,6 +929,8 @@ _mm_cmpnge_ss(__m128 __a, __m128 __b) /// 128-bit vectors of [4 x float] to determine if the values in the first /// operand are not greater than or equal to those in the second operand. /// +/// Each comparison yields 0x0 for false, 0xFFFFFFFF for true. +/// /// \headerfile /// /// This intrinsic corresponds to the VCMPNLEPS / CMPNLEPS @@ -914,9 +949,10 @@ _mm_cmpnge_ps(__m128 __a, __m128 __b) /// Compares two 32-bit float values in the low-order bits of both /// operands to determine if the value in the first operand is ordered with -/// respect to the corresponding value in the second operand and returns the -/// result of the comparison in the low-order bits of a vector of -/// [4 x float]. +/// respect to the corresponding value in the second operand. +/// +/// Each comparison yields 0x0 for false, 0xFFFFFFFF for true, in the +/// low-order bits of a vector of [4 x float]. /// /// \headerfile /// @@ -941,6 +977,8 @@ _mm_cmpord_ss(__m128 __a, __m128 __b) /// 128-bit vectors of [4 x float] to determine if the values in the first /// operand are ordered with respect to those in the second operand. /// +/// Each comparison yields 0x0 for false, 0xFFFFFFFF for true. +/// /// \headerfile /// /// This intrinsic corresponds to the VCMPORDPS / CMPORDPS @@ -959,9 +997,10 @@ _mm_cmpord_ps(__m128 __a, __m128 __b) /// Compares two 32-bit float values in the low-order bits of both /// operands to determine if the value in the first operand is unordered -/// with respect to the corresponding value in the second operand and -/// returns the result of the comparison in the low-order bits of a vector -/// of [4 x float]. +/// with respect to the corresponding value in the second operand. +/// +/// Each comparison yields 0x0 for false, 0xFFFFFFFF for true, in the +/// low-order bits of a vector of [4 x float]. /// /// \headerfile /// @@ -986,6 +1025,8 @@ _mm_cmpunord_ss(__m128 __a, __m128 __b) /// 128-bit vectors of [4 x float] to determine if the values in the first /// operand are unordered with respect to those in the second operand. /// +/// Each comparison yields 0x0 for false, 0xFFFFFFFF for true. +/// /// \headerfile /// /// This intrinsic corresponds to the VCMPUNORDPS / CMPUNORDPS @@ -1003,9 +1044,10 @@ _mm_cmpunord_ps(__m128 __a, __m128 __b) } /// Compares two 32-bit float values in the low-order bits of both -/// operands for equality and returns the result of the comparison. +/// operands for equality. /// -/// If either of the two lower 32-bit values is NaN, 0 is returned. +/// The comparison returns 0 for false, 1 for true. If either of the two +/// lower floating-point values is NaN, returns 0. /// /// \headerfile /// @@ -1018,8 +1060,7 @@ _mm_cmpunord_ps(__m128 __a, __m128 __b) /// \param __b /// A 128-bit vector of [4 x float]. The lower 32 bits of this operand are /// used in the comparison. -/// \returns An integer containing the comparison results. If either of the -/// two lower 32-bit values is NaN, 0 is returned. +/// \returns An integer containing the comparison results. static __inline__ int __DEFAULT_FN_ATTRS _mm_comieq_ss(__m128 __a, __m128 __b) { @@ -1028,9 +1069,10 @@ _mm_comieq_ss(__m128 __a, __m128 __b) /// Compares two 32-bit float values in the low-order bits of both /// operands to determine if the first operand is less than the second -/// operand and returns the result of the comparison. +/// operand. /// -/// If either of the two lower 32-bit values is NaN, 0 is returned. +/// The comparison returns 0 for false, 1 for true. If either of the two +/// lower floating-point values is NaN, returns 0. /// /// \headerfile /// @@ -1043,8 +1085,7 @@ _mm_comieq_ss(__m128 __a, __m128 __b) /// \param __b /// A 128-bit vector of [4 x float]. The lower 32 bits of this operand are /// used in the comparison. -/// \returns An integer containing the comparison results. If either of the two -/// lower 32-bit values is NaN, 0 is returned. +/// \returns An integer containing the comparison results. static __inline__ int __DEFAULT_FN_ATTRS _mm_comilt_ss(__m128 __a, __m128 __b) { @@ -1053,9 +1094,10 @@ _mm_comilt_ss(__m128 __a, __m128 __b) /// Compares two 32-bit float values in the low-order bits of both /// operands to determine if the first operand is less than or equal to the -/// second operand and returns the result of the comparison. +/// second operand. /// -/// If either of the two lower 32-bit values is NaN, 0 is returned. +/// The comparison returns 0 for false, 1 for true. If either of the two +/// lower floating-point values is NaN, returns 0. /// /// \headerfile /// @@ -1067,8 +1109,7 @@ _mm_comilt_ss(__m128 __a, __m128 __b) /// \param __b /// A 128-bit vector of [4 x float]. The lower 32 bits of this operand are /// used in the comparison. -/// \returns An integer containing the comparison results. If either of the two -/// lower 32-bit values is NaN, 0 is returned. +/// \returns An integer containing the comparison results. static __inline__ int __DEFAULT_FN_ATTRS _mm_comile_ss(__m128 __a, __m128 __b) { @@ -1077,9 +1118,10 @@ _mm_comile_ss(__m128 __a, __m128 __b) /// Compares two 32-bit float values in the low-order bits of both /// operands to determine if the first operand is greater than the second -/// operand and returns the result of the comparison. +/// operand. /// -/// If either of the two lower 32-bit values is NaN, 0 is returned. +/// The comparison returns 0 for false, 1 for true. If either of the two +/// lower floating-point values is NaN, returns 0. /// /// \headerfile /// @@ -1091,8 +1133,7 @@ _mm_comile_ss(__m128 __a, __m128 __b) /// \param __b /// A 128-bit vector of [4 x float]. The lower 32 bits of this operand are /// used in the comparison. -/// \returns An integer containing the comparison results. If either of the -/// two lower 32-bit values is NaN, 0 is returned. +/// \returns An integer containing the comparison results. static __inline__ int __DEFAULT_FN_ATTRS _mm_comigt_ss(__m128 __a, __m128 __b) { @@ -1101,9 +1142,10 @@ _mm_comigt_ss(__m128 __a, __m128 __b) /// Compares two 32-bit float values in the low-order bits of both /// operands to determine if the first operand is greater than or equal to -/// the second operand and returns the result of the comparison. +/// the second operand. /// -/// If either of the two lower 32-bit values is NaN, 0 is returned. +/// The comparison returns 0 for false, 1 for true. If either of the two +/// lower floating-point values is NaN, returns 0. /// /// \headerfile /// @@ -1115,8 +1157,7 @@ _mm_comigt_ss(__m128 __a, __m128 __b) /// \param __b /// A 128-bit vector of [4 x float]. The lower 32 bits of this operand are /// used in the comparison. -/// \returns An integer containing the comparison results. If either of the two -/// lower 32-bit values is NaN, 0 is returned. +/// \returns An integer containing the comparison results. static __inline__ int __DEFAULT_FN_ATTRS _mm_comige_ss(__m128 __a, __m128 __b) { @@ -1125,9 +1166,10 @@ _mm_comige_ss(__m128 __a, __m128 __b) /// Compares two 32-bit float values in the low-order bits of both /// operands to determine if the first operand is not equal to the second -/// operand and returns the result of the comparison. +/// operand. /// -/// If either of the two lower 32-bit values is NaN, 1 is returned. +/// The comparison returns 0 for false, 1 for true. If either of the two +/// lower floating-point values is NaN, returns 0. /// /// \headerfile /// @@ -1139,8 +1181,7 @@ _mm_comige_ss(__m128 __a, __m128 __b) /// \param __b /// A 128-bit vector of [4 x float]. The lower 32 bits of this operand are /// used in the comparison. -/// \returns An integer containing the comparison results. If either of the -/// two lower 32-bit values is NaN, 1 is returned. +/// \returns An integer containing the comparison results. static __inline__ int __DEFAULT_FN_ATTRS _mm_comineq_ss(__m128 __a, __m128 __b) { @@ -1148,10 +1189,10 @@ _mm_comineq_ss(__m128 __a, __m128 __b) } /// Performs an unordered comparison of two 32-bit float values using -/// the low-order bits of both operands to determine equality and returns -/// the result of the comparison. +/// the low-order bits of both operands to determine equality. /// -/// If either of the two lower 32-bit values is NaN, 0 is returned. +/// The comparison returns 0 for false, 1 for true. If either of the two +/// lower floating-point values is NaN, returns 0. /// /// \headerfile /// @@ -1163,8 +1204,7 @@ _mm_comineq_ss(__m128 __a, __m128 __b) /// \param __b /// A 128-bit vector of [4 x float]. The lower 32 bits of this operand are /// used in the comparison. -/// \returns An integer containing the comparison results. If either of the two -/// lower 32-bit values is NaN, 0 is returned. +/// \returns An integer containing the comparison results. static __inline__ int __DEFAULT_FN_ATTRS _mm_ucomieq_ss(__m128 __a, __m128 __b) { @@ -1173,9 +1213,10 @@ _mm_ucomieq_ss(__m128 __a, __m128 __b) /// Performs an unordered comparison of two 32-bit float values using /// the low-order bits of both operands to determine if the first operand is -/// less than the second operand and returns the result of the comparison. +/// less than the second operand. /// -/// If either of the two lower 32-bit values is NaN, 0 is returned. +/// The comparison returns 0 for false, 1 for true. If either of the two +/// lower floating-point values is NaN, returns 0. /// /// \headerfile /// @@ -1187,8 +1228,7 @@ _mm_ucomieq_ss(__m128 __a, __m128 __b) /// \param __b /// A 128-bit vector of [4 x float]. The lower 32 bits of this operand are /// used in the comparison. -/// \returns An integer containing the comparison results. If either of the two -/// lower 32-bit values is NaN, 0 is returned. +/// \returns An integer containing the comparison results. static __inline__ int __DEFAULT_FN_ATTRS _mm_ucomilt_ss(__m128 __a, __m128 __b) { @@ -1197,10 +1237,10 @@ _mm_ucomilt_ss(__m128 __a, __m128 __b) /// Performs an unordered comparison of two 32-bit float values using /// the low-order bits of both operands to determine if the first operand is -/// less than or equal to the second operand and returns the result of the -/// comparison. +/// less than or equal to the second operand. /// -/// If either of the two lower 32-bit values is NaN, 0 is returned. +/// The comparison returns 0 for false, 1 for true. If either of the two +/// lower floating-point values is NaN, returns 0. /// /// \headerfile /// @@ -1212,8 +1252,7 @@ _mm_ucomilt_ss(__m128 __a, __m128 __b) /// \param __b /// A 128-bit vector of [4 x float]. The lower 32 bits of this operand are /// used in the comparison. -/// \returns An integer containing the comparison results. If either of the two -/// lower 32-bit values is NaN, 0 is returned. +/// \returns An integer containing the comparison results. static __inline__ int __DEFAULT_FN_ATTRS _mm_ucomile_ss(__m128 __a, __m128 __b) { @@ -1222,10 +1261,10 @@ _mm_ucomile_ss(__m128 __a, __m128 __b) /// Performs an unordered comparison of two 32-bit float values using /// the low-order bits of both operands to determine if the first operand is -/// greater than the second operand and returns the result of the -/// comparison. +/// greater than the second operand. /// -/// If either of the two lower 32-bit values is NaN, 0 is returned. +/// The comparison returns 0 for false, 1 for true. If either of the two +/// lower floating-point values is NaN, returns 0. /// /// \headerfile /// @@ -1237,8 +1276,7 @@ _mm_ucomile_ss(__m128 __a, __m128 __b) /// \param __b /// A 128-bit vector of [4 x float]. The lower 32 bits of this operand are /// used in the comparison. -/// \returns An integer containing the comparison results. If either of the two -/// lower 32-bit values is NaN, 0 is returned. +/// \returns An integer containing the comparison results. static __inline__ int __DEFAULT_FN_ATTRS _mm_ucomigt_ss(__m128 __a, __m128 __b) { @@ -1247,10 +1285,10 @@ _mm_ucomigt_ss(__m128 __a, __m128 __b) /// Performs an unordered comparison of two 32-bit float values using /// the low-order bits of both operands to determine if the first operand is -/// greater than or equal to the second operand and returns the result of -/// the comparison. +/// greater than or equal to the second operand. /// -/// If either of the two lower 32-bit values is NaN, 0 is returned. +/// The comparison returns 0 for false, 1 for true. If either of the two +/// lower floating-point values is NaN, returns 0. /// /// \headerfile /// @@ -1262,8 +1300,7 @@ _mm_ucomigt_ss(__m128 __a, __m128 __b) /// \param __b /// A 128-bit vector of [4 x float]. The lower 32 bits of this operand are /// used in the comparison. -/// \returns An integer containing the comparison results. If either of the two -/// lower 32-bit values is NaN, 0 is returned. +/// \returns An integer containing the comparison results. static __inline__ int __DEFAULT_FN_ATTRS _mm_ucomige_ss(__m128 __a, __m128 __b) { @@ -1271,10 +1308,10 @@ _mm_ucomige_ss(__m128 __a, __m128 __b) } /// Performs an unordered comparison of two 32-bit float values using -/// the low-order bits of both operands to determine inequality and returns -/// the result of the comparison. +/// the low-order bits of both operands to determine inequality. /// -/// If either of the two lower 32-bit values is NaN, 1 is returned. +/// The comparison returns 0 for false, 1 for true. If either of the two +/// lower floating-point values is NaN, returns 0. /// /// \headerfile /// @@ -1286,8 +1323,7 @@ _mm_ucomige_ss(__m128 __a, __m128 __b) /// \param __b /// A 128-bit vector of [4 x float]. The lower 32 bits of this operand are /// used in the comparison. -/// \returns An integer containing the comparison results. If either of the two -/// lower 32-bit values is NaN, 1 is returned. +/// \returns An integer containing the comparison results. static __inline__ int __DEFAULT_FN_ATTRS _mm_ucomineq_ss(__m128 __a, __m128 __b) { @@ -2940,6 +2976,81 @@ _mm_movemask_ps(__m128 __a) return __builtin_ia32_movmskps((__v4sf)__a); } +/* Compare */ +#define _CMP_EQ_OQ 0x00 /* Equal (ordered, non-signaling) */ +#define _CMP_LT_OS 0x01 /* Less-than (ordered, signaling) */ +#define _CMP_LE_OS 0x02 /* Less-than-or-equal (ordered, signaling) */ +#define _CMP_UNORD_Q 0x03 /* Unordered (non-signaling) */ +#define _CMP_NEQ_UQ 0x04 /* Not-equal (unordered, non-signaling) */ +#define _CMP_NLT_US 0x05 /* Not-less-than (unordered, signaling) */ +#define _CMP_NLE_US 0x06 /* Not-less-than-or-equal (unordered, signaling) */ +#define _CMP_ORD_Q 0x07 /* Ordered (non-signaling) */ + +/// Compares each of the corresponding values of two 128-bit vectors of +/// [4 x float], using the operation specified by the immediate integer +/// operand. +/// +/// Each comparison yields 0x0 for false, 0xFFFFFFFF for true. +/// +/// \headerfile +/// +/// \code +/// __m128 _mm_cmp_ps(__m128 a, __m128 b, const int c); +/// \endcode +/// +/// This intrinsic corresponds to the (V)CMPPS instruction. +/// +/// \param a +/// A 128-bit vector of [4 x float]. +/// \param b +/// A 128-bit vector of [4 x float]. +/// \param c +/// An immediate integer operand, with bits [4:0] specifying which comparison +/// operation to use: \n +/// 0x00: Equal (ordered, non-signaling) \n +/// 0x01: Less-than (ordered, signaling) \n +/// 0x02: Less-than-or-equal (ordered, signaling) \n +/// 0x03: Unordered (non-signaling) \n +/// 0x04: Not-equal (unordered, non-signaling) \n +/// 0x05: Not-less-than (unordered, signaling) \n +/// 0x06: Not-less-than-or-equal (unordered, signaling) \n +/// 0x07: Ordered (non-signaling) \n +/// \returns A 128-bit vector of [4 x float] containing the comparison results. +#define _mm_cmp_ps(a, b, c) \ + ((__m128)__builtin_ia32_cmpps((__v4sf)(__m128)(a), (__v4sf)(__m128)(b), (c))) + +/// Compares each of the corresponding scalar values of two 128-bit +/// vectors of [4 x float], using the operation specified by the immediate +/// integer operand. +/// +/// Each comparison yields 0x0 for false, 0xFFFFFFFF for true. +/// +/// \headerfile +/// +/// \code +/// __m128 _mm_cmp_ss(__m128 a, __m128 b, const int c); +/// \endcode +/// +/// This intrinsic corresponds to the (V)CMPSS instruction. +/// +/// \param a +/// A 128-bit vector of [4 x float]. +/// \param b +/// A 128-bit vector of [4 x float]. +/// \param c +/// An immediate integer operand, with bits [4:0] specifying which comparison +/// operation to use: \n +/// 0x00: Equal (ordered, non-signaling) \n +/// 0x01: Less-than (ordered, signaling) \n +/// 0x02: Less-than-or-equal (ordered, signaling) \n +/// 0x03: Unordered (non-signaling) \n +/// 0x04: Not-equal (unordered, non-signaling) \n +/// 0x05: Not-less-than (unordered, signaling) \n +/// 0x06: Not-less-than-or-equal (unordered, signaling) \n +/// 0x07: Ordered (non-signaling) \n +/// \returns A 128-bit vector of [4 x float] containing the comparison results. +#define _mm_cmp_ss(a, b, c) \ + ((__m128)__builtin_ia32_cmpss((__v4sf)(__m128)(a), (__v4sf)(__m128)(b), (c))) #define _MM_ALIGN16 __attribute__((aligned(16))) diff --git a/clang/lib/InstallAPI/CMakeLists.txt b/clang/lib/InstallAPI/CMakeLists.txt index dc90d6370de418f34f981e3993af658de62d9f38..894db699578f209a3300cd53fa7527b70d1229bd 100644 --- a/clang/lib/InstallAPI/CMakeLists.txt +++ b/clang/lib/InstallAPI/CMakeLists.txt @@ -1,10 +1,12 @@ set(LLVM_LINK_COMPONENTS Support TextAPI + Demangle Core ) add_clang_library(clangInstallAPI + DylibVerifier.cpp FileList.cpp Frontend.cpp HeaderFile.cpp diff --git a/clang/lib/InstallAPI/DylibVerifier.cpp b/clang/lib/InstallAPI/DylibVerifier.cpp new file mode 100644 index 0000000000000000000000000000000000000000..b7dd85d63fa14fb88afd7682fec56d5938311dfe --- /dev/null +++ b/clang/lib/InstallAPI/DylibVerifier.cpp @@ -0,0 +1,212 @@ +#include "clang/InstallAPI/DylibVerifier.h" +#include "clang/InstallAPI/FrontendRecords.h" +#include "llvm/Demangle/Demangle.h" + +using namespace llvm::MachO; + +namespace clang { +namespace installapi { + +/// Metadata stored about a mapping of a declaration to a symbol. +struct DylibVerifier::SymbolContext { + // Name to use for printing in diagnostics. + std::string PrettyPrintName{""}; + + // Name to use for all querying and verification + // purposes. + std::string SymbolName{""}; + + // Kind to map symbol type against record. + EncodeKind Kind = EncodeKind::GlobalSymbol; + + // Frontend Attributes tied to the AST. + const FrontendAttrs *FA = nullptr; + + // The ObjCInterface symbol type, if applicable. + ObjCIFSymbolKind ObjCIFKind = ObjCIFSymbolKind::None; +}; + +static std::string +getAnnotatedName(const Record *R, EncodeKind Kind, StringRef Name, + bool ValidSourceLoc = true, + ObjCIFSymbolKind ObjCIF = ObjCIFSymbolKind::None) { + assert(!Name.empty() && "Need symbol name for printing"); + + std::string Annotation; + if (R->isWeakDefined()) + Annotation += "(weak-def) "; + if (R->isWeakReferenced()) + Annotation += "(weak-ref) "; + if (R->isThreadLocalValue()) + Annotation += "(tlv) "; + + // Check if symbol represents only part of a @interface declaration. + const bool IsAnnotatedObjCClass = ((ObjCIF != ObjCIFSymbolKind::None) && + (ObjCIF <= ObjCIFSymbolKind::EHType)); + + if (IsAnnotatedObjCClass) { + if (ObjCIF == ObjCIFSymbolKind::EHType) + Annotation += "Exception Type of "; + if (ObjCIF == ObjCIFSymbolKind::MetaClass) + Annotation += "Metaclass of "; + if (ObjCIF == ObjCIFSymbolKind::Class) + Annotation += "Class of "; + } + + // Only print symbol type prefix or leading "_" if there is no source location + // tied to it. This can only ever happen when the location has to come from + // debug info. + if (ValidSourceLoc) { + if ((Kind == EncodeKind::GlobalSymbol) && Name.starts_with("_")) + return Annotation + Name.drop_front(1).str(); + return Annotation + Name.str(); + } + + if (IsAnnotatedObjCClass) + return Annotation + Name.str(); + + switch (Kind) { + case EncodeKind::GlobalSymbol: + return Annotation + Name.str(); + case EncodeKind::ObjectiveCInstanceVariable: + return Annotation + "(ObjC IVar) " + Name.str(); + case EncodeKind::ObjectiveCClass: + return Annotation + "(ObjC Class) " + Name.str(); + case EncodeKind::ObjectiveCClassEHType: + return Annotation + "(ObjC Class EH) " + Name.str(); + } + + llvm_unreachable("unexpected case for EncodeKind"); +} + +static std::string demangle(StringRef Name) { + // Itanium encoding requires 1 or 3 leading underscores, followed by 'Z'. + if (!(Name.starts_with("_Z") || Name.starts_with("___Z"))) + return Name.str(); + char *Result = llvm::itaniumDemangle(Name.data()); + if (!Result) + return Name.str(); + + std::string Demangled(Result); + free(Result); + return Demangled; +} + +static DylibVerifier::Result updateResult(const DylibVerifier::Result Prev, + const DylibVerifier::Result Curr) { + if (Prev == Curr) + return Prev; + + // Never update from invalid or noverify state. + if ((Prev == DylibVerifier::Result::Invalid) || + (Prev == DylibVerifier::Result::NoVerify)) + return Prev; + + // Don't let an ignored verification remove a valid one. + if (Prev == DylibVerifier::Result::Valid && + Curr == DylibVerifier::Result::Ignore) + return Prev; + + return Curr; +} + +void DylibVerifier::updateState(Result State) { + Ctx.FrontendState = updateResult(Ctx.FrontendState, State); +} + +void DylibVerifier::addSymbol(const Record *R, SymbolContext &SymCtx, + TargetList &&Targets) { + if (Targets.empty()) + Targets = {Ctx.Target}; + + Exports->addGlobal(SymCtx.Kind, SymCtx.SymbolName, R->getFlags(), Targets); +} + +DylibVerifier::Result DylibVerifier::verifyImpl(Record *R, + SymbolContext &SymCtx) { + R->setVerify(); + if (!canVerify()) { + // Accumulate symbols when not in verifying against dylib. + if (R->isExported() && !SymCtx.FA->Avail.isUnconditionallyUnavailable() && + !SymCtx.FA->Avail.isObsoleted()) { + addSymbol(R, SymCtx); + } + return Ctx.FrontendState; + } + return Ctx.FrontendState; +} + +bool DylibVerifier::canVerify() { + return Ctx.FrontendState != Result::NoVerify; +} + +void DylibVerifier::setTarget(const Target &T) { + Ctx.Target = T; + Ctx.DiscoveredFirstError = false; + updateState(Dylib.empty() ? Result::NoVerify : Result::Ignore); +} + +DylibVerifier::Result DylibVerifier::verify(ObjCIVarRecord *R, + const FrontendAttrs *FA, + const StringRef SuperClass) { + if (R->isVerified()) + return getState(); + + std::string FullName = + ObjCIVarRecord::createScopedName(SuperClass, R->getName()); + SymbolContext SymCtx{ + getAnnotatedName(R, EncodeKind::ObjectiveCInstanceVariable, + Demangle ? demangle(FullName) : FullName), + FullName, EncodeKind::ObjectiveCInstanceVariable, FA}; + return verifyImpl(R, SymCtx); +} + +static ObjCIFSymbolKind assignObjCIFSymbolKind(const ObjCInterfaceRecord *R) { + ObjCIFSymbolKind Result = ObjCIFSymbolKind::None; + if (R->getLinkageForSymbol(ObjCIFSymbolKind::Class) != RecordLinkage::Unknown) + Result |= ObjCIFSymbolKind::Class; + if (R->getLinkageForSymbol(ObjCIFSymbolKind::MetaClass) != + RecordLinkage::Unknown) + Result |= ObjCIFSymbolKind::MetaClass; + if (R->getLinkageForSymbol(ObjCIFSymbolKind::EHType) != + RecordLinkage::Unknown) + Result |= ObjCIFSymbolKind::EHType; + return Result; +} + +DylibVerifier::Result DylibVerifier::verify(ObjCInterfaceRecord *R, + const FrontendAttrs *FA) { + if (R->isVerified()) + return getState(); + SymbolContext SymCtx; + SymCtx.SymbolName = R->getName(); + SymCtx.ObjCIFKind = assignObjCIFSymbolKind(R); + + std::string DisplayName = + Demangle ? demangle(SymCtx.SymbolName) : SymCtx.SymbolName; + SymCtx.Kind = R->hasExceptionAttribute() ? EncodeKind::ObjectiveCClassEHType + : EncodeKind::ObjectiveCClass; + SymCtx.PrettyPrintName = getAnnotatedName(R, SymCtx.Kind, DisplayName); + SymCtx.FA = FA; + + return verifyImpl(R, SymCtx); +} + +DylibVerifier::Result DylibVerifier::verify(GlobalRecord *R, + const FrontendAttrs *FA) { + if (R->isVerified()) + return getState(); + + // Global classifications could be obfusciated with `asm`. + SimpleSymbol Sym = parseSymbol(R->getName()); + SymbolContext SymCtx; + SymCtx.SymbolName = Sym.Name; + SymCtx.PrettyPrintName = + getAnnotatedName(R, Sym.Kind, Demangle ? demangle(Sym.Name) : Sym.Name); + SymCtx.Kind = Sym.Kind; + SymCtx.FA = FA; + return verifyImpl(R, SymCtx); +} + +} // namespace installapi +} // namespace clang diff --git a/clang/lib/InstallAPI/Frontend.cpp b/clang/lib/InstallAPI/Frontend.cpp index 1edbdf5bb983608324f24789667cf6dd3ae3ff55..12cd5fcbc22bf73fd40225d8c2b3457efeacf2c7 100644 --- a/clang/lib/InstallAPI/Frontend.cpp +++ b/clang/lib/InstallAPI/Frontend.cpp @@ -8,6 +8,7 @@ #include "clang/InstallAPI/Frontend.h" #include "clang/AST/Availability.h" +#include "clang/InstallAPI/FrontendRecords.h" #include "llvm/ADT/SmallString.h" #include "llvm/ADT/StringRef.h" @@ -15,41 +16,47 @@ using namespace llvm; using namespace llvm::MachO; namespace clang::installapi { - -GlobalRecord *FrontendRecordsSlice::addGlobal( +std::pair FrontendRecordsSlice::addGlobal( StringRef Name, RecordLinkage Linkage, GlobalRecord::Kind GV, const clang::AvailabilityInfo Avail, const Decl *D, const HeaderType Access, SymbolFlags Flags, bool Inlined) { - auto *GR = + GlobalRecord *GR = llvm::MachO::RecordsSlice::addGlobal(Name, Linkage, GV, Flags, Inlined); - FrontendRecords.insert({GR, FrontendAttrs{Avail, D, Access}}); - return GR; + auto Result = FrontendRecords.insert({GR, FrontendAttrs{Avail, D, Access}}); + return {GR, &(Result.first->second)}; } -ObjCInterfaceRecord *FrontendRecordsSlice::addObjCInterface( - StringRef Name, RecordLinkage Linkage, const clang::AvailabilityInfo Avail, - const Decl *D, HeaderType Access, bool IsEHType) { +std::pair +FrontendRecordsSlice::addObjCInterface(StringRef Name, RecordLinkage Linkage, + const clang::AvailabilityInfo Avail, + const Decl *D, HeaderType Access, + bool IsEHType) { ObjCIFSymbolKind SymType = ObjCIFSymbolKind::Class | ObjCIFSymbolKind::MetaClass; if (IsEHType) SymType |= ObjCIFSymbolKind::EHType; - auto *ObjCR = + + ObjCInterfaceRecord *ObjCR = llvm::MachO::RecordsSlice::addObjCInterface(Name, Linkage, SymType); - FrontendRecords.insert({ObjCR, FrontendAttrs{Avail, D, Access}}); - return ObjCR; + auto Result = + FrontendRecords.insert({ObjCR, FrontendAttrs{Avail, D, Access}}); + return {ObjCR, &(Result.first->second)}; } -ObjCCategoryRecord *FrontendRecordsSlice::addObjCCategory( - StringRef ClassToExtend, StringRef CategoryName, - const clang::AvailabilityInfo Avail, const Decl *D, HeaderType Access) { - auto *ObjCR = +std::pair +FrontendRecordsSlice::addObjCCategory(StringRef ClassToExtend, + StringRef CategoryName, + const clang::AvailabilityInfo Avail, + const Decl *D, HeaderType Access) { + ObjCCategoryRecord *ObjCR = llvm::MachO::RecordsSlice::addObjCCategory(ClassToExtend, CategoryName); - FrontendRecords.insert({ObjCR, FrontendAttrs{Avail, D, Access}}); - return ObjCR; + auto Result = + FrontendRecords.insert({ObjCR, FrontendAttrs{Avail, D, Access}}); + return {ObjCR, &(Result.first->second)}; } -ObjCIVarRecord *FrontendRecordsSlice::addObjCIVar( +std::pair FrontendRecordsSlice::addObjCIVar( ObjCContainerRecord *Container, StringRef IvarName, RecordLinkage Linkage, const clang::AvailabilityInfo Avail, const Decl *D, HeaderType Access, const clang::ObjCIvarDecl::AccessControl AC) { @@ -58,11 +65,12 @@ ObjCIVarRecord *FrontendRecordsSlice::addObjCIVar( if ((Linkage == RecordLinkage::Exported) && ((AC == ObjCIvarDecl::Private) || (AC == ObjCIvarDecl::Package))) Linkage = RecordLinkage::Internal; - auto *ObjCR = + ObjCIVarRecord *ObjCR = llvm::MachO::RecordsSlice::addObjCIVar(Container, IvarName, Linkage); - FrontendRecords.insert({ObjCR, FrontendAttrs{Avail, D, Access}}); + auto Result = + FrontendRecords.insert({ObjCR, FrontendAttrs{Avail, D, Access}}); - return nullptr; + return {ObjCR, &(Result.first->second)}; } std::optional @@ -137,9 +145,9 @@ std::unique_ptr createInputBuffer(InstallAPIContext &Ctx) { else OS << "#import "; if (H.useIncludeName()) - OS << "<" << H.getIncludeName() << ">"; + OS << "<" << H.getIncludeName() << ">\n"; else - OS << "\"" << H.getPath() << "\""; + OS << "\"" << H.getPath() << "\"\n"; Ctx.addKnownHeader(H); } diff --git a/clang/lib/InstallAPI/Visitor.cpp b/clang/lib/InstallAPI/Visitor.cpp index 1f2ef08e5aa252f9525d33f0e582650907bf1cec..187afe59309d37e43a72260c40c89a452701092f 100644 --- a/clang/lib/InstallAPI/Visitor.cpp +++ b/clang/lib/InstallAPI/Visitor.cpp @@ -7,9 +7,12 @@ //===----------------------------------------------------------------------===// #include "clang/InstallAPI/Visitor.h" +#include "clang/AST/Availability.h" #include "clang/AST/ParentMapContext.h" +#include "clang/AST/VTableBuilder.h" #include "clang/Basic/Linkage.h" -#include "clang/InstallAPI/Frontend.h" +#include "clang/InstallAPI/DylibVerifier.h" +#include "clang/InstallAPI/FrontendRecords.h" #include "llvm/ADT/SmallString.h" #include "llvm/ADT/StringRef.h" #include "llvm/IR/DataLayout.h" @@ -18,6 +21,15 @@ using namespace llvm; using namespace llvm::MachO; +namespace { +enum class CXXLinkage { + ExternalLinkage, + LinkOnceODRLinkage, + WeakODRLinkage, + PrivateLinkage, +}; +} + namespace clang::installapi { // Exported NamedDecl needs to have external linkage and @@ -53,7 +65,7 @@ static bool isInlined(const FunctionDecl *D) { return true; } -static SymbolFlags getFlags(bool WeakDef, bool ThreadLocal) { +static SymbolFlags getFlags(bool WeakDef, bool ThreadLocal = false) { SymbolFlags Result = SymbolFlags::None; if (WeakDef) Result |= SymbolFlags::WeakDefined; @@ -145,7 +157,9 @@ void InstallAPIVisitor::recordObjCInstanceVariables( StringRef Name = IV->getName(); const AvailabilityInfo Avail = AvailabilityInfo::createFromDecl(IV); auto AC = IV->getCanonicalAccessControl(); - Ctx.Slice->addObjCIVar(Record, Name, Linkage, Avail, IV, *Access, AC); + auto [ObjCIVR, FA] = + Ctx.Slice->addObjCIVar(Record, Name, Linkage, Avail, IV, *Access, AC); + Ctx.Verifier->verify(ObjCIVR, FA, SuperClass); } } @@ -167,15 +181,16 @@ bool InstallAPIVisitor::VisitObjCInterfaceDecl(const ObjCInterfaceDecl *D) { (!D->getASTContext().getLangOpts().ObjCRuntime.isFragile() && hasObjCExceptionAttribute(D)); - ObjCInterfaceRecord *Class = + auto [Class, FA] = Ctx.Slice->addObjCInterface(Name, Linkage, Avail, D, *Access, IsEHType); + Ctx.Verifier->verify(Class, FA); // Get base class. StringRef SuperClassName; if (const auto *SuperClass = D->getSuperClass()) SuperClassName = SuperClass->getObjCRuntimeNameAsString(); - recordObjCInstanceVariables(D->getASTContext(), Class, SuperClassName, + recordObjCInstanceVariables(D->getASTContext(), Class, Class->getName(), D->ivars()); return true; } @@ -190,8 +205,8 @@ bool InstallAPIVisitor::VisitObjCCategoryDecl(const ObjCCategoryDecl *D) { const ObjCInterfaceDecl *InterfaceD = D->getClassInterface(); const StringRef InterfaceName = InterfaceD->getName(); - ObjCCategoryRecord *Category = Ctx.Slice->addObjCCategory( - InterfaceName, CategoryName, Avail, D, *Access); + auto [Category, FA] = Ctx.Slice->addObjCCategory(InterfaceName, CategoryName, + Avail, D, *Access); recordObjCInstanceVariables(D->getASTContext(), Category, InterfaceName, D->ivars()); return true; @@ -225,8 +240,10 @@ bool InstallAPIVisitor::VisitVarDecl(const VarDecl *D) { const bool WeakDef = D->hasAttr(); const bool ThreadLocal = D->getTLSKind() != VarDecl::TLS_None; const AvailabilityInfo Avail = AvailabilityInfo::createFromDecl(D); - Ctx.Slice->addGlobal(getMangledName(D), Linkage, GlobalRecord::Kind::Variable, - Avail, D, *Access, getFlags(WeakDef, ThreadLocal)); + auto [GR, FA] = Ctx.Slice->addGlobal(getMangledName(D), Linkage, + GlobalRecord::Kind::Variable, Avail, D, + *Access, getFlags(WeakDef, ThreadLocal)); + Ctx.Verifier->verify(GR, FA); return true; } @@ -276,9 +293,433 @@ bool InstallAPIVisitor::VisitFunctionDecl(const FunctionDecl *D) { const RecordLinkage Linkage = (Inlined || !isExported(D)) ? RecordLinkage::Internal : RecordLinkage::Exported; - Ctx.Slice->addGlobal(Name, Linkage, GlobalRecord::Kind::Function, Avail, D, - *Access, getFlags(WeakDef, /*ThreadLocal=*/false), - Inlined); + auto [GR, FA] = + Ctx.Slice->addGlobal(Name, Linkage, GlobalRecord::Kind::Function, Avail, + D, *Access, getFlags(WeakDef), Inlined); + Ctx.Verifier->verify(GR, FA); + return true; +} + +static bool hasVTable(const CXXRecordDecl *D) { + // Check if vtable symbols should be emitted, only dynamic classes need + // vtables. + if (!D->hasDefinition() || !D->isDynamicClass()) + return false; + + assert(D->isExternallyVisible() && "Should be externally visible"); + assert(D->isCompleteDefinition() && "Only works on complete definitions"); + + const CXXMethodDecl *KeyFunctionD = + D->getASTContext().getCurrentKeyFunction(D); + // If this class has a key function, then there is a vtable, possibly internal + // though. + if (KeyFunctionD) { + switch (KeyFunctionD->getTemplateSpecializationKind()) { + case TSK_Undeclared: + case TSK_ExplicitSpecialization: + case TSK_ImplicitInstantiation: + case TSK_ExplicitInstantiationDefinition: + return true; + case TSK_ExplicitInstantiationDeclaration: + llvm_unreachable( + "Unexpected TemplateSpecializationKind for key function"); + } + } else if (D->isAbstract()) { + // If the class is abstract and it doesn't have a key function, it is a + // 'pure' virtual class. It doesn't need a vtable. + return false; + } + + switch (D->getTemplateSpecializationKind()) { + case TSK_Undeclared: + case TSK_ExplicitSpecialization: + case TSK_ImplicitInstantiation: + return false; + + case TSK_ExplicitInstantiationDeclaration: + case TSK_ExplicitInstantiationDefinition: + return true; + } + + llvm_unreachable("Invalid TemplateSpecializationKind!"); +} + +static CXXLinkage getVTableLinkage(const CXXRecordDecl *D) { + assert((D->hasDefinition() && D->isDynamicClass()) && "Record has no vtable"); + assert(D->isExternallyVisible() && "Record should be externally visible"); + if (D->getVisibility() == HiddenVisibility) + return CXXLinkage::PrivateLinkage; + + const CXXMethodDecl *KeyFunctionD = + D->getASTContext().getCurrentKeyFunction(D); + if (KeyFunctionD) { + // If this class has a key function, use that to determine the + // linkage of the vtable. + switch (KeyFunctionD->getTemplateSpecializationKind()) { + case TSK_Undeclared: + case TSK_ExplicitSpecialization: + if (isInlined(KeyFunctionD)) + return CXXLinkage::LinkOnceODRLinkage; + return CXXLinkage::ExternalLinkage; + case TSK_ImplicitInstantiation: + llvm_unreachable("No external vtable for implicit instantiations"); + case TSK_ExplicitInstantiationDefinition: + return CXXLinkage::WeakODRLinkage; + case TSK_ExplicitInstantiationDeclaration: + llvm_unreachable( + "Unexpected TemplateSpecializationKind for key function"); + } + } + + switch (D->getTemplateSpecializationKind()) { + case TSK_Undeclared: + case TSK_ExplicitSpecialization: + case TSK_ImplicitInstantiation: + return CXXLinkage::LinkOnceODRLinkage; + case TSK_ExplicitInstantiationDeclaration: + case TSK_ExplicitInstantiationDefinition: + return CXXLinkage::WeakODRLinkage; + } + + llvm_unreachable("Invalid TemplateSpecializationKind!"); +} + +static bool isRTTIWeakDef(const CXXRecordDecl *D) { + if (D->hasAttr()) + return true; + + if (D->isAbstract() && D->getASTContext().getCurrentKeyFunction(D) == nullptr) + return true; + + if (D->isDynamicClass()) + return getVTableLinkage(D) != CXXLinkage::ExternalLinkage; + + return false; +} + +static bool hasRTTI(const CXXRecordDecl *D) { + if (!D->getASTContext().getLangOpts().RTTI) + return false; + + if (!D->hasDefinition()) + return false; + + if (!D->isDynamicClass()) + return false; + + // Don't emit weak-def RTTI information. InstallAPI cannot reliably determine + // if the final binary will have those weak defined RTTI symbols. This depends + // on the optimization level and if the class has been instantiated and used. + // + // Luckily, the Apple static linker doesn't need those weak defined RTTI + // symbols for linking. They are only needed by the runtime linker. That means + // they can be safely dropped. + if (isRTTIWeakDef(D)) + return false; + + return true; +} + +std::string +InstallAPIVisitor::getMangledCXXRTTIName(const CXXRecordDecl *D) const { + SmallString<256> Name; + raw_svector_ostream NameStream(Name); + MC->mangleCXXRTTIName(QualType(D->getTypeForDecl(), 0), NameStream); + + return getBackendMangledName(Name); +} + +std::string InstallAPIVisitor::getMangledCXXRTTI(const CXXRecordDecl *D) const { + SmallString<256> Name; + raw_svector_ostream NameStream(Name); + MC->mangleCXXRTTI(QualType(D->getTypeForDecl(), 0), NameStream); + + return getBackendMangledName(Name); +} + +std::string +InstallAPIVisitor::getMangledCXXVTableName(const CXXRecordDecl *D) const { + SmallString<256> Name; + raw_svector_ostream NameStream(Name); + MC->mangleCXXVTable(D, NameStream); + + return getBackendMangledName(Name); +} + +std::string +InstallAPIVisitor::getMangledCXXThunk(const GlobalDecl &D, + const ThunkInfo &Thunk) const { + SmallString<256> Name; + raw_svector_ostream NameStream(Name); + const auto *Method = cast(D.getDecl()); + if (const auto *Dtor = dyn_cast(Method)) + MC->mangleCXXDtorThunk(Dtor, D.getDtorType(), Thunk.This, NameStream); + else + MC->mangleThunk(Method, Thunk, NameStream); + + return getBackendMangledName(Name); +} + +std::string InstallAPIVisitor::getMangledCtorDtor(const CXXMethodDecl *D, + int Type) const { + SmallString<256> Name; + raw_svector_ostream NameStream(Name); + GlobalDecl GD; + if (const auto *Ctor = dyn_cast(D)) + GD = GlobalDecl(Ctor, CXXCtorType(Type)); + else { + const auto *Dtor = cast(D); + GD = GlobalDecl(Dtor, CXXDtorType(Type)); + } + MC->mangleName(GD, NameStream); + return getBackendMangledName(Name); +} + +void InstallAPIVisitor::emitVTableSymbols(const CXXRecordDecl *D, + const AvailabilityInfo &Avail, + const HeaderType Access, + bool EmittedVTable) { + if (hasVTable(D)) { + EmittedVTable = true; + const CXXLinkage VTableLinkage = getVTableLinkage(D); + if (VTableLinkage == CXXLinkage::ExternalLinkage || + VTableLinkage == CXXLinkage::WeakODRLinkage) { + const std::string Name = getMangledCXXVTableName(D); + const bool WeakDef = VTableLinkage == CXXLinkage::WeakODRLinkage; + auto [GR, FA] = Ctx.Slice->addGlobal(Name, RecordLinkage::Exported, + GlobalRecord::Kind::Variable, Avail, + D, Access, getFlags(WeakDef)); + Ctx.Verifier->verify(GR, FA); + if (!D->getDescribedClassTemplate() && !D->isInvalidDecl()) { + VTableContextBase *VTable = D->getASTContext().getVTableContext(); + auto AddThunk = [&](GlobalDecl GD) { + const ItaniumVTableContext::ThunkInfoVectorTy *Thunks = + VTable->getThunkInfo(GD); + if (!Thunks) + return; + + for (const auto &Thunk : *Thunks) { + const std::string Name = getMangledCXXThunk(GD, Thunk); + auto [GR, FA] = Ctx.Slice->addGlobal(Name, RecordLinkage::Exported, + GlobalRecord::Kind::Function, + Avail, GD.getDecl(), Access); + Ctx.Verifier->verify(GR, FA); + } + }; + + for (const auto *Method : D->methods()) { + if (isa(Method) || !Method->isVirtual()) + continue; + + if (auto Dtor = dyn_cast(Method)) { + // Skip default destructor. + if (Dtor->isDefaulted()) + continue; + AddThunk({Dtor, Dtor_Deleting}); + AddThunk({Dtor, Dtor_Complete}); + } else + AddThunk(Method); + } + } + } + } + + if (!EmittedVTable) + return; + + if (hasRTTI(D)) { + std::string Name = getMangledCXXRTTI(D); + auto [GR, FA] = + Ctx.Slice->addGlobal(Name, RecordLinkage::Exported, + GlobalRecord::Kind::Variable, Avail, D, Access); + Ctx.Verifier->verify(GR, FA); + + Name = getMangledCXXRTTIName(D); + auto [NamedGR, NamedFA] = + Ctx.Slice->addGlobal(Name, RecordLinkage::Exported, + GlobalRecord::Kind::Variable, Avail, D, Access); + Ctx.Verifier->verify(NamedGR, NamedFA); + } + + for (const auto &It : D->bases()) { + const CXXRecordDecl *Base = + cast(It.getType()->castAs()->getDecl()); + const auto BaseAccess = getAccessForDecl(Base); + if (!BaseAccess) + continue; + const AvailabilityInfo BaseAvail = AvailabilityInfo::createFromDecl(Base); + emitVTableSymbols(Base, BaseAvail, *BaseAccess, /*EmittedVTable=*/true); + } +} + +bool InstallAPIVisitor::VisitCXXRecordDecl(const CXXRecordDecl *D) { + if (!D->isCompleteDefinition()) + return true; + + // Skip templated classes. + if (D->getDescribedClassTemplate() != nullptr) + return true; + + // Skip partial templated classes too. + if (isa(D)) + return true; + + auto Access = getAccessForDecl(D); + if (!Access) + return true; + const AvailabilityInfo Avail = AvailabilityInfo::createFromDecl(D); + + // Check whether to emit the vtable/rtti symbols. + if (isExported(D)) + emitVTableSymbols(D, Avail, *Access); + + TemplateSpecializationKind ClassSK = TSK_Undeclared; + bool KeepInlineAsWeak = false; + if (auto *Templ = dyn_cast(D)) { + ClassSK = Templ->getTemplateSpecializationKind(); + if (ClassSK == TSK_ExplicitInstantiationDeclaration) + KeepInlineAsWeak = true; + } + + // Record the class methods. + for (const auto *M : D->methods()) { + // Inlined methods are usually not emitted, except when it comes from a + // specialized template. + bool WeakDef = false; + if (isInlined(M)) { + if (!KeepInlineAsWeak) + continue; + + WeakDef = true; + } + + if (!isExported(M)) + continue; + + switch (M->getTemplateSpecializationKind()) { + case TSK_Undeclared: + case TSK_ExplicitSpecialization: + break; + case TSK_ImplicitInstantiation: + continue; + case TSK_ExplicitInstantiationDeclaration: + if (ClassSK == TSK_ExplicitInstantiationDeclaration) + WeakDef = true; + break; + case TSK_ExplicitInstantiationDefinition: + WeakDef = true; + break; + } + + if (!M->isUserProvided()) + continue; + + // Methods that are deleted are not exported. + if (M->isDeleted()) + continue; + + const auto Access = getAccessForDecl(M); + if (!Access) + return true; + const AvailabilityInfo Avail = AvailabilityInfo::createFromDecl(M); + + if (const auto *Ctor = dyn_cast(M)) { + // Defaulted constructors are not exported. + if (Ctor->isDefaulted()) + continue; + + std::string Name = getMangledCtorDtor(M, Ctor_Base); + auto [GR, FA] = Ctx.Slice->addGlobal(Name, RecordLinkage::Exported, + GlobalRecord::Kind::Function, Avail, + D, *Access, getFlags(WeakDef)); + Ctx.Verifier->verify(GR, FA); + + if (!D->isAbstract()) { + std::string Name = getMangledCtorDtor(M, Ctor_Complete); + auto [GR, FA] = Ctx.Slice->addGlobal( + Name, RecordLinkage::Exported, GlobalRecord::Kind::Function, Avail, + D, *Access, getFlags(WeakDef)); + Ctx.Verifier->verify(GR, FA); + } + + continue; + } + + if (const auto *Dtor = dyn_cast(M)) { + // Defaulted destructors are not exported. + if (Dtor->isDefaulted()) + continue; + + std::string Name = getMangledCtorDtor(M, Dtor_Base); + auto [GR, FA] = Ctx.Slice->addGlobal(Name, RecordLinkage::Exported, + GlobalRecord::Kind::Function, Avail, + D, *Access, getFlags(WeakDef)); + Ctx.Verifier->verify(GR, FA); + + Name = getMangledCtorDtor(M, Dtor_Complete); + auto [CompleteGR, CompleteFA] = Ctx.Slice->addGlobal( + Name, RecordLinkage::Exported, GlobalRecord::Kind::Function, Avail, D, + *Access, getFlags(WeakDef)); + Ctx.Verifier->verify(CompleteGR, CompleteFA); + + if (Dtor->isVirtual()) { + Name = getMangledCtorDtor(M, Dtor_Deleting); + auto [VirtualGR, VirtualFA] = Ctx.Slice->addGlobal( + Name, RecordLinkage::Exported, GlobalRecord::Kind::Function, Avail, + D, *Access, getFlags(WeakDef)); + Ctx.Verifier->verify(VirtualGR, VirtualFA); + } + + continue; + } + + // Though abstract methods can map to exports, this is generally unexpected. + // Except in the case of destructors. Only ignore pure virtuals after + // checking if the member function was a destructor. + if (M->isPureVirtual()) + continue; + + std::string Name = getMangledName(M); + auto [GR, FA] = Ctx.Slice->addGlobal(Name, RecordLinkage::Exported, + GlobalRecord::Kind::Function, Avail, D, + *Access, getFlags(WeakDef)); + Ctx.Verifier->verify(GR, FA); + } + + if (auto *Templ = dyn_cast(D)) { + if (!Templ->isExplicitInstantiationOrSpecialization()) + return true; + } + + using var_iter = CXXRecordDecl::specific_decl_iterator; + using var_range = iterator_range; + for (const auto *Var : var_range(D->decls())) { + // Skip const static member variables. + // \code + // struct S { + // static const int x = 0; + // }; + // \endcode + if (Var->isStaticDataMember() && Var->hasInit()) + continue; + + // Skip unexported var decls. + if (!isExported(Var)) + continue; + + const std::string Name = getMangledName(Var); + const auto Access = getAccessForDecl(Var); + if (!Access) + return true; + const AvailabilityInfo Avail = AvailabilityInfo::createFromDecl(Var); + const bool WeakDef = Var->hasAttr() || KeepInlineAsWeak; + + auto [GR, FA] = Ctx.Slice->addGlobal(Name, RecordLinkage::Exported, + GlobalRecord::Kind::Variable, Avail, D, + *Access, getFlags(WeakDef)); + Ctx.Verifier->verify(GR, FA); + } + return true; } diff --git a/clang/lib/Interpreter/Interpreter.cpp b/clang/lib/Interpreter/Interpreter.cpp index 37696b2897642867a8c5c3523a1abe616436c097..7fa52f2f15fc4951da35e5700deb54ecc4e6b64d 100644 --- a/clang/lib/Interpreter/Interpreter.cpp +++ b/clang/lib/Interpreter/Interpreter.cpp @@ -280,15 +280,14 @@ Interpreter::create(std::unique_ptr CI) { if (Err) return std::move(Err); + // Add runtime code and set a marker to hide it from user code. Undo will not + // go through that. auto PTU = Interp->Parse(Runtimes); if (!PTU) return PTU.takeError(); + Interp->markUserCodeStart(); Interp->ValuePrintingInfo.resize(4); - // FIXME: This is a ugly hack. Undo command checks its availability by looking - // at the size of the PTU list. However we have parsed something in the - // beginning of the REPL so we have to mark them as 'Irrevocable'. - Interp->InitPTUSize = Interp->IncrParser->getPTUs().size(); return std::move(Interp); } @@ -345,6 +344,11 @@ const ASTContext &Interpreter::getASTContext() const { return getCompilerInstance()->getASTContext(); } +void Interpreter::markUserCodeStart() { + assert(!InitPTUSize && "We only do this once"); + InitPTUSize = IncrParser->getPTUs().size(); +} + size_t Interpreter::getEffectivePTUSize() const { std::list &PTUs = IncrParser->getPTUs(); assert(PTUs.size() >= InitPTUSize && "empty PTU list?"); @@ -371,6 +375,10 @@ Interpreter::Parse(llvm::StringRef Code) { llvm::Error Interpreter::CreateExecutor() { const clang::TargetInfo &TI = getCompilerInstance()->getASTContext().getTargetInfo(); + if (IncrExecutor) + return llvm::make_error("Operation failed. " + "Execution engine exists", + std::error_code()); llvm::Error Err = llvm::Error::success(); auto Executor = std::make_unique(*TSCtx, Err, TI); if (!Err) @@ -379,6 +387,8 @@ llvm::Error Interpreter::CreateExecutor() { return Err; } +void Interpreter::ResetExecutor() { IncrExecutor.reset(); } + llvm::Error Interpreter::Execute(PartialTranslationUnit &T) { assert(T.TheModule); if (!IncrExecutor) { @@ -507,9 +517,13 @@ static constexpr llvm::StringRef MagicRuntimeInterface[] = { "__clang_Interpreter_SetValueWithAlloc", "__clang_Interpreter_SetValueCopyArr", "__ci_newtag"}; -bool Interpreter::FindRuntimeInterface() { +static std::unique_ptr +createInProcessRuntimeInterfaceBuilder(Interpreter &Interp, ASTContext &Ctx, + Sema &S); + +std::unique_ptr Interpreter::FindRuntimeInterface() { if (llvm::all_of(ValuePrintingInfo, [](Expr *E) { return E != nullptr; })) - return true; + return nullptr; Sema &S = getCompilerInstance()->getSema(); ASTContext &Ctx = S.getASTContext(); @@ -528,120 +542,34 @@ bool Interpreter::FindRuntimeInterface() { if (!LookupInterface(ValuePrintingInfo[NoAlloc], MagicRuntimeInterface[NoAlloc])) - return false; + return nullptr; if (!LookupInterface(ValuePrintingInfo[WithAlloc], MagicRuntimeInterface[WithAlloc])) - return false; + return nullptr; if (!LookupInterface(ValuePrintingInfo[CopyArray], MagicRuntimeInterface[CopyArray])) - return false; + return nullptr; if (!LookupInterface(ValuePrintingInfo[NewTag], MagicRuntimeInterface[NewTag])) - return false; - return true; + return nullptr; + + return createInProcessRuntimeInterfaceBuilder(*this, Ctx, S); } namespace { -class RuntimeInterfaceBuilder - : public TypeVisitor { - clang::Interpreter &Interp; +class InterfaceKindVisitor + : public TypeVisitor { + friend class InProcessRuntimeInterfaceBuilder; + ASTContext &Ctx; Sema &S; Expr *E; llvm::SmallVector Args; public: - RuntimeInterfaceBuilder(clang::Interpreter &In, ASTContext &C, Sema &SemaRef, - Expr *VE, ArrayRef FixedArgs) - : Interp(In), Ctx(C), S(SemaRef), E(VE) { - // The Interpreter* parameter and the out parameter `OutVal`. - for (Expr *E : FixedArgs) - Args.push_back(E); - - // Get rid of ExprWithCleanups. - if (auto *EWC = llvm::dyn_cast_if_present(E)) - E = EWC->getSubExpr(); - } - - ExprResult getCall() { - QualType Ty = E->getType(); - QualType DesugaredTy = Ty.getDesugaredType(Ctx); - - // For lvalue struct, we treat it as a reference. - if (DesugaredTy->isRecordType() && E->isLValue()) { - DesugaredTy = Ctx.getLValueReferenceType(DesugaredTy); - Ty = Ctx.getLValueReferenceType(Ty); - } - - Expr *TypeArg = - CStyleCastPtrExpr(S, Ctx.VoidPtrTy, (uintptr_t)Ty.getAsOpaquePtr()); - // The QualType parameter `OpaqueType`, represented as `void*`. - Args.push_back(TypeArg); - - // We push the last parameter based on the type of the Expr. Note we need - // special care for rvalue struct. - Interpreter::InterfaceKind Kind = Visit(&*DesugaredTy); - switch (Kind) { - case Interpreter::InterfaceKind::WithAlloc: - case Interpreter::InterfaceKind::CopyArray: { - // __clang_Interpreter_SetValueWithAlloc. - ExprResult AllocCall = S.ActOnCallExpr( - /*Scope=*/nullptr, - Interp.getValuePrintingInfo()[Interpreter::InterfaceKind::WithAlloc], - E->getBeginLoc(), Args, E->getEndLoc()); - assert(!AllocCall.isInvalid() && "Can't create runtime interface call!"); - - TypeSourceInfo *TSI = Ctx.getTrivialTypeSourceInfo(Ty, SourceLocation()); - - // Force CodeGen to emit destructor. - if (auto *RD = Ty->getAsCXXRecordDecl()) { - auto *Dtor = S.LookupDestructor(RD); - Dtor->addAttr(UsedAttr::CreateImplicit(Ctx)); - Interp.getCompilerInstance()->getASTConsumer().HandleTopLevelDecl( - DeclGroupRef(Dtor)); - } - - // __clang_Interpreter_SetValueCopyArr. - if (Kind == Interpreter::InterfaceKind::CopyArray) { - const auto *ConstantArrTy = - cast(DesugaredTy.getTypePtr()); - size_t ArrSize = Ctx.getConstantArrayElementCount(ConstantArrTy); - Expr *ArrSizeExpr = IntegerLiteralExpr(Ctx, ArrSize); - Expr *Args[] = {E, AllocCall.get(), ArrSizeExpr}; - return S.ActOnCallExpr( - /*Scope *=*/nullptr, - Interp - .getValuePrintingInfo()[Interpreter::InterfaceKind::CopyArray], - SourceLocation(), Args, SourceLocation()); - } - Expr *Args[] = { - AllocCall.get(), - Interp.getValuePrintingInfo()[Interpreter::InterfaceKind::NewTag]}; - ExprResult CXXNewCall = S.BuildCXXNew( - E->getSourceRange(), - /*UseGlobal=*/true, /*PlacementLParen=*/SourceLocation(), Args, - /*PlacementRParen=*/SourceLocation(), - /*TypeIdParens=*/SourceRange(), TSI->getType(), TSI, std::nullopt, - E->getSourceRange(), E); - - assert(!CXXNewCall.isInvalid() && - "Can't create runtime placement new call!"); - - return S.ActOnFinishFullExpr(CXXNewCall.get(), - /*DiscardedValue=*/false); - } - // __clang_Interpreter_SetValueNoAlloc. - case Interpreter::InterfaceKind::NoAlloc: { - return S.ActOnCallExpr( - /*Scope=*/nullptr, - Interp.getValuePrintingInfo()[Interpreter::InterfaceKind::NoAlloc], - E->getBeginLoc(), Args, E->getEndLoc()); - } - default: - llvm_unreachable("Unhandled Interpreter::InterfaceKind"); - } - } + InterfaceKindVisitor(ASTContext &Ctx, Sema &S, Expr *E) + : Ctx(Ctx), S(S), E(E) {} Interpreter::InterfaceKind VisitRecordType(const RecordType *Ty) { return Interpreter::InterfaceKind::WithAlloc; @@ -713,8 +641,124 @@ private: Args.push_back(CastedExpr.get()); } }; + +class InProcessRuntimeInterfaceBuilder : public RuntimeInterfaceBuilder { + Interpreter &Interp; + ASTContext &Ctx; + Sema &S; + +public: + InProcessRuntimeInterfaceBuilder(Interpreter &Interp, ASTContext &C, Sema &S) + : Interp(Interp), Ctx(C), S(S) {} + + TransformExprFunction *getPrintValueTransformer() override { + return &transformForValuePrinting; + } + +private: + static ExprResult transformForValuePrinting(RuntimeInterfaceBuilder *Builder, + Expr *E, + ArrayRef FixedArgs) { + auto *B = static_cast(Builder); + + // Get rid of ExprWithCleanups. + if (auto *EWC = llvm::dyn_cast_if_present(E)) + E = EWC->getSubExpr(); + + InterfaceKindVisitor Visitor(B->Ctx, B->S, E); + + // The Interpreter* parameter and the out parameter `OutVal`. + for (Expr *E : FixedArgs) + Visitor.Args.push_back(E); + + QualType Ty = E->getType(); + QualType DesugaredTy = Ty.getDesugaredType(B->Ctx); + + // For lvalue struct, we treat it as a reference. + if (DesugaredTy->isRecordType() && E->isLValue()) { + DesugaredTy = B->Ctx.getLValueReferenceType(DesugaredTy); + Ty = B->Ctx.getLValueReferenceType(Ty); + } + + Expr *TypeArg = CStyleCastPtrExpr(B->S, B->Ctx.VoidPtrTy, + (uintptr_t)Ty.getAsOpaquePtr()); + // The QualType parameter `OpaqueType`, represented as `void*`. + Visitor.Args.push_back(TypeArg); + + // We push the last parameter based on the type of the Expr. Note we need + // special care for rvalue struct. + Interpreter::InterfaceKind Kind = Visitor.Visit(&*DesugaredTy); + switch (Kind) { + case Interpreter::InterfaceKind::WithAlloc: + case Interpreter::InterfaceKind::CopyArray: { + // __clang_Interpreter_SetValueWithAlloc. + ExprResult AllocCall = B->S.ActOnCallExpr( + /*Scope=*/nullptr, + B->Interp + .getValuePrintingInfo()[Interpreter::InterfaceKind::WithAlloc], + E->getBeginLoc(), Visitor.Args, E->getEndLoc()); + assert(!AllocCall.isInvalid() && "Can't create runtime interface call!"); + + TypeSourceInfo *TSI = + B->Ctx.getTrivialTypeSourceInfo(Ty, SourceLocation()); + + // Force CodeGen to emit destructor. + if (auto *RD = Ty->getAsCXXRecordDecl()) { + auto *Dtor = B->S.LookupDestructor(RD); + Dtor->addAttr(UsedAttr::CreateImplicit(B->Ctx)); + B->Interp.getCompilerInstance()->getASTConsumer().HandleTopLevelDecl( + DeclGroupRef(Dtor)); + } + + // __clang_Interpreter_SetValueCopyArr. + if (Kind == Interpreter::InterfaceKind::CopyArray) { + const auto *ConstantArrTy = + cast(DesugaredTy.getTypePtr()); + size_t ArrSize = B->Ctx.getConstantArrayElementCount(ConstantArrTy); + Expr *ArrSizeExpr = IntegerLiteralExpr(B->Ctx, ArrSize); + Expr *Args[] = {E, AllocCall.get(), ArrSizeExpr}; + return B->S.ActOnCallExpr( + /*Scope *=*/nullptr, + B->Interp + .getValuePrintingInfo()[Interpreter::InterfaceKind::CopyArray], + SourceLocation(), Args, SourceLocation()); + } + Expr *Args[] = { + AllocCall.get(), + B->Interp.getValuePrintingInfo()[Interpreter::InterfaceKind::NewTag]}; + ExprResult CXXNewCall = B->S.BuildCXXNew( + E->getSourceRange(), + /*UseGlobal=*/true, /*PlacementLParen=*/SourceLocation(), Args, + /*PlacementRParen=*/SourceLocation(), + /*TypeIdParens=*/SourceRange(), TSI->getType(), TSI, std::nullopt, + E->getSourceRange(), E); + + assert(!CXXNewCall.isInvalid() && + "Can't create runtime placement new call!"); + + return B->S.ActOnFinishFullExpr(CXXNewCall.get(), + /*DiscardedValue=*/false); + } + // __clang_Interpreter_SetValueNoAlloc. + case Interpreter::InterfaceKind::NoAlloc: { + return B->S.ActOnCallExpr( + /*Scope=*/nullptr, + B->Interp.getValuePrintingInfo()[Interpreter::InterfaceKind::NoAlloc], + E->getBeginLoc(), Visitor.Args, E->getEndLoc()); + } + default: + llvm_unreachable("Unhandled Interpreter::InterfaceKind"); + } + } +}; } // namespace +static std::unique_ptr +createInProcessRuntimeInterfaceBuilder(Interpreter &Interp, ASTContext &Ctx, + Sema &S) { + return std::make_unique(Interp, Ctx, S); +} + // This synthesizes a call expression to a speciall // function that is responsible for generating the Value. // In general, we transform: @@ -733,8 +777,13 @@ Expr *Interpreter::SynthesizeExpr(Expr *E) { Sema &S = getCompilerInstance()->getSema(); ASTContext &Ctx = S.getASTContext(); - if (!FindRuntimeInterface()) - llvm_unreachable("We can't find the runtime iterface for pretty print!"); + if (!RuntimeIB) { + RuntimeIB = FindRuntimeInterface(); + AddPrintValueCall = RuntimeIB->getPrintValueTransformer(); + } + + assert(AddPrintValueCall && + "We don't have a runtime interface for pretty print!"); // Create parameter `ThisInterp`. auto *ThisInterp = CStyleCastPtrExpr(S, Ctx.VoidPtrTy, (uintptr_t)this); @@ -743,9 +792,9 @@ Expr *Interpreter::SynthesizeExpr(Expr *E) { auto *OutValue = CStyleCastPtrExpr(S, Ctx.VoidPtrTy, (uintptr_t)&LastValue); // Build `__clang_Interpreter_SetValue*` call. - RuntimeInterfaceBuilder Builder(*this, Ctx, S, E, {ThisInterp, OutValue}); + ExprResult Result = + AddPrintValueCall(RuntimeIB.get(), E, {ThisInterp, OutValue}); - ExprResult Result = Builder.getCall(); // It could fail, like printing an array type in C. (not supported) if (Result.isInvalid()) return E; diff --git a/clang/lib/Lex/ModuleMap.cpp b/clang/lib/Lex/ModuleMap.cpp index afb2948f05ae5b4c30073f1b8dc9dad08b0c0be2..10c475f617d48549b2b0943bf8b2851c59a70a4c 100644 --- a/clang/lib/Lex/ModuleMap.cpp +++ b/clang/lib/Lex/ModuleMap.cpp @@ -2498,9 +2498,12 @@ void ModuleMapParser::parseHeaderDecl(MMToken::TokenKind LeadingToken, } bool NeedsFramework = false; - // Don't add the top level headers to the builtin modules if the builtin headers - // belong to the system modules. - if (!Map.LangOpts.BuiltinHeadersInSystemModules || ActiveModule->isSubModule() || !isBuiltInModuleName(ActiveModule->Name)) + // Don't add headers to the builtin modules if the builtin headers belong to + // the system modules, with the exception of __stddef_max_align_t.h which + // always had its own module. + if (!Map.LangOpts.BuiltinHeadersInSystemModules || + !isBuiltInModuleName(ActiveModule->getTopLevelModuleName()) || + ActiveModule->fullModuleNameIs({"_Builtin_stddef", "max_align_t"})) Map.addUnresolvedHeader(ActiveModule, std::move(Header), NeedsFramework); if (NeedsFramework) diff --git a/clang/lib/Parse/ParseDeclCXX.cpp b/clang/lib/Parse/ParseDeclCXX.cpp index 62632b2d79792efeb7c2d57ad20de7000a3b88d3..77d2382ea6d907ae94d1caeefb7b0d0e8756331d 100644 --- a/clang/lib/Parse/ParseDeclCXX.cpp +++ b/clang/lib/Parse/ParseDeclCXX.cpp @@ -4528,6 +4528,61 @@ static bool IsBuiltInOrStandardCXX11Attribute(IdentifierInfo *AttrName, } } +/// Parse the argument to C++23's [[assume()]] attribute. +bool Parser::ParseCXXAssumeAttributeArg(ParsedAttributes &Attrs, + IdentifierInfo *AttrName, + SourceLocation AttrNameLoc, + SourceLocation *EndLoc) { + assert(Tok.is(tok::l_paren) && "Not a C++11 attribute argument list"); + BalancedDelimiterTracker T(*this, tok::l_paren); + T.consumeOpen(); + + // [dcl.attr.assume]: The expression is potentially evaluated. + EnterExpressionEvaluationContext Unevaluated( + Actions, Sema::ExpressionEvaluationContext::PotentiallyEvaluated); + + TentativeParsingAction TPA(*this); + ExprResult Res( + Actions.CorrectDelayedTyposInExpr(ParseConditionalExpression())); + if (Res.isInvalid()) { + TPA.Commit(); + SkipUntil(tok::r_paren, tok::r_square, StopAtSemi | StopBeforeMatch); + if (Tok.is(tok::r_paren)) + T.consumeClose(); + return true; + } + + if (!Tok.isOneOf(tok::r_paren, tok::r_square)) { + // Emit a better diagnostic if this is an otherwise valid expression that + // is not allowed here. + TPA.Revert(); + Res = ParseExpression(); + if (!Res.isInvalid()) { + auto *E = Res.get(); + Diag(E->getExprLoc(), diag::err_assume_attr_expects_cond_expr) + << AttrName << FixItHint::CreateInsertion(E->getBeginLoc(), "(") + << FixItHint::CreateInsertion(PP.getLocForEndOfToken(E->getEndLoc()), + ")") + << E->getSourceRange(); + } + + T.consumeClose(); + return true; + } + + TPA.Commit(); + ArgsUnion Assumption = Res.get(); + auto RParen = Tok.getLocation(); + T.consumeClose(); + Attrs.addNew(AttrName, SourceRange(AttrNameLoc, RParen), nullptr, + SourceLocation(), &Assumption, 1, ParsedAttr::Form::CXX11()); + + if (EndLoc) + *EndLoc = RParen; + + return false; +} + /// ParseCXX11AttributeArgs -- Parse a C++11 attribute-argument-clause. /// /// [C++11] attribute-argument-clause: @@ -4579,7 +4634,9 @@ bool Parser::ParseCXX11AttributeArgs( return true; } - if (ScopeName && ScopeName->isStr("omp")) { + // [[omp::directive]] and [[omp::sequence]] need special handling. + if (ScopeName && ScopeName->isStr("omp") && + (AttrName->isStr("directive") || AttrName->isStr("sequence"))) { Diag(AttrNameLoc, getLangOpts().OpenMP >= 51 ? diag::warn_omp51_compat_attributes : diag::ext_omp_attributes); @@ -4596,7 +4653,12 @@ bool Parser::ParseCXX11AttributeArgs( if (ScopeName && (ScopeName->isStr("clang") || ScopeName->isStr("_Clang"))) NumArgs = ParseClangAttributeArgs(AttrName, AttrNameLoc, Attrs, EndLoc, ScopeName, ScopeLoc, Form); - else + // So does C++23's assume() attribute. + else if (!ScopeName && AttrName->isStr("assume")) { + if (ParseCXXAssumeAttributeArg(Attrs, AttrName, AttrNameLoc, EndLoc)) + return true; + NumArgs = 1; + } else NumArgs = ParseAttributeArgsCommon(AttrName, AttrNameLoc, Attrs, EndLoc, ScopeName, ScopeLoc, Form); diff --git a/clang/lib/Parse/ParseExpr.cpp b/clang/lib/Parse/ParseExpr.cpp index 1f07eddb0fb3783514bf95e5cc17329280c62aaa..88c3a1469e8ed44e9bb7622cf1c64f6fe1aa65f7 100644 --- a/clang/lib/Parse/ParseExpr.cpp +++ b/clang/lib/Parse/ParseExpr.cpp @@ -179,6 +179,19 @@ ExprResult Parser::ParseAssignmentExpression(TypeCastState isTypeCast) { return ParseRHSOfBinaryExpression(LHS, prec::Assignment); } +ExprResult Parser::ParseConditionalExpression() { + if (Tok.is(tok::code_completion)) { + cutOffParsing(); + Actions.CodeCompleteExpression(getCurScope(), + PreferredType.get(Tok.getLocation())); + return ExprError(); + } + + ExprResult LHS = ParseCastExpression( + AnyCastExpr, /*isAddressOfOperand=*/false, NotTypeCast); + return ParseRHSOfBinaryExpression(LHS, prec::Conditional); +} + /// Parse an assignment expression where part of an Objective-C message /// send has already been parsed. /// diff --git a/clang/lib/Parse/Parser.cpp b/clang/lib/Parse/Parser.cpp index 1701d153bd0ecaab8273c4933a1067924cbee4d1..cc0e41ed221c4f1d0058ea30a685e5ad01045824 100644 --- a/clang/lib/Parse/Parser.cpp +++ b/clang/lib/Parse/Parser.cpp @@ -685,7 +685,7 @@ bool Parser::ParseTopLevelDecl(DeclGroupPtrTy &Result, // FIXME: We need a better way to disambiguate C++ clang modules and // standard C++ modules. if (!getLangOpts().CPlusPlusModules || !Mod->isHeaderUnit()) - Actions.ActOnModuleInclude(Loc, Mod); + Actions.ActOnAnnotModuleInclude(Loc, Mod); else { DeclResult Import = Actions.ActOnModuleImport(Loc, SourceLocation(), Loc, Mod); @@ -697,15 +697,17 @@ bool Parser::ParseTopLevelDecl(DeclGroupPtrTy &Result, } case tok::annot_module_begin: - Actions.ActOnModuleBegin(Tok.getLocation(), reinterpret_cast( - Tok.getAnnotationValue())); + Actions.ActOnAnnotModuleBegin( + Tok.getLocation(), + reinterpret_cast(Tok.getAnnotationValue())); ConsumeAnnotationToken(); ImportState = Sema::ModuleImportState::NotACXX20Module; return false; case tok::annot_module_end: - Actions.ActOnModuleEnd(Tok.getLocation(), reinterpret_cast( - Tok.getAnnotationValue())); + Actions.ActOnAnnotModuleEnd( + Tok.getLocation(), + reinterpret_cast(Tok.getAnnotationValue())); ConsumeAnnotationToken(); ImportState = Sema::ModuleImportState::NotACXX20Module; return false; @@ -2708,9 +2710,9 @@ bool Parser::parseMisplacedModuleImport() { // happens. if (MisplacedModuleBeginCount) { --MisplacedModuleBeginCount; - Actions.ActOnModuleEnd(Tok.getLocation(), - reinterpret_cast( - Tok.getAnnotationValue())); + Actions.ActOnAnnotModuleEnd( + Tok.getLocation(), + reinterpret_cast(Tok.getAnnotationValue())); ConsumeAnnotationToken(); continue; } @@ -2720,18 +2722,18 @@ bool Parser::parseMisplacedModuleImport() { return true; case tok::annot_module_begin: // Recover by entering the module (Sema will diagnose). - Actions.ActOnModuleBegin(Tok.getLocation(), - reinterpret_cast( - Tok.getAnnotationValue())); + Actions.ActOnAnnotModuleBegin( + Tok.getLocation(), + reinterpret_cast(Tok.getAnnotationValue())); ConsumeAnnotationToken(); ++MisplacedModuleBeginCount; continue; case tok::annot_module_include: // Module import found where it should not be, for instance, inside a // namespace. Recover by importing the module. - Actions.ActOnModuleInclude(Tok.getLocation(), - reinterpret_cast( - Tok.getAnnotationValue())); + Actions.ActOnAnnotModuleInclude( + Tok.getLocation(), + reinterpret_cast(Tok.getAnnotationValue())); ConsumeAnnotationToken(); // If there is another module import, process it. continue; diff --git a/clang/lib/Sema/Sema.cpp b/clang/lib/Sema/Sema.cpp index 720d5fd5f0428dda84bc7c90008debb5e0c7ba89..cd0c42d5ffbacd3de3e7a744fa48762293d3cff6 100644 --- a/clang/lib/Sema/Sema.cpp +++ b/clang/lib/Sema/Sema.cpp @@ -1207,26 +1207,35 @@ void Sema::ActOnEndOfTranslationUnit() { } // A global-module-fragment is only permitted within a module unit. - bool DiagnosedMissingModuleDeclaration = false; if (!ModuleScopes.empty() && ModuleScopes.back().Module->Kind == Module::ExplicitGlobalModuleFragment) { Diag(ModuleScopes.back().BeginLoc, diag::err_module_declaration_missing_after_global_module_introducer); - DiagnosedMissingModuleDeclaration = true; - } - - if (TUKind == TU_Module) { - // If we are building a module interface unit, we need to have seen the - // module declaration by now. - if (getLangOpts().getCompilingModule() == - LangOptions::CMK_ModuleInterface && - !isCurrentModulePurview() && !DiagnosedMissingModuleDeclaration) { - // FIXME: Make a better guess as to where to put the module declaration. - Diag(getSourceManager().getLocForStartOfFile( - getSourceManager().getMainFileID()), - diag::err_module_declaration_missing); - } + } + + // Now we can decide whether the modules we're building need an initializer. + if (Module *CurrentModule = getCurrentModule(); + CurrentModule && CurrentModule->isInterfaceOrPartition()) { + auto DoesModNeedInit = [this](Module *M) { + if (!getASTContext().getModuleInitializers(M).empty()) + return true; + for (auto [Exported, _] : M->Exports) + if (Exported->isNamedModuleInterfaceHasInit()) + return true; + for (Module *I : M->Imports) + if (I->isNamedModuleInterfaceHasInit()) + return true; + + return false; + }; + CurrentModule->NamedModuleHasInit = + DoesModNeedInit(CurrentModule) || + llvm::any_of(CurrentModule->submodules(), + [&](auto *SubM) { return DoesModNeedInit(SubM); }); + } + + if (TUKind == TU_ClangModule) { // If we are building a module, resolve all of the exported declarations // now. if (Module *CurrentModule = PP.getCurrentModule()) { @@ -1251,28 +1260,6 @@ void Sema::ActOnEndOfTranslationUnit() { } } - // Now we can decide whether the modules we're building need an initializer. - if (Module *CurrentModule = getCurrentModule(); - CurrentModule && CurrentModule->isInterfaceOrPartition()) { - auto DoesModNeedInit = [this](Module *M) { - if (!getASTContext().getModuleInitializers(M).empty()) - return true; - for (auto [Exported, _] : M->Exports) - if (Exported->isNamedModuleInterfaceHasInit()) - return true; - for (Module *I : M->Imports) - if (I->isNamedModuleInterfaceHasInit()) - return true; - - return false; - }; - - CurrentModule->NamedModuleHasInit = - DoesModNeedInit(CurrentModule) || - llvm::any_of(CurrentModule->submodules(), - [&](auto *SubM) { return DoesModNeedInit(SubM); }); - } - // Warnings emitted in ActOnEndOfTranslationUnit() should be emitted for // modules when they are built, not every time they are used. emitAndClearUnusedLocalTypedefWarnings(); @@ -1358,7 +1345,7 @@ void Sema::ActOnEndOfTranslationUnit() { // noise. Don't warn for a use from a module: either we should warn on all // file-scope declarations in modules or not at all, but whether the // declaration is used is immaterial. - if (!Diags.hasErrorOccurred() && TUKind != TU_Module) { + if (!Diags.hasErrorOccurred() && TUKind != TU_ClangModule) { // Output warning for unused file scoped decls. for (UnusedFileScopedDeclsType::iterator I = UnusedFileScopedDecls.begin(ExternalSource.get()), diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp index a5f42b630c3fa2459b7d6e360838597d22028186..a0b256ab5579ee04d6581e11c0ee94a0e9530ad3 100644 --- a/clang/lib/Sema/SemaChecking.cpp +++ b/clang/lib/Sema/SemaChecking.cpp @@ -1971,6 +1971,191 @@ static bool SemaOpenCLBuiltinToAddr(Sema &S, unsigned BuiltinID, return false; } +namespace { +enum PointerAuthOpKind { + PAO_Strip, + PAO_Sign, + PAO_Auth, + PAO_SignGeneric, + PAO_Discriminator, + PAO_BlendPointer, + PAO_BlendInteger +}; +} + +static bool checkPointerAuthEnabled(Sema &S, Expr *E) { + if (S.getLangOpts().PointerAuthIntrinsics) + return false; + + S.Diag(E->getExprLoc(), diag::err_ptrauth_disabled) << E->getSourceRange(); + return true; +} + +static bool checkPointerAuthKey(Sema &S, Expr *&Arg) { + // Convert it to type 'int'. + if (convertArgumentToType(S, Arg, S.Context.IntTy)) + return true; + + // Value-dependent expressions are okay; wait for template instantiation. + if (Arg->isValueDependent()) + return false; + + unsigned KeyValue; + return S.checkConstantPointerAuthKey(Arg, KeyValue); +} + +bool Sema::checkConstantPointerAuthKey(Expr *Arg, unsigned &Result) { + // Attempt to constant-evaluate the expression. + std::optional KeyValue = Arg->getIntegerConstantExpr(Context); + if (!KeyValue) { + Diag(Arg->getExprLoc(), diag::err_expr_not_ice) + << 0 << Arg->getSourceRange(); + return true; + } + + // Ask the target to validate the key parameter. + if (!Context.getTargetInfo().validatePointerAuthKey(*KeyValue)) { + llvm::SmallString<32> Value; + { + llvm::raw_svector_ostream Str(Value); + Str << *KeyValue; + } + + Diag(Arg->getExprLoc(), diag::err_ptrauth_invalid_key) + << Value << Arg->getSourceRange(); + return true; + } + + Result = KeyValue->getZExtValue(); + return false; +} + +static bool checkPointerAuthValue(Sema &S, Expr *&Arg, + PointerAuthOpKind OpKind) { + if (Arg->hasPlaceholderType()) { + ExprResult R = S.CheckPlaceholderExpr(Arg); + if (R.isInvalid()) + return true; + Arg = R.get(); + } + + auto AllowsPointer = [](PointerAuthOpKind OpKind) { + return OpKind != PAO_BlendInteger; + }; + auto AllowsInteger = [](PointerAuthOpKind OpKind) { + return OpKind == PAO_Discriminator || OpKind == PAO_BlendInteger || + OpKind == PAO_SignGeneric; + }; + + // Require the value to have the right range of type. + QualType ExpectedTy; + if (AllowsPointer(OpKind) && Arg->getType()->isPointerType()) { + ExpectedTy = Arg->getType().getUnqualifiedType(); + } else if (AllowsPointer(OpKind) && Arg->getType()->isNullPtrType()) { + ExpectedTy = S.Context.VoidPtrTy; + } else if (AllowsInteger(OpKind) && + Arg->getType()->isIntegralOrUnscopedEnumerationType()) { + ExpectedTy = S.Context.getUIntPtrType(); + + } else { + // Diagnose the failures. + S.Diag(Arg->getExprLoc(), diag::err_ptrauth_value_bad_type) + << unsigned(OpKind == PAO_Discriminator ? 1 + : OpKind == PAO_BlendPointer ? 2 + : OpKind == PAO_BlendInteger ? 3 + : 0) + << unsigned(AllowsInteger(OpKind) ? (AllowsPointer(OpKind) ? 2 : 1) : 0) + << Arg->getType() << Arg->getSourceRange(); + return true; + } + + // Convert to that type. This should just be an lvalue-to-rvalue + // conversion. + if (convertArgumentToType(S, Arg, ExpectedTy)) + return true; + + // Warn about null pointers for non-generic sign and auth operations. + if ((OpKind == PAO_Sign || OpKind == PAO_Auth) && + Arg->isNullPointerConstant(S.Context, Expr::NPC_ValueDependentIsNull)) { + S.Diag(Arg->getExprLoc(), OpKind == PAO_Sign + ? diag::warn_ptrauth_sign_null_pointer + : diag::warn_ptrauth_auth_null_pointer) + << Arg->getSourceRange(); + } + + return false; +} + +static ExprResult SemaPointerAuthStrip(Sema &S, CallExpr *Call) { + if (checkArgCount(S, Call, 2)) + return ExprError(); + if (checkPointerAuthEnabled(S, Call)) + return ExprError(); + if (checkPointerAuthValue(S, Call->getArgs()[0], PAO_Strip) || + checkPointerAuthKey(S, Call->getArgs()[1])) + return ExprError(); + + Call->setType(Call->getArgs()[0]->getType()); + return Call; +} + +static ExprResult SemaPointerAuthBlendDiscriminator(Sema &S, CallExpr *Call) { + if (checkArgCount(S, Call, 2)) + return ExprError(); + if (checkPointerAuthEnabled(S, Call)) + return ExprError(); + if (checkPointerAuthValue(S, Call->getArgs()[0], PAO_BlendPointer) || + checkPointerAuthValue(S, Call->getArgs()[1], PAO_BlendInteger)) + return ExprError(); + + Call->setType(S.Context.getUIntPtrType()); + return Call; +} + +static ExprResult SemaPointerAuthSignGenericData(Sema &S, CallExpr *Call) { + if (checkArgCount(S, Call, 2)) + return ExprError(); + if (checkPointerAuthEnabled(S, Call)) + return ExprError(); + if (checkPointerAuthValue(S, Call->getArgs()[0], PAO_SignGeneric) || + checkPointerAuthValue(S, Call->getArgs()[1], PAO_Discriminator)) + return ExprError(); + + Call->setType(S.Context.getUIntPtrType()); + return Call; +} + +static ExprResult SemaPointerAuthSignOrAuth(Sema &S, CallExpr *Call, + PointerAuthOpKind OpKind) { + if (checkArgCount(S, Call, 3)) + return ExprError(); + if (checkPointerAuthEnabled(S, Call)) + return ExprError(); + if (checkPointerAuthValue(S, Call->getArgs()[0], OpKind) || + checkPointerAuthKey(S, Call->getArgs()[1]) || + checkPointerAuthValue(S, Call->getArgs()[2], PAO_Discriminator)) + return ExprError(); + + Call->setType(Call->getArgs()[0]->getType()); + return Call; +} + +static ExprResult SemaPointerAuthAuthAndResign(Sema &S, CallExpr *Call) { + if (checkArgCount(S, Call, 5)) + return ExprError(); + if (checkPointerAuthEnabled(S, Call)) + return ExprError(); + if (checkPointerAuthValue(S, Call->getArgs()[0], PAO_Auth) || + checkPointerAuthKey(S, Call->getArgs()[1]) || + checkPointerAuthValue(S, Call->getArgs()[2], PAO_Discriminator) || + checkPointerAuthKey(S, Call->getArgs()[3]) || + checkPointerAuthValue(S, Call->getArgs()[4], PAO_Discriminator)) + return ExprError(); + + Call->setType(Call->getArgs()[0]->getType()); + return Call; +} + static ExprResult SemaBuiltinLaunder(Sema &S, CallExpr *TheCall) { if (checkArgCount(S, TheCall, 1)) return ExprError(); @@ -2683,6 +2868,18 @@ Sema::CheckBuiltinFunctionCall(FunctionDecl *FDecl, unsigned BuiltinID, } break; } + case Builtin::BI__builtin_ptrauth_strip: + return SemaPointerAuthStrip(*this, TheCall); + case Builtin::BI__builtin_ptrauth_blend_discriminator: + return SemaPointerAuthBlendDiscriminator(*this, TheCall); + case Builtin::BI__builtin_ptrauth_sign_unauthenticated: + return SemaPointerAuthSignOrAuth(*this, TheCall, PAO_Sign); + case Builtin::BI__builtin_ptrauth_auth: + return SemaPointerAuthSignOrAuth(*this, TheCall, PAO_Auth); + case Builtin::BI__builtin_ptrauth_sign_generic_data: + return SemaPointerAuthSignGenericData(*this, TheCall); + case Builtin::BI__builtin_ptrauth_auth_and_resign: + return SemaPointerAuthAuthAndResign(*this, TheCall); // OpenCL v2.0, s6.13.16 - Pipe functions case Builtin::BIread_pipe: case Builtin::BIwrite_pipe: @@ -4992,6 +5189,7 @@ static bool isPPC_64Builtin(unsigned BuiltinID) { case PPC::BI__builtin_ppc_fetch_and_andlp: case PPC::BI__builtin_ppc_fetch_and_orlp: case PPC::BI__builtin_ppc_fetch_and_swaplp: + case PPC::BI__builtin_ppc_rldimi: return true; } return false; @@ -5093,8 +5291,10 @@ bool Sema::CheckPPCBuiltinFunctionCall(const TargetInfo &TI, unsigned BuiltinID, case PPC::BI__builtin_ppc_rlwnm: return SemaValueIsRunOfOnes(TheCall, 2); case PPC::BI__builtin_ppc_rlwimi: + return SemaBuiltinConstantArgRange(TheCall, 2, 0, 31) || + SemaValueIsRunOfOnes(TheCall, 3); case PPC::BI__builtin_ppc_rldimi: - return SemaBuiltinConstantArg(TheCall, 2, Result) || + return SemaBuiltinConstantArgRange(TheCall, 2, 0, 63) || SemaValueIsRunOfOnes(TheCall, 3); case PPC::BI__builtin_ppc_addex: { if (SemaBuiltinConstantArgRange(TheCall, 2, 0, 3)) @@ -5233,10 +5433,6 @@ bool CheckVectorElementCallArgs(Sema *S, CallExpr *TheCall) { TheCall->getArg(1)->getEndLoc()); retValue = true; } - - if (!retValue) - TheCall->setType(VecTyA->getElementType()); - return retValue; } } @@ -5250,11 +5446,12 @@ bool CheckVectorElementCallArgs(Sema *S, CallExpr *TheCall) { return true; } -bool CheckAllArgsHaveFloatRepresentation(Sema *S, CallExpr *TheCall) { - QualType ExpectedType = S->Context.FloatTy; +bool CheckArgsTypesAreCorrect( + Sema *S, CallExpr *TheCall, QualType ExpectedType, + llvm::function_ref Check) { for (unsigned i = 0; i < TheCall->getNumArgs(); ++i) { QualType PassedType = TheCall->getArg(i)->getType(); - if (!PassedType->hasFloatingRepresentation()) { + if (Check(PassedType)) { if (auto *VecTyA = PassedType->getAs()) ExpectedType = S->Context.getVectorType( ExpectedType, VecTyA->getNumElements(), VecTyA->getVectorKind()); @@ -5267,6 +5464,35 @@ bool CheckAllArgsHaveFloatRepresentation(Sema *S, CallExpr *TheCall) { return false; } +bool CheckAllArgsHaveFloatRepresentation(Sema *S, CallExpr *TheCall) { + auto checkAllFloatTypes = [](clang::QualType PassedType) -> bool { + return !PassedType->hasFloatingRepresentation(); + }; + return CheckArgsTypesAreCorrect(S, TheCall, S->Context.FloatTy, + checkAllFloatTypes); +} + +bool CheckFloatOrHalfRepresentations(Sema *S, CallExpr *TheCall) { + auto checkFloatorHalf = [](clang::QualType PassedType) -> bool { + clang::QualType BaseType = + PassedType->isVectorType() + ? PassedType->getAs()->getElementType() + : PassedType; + return !BaseType->isHalfType() && !BaseType->isFloat32Type(); + }; + return CheckArgsTypesAreCorrect(S, TheCall, S->Context.FloatTy, + checkFloatorHalf); +} + +void SetElementTypeAsReturnType(Sema *S, CallExpr *TheCall, + QualType ReturnType) { + auto *VecTyA = TheCall->getArg(0)->getType()->getAs(); + if (VecTyA) + ReturnType = S->Context.getVectorType(ReturnType, VecTyA->getNumElements(), + VectorKind::Generic); + TheCall->setType(ReturnType); +} + // Note: returning true in this case results in CheckBuiltinFunctionCall // returning an ExprError bool Sema::CheckHLSLBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall) { @@ -5276,6 +5502,17 @@ bool Sema::CheckHLSLBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall) { return true; break; } + case Builtin::BI__builtin_hlsl_elementwise_clamp: { + if (checkArgCount(*this, TheCall, 3)) + return true; + if (CheckVectorElementCallArgs(this, TheCall)) + return true; + if (SemaBuiltinElementwiseTernaryMath( + TheCall, /*CheckForFloatArgs*/ + TheCall->getArg(0)->getType()->hasFloatingRepresentation())) + return true; + break; + } case Builtin::BI__builtin_hlsl_dot: { if (checkArgCount(*this, TheCall, 2)) return true; @@ -5285,12 +5522,27 @@ bool Sema::CheckHLSLBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall) { return true; break; } - case Builtin::BI__builtin_hlsl_elementwise_rcp: + case Builtin::BI__builtin_hlsl_elementwise_rcp: { + if (CheckAllArgsHaveFloatRepresentation(this, TheCall)) + return true; + if (PrepareBuiltinElementwiseMathOneArgCall(TheCall)) + return true; + break; + } + case Builtin::BI__builtin_hlsl_elementwise_rsqrt: case Builtin::BI__builtin_hlsl_elementwise_frac: { + if (CheckFloatOrHalfRepresentations(this, TheCall)) + return true; if (PrepareBuiltinElementwiseMathOneArgCall(TheCall)) return true; - if (CheckAllArgsHaveFloatRepresentation(this, TheCall)) + break; + } + case Builtin::BI__builtin_hlsl_elementwise_isinf: { + if (CheckFloatOrHalfRepresentations(this, TheCall)) return true; + if (PrepareBuiltinElementwiseMathOneArgCall(TheCall)) + return true; + SetElementTypeAsReturnType(this, TheCall, this->Context.BoolTy); break; } case Builtin::BI__builtin_hlsl_lerp: { @@ -5300,7 +5552,7 @@ bool Sema::CheckHLSLBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall) { return true; if (SemaBuiltinElementwiseTernaryMath(TheCall)) return true; - if (CheckAllArgsHaveFloatRepresentation(this, TheCall)) + if (CheckFloatOrHalfRepresentations(this, TheCall)) return true; break; } @@ -5309,7 +5561,9 @@ bool Sema::CheckHLSLBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall) { return true; if (CheckVectorElementCallArgs(this, TheCall)) return true; - if (SemaBuiltinElementwiseTernaryMath(TheCall, /*CheckForFloatArgs*/ false)) + if (SemaBuiltinElementwiseTernaryMath( + TheCall, /*CheckForFloatArgs*/ + TheCall->getArg(0)->getType()->hasFloatingRepresentation())) return true; } } @@ -16351,12 +16605,26 @@ static void AnalyzeImplicitConversions( BO->getRHS()->isKnownToHaveBooleanValue() && BO->getLHS()->HasSideEffects(S.Context) && BO->getRHS()->HasSideEffects(S.Context)) { - S.Diag(BO->getBeginLoc(), diag::warn_bitwise_instead_of_logical) - << (BO->getOpcode() == BO_And ? "&" : "|") << OrigE->getSourceRange() - << FixItHint::CreateReplacement( - BO->getOperatorLoc(), - (BO->getOpcode() == BO_And ? "&&" : "||")); - S.Diag(BO->getBeginLoc(), diag::note_cast_operand_to_int); + SourceManager &SM = S.getSourceManager(); + const LangOptions &LO = S.getLangOpts(); + SourceLocation BLoc = BO->getOperatorLoc(); + SourceLocation ELoc = Lexer::getLocForEndOfToken(BLoc, 0, SM, LO); + StringRef SR = clang::Lexer::getSourceText( + clang::CharSourceRange::getTokenRange(BLoc, ELoc), SM, LO); + // To reduce false positives, only issue the diagnostic if the operator + // is explicitly spelled as a punctuator. This suppresses the diagnostic + // when using 'bitand' or 'bitor' either as keywords in C++ or as macros + // in C, along with other macro spellings the user might invent. + if (SR.str() == "&" || SR.str() == "|") { + + S.Diag(BO->getBeginLoc(), diag::warn_bitwise_instead_of_logical) + << (BO->getOpcode() == BO_And ? "&" : "|") + << OrigE->getSourceRange() + << FixItHint::CreateReplacement( + BO->getOperatorLoc(), + (BO->getOpcode() == BO_And ? "&&" : "||")); + S.Diag(BO->getBeginLoc(), diag::note_cast_operand_to_int); + } } // For conditional operators, we analyze the arguments as if they diff --git a/clang/lib/Sema/SemaCodeComplete.cpp b/clang/lib/Sema/SemaCodeComplete.cpp index 8d75239009401e22a2f57370b2be4f5725852098..73e6baa5278262e29397f9b617e512ffa5d8423c 100644 --- a/clang/lib/Sema/SemaCodeComplete.cpp +++ b/clang/lib/Sema/SemaCodeComplete.cpp @@ -764,6 +764,10 @@ getRequiredQualification(ASTContext &Context, const DeclContext *CurContext, // Filter out names reserved for the implementation if they come from a // system header. static bool shouldIgnoreDueToReservedName(const NamedDecl *ND, Sema &SemaRef) { + // Debuggers want access to all identifiers, including reserved ones. + if (SemaRef.getLangOpts().DebuggerSupport) + return false; + ReservedIdentifierStatus Status = ND->isReserved(SemaRef.getLangOpts()); // Ignore reserved names for compiler provided decls. if (isReservedInAllContexts(Status) && ND->getLocation().isInvalid()) diff --git a/clang/lib/Sema/SemaConcept.cpp b/clang/lib/Sema/SemaConcept.cpp index a8e387e35fb4c90095cb18212f413a34c6b7f87a..1c546e9f5894f024521d2410062e35204f35fa0b 100644 --- a/clang/lib/Sema/SemaConcept.cpp +++ b/clang/lib/Sema/SemaConcept.cpp @@ -692,11 +692,15 @@ bool Sema::CheckFunctionConstraints(const FunctionDecl *FD, // A lambda conversion operator has the same constraints as the call operator // and constraints checking relies on whether we are in a lambda call operator // (and may refer to its parameters), so check the call operator instead. + // Note that the declarations outside of the lambda should also be + // considered. Turning on the 'ForOverloadResolution' flag results in the + // LocalInstantiationScope not looking into its parents, but we can still + // access Decls from the parents while building a lambda RAII scope later. if (const auto *MD = dyn_cast(FD); MD && isLambdaConversionOperator(const_cast(MD))) return CheckFunctionConstraints(MD->getParent()->getLambdaCallOperator(), Satisfaction, UsageLoc, - ForOverloadResolution); + /*ShouldAddDeclsFromParentScope=*/true); DeclContext *CtxToSave = const_cast(FD); diff --git a/clang/lib/Sema/SemaCoroutine.cpp b/clang/lib/Sema/SemaCoroutine.cpp index 301a5ff72a3b2abe5f9ac2bff96fbf8bc3e0b6c5..736632857efc36997d039c0037e7ffdbe1e88b98 100644 --- a/clang/lib/Sema/SemaCoroutine.cpp +++ b/clang/lib/Sema/SemaCoroutine.cpp @@ -25,7 +25,6 @@ #include "clang/Sema/Initialization.h" #include "clang/Sema/Overload.h" #include "clang/Sema/ScopeInfo.h" -#include "clang/Sema/Sema.h" #include "clang/Sema/SemaInternal.h" #include "llvm/ADT/SmallSet.h" @@ -348,99 +347,15 @@ static Expr *maybeTailCall(Sema &S, QualType RetType, Expr *E, Expr *JustAddress = AddressExpr.get(); - // FIXME: Without optimizations, the temporary result from `await_suspend()` - // may be put on the coroutine frame since the coroutine frame constructor - // will think the temporary variable will escape from the - // `coroutine_handle<>::address()` call. This is problematic since the - // coroutine should be considered to be suspended after it enters - // `await_suspend` so it shouldn't access/update the coroutine frame after - // that. - // - // See https://github.com/llvm/llvm-project/issues/65054 for the report. - // - // The long term solution may wrap the whole logic about `await-suspend` - // into a standalone function. This is similar to the proposed solution - // in tryMarkAwaitSuspendNoInline. See the comments there for details. - // - // The short term solution here is to mark `coroutine_handle<>::address()` - // function as always-inline so that the coroutine frame constructor won't - // think the temporary result is escaped incorrectly. - if (auto *FD = cast(JustAddress)->getDirectCallee()) - if (!FD->hasAttr() && !FD->hasAttr()) - FD->addAttr(AlwaysInlineAttr::CreateImplicit(S.getASTContext(), - FD->getLocation())); - // Check that the type of AddressExpr is void* if (!JustAddress->getType().getTypePtr()->isVoidPointerType()) S.Diag(cast(JustAddress)->getCalleeDecl()->getLocation(), diag::warn_coroutine_handle_address_invalid_return_type) << JustAddress->getType(); - // Clean up temporary objects so that they don't live across suspension points - // unnecessarily. We choose to clean up before the call to - // __builtin_coro_resume so that the cleanup code are not inserted in-between - // the resume call and return instruction, which would interfere with the - // musttail call contract. - JustAddress = S.MaybeCreateExprWithCleanups(JustAddress); - return S.BuildBuiltinCallExpr(Loc, Builtin::BI__builtin_coro_resume, - JustAddress); -} - -/// The await_suspend call performed by co_await is essentially asynchronous -/// to the execution of the coroutine. Inlining it normally into an unsplit -/// coroutine can cause miscompilation because the coroutine CFG misrepresents -/// the true control flow of the program: things that happen in the -/// await_suspend are not guaranteed to happen prior to the resumption of the -/// coroutine, and things that happen after the resumption of the coroutine -/// (including its exit and the potential deallocation of the coroutine frame) -/// are not guaranteed to happen only after the end of await_suspend. -/// -/// See https://github.com/llvm/llvm-project/issues/56301 and -/// https://reviews.llvm.org/D157070 for the example and the full discussion. -/// -/// The short-term solution to this problem is to mark the call as uninlinable. -/// But we don't want to do this if the call is known to be trivial, which is -/// very common. -/// -/// The long-term solution may introduce patterns like: -/// -/// call @llvm.coro.await_suspend(ptr %awaiter, ptr %handle, -/// ptr @awaitSuspendFn) -/// -/// Then it is much easier to perform the safety analysis in the middle end. -/// If it is safe to inline the call to awaitSuspend, we can replace it in the -/// CoroEarly pass. Otherwise we could replace it in the CoroSplit pass. -static void tryMarkAwaitSuspendNoInline(Sema &S, OpaqueValueExpr *Awaiter, - CallExpr *AwaitSuspend) { - // The method here to extract the awaiter decl is not precise. - // This is intentional. Since it is hard to perform the analysis in the - // frontend due to the complexity of C++'s type systems. - // And we prefer to perform such analysis in the middle end since it is - // easier to implement and more powerful. - CXXRecordDecl *AwaiterDecl = - Awaiter->getType().getNonReferenceType()->getAsCXXRecordDecl(); - - if (AwaiterDecl && AwaiterDecl->field_empty()) - return; - - FunctionDecl *FD = AwaitSuspend->getDirectCallee(); - - assert(FD); - - // If the `await_suspend()` function is marked as `always_inline` explicitly, - // we should give the user the right to control the codegen. - if (FD->hasAttr() || FD->hasAttr()) - return; - - // This is problematic if the user calls the await_suspend standalone. But on - // the on hand, it is not incorrect semantically since inlining is not part - // of the standard. On the other hand, it is relatively rare to call - // the await_suspend function standalone. - // - // And given we've already had the long-term plan, the current workaround - // looks relatively tolerant. - FD->addAttr( - NoInlineAttr::CreateImplicit(S.getASTContext(), FD->getLocation())); + // Clean up temporary objects, because the resulting expression + // will become the body of await_suspend wrapper. + return S.MaybeCreateExprWithCleanups(JustAddress); } /// Build calls to await_ready, await_suspend, and await_resume for a co_await @@ -514,10 +429,6 @@ static ReadySuspendResumeResult buildCoawaitCalls(Sema &S, VarDecl *CoroPromise, // type Z. QualType RetType = AwaitSuspend->getCallReturnType(S.Context); - // We need to mark await_suspend as noinline temporarily. See the comment - // of tryMarkAwaitSuspendNoInline for details. - tryMarkAwaitSuspendNoInline(S, Operand, AwaitSuspend); - // Support for coroutine_handle returning await_suspend. if (Expr *TailCallSuspend = maybeTailCall(S, RetType, AwaitSuspend, Loc)) @@ -1379,21 +1290,8 @@ bool CoroutineStmtBuilder::makeReturnOnAllocFailure() { static bool collectPlacementArgs(Sema &S, FunctionDecl &FD, SourceLocation Loc, SmallVectorImpl &PlacementArgs) { if (auto *MD = dyn_cast(&FD)) { - if (MD->isImplicitObjectMemberFunction()) { - ExprResult ThisExpr{}; - - if (isLambdaCallOperator(MD) && !MD->isStatic()) { - Qualifiers ThisQuals = MD->getMethodQualifiers(); - CXXRecordDecl *Record = MD->getParent(); - - Sema::CXXThisScopeRAII ThisScope(S, Record, ThisQuals, - Record != nullptr); - - ThisExpr = S.ActOnCXXThis(Loc, /*ThisRefersToClosureObject=*/true); - } else { - ThisExpr = S.ActOnCXXThis(Loc); - } - + if (MD->isImplicitObjectMemberFunction() && !isLambdaCallOperator(MD)) { + ExprResult ThisExpr = S.ActOnCXXThis(Loc); if (ThisExpr.isInvalid()) return false; ThisExpr = S.CreateBuiltinUnaryOp(Loc, UO_Deref, ThisExpr.get()); diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index 1f4a041e88dfff1b2fea8154c549322808beb66d..5850cd0ab6b9aa48165ed2b97e8f5af5fe1b1839 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -1192,9 +1192,13 @@ Corrected: return ParsedType::make(T); } - if (isa(FirstDecl)) + if (isa(FirstDecl)) { + // We want to preserve the UsingShadowDecl for concepts. + if (auto *USD = dyn_cast(Result.getRepresentativeDecl())) + return NameClassification::Concept(TemplateName(USD)); return NameClassification::Concept( TemplateName(cast(FirstDecl))); + } if (auto *EmptyD = dyn_cast(FirstDecl)) { (void)DiagnoseUseOfDecl(EmptyD, NameLoc); diff --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp index e6943efb345ce03ab24109df6ac9be822ac750ef..ec00fdf3f88d9e411199f9f96f1bbeaec9a14340 100644 --- a/clang/lib/Sema/SemaDeclAttr.cpp +++ b/clang/lib/Sema/SemaDeclAttr.cpp @@ -1771,8 +1771,8 @@ void Sema::AddAllocAlignAttr(Decl *D, const AttributeCommonInfo &CI, } /// Check if \p AssumptionStr is a known assumption and warn if not. -static void checkAssumptionAttr(Sema &S, SourceLocation Loc, - StringRef AssumptionStr) { +static void checkOMPAssumeAttr(Sema &S, SourceLocation Loc, + StringRef AssumptionStr) { if (llvm::KnownAssumptionStrings.count(AssumptionStr)) return; @@ -1788,22 +1788,23 @@ static void checkAssumptionAttr(Sema &S, SourceLocation Loc, } if (!Suggestion.empty()) - S.Diag(Loc, diag::warn_assume_attribute_string_unknown_suggested) + S.Diag(Loc, diag::warn_omp_assume_attribute_string_unknown_suggested) << AssumptionStr << Suggestion; else - S.Diag(Loc, diag::warn_assume_attribute_string_unknown) << AssumptionStr; + S.Diag(Loc, diag::warn_omp_assume_attribute_string_unknown) + << AssumptionStr; } -static void handleAssumumptionAttr(Sema &S, Decl *D, const ParsedAttr &AL) { +static void handleOMPAssumeAttr(Sema &S, Decl *D, const ParsedAttr &AL) { // Handle the case where the attribute has a text message. StringRef Str; SourceLocation AttrStrLoc; if (!S.checkStringLiteralArgumentAttr(AL, 0, Str, &AttrStrLoc)) return; - checkAssumptionAttr(S, AttrStrLoc, Str); + checkOMPAssumeAttr(S, AttrStrLoc, Str); - D->addAttr(::new (S.Context) AssumptionAttr(S.Context, AL, Str)); + D->addAttr(::new (S.Context) OMPAssumeAttr(S.Context, AL, Str)); } /// Normalize the attribute, __foo__ becomes foo. @@ -3786,6 +3787,30 @@ static void handleCleanupAttr(Sema &S, Decl *D, const ParsedAttr &AL) { << NI.getName() << ParamTy << Ty; return; } + VarDecl *VD = cast(D); + // Create a reference to the variable declaration. This is a fake/dummy + // reference. + DeclRefExpr *VariableReference = DeclRefExpr::Create( + S.Context, NestedNameSpecifierLoc{}, FD->getLocation(), VD, false, + DeclarationNameInfo{VD->getDeclName(), VD->getLocation()}, VD->getType(), + VK_LValue); + + // Create a unary operator expression that represents taking the address of + // the variable. This is a fake/dummy expression. + Expr *AddressOfVariable = UnaryOperator::Create( + S.Context, VariableReference, UnaryOperatorKind::UO_AddrOf, + S.Context.getPointerType(VD->getType()), VK_PRValue, OK_Ordinary, Loc, + +false, FPOptionsOverride{}); + + // Create a function call expression. This is a fake/dummy call expression. + CallExpr *FunctionCallExpression = + CallExpr::Create(S.Context, E, ArrayRef{AddressOfVariable}, + S.Context.VoidTy, VK_PRValue, Loc, FPOptionsOverride{}); + + if (S.CheckFunctionCall(FD, FunctionCallExpression, + FD->getType()->getAs())) { + return; + } D->addAttr(::new (S.Context) CleanupAttr(S.Context, AL, FD)); } @@ -8078,6 +8103,65 @@ static void handleAMDGPUNumVGPRAttr(Sema &S, Decl *D, const ParsedAttr &AL) { D->addAttr(::new (S.Context) AMDGPUNumVGPRAttr(S.Context, AL, NumVGPR)); } +static bool +checkAMDGPUMaxNumWorkGroupsArguments(Sema &S, Expr *XExpr, Expr *YExpr, + Expr *ZExpr, + const AMDGPUMaxNumWorkGroupsAttr &Attr) { + if (S.DiagnoseUnexpandedParameterPack(XExpr) || + (YExpr && S.DiagnoseUnexpandedParameterPack(YExpr)) || + (ZExpr && S.DiagnoseUnexpandedParameterPack(ZExpr))) + return true; + + // Accept template arguments for now as they depend on something else. + // We'll get to check them when they eventually get instantiated. + if (XExpr->isValueDependent() || (YExpr && YExpr->isValueDependent()) || + (ZExpr && ZExpr->isValueDependent())) + return false; + + uint32_t NumWG = 0; + Expr *Exprs[3] = {XExpr, YExpr, ZExpr}; + for (int i = 0; i < 3; i++) { + if (Exprs[i]) { + if (!checkUInt32Argument(S, Attr, Exprs[i], NumWG, i, + /*StrictlyUnsigned=*/true)) + return true; + if (NumWG == 0) { + S.Diag(Attr.getLoc(), diag::err_attribute_argument_is_zero) + << &Attr << Exprs[i]->getSourceRange(); + return true; + } + } + } + + return false; +} + +AMDGPUMaxNumWorkGroupsAttr * +Sema::CreateAMDGPUMaxNumWorkGroupsAttr(const AttributeCommonInfo &CI, + Expr *XExpr, Expr *YExpr, Expr *ZExpr) { + AMDGPUMaxNumWorkGroupsAttr TmpAttr(Context, CI, XExpr, YExpr, ZExpr); + + if (checkAMDGPUMaxNumWorkGroupsArguments(*this, XExpr, YExpr, ZExpr, TmpAttr)) + return nullptr; + + return ::new (Context) + AMDGPUMaxNumWorkGroupsAttr(Context, CI, XExpr, YExpr, ZExpr); +} + +void Sema::addAMDGPUMaxNumWorkGroupsAttr(Decl *D, const AttributeCommonInfo &CI, + Expr *XExpr, Expr *YExpr, + Expr *ZExpr) { + if (auto *Attr = CreateAMDGPUMaxNumWorkGroupsAttr(CI, XExpr, YExpr, ZExpr)) + D->addAttr(Attr); +} + +static void handleAMDGPUMaxNumWorkGroupsAttr(Sema &S, Decl *D, + const ParsedAttr &AL) { + Expr *YExpr = (AL.getNumArgs() > 1) ? AL.getArgAsExpr(1) : nullptr; + Expr *ZExpr = (AL.getNumArgs() > 2) ? AL.getArgAsExpr(2) : nullptr; + S.addAMDGPUMaxNumWorkGroupsAttr(D, AL, AL.getArgAsExpr(0), YExpr, ZExpr); +} + static void handleX86ForceAlignArgPointerAttr(Sema &S, Decl *D, const ParsedAttr &AL) { // If we try to apply it to a function pointer, don't warn, but don't @@ -9182,6 +9266,9 @@ ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D, const ParsedAttr &AL, case ParsedAttr::AT_AMDGPUNumVGPR: handleAMDGPUNumVGPRAttr(S, D, AL); break; + case ParsedAttr::AT_AMDGPUMaxNumWorkGroups: + handleAMDGPUMaxNumWorkGroupsAttr(S, D, AL); + break; case ParsedAttr::AT_AVRSignal: handleAVRSignalAttr(S, D, AL); break; @@ -9491,8 +9578,8 @@ ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D, const ParsedAttr &AL, case ParsedAttr::AT_Unavailable: handleAttrWithMessage(S, D, AL); break; - case ParsedAttr::AT_Assumption: - handleAssumumptionAttr(S, D, AL); + case ParsedAttr::AT_OMPAssume: + handleOMPAssumeAttr(S, D, AL); break; case ParsedAttr::AT_ObjCDirect: handleObjCDirectAttr(S, D, AL); diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index 93f82e68ab644047ec31fbc03150060bda3358f9..8725b09f8546cf742b2094270f74616750f33bdb 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -1099,12 +1099,13 @@ ExprResult Sema::DefaultVariadicArgumentPromotion(Expr *E, VariadicCallType CT, return E; } -/// Converts an integer to complex float type. Helper function of +/// Convert complex integers to complex floats and real integers to +/// real floats as required for complex arithmetic. Helper function of /// UsualArithmeticConversions() /// /// \return false if the integer expression is an integer type and is -/// successfully converted to the complex type. -static bool handleIntegerToComplexFloatConversion(Sema &S, ExprResult &IntExpr, +/// successfully converted to the (complex) float type. +static bool handleComplexIntegerToFloatConversion(Sema &S, ExprResult &IntExpr, ExprResult &ComplexExpr, QualType IntTy, QualType ComplexTy, @@ -1114,8 +1115,6 @@ static bool handleIntegerToComplexFloatConversion(Sema &S, ExprResult &IntExpr, if (IntTy->isIntegerType()) { QualType fpTy = ComplexTy->castAs()->getElementType(); IntExpr = S.ImpCastExprToType(IntExpr.get(), fpTy, CK_IntegralToFloating); - IntExpr = S.ImpCastExprToType(IntExpr.get(), ComplexTy, - CK_FloatingRealToComplex); } else { assert(IntTy->isComplexIntegerType()); IntExpr = S.ImpCastExprToType(IntExpr.get(), ComplexTy, @@ -1160,11 +1159,11 @@ static QualType handleComplexFloatConversion(Sema &S, ExprResult &Shorter, static QualType handleComplexConversion(Sema &S, ExprResult &LHS, ExprResult &RHS, QualType LHSType, QualType RHSType, bool IsCompAssign) { - // if we have an integer operand, the result is the complex type. - if (!handleIntegerToComplexFloatConversion(S, RHS, LHS, RHSType, LHSType, + // Handle (complex) integer types. + if (!handleComplexIntegerToFloatConversion(S, RHS, LHS, RHSType, LHSType, /*SkipCast=*/false)) return LHSType; - if (!handleIntegerToComplexFloatConversion(S, LHS, RHS, LHSType, RHSType, + if (!handleComplexIntegerToFloatConversion(S, LHS, RHS, LHSType, RHSType, /*SkipCast=*/IsCompAssign)) return RHSType; diff --git a/clang/lib/Sema/SemaExprCXX.cpp b/clang/lib/Sema/SemaExprCXX.cpp index 88e3d9ced044cb49d9f868a90fe5b0b06f59d0c2..c34a40fa7c81ac9ac3d3c67371a1da05ebe17a92 100644 --- a/clang/lib/Sema/SemaExprCXX.cpp +++ b/clang/lib/Sema/SemaExprCXX.cpp @@ -1414,8 +1414,7 @@ bool Sema::CheckCXXThisCapture(SourceLocation Loc, const bool Explicit, return false; } -ExprResult Sema::ActOnCXXThis(SourceLocation Loc, - bool ThisRefersToClosureObject) { +ExprResult Sema::ActOnCXXThis(SourceLocation Loc) { /// C++ 9.3.2: In the body of a non-static member function, the keyword this /// is a non-lvalue expression whose value is the address of the object for /// which the function is called. @@ -1435,18 +1434,13 @@ ExprResult Sema::ActOnCXXThis(SourceLocation Loc, return Diag(Loc, diag::err_invalid_this_use) << 0; } - return BuildCXXThisExpr(Loc, ThisTy, /*IsImplicit=*/false, - ThisRefersToClosureObject); + return BuildCXXThisExpr(Loc, ThisTy, /*IsImplicit=*/false); } -Expr *Sema::BuildCXXThisExpr(SourceLocation Loc, QualType Type, bool IsImplicit, - bool ThisRefersToClosureObject) { +Expr *Sema::BuildCXXThisExpr(SourceLocation Loc, QualType Type, + bool IsImplicit) { auto *This = CXXThisExpr::Create(Context, Loc, Type, IsImplicit); - - if (!ThisRefersToClosureObject) { - MarkThisReferenced(This); - } - + MarkThisReferenced(This); return This; } diff --git a/clang/lib/Sema/SemaModule.cpp b/clang/lib/Sema/SemaModule.cpp index f08c1cb3a13ef525add8252751fe1bebf4dff677..2ddf9d70263a094d1cf0d9e7fa387247771521a5 100644 --- a/clang/lib/Sema/SemaModule.cpp +++ b/clang/lib/Sema/SemaModule.cpp @@ -713,7 +713,7 @@ DeclResult Sema::ActOnModuleImport(SourceLocation StartLoc, return Import; } -void Sema::ActOnModuleInclude(SourceLocation DirectiveLoc, Module *Mod) { +void Sema::ActOnAnnotModuleInclude(SourceLocation DirectiveLoc, Module *Mod) { checkModuleImportContext(*this, Mod, DirectiveLoc, CurContext, true); BuildModuleInclude(DirectiveLoc, Mod); } @@ -723,9 +723,9 @@ void Sema::BuildModuleInclude(SourceLocation DirectiveLoc, Module *Mod) { // in that buffer do not qualify as module imports; they're just an // implementation detail of us building the module. // - // FIXME: Should we even get ActOnModuleInclude calls for those? + // FIXME: Should we even get ActOnAnnotModuleInclude calls for those? bool IsInModuleIncludes = - TUKind == TU_Module && + TUKind == TU_ClangModule && getSourceManager().isWrittenInMainFile(DirectiveLoc); // If we are really importing a module (not just checking layering) due to an @@ -752,7 +752,7 @@ void Sema::BuildModuleInclude(SourceLocation DirectiveLoc, Module *Mod) { } } -void Sema::ActOnModuleBegin(SourceLocation DirectiveLoc, Module *Mod) { +void Sema::ActOnAnnotModuleBegin(SourceLocation DirectiveLoc, Module *Mod) { checkModuleImportContext(*this, Mod, DirectiveLoc, CurContext, true); ModuleScopes.push_back({}); @@ -776,7 +776,7 @@ void Sema::ActOnModuleBegin(SourceLocation DirectiveLoc, Module *Mod) { } } -void Sema::ActOnModuleEnd(SourceLocation EomLoc, Module *Mod) { +void Sema::ActOnAnnotModuleEnd(SourceLocation EomLoc, Module *Mod) { if (getLangOpts().ModulesLocalVisibility) { VisibleModules = std::move(ModuleScopes.back().OuterVisibleModules); // Leaving a module hides namespace names, so our visible namespace cache diff --git a/clang/lib/Sema/SemaOpenMP.cpp b/clang/lib/Sema/SemaOpenMP.cpp index afffd371c58d9d051356a9ba5cc0d529c5591c51..e9ad7bbde0f9b5d71e51e929a825b0e253d43cb3 100644 --- a/clang/lib/Sema/SemaOpenMP.cpp +++ b/clang/lib/Sema/SemaOpenMP.cpp @@ -3496,7 +3496,7 @@ void Sema::ActOnOpenMPAssumesDirective(SourceLocation Loc, << llvm::omp::getAllAssumeClauseOptions() << llvm::omp::getOpenMPDirectiveName(DKind); - auto *AA = AssumptionAttr::Create(Context, llvm::join(Assumptions, ","), Loc); + auto *AA = OMPAssumeAttr::Create(Context, llvm::join(Assumptions, ","), Loc); if (DKind == llvm::omp::Directive::OMPD_begin_assumes) { OMPAssumeScoped.push_back(AA); return; @@ -7275,10 +7275,10 @@ void Sema::ActOnFinishedFunctionDefinitionInOpenMPAssumeScope(Decl *D) { // only global ones. We apply scoped assumption to the template definition // though. if (!inTemplateInstantiation()) { - for (AssumptionAttr *AA : OMPAssumeScoped) + for (OMPAssumeAttr *AA : OMPAssumeScoped) FD->addAttr(AA); } - for (AssumptionAttr *AA : OMPAssumeGlobal) + for (OMPAssumeAttr *AA : OMPAssumeGlobal) FD->addAttr(AA); } @@ -14366,7 +14366,8 @@ StmtResult Sema::ActOnOpenMPTargetParallelForSimdDirective( // The point of exit cannot be a branch out of the structured block. // longjmp() and throw() must not violate the entry/exit criteria. CS->getCapturedDecl()->setNothrow(); - for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel_for); + for (int ThisCaptureLevel = + getOpenMPCaptureLevels(OMPD_target_parallel_for_simd); ThisCaptureLevel > 1; --ThisCaptureLevel) { CS = cast(CS->getCapturedStmt()); // 1.2.2 OpenMP Language Terminology diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp index b0c693f078efe2cc47eb9f326861bd5c55d5c86d..f6bd85bdc64692e3de882b9006694bdf40e505eb 100644 --- a/clang/lib/Sema/SemaOverload.cpp +++ b/clang/lib/Sema/SemaOverload.cpp @@ -8516,6 +8516,9 @@ class BuiltinCandidateTypeSet { /// candidates. TypeSet MatrixTypes; + /// The set of _BitInt types that will be used in the built-in candidates. + TypeSet BitIntTypes; + /// A flag indicating non-record types are viable candidates bool HasNonRecordTypes; @@ -8564,6 +8567,7 @@ public: } llvm::iterator_range vector_types() { return VectorTypes; } llvm::iterator_range matrix_types() { return MatrixTypes; } + llvm::iterator_range bitint_types() { return BitIntTypes; } bool containsMatrixType(QualType Ty) const { return MatrixTypes.count(Ty); } bool hasNonRecordTypes() { return HasNonRecordTypes; } @@ -8735,6 +8739,9 @@ BuiltinCandidateTypeSet::AddTypesConvertedFrom(QualType Ty, } else if (Ty->isEnumeralType()) { HasArithmeticOrEnumeralTypes = true; EnumerationTypes.insert(Ty); + } else if (Ty->isBitIntType()) { + HasArithmeticOrEnumeralTypes = true; + BitIntTypes.insert(Ty); } else if (Ty->isVectorType()) { // We treat vector types as arithmetic types in many contexts as an // extension. @@ -8913,7 +8920,7 @@ class BuiltinOperatorOverloadBuilder { SmallVectorImpl &CandidateTypes; OverloadCandidateSet &CandidateSet; - static constexpr int ArithmeticTypesCap = 24; + static constexpr int ArithmeticTypesCap = 26; SmallVector ArithmeticTypes; // Define some indices used to iterate over the arithmetic types in @@ -8955,6 +8962,20 @@ class BuiltinOperatorOverloadBuilder { (S.Context.getAuxTargetInfo() && S.Context.getAuxTargetInfo()->hasInt128Type())) ArithmeticTypes.push_back(S.Context.UnsignedInt128Ty); + + /// We add candidates for the unique, unqualified _BitInt types present in + /// the candidate type set. The candidate set already handled ensuring the + /// type is unqualified and canonical, but because we're adding from N + /// different sets, we need to do some extra work to unique things. Insert + /// the candidates into a unique set, then move from that set into the list + /// of arithmetic types. + llvm::SmallSetVector BitIntCandidates; + llvm::for_each(CandidateTypes, [&BitIntCandidates]( + BuiltinCandidateTypeSet &Candidate) { + for (QualType BitTy : Candidate.bitint_types()) + BitIntCandidates.insert(CanQualType::CreateUnsafe(BitTy)); + }); + llvm::move(BitIntCandidates, std::back_inserter(ArithmeticTypes)); LastPromotedIntegralType = ArithmeticTypes.size(); LastPromotedArithmeticType = ArithmeticTypes.size(); // End of promoted types. @@ -8975,7 +8996,11 @@ class BuiltinOperatorOverloadBuilder { // End of integral types. // FIXME: What about complex? What about half? - assert(ArithmeticTypes.size() <= ArithmeticTypesCap && + // We don't know for sure how many bit-precise candidates were involved, so + // we subtract those from the total when testing whether we're under the + // cap or not. + assert(ArithmeticTypes.size() - BitIntCandidates.size() <= + ArithmeticTypesCap && "Enough inline storage for all arithmetic types."); } diff --git a/clang/lib/Sema/SemaStmtAttr.cpp b/clang/lib/Sema/SemaStmtAttr.cpp index e6a4d3e63e4aa87e7173e1e3fc01dd5e3bf74fef..691857e88beb490089f23789e85e7c1709ceaeae 100644 --- a/clang/lib/Sema/SemaStmtAttr.cpp +++ b/clang/lib/Sema/SemaStmtAttr.cpp @@ -303,6 +303,15 @@ static Attr *handleAlwaysInlineAttr(Sema &S, Stmt *St, const ParsedAttr &A, return ::new (S.Context) AlwaysInlineAttr(S.Context, A); } +static Attr *handleCXXAssumeAttr(Sema &S, Stmt *St, const ParsedAttr &A, + SourceRange Range) { + ExprResult Res = S.ActOnCXXAssumeAttr(St, A, Range); + if (!Res.isUsable()) + return nullptr; + + return ::new (S.Context) CXXAssumeAttr(S.Context, A, Res.get()); +} + static Attr *handleMustTailAttr(Sema &S, Stmt *St, const ParsedAttr &A, SourceRange Range) { // Validation is in Sema::ActOnAttributedStmt(). @@ -594,6 +603,8 @@ static Attr *ProcessStmtAttribute(Sema &S, Stmt *St, const ParsedAttr &A, switch (A.getKind()) { case ParsedAttr::AT_AlwaysInline: return handleAlwaysInlineAttr(S, St, A, Range); + case ParsedAttr::AT_CXXAssume: + return handleCXXAssumeAttr(S, St, A, Range); case ParsedAttr::AT_FallThrough: return handleFallThroughAttr(S, St, A, Range); case ParsedAttr::AT_LoopHint: @@ -641,3 +652,47 @@ bool Sema::CheckRebuiltStmtAttributes(ArrayRef Attrs) { CheckForDuplicateLoopAttrs(*this, Attrs); return false; } + +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; + return ExprError(); + } + + auto *Assumption = A.getArgAsExpr(0); + if (Assumption->getDependence() == ExprDependence::None) { + ExprResult Res = BuildCXXAssumeExpr(Assumption, A.getAttrName(), Range); + if (Res.isInvalid()) + return ExprError(); + Assumption = Res.get(); + } + + if (!getLangOpts().CPlusPlus23) + Diag(A.getLoc(), diag::ext_cxx23_attr) << A << Range; + + return Assumption; +} + +ExprResult Sema::BuildCXXAssumeExpr(Expr *Assumption, + const IdentifierInfo *AttrName, + SourceRange Range) { + ExprResult Res = CorrectDelayedTyposInExpr(Assumption); + if (Res.isInvalid()) + return ExprError(); + + Res = CheckPlaceholderExpr(Res.get()); + if (Res.isInvalid()) + return ExprError(); + + Res = PerformContextuallyConvertToBool(Res.get()); + if (Res.isInvalid()) + return ExprError(); + + Assumption = Res.get(); + if (Assumption->HasSideEffects(Context)) + Diag(Assumption->getBeginLoc(), diag::warn_assume_side_effects) + << AttrName << Range; + + return Assumption; +} diff --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp index d62095558d0ffbd29b1703e8f9fba23153062432..005529a53270c30a25124e94559ed190f32bf86e 100644 --- a/clang/lib/Sema/SemaTemplate.cpp +++ b/clang/lib/Sema/SemaTemplate.cpp @@ -1156,6 +1156,7 @@ bool Sema::BuildTypeConstraint(const CXXScopeSpec &SS, TemplateName TN = TypeConstr->Template.get(); ConceptDecl *CD = cast(TN.getAsTemplateDecl()); + UsingShadowDecl *USD = TN.getAsUsingShadowDecl(); DeclarationNameInfo ConceptName(DeclarationName(TypeConstr->Name), TypeConstr->TemplateNameLoc); @@ -1174,15 +1175,15 @@ bool Sema::BuildTypeConstraint(const CXXScopeSpec &SS, } return AttachTypeConstraint( SS.isSet() ? SS.getWithLocInContext(Context) : NestedNameSpecifierLoc(), - ConceptName, CD, + ConceptName, CD, /*FoundDecl=*/USD ? cast(USD) : CD, TypeConstr->LAngleLoc.isValid() ? &TemplateArgs : nullptr, ConstrainedParameter, EllipsisLoc); } -template +template static ExprResult formImmediatelyDeclaredConstraint( Sema &S, NestedNameSpecifierLoc NS, DeclarationNameInfo NameInfo, - ConceptDecl *NamedConcept, SourceLocation LAngleLoc, + ConceptDecl *NamedConcept, NamedDecl *FoundDecl, SourceLocation LAngleLoc, SourceLocation RAngleLoc, QualType ConstrainedType, SourceLocation ParamNameLoc, ArgumentLocAppender Appender, SourceLocation EllipsisLoc) { @@ -1203,7 +1204,8 @@ static ExprResult formImmediatelyDeclaredConstraint( SS.Adopt(NS); ExprResult ImmediatelyDeclaredConstraint = S.CheckConceptTemplateId( SS, /*TemplateKWLoc=*/SourceLocation(), NameInfo, - /*FoundDecl=*/NamedConcept, NamedConcept, &ConstraintArgs); + /*FoundDecl=*/FoundDecl ? FoundDecl : NamedConcept, NamedConcept, + &ConstraintArgs); if (ImmediatelyDeclaredConstraint.isInvalid() || !EllipsisLoc.isValid()) return ImmediatelyDeclaredConstraint; @@ -1233,7 +1235,7 @@ static ExprResult formImmediatelyDeclaredConstraint( /// of arguments for the named concept). bool Sema::AttachTypeConstraint(NestedNameSpecifierLoc NS, DeclarationNameInfo NameInfo, - ConceptDecl *NamedConcept, + ConceptDecl *NamedConcept, NamedDecl *FoundDecl, const TemplateArgumentListInfo *TemplateArgs, TemplateTypeParmDecl *ConstrainedParameter, SourceLocation EllipsisLoc) { @@ -1246,24 +1248,24 @@ bool Sema::AttachTypeConstraint(NestedNameSpecifierLoc NS, QualType ParamAsArgument(ConstrainedParameter->getTypeForDecl(), 0); - ExprResult ImmediatelyDeclaredConstraint = - formImmediatelyDeclaredConstraint( - *this, NS, NameInfo, NamedConcept, - TemplateArgs ? TemplateArgs->getLAngleLoc() : SourceLocation(), - TemplateArgs ? TemplateArgs->getRAngleLoc() : SourceLocation(), - ParamAsArgument, ConstrainedParameter->getLocation(), - [&] (TemplateArgumentListInfo &ConstraintArgs) { - if (TemplateArgs) - for (const auto &ArgLoc : TemplateArgs->arguments()) - ConstraintArgs.addArgument(ArgLoc); - }, EllipsisLoc); + ExprResult ImmediatelyDeclaredConstraint = formImmediatelyDeclaredConstraint( + *this, NS, NameInfo, NamedConcept, FoundDecl, + TemplateArgs ? TemplateArgs->getLAngleLoc() : SourceLocation(), + TemplateArgs ? TemplateArgs->getRAngleLoc() : SourceLocation(), + ParamAsArgument, ConstrainedParameter->getLocation(), + [&](TemplateArgumentListInfo &ConstraintArgs) { + if (TemplateArgs) + for (const auto &ArgLoc : TemplateArgs->arguments()) + ConstraintArgs.addArgument(ArgLoc); + }, + EllipsisLoc); if (ImmediatelyDeclaredConstraint.isInvalid()) return true; auto *CL = ConceptReference::Create(Context, /*NNS=*/NS, /*TemplateKWLoc=*/SourceLocation{}, /*ConceptNameInfo=*/NameInfo, - /*FoundDecl=*/NamedConcept, + /*FoundDecl=*/FoundDecl, /*NamedConcept=*/NamedConcept, /*ArgsWritten=*/ArgsAsWritten); ConstrainedParameter->setTypeConstraint(CL, @@ -1293,8 +1295,9 @@ bool Sema::AttachTypeConstraint(AutoTypeLoc TL, return true; ExprResult ImmediatelyDeclaredConstraint = formImmediatelyDeclaredConstraint( *this, TL.getNestedNameSpecifierLoc(), TL.getConceptNameInfo(), - TL.getNamedConcept(), TL.getLAngleLoc(), TL.getRAngleLoc(), - BuildDecltypeType(Ref), OrigConstrainedParm->getLocation(), + TL.getNamedConcept(), /*FoundDecl=*/TL.getFoundDecl(), TL.getLAngleLoc(), + TL.getRAngleLoc(), BuildDecltypeType(Ref), + OrigConstrainedParm->getLocation(), [&](TemplateArgumentListInfo &ConstraintArgs) { for (unsigned I = 0, C = TL.getNumArgs(); I != C; ++I) ConstraintArgs.addArgument(TL.getArgLoc(I)); @@ -2906,18 +2909,27 @@ void DeclareImplicitDeductionGuidesForTypeAlias( Context.getCanonicalTemplateArgument( Context.getInjectedTemplateArg(NewParam)); } - // FIXME: implement the associated constraint per C++ + // Substitute new template parameters into requires-clause if present. + Expr *RequiresClause = nullptr; + if (Expr *InnerRC = F->getTemplateParameters()->getRequiresClause()) { + MultiLevelTemplateArgumentList Args; + Args.setKind(TemplateSubstitutionKind::Rewrite); + Args.addOuterTemplateArguments(TemplateArgsForBuildingFPrime); + ExprResult E = SemaRef.SubstExpr(InnerRC, Args); + if (E.isInvalid()) + return; + RequiresClause = E.getAs(); + } + // FIXME: implement the is_deducible constraint per C++ // [over.match.class.deduct]p3.3: - // The associated constraints ([temp.constr.decl]) are the - // conjunction of the associated constraints of g and a - // constraint that is satisfied if and only if the arguments + // ... and a constraint that is satisfied if and only if the arguments // of A are deducible (see below) from the return type. auto *FPrimeTemplateParamList = TemplateParameterList::Create( Context, AliasTemplate->getTemplateParameters()->getTemplateLoc(), AliasTemplate->getTemplateParameters()->getLAngleLoc(), FPrimeTemplateParams, AliasTemplate->getTemplateParameters()->getRAngleLoc(), - /*RequiresClause=*/nullptr); + /*RequiresClause=*/RequiresClause); // To form a deduction guide f' from f, we leverage clang's instantiation // mechanism, we construct a template argument list where the template @@ -4343,9 +4355,13 @@ QualType Sema::CheckTemplateIdType(TemplateName Name, if (Inst.isInvalid()) return QualType(); - CanonType = SubstType(Pattern->getUnderlyingType(), - TemplateArgLists, AliasTemplate->getLocation(), - AliasTemplate->getDeclName()); + std::optional SavedContext; + if (!AliasTemplate->getDeclContext()->isFileContext()) + SavedContext.emplace(*this, AliasTemplate->getDeclContext()); + + CanonType = + SubstType(Pattern->getUnderlyingType(), TemplateArgLists, + AliasTemplate->getLocation(), AliasTemplate->getDeclName()); if (CanonType.isNull()) { // If this was enable_if and we failed to find the nested type // within enable_if in a SFINAE context, dig out the specific @@ -5402,7 +5418,7 @@ ExprResult Sema::BuildTemplateIdExpr(const CXXScopeSpec &SS, if (R.getAsSingle()) { return CheckConceptTemplateId(SS, TemplateKWLoc, R.getLookupNameInfo(), - R.getFoundDecl(), + R.getRepresentativeDecl(), R.getAsSingle(), TemplateArgs); } diff --git a/clang/lib/Sema/SemaTemplateInstantiate.cpp b/clang/lib/Sema/SemaTemplateInstantiate.cpp index d9994d7fd37adbb8025105ff5f715bb73a557eef..5e05cb4f790b8504039f5e777542f6d3ed6f7255 100644 --- a/clang/lib/Sema/SemaTemplateInstantiate.cpp +++ b/clang/lib/Sema/SemaTemplateInstantiate.cpp @@ -1411,6 +1411,7 @@ namespace { NamedDecl *FirstQualifierInScope = nullptr, bool AllowInjectedClassName = false); + const CXXAssumeAttr *TransformCXXAssumeAttr(const CXXAssumeAttr *AA); const LoopHintAttr *TransformLoopHintAttr(const LoopHintAttr *LH); const NoInlineAttr *TransformStmtNoInlineAttr(const Stmt *OrigS, const Stmt *InstS, @@ -1980,6 +1981,21 @@ TemplateInstantiator::TransformTemplateParmRefExpr(DeclRefExpr *E, Arg, PackIndex); } +const CXXAssumeAttr * +TemplateInstantiator::TransformCXXAssumeAttr(const CXXAssumeAttr *AA) { + ExprResult Res = getDerived().TransformExpr(AA->getAssumption()); + if (!Res.isUsable()) + return AA; + + Res = getSema().BuildCXXAssumeExpr(Res.get(), AA->getAttrName(), + AA->getRange()); + if (!Res.isUsable()) + return AA; + + return CXXAssumeAttr::CreateImplicit(getSema().Context, Res.get(), + AA->getRange()); +} + const LoopHintAttr * TemplateInstantiator::TransformLoopHintAttr(const LoopHintAttr *LH) { Expr *TransformedExpr = getDerived().TransformExpr(LH->getValue()).get(); @@ -2954,7 +2970,8 @@ bool Sema::SubstTypeConstraint( } return AttachTypeConstraint( TC->getNestedNameSpecifierLoc(), TC->getConceptNameInfo(), - TC->getNamedConcept(), &InstArgs, Inst, + TC->getNamedConcept(), + /*FoundDecl=*/TC->getConceptReference()->getFoundDecl(), &InstArgs, Inst, Inst->isParameterPack() ? cast(TC->getImmediatelyDeclaredConstraint()) ->getEllipsisLoc() diff --git a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp index 20c2c93ac9c7b415ece248f4119532bde1b0ab5e..dc972018e7b2815042708edf6a3cab1942f096f3 100644 --- a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp +++ b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp @@ -607,6 +607,29 @@ static void instantiateDependentAMDGPUWavesPerEUAttr( S.addAMDGPUWavesPerEUAttr(New, Attr, MinExpr, MaxExpr); } +static void instantiateDependentAMDGPUMaxNumWorkGroupsAttr( + Sema &S, const MultiLevelTemplateArgumentList &TemplateArgs, + const AMDGPUMaxNumWorkGroupsAttr &Attr, Decl *New) { + EnterExpressionEvaluationContext Unevaluated( + S, Sema::ExpressionEvaluationContext::ConstantEvaluated); + + ExprResult ResultX = S.SubstExpr(Attr.getMaxNumWorkGroupsX(), TemplateArgs); + if (!ResultX.isUsable()) + return; + ExprResult ResultY = S.SubstExpr(Attr.getMaxNumWorkGroupsY(), TemplateArgs); + if (!ResultY.isUsable()) + return; + ExprResult ResultZ = S.SubstExpr(Attr.getMaxNumWorkGroupsZ(), TemplateArgs); + if (!ResultZ.isUsable()) + return; + + Expr *XExpr = ResultX.getAs(); + Expr *YExpr = ResultY.getAs(); + Expr *ZExpr = ResultZ.getAs(); + + S.addAMDGPUMaxNumWorkGroupsAttr(New, Attr, XExpr, YExpr, ZExpr); +} + // This doesn't take any template parameters, but we have a custom action that // needs to happen when the kernel itself is instantiated. We need to run the // ItaniumMangler to mark the names required to name this kernel. @@ -792,6 +815,12 @@ void Sema::InstantiateAttrs(const MultiLevelTemplateArgumentList &TemplateArgs, *AMDGPUFlatWorkGroupSize, New); } + if (const auto *AMDGPUMaxNumWorkGroups = + dyn_cast(TmplAttr)) { + instantiateDependentAMDGPUMaxNumWorkGroupsAttr( + *this, TemplateArgs, *AMDGPUMaxNumWorkGroups, New); + } + if (const auto *ParamAttr = dyn_cast(TmplAttr)) { instantiateDependentHLSLParamModifierAttr(*this, TemplateArgs, ParamAttr, New); @@ -1698,6 +1727,7 @@ Decl *TemplateDeclInstantiator::VisitClassTemplateDecl(ClassTemplateDecl *D) { assert(!Owner->isDependentContext()); Inst->setLexicalDeclContext(Owner); RecordInst->setLexicalDeclContext(Owner); + Inst->setObjectOfFriendDecl(); if (PrevClassTemplate) { Inst->setCommonPtr(PrevClassTemplate->getCommonPtr()); diff --git a/clang/lib/Sema/SemaType.cpp b/clang/lib/Sema/SemaType.cpp index 3148299f6467af7f260b10de9d820947ed305128..9aaacaa0771f2febd26411502ba02ea709d36150 100644 --- a/clang/lib/Sema/SemaType.cpp +++ b/clang/lib/Sema/SemaType.cpp @@ -3499,7 +3499,7 @@ InventTemplateParameter(TypeProcessingState &state, QualType T, if (!Invalid) { S.AttachTypeConstraint( AutoLoc.getNestedNameSpecifierLoc(), AutoLoc.getConceptNameInfo(), - AutoLoc.getNamedConcept(), + AutoLoc.getNamedConcept(), /*FoundDecl=*/AutoLoc.getFoundDecl(), AutoLoc.hasExplicitTemplateArgs() ? &TAL : nullptr, InventedTemplateParam, D.getEllipsisLoc()); } @@ -3525,11 +3525,17 @@ InventTemplateParameter(TypeProcessingState &state, QualType T, } } if (!Invalid) { + UsingShadowDecl *USD = + TemplateId->Template.get().getAsUsingShadowDecl(); + auto *CD = + cast(TemplateId->Template.get().getAsTemplateDecl()); S.AttachTypeConstraint( D.getDeclSpec().getTypeSpecScope().getWithLocInContext(S.Context), DeclarationNameInfo(DeclarationName(TemplateId->Name), TemplateId->TemplateNameLoc), - cast(TemplateId->Template.get().getAsTemplateDecl()), + CD, + /*FoundDecl=*/ + USD ? cast(USD) : CD, TemplateId->LAngleLoc.isValid() ? &TemplateArgsInfo : nullptr, InventedTemplateParam, D.getEllipsisLoc()); } @@ -6423,9 +6429,12 @@ namespace { DeclarationNameInfo DNI = DeclarationNameInfo( TL.getTypePtr()->getTypeConstraintConcept()->getDeclName(), TemplateId->TemplateNameLoc); + auto TN = TemplateId->Template.get(); auto *CR = ConceptReference::Create( Context, NNS, TemplateId->TemplateKWLoc, DNI, - /*FoundDecl=*/nullptr, + /*FoundDecl=*/TN.getKind() == TemplateName::NameKind::UsingTemplate + ? cast(TN.getAsUsingShadowDecl()) + : cast_if_present(TN.getAsTemplateDecl()), /*NamedDecl=*/TL.getTypePtr()->getTypeConstraintConcept(), ASTTemplateArgumentListInfo::Create(Context, TemplateArgsInfo)); TL.setConceptReference(CR); diff --git a/clang/lib/Serialization/ASTReader.cpp b/clang/lib/Serialization/ASTReader.cpp index 683a076e6bc3998b500c580fb8f1001fb52f2933..ede9f6e93469b7ea32c4c3bc5eb863f145ffe75f 100644 --- a/clang/lib/Serialization/ASTReader.cpp +++ b/clang/lib/Serialization/ASTReader.cpp @@ -9762,7 +9762,7 @@ void ASTReader::finishPendingActions() { !NonConstDefn->isLateTemplateParsed() && // We only perform ODR checks for decls not in the explicit // global module fragment. - !shouldSkipCheckingODR(FD) && + !FD->shouldSkipCheckingODR() && FD->getODRHash() != NonConstDefn->getODRHash()) { if (!isa(FD)) { PendingFunctionOdrMergeFailures[FD].push_back(NonConstDefn); diff --git a/clang/lib/Serialization/ASTReaderDecl.cpp b/clang/lib/Serialization/ASTReaderDecl.cpp index d5309e3fc31f709921845aec951d2107fbea89b9..a22f760408c634f93adde1c846fa09e7b5bd8263 100644 --- a/clang/lib/Serialization/ASTReaderDecl.cpp +++ b/clang/lib/Serialization/ASTReaderDecl.cpp @@ -832,7 +832,7 @@ void ASTDeclReader::VisitEnumDecl(EnumDecl *ED) { Reader.mergeDefinitionVisibility(OldDef, ED); // We don't want to check the ODR hash value for declarations from global // module fragment. - if (!shouldSkipCheckingODR(ED) && + if (!ED->shouldSkipCheckingODR() && OldDef->getODRHash() != ED->getODRHash()) Reader.PendingEnumOdrMergeFailures[OldDef].push_back(ED); } else { @@ -874,7 +874,7 @@ void ASTDeclReader::VisitRecordDecl(RecordDecl *RD) { VisitRecordDeclImpl(RD); // We should only reach here if we're in C/Objective-C. There is no // global module fragment. - assert(!shouldSkipCheckingODR(RD)); + assert(!RD->shouldSkipCheckingODR()); RD->setODRHash(Record.readInt()); // Maintain the invariant of a redeclaration chain containing only @@ -2152,7 +2152,7 @@ void ASTDeclReader::MergeDefinitionData( } // We don't want to check ODR for decls in the global module fragment. - if (shouldSkipCheckingODR(MergeDD.Definition)) + if (MergeDD.Definition->shouldSkipCheckingODR()) return; if (D->getODRHash() != MergeDD.ODRHash) { @@ -3526,7 +3526,7 @@ ASTDeclReader::FindExistingResult ASTDeclReader::findExisting(NamedDecl *D) { // same template specialization into the same CXXRecordDecl. auto MergedDCIt = Reader.MergedDeclContexts.find(D->getLexicalDeclContext()); if (MergedDCIt != Reader.MergedDeclContexts.end() && - !shouldSkipCheckingODR(D) && MergedDCIt->second == D->getDeclContext()) + !D->shouldSkipCheckingODR() && MergedDCIt->second == D->getDeclContext()) Reader.PendingOdrMergeChecks.push_back(D); return FindExistingResult(Reader, D, /*Existing=*/nullptr, diff --git a/clang/lib/Serialization/ASTWriter.cpp b/clang/lib/Serialization/ASTWriter.cpp index 6904c924c2fd3df283754cf77d9300363d3a5dc9..3653d94c6e073964eac259647f47059a90c0751c 100644 --- a/clang/lib/Serialization/ASTWriter.cpp +++ b/clang/lib/Serialization/ASTWriter.cpp @@ -6060,7 +6060,7 @@ void ASTRecordWriter::AddCXXDefinitionData(const CXXRecordDecl *D) { BitsPacker DefinitionBits; - bool ShouldSkipCheckingODR = shouldSkipCheckingODR(D); + bool ShouldSkipCheckingODR = D->shouldSkipCheckingODR(); DefinitionBits.addBit(ShouldSkipCheckingODR); #define FIELD(Name, Width, Merge) \ diff --git a/clang/lib/Serialization/ASTWriterDecl.cpp b/clang/lib/Serialization/ASTWriterDecl.cpp index e1862de4a35b8faa1b4044751b61c05a0c542b8e..86f64bf2a24250b5ba50e854968fe897527c7fb1 100644 --- a/clang/lib/Serialization/ASTWriterDecl.cpp +++ b/clang/lib/Serialization/ASTWriterDecl.cpp @@ -281,11 +281,18 @@ bool clang::CanElideDeclDef(const Decl *D) { if (FD->isDependentContext()) return false; + + if (FD->getTemplateSpecializationKind() == TSK_ImplicitInstantiation) + return false; } if (auto *VD = dyn_cast(D)) { if (!VD->getDeclContext()->getRedeclContext()->isFileContext() || - VD->isInline() || VD->isConstexpr() || isa(VD)) + VD->isInline() || VD->isConstexpr() || isa(VD) || + // Constant initialized variable may not affect the ABI, but they + // may be used in constant evaluation in the frontend, so we have + // to remain them. + VD->hasConstantInitialization()) return false; if (VD->getTemplateSpecializationKind() == TSK_ImplicitInstantiation) @@ -519,7 +526,7 @@ void ASTDeclWriter::VisitEnumDecl(EnumDecl *D) { BitsPacker EnumDeclBits; EnumDeclBits.addBits(D->getNumPositiveBits(), /*BitWidth=*/8); EnumDeclBits.addBits(D->getNumNegativeBits(), /*BitWidth=*/8); - bool ShouldSkipCheckingODR = shouldSkipCheckingODR(D); + bool ShouldSkipCheckingODR = D->shouldSkipCheckingODR(); EnumDeclBits.addBit(ShouldSkipCheckingODR); EnumDeclBits.addBit(D->isScoped()); EnumDeclBits.addBit(D->isScopedUsingClassTag()); @@ -545,7 +552,7 @@ void ASTDeclWriter::VisitEnumDecl(EnumDecl *D) { !D->isTopLevelDeclInObjCContainer() && !CXXRecordDecl::classofKind(D->getKind()) && !D->getIntegerTypeSourceInfo() && !D->getMemberSpecializationInfo() && - !needsAnonymousDeclarationNumber(D) && !shouldSkipCheckingODR(D) && + !needsAnonymousDeclarationNumber(D) && !D->shouldSkipCheckingODR() && D->getDeclName().getNameKind() == DeclarationName::Identifier) AbbrevToUse = Writer.getDeclEnumAbbrev(); @@ -711,7 +718,7 @@ void ASTDeclWriter::VisitFunctionDecl(FunctionDecl *D) { // FIXME: stable encoding FunctionDeclBits.addBits(llvm::to_underlying(D->getLinkageInternal()), 3); FunctionDeclBits.addBits((uint32_t)D->getStorageClass(), /*BitWidth=*/3); - bool ShouldSkipCheckingODR = shouldSkipCheckingODR(D); + bool ShouldSkipCheckingODR = D->shouldSkipCheckingODR(); FunctionDeclBits.addBit(ShouldSkipCheckingODR); FunctionDeclBits.addBit(D->isInlineSpecified()); FunctionDeclBits.addBit(D->isInlined()); @@ -1545,7 +1552,7 @@ void ASTDeclWriter::VisitCXXMethodDecl(CXXMethodDecl *D) { D->getFirstDecl() == D->getMostRecentDecl() && !D->isInvalidDecl() && !D->hasAttrs() && !D->isTopLevelDeclInObjCContainer() && D->getDeclName().getNameKind() == DeclarationName::Identifier && - !shouldSkipCheckingODR(D) && !D->hasExtInfo() && + !D->shouldSkipCheckingODR() && !D->hasExtInfo() && !D->isExplicitlyDefaulted()) { if (D->getTemplatedKind() == FunctionDecl::TK_NonTemplate || D->getTemplatedKind() == FunctionDecl::TK_FunctionTemplate || diff --git a/clang/lib/Serialization/GeneratePCH.cpp b/clang/lib/Serialization/GeneratePCH.cpp index 2b511b2d5a90a219c655d8e73bbbf7f2dccbff27..f54db36d4a0199b8faac082dac18963d7c2f916f 100644 --- a/clang/lib/Serialization/GeneratePCH.cpp +++ b/clang/lib/Serialization/GeneratePCH.cpp @@ -41,6 +41,21 @@ PCHGenerator::PCHGenerator( PCHGenerator::~PCHGenerator() { } +Module *PCHGenerator::getEmittingModule(ASTContext &) { + Module *M = nullptr; + + if (PP.getLangOpts().isCompilingModule()) { + M = PP.getHeaderSearchInfo().lookupModule(PP.getLangOpts().CurrentModule, + SourceLocation(), + /*AllowSearch*/ false); + if (!M) + assert(PP.getDiagnostics().hasErrorOccurred() && + "emitting module but current module doesn't exist"); + } + + return M; +} + void PCHGenerator::HandleTranslationUnit(ASTContext &Ctx) { // Don't create a PCH if there were fatal failures during module loading. if (PP.getModuleLoader().HadFatalFailure) @@ -50,16 +65,7 @@ void PCHGenerator::HandleTranslationUnit(ASTContext &Ctx) { if (hasErrors && !AllowASTWithErrors) return; - Module *Module = nullptr; - if (PP.getLangOpts().isCompilingModule()) { - Module = PP.getHeaderSearchInfo().lookupModule( - PP.getLangOpts().CurrentModule, SourceLocation(), - /*AllowSearch*/ false); - if (!Module) { - assert(hasErrors && "emitting module but current module doesn't exist"); - return; - } - } + Module *Module = getEmittingModule(Ctx); // Errors that do not prevent the PCH from being written should not cause the // overall compilation to fail either. @@ -84,16 +90,22 @@ ASTDeserializationListener *PCHGenerator::GetASTDeserializationListener() { ReducedBMIGenerator::ReducedBMIGenerator(const Preprocessor &PP, InMemoryModuleCache &ModuleCache, - StringRef OutputFile, - std::shared_ptr Buffer, - bool IncludeTimestamps) + StringRef OutputFile) : PCHGenerator( - PP, ModuleCache, OutputFile, llvm::StringRef(), Buffer, + PP, ModuleCache, OutputFile, llvm::StringRef(), + std::make_shared(), /*Extensions=*/ArrayRef>(), - /*AllowASTWithErrors*/ false, /*IncludeTimestamps=*/IncludeTimestamps, + /*AllowASTWithErrors*/ false, /*IncludeTimestamps=*/false, /*BuildingImplicitModule=*/false, /*ShouldCacheASTInMemory=*/false, /*GeneratingReducedBMI=*/true) {} +Module *ReducedBMIGenerator::getEmittingModule(ASTContext &Ctx) { + Module *M = Ctx.getCurrentNamedModule(); + assert(M->isNamedModuleUnit() && + "ReducedBMIGenerator should only be used with C++20 Named modules."); + return M; +} + void ReducedBMIGenerator::HandleTranslationUnit(ASTContext &Ctx) { PCHGenerator::HandleTranslationUnit(Ctx); diff --git a/clang/lib/StaticAnalyzer/Checkers/BlockInCriticalSectionChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/BlockInCriticalSectionChecker.cpp index 66e080adb1382bcc273bb5161b93565a714a3d0c..e4373915410fb29e2f145bf3546a3a0f2e9a412a 100644 --- a/clang/lib/StaticAnalyzer/Checkers/BlockInCriticalSectionChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/BlockInCriticalSectionChecker.cpp @@ -20,48 +20,178 @@ #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/ProgramStateTrait.h" +#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState_Fwd.h" +#include "clang/StaticAnalyzer/Core/PathSensitive/SVals.h" +#include "llvm/ADT/STLExtras.h" +#include "llvm/ADT/SmallString.h" +#include "llvm/ADT/StringExtras.h" + +#include +#include +#include using namespace clang; using namespace ento; namespace { + +struct CritSectionMarker { + const Expr *LockExpr{}; + const MemRegion *LockReg{}; + + void Profile(llvm::FoldingSetNodeID &ID) const { + ID.Add(LockExpr); + ID.Add(LockReg); + } + + [[nodiscard]] constexpr bool + operator==(const CritSectionMarker &Other) const noexcept { + return LockExpr == Other.LockExpr && LockReg == Other.LockReg; + } + [[nodiscard]] constexpr bool + operator!=(const CritSectionMarker &Other) const noexcept { + return !(*this == Other); + } +}; + +class CallDescriptionBasedMatcher { + CallDescription LockFn; + CallDescription UnlockFn; + +public: + CallDescriptionBasedMatcher(CallDescription &&LockFn, + CallDescription &&UnlockFn) + : LockFn(std::move(LockFn)), UnlockFn(std::move(UnlockFn)) {} + [[nodiscard]] bool matches(const CallEvent &Call, bool IsLock) const { + if (IsLock) { + return LockFn.matches(Call); + } + return UnlockFn.matches(Call); + } +}; + +class FirstArgMutexDescriptor : public CallDescriptionBasedMatcher { +public: + FirstArgMutexDescriptor(CallDescription &&LockFn, CallDescription &&UnlockFn) + : CallDescriptionBasedMatcher(std::move(LockFn), std::move(UnlockFn)) {} + + [[nodiscard]] const MemRegion *getRegion(const CallEvent &Call, bool) const { + return Call.getArgSVal(0).getAsRegion(); + } +}; + +class MemberMutexDescriptor : public CallDescriptionBasedMatcher { +public: + MemberMutexDescriptor(CallDescription &&LockFn, CallDescription &&UnlockFn) + : CallDescriptionBasedMatcher(std::move(LockFn), std::move(UnlockFn)) {} + + [[nodiscard]] const MemRegion *getRegion(const CallEvent &Call, bool) const { + return cast(Call).getCXXThisVal().getAsRegion(); + } +}; + +class RAIIMutexDescriptor { + mutable const IdentifierInfo *Guard{}; + mutable bool IdentifierInfoInitialized{}; + mutable llvm::SmallString<32> GuardName{}; + + void initIdentifierInfo(const CallEvent &Call) const { + if (!IdentifierInfoInitialized) { + // In case of checking C code, or when the corresponding headers are not + // included, we might end up query the identifier table every time when + // this function is called instead of early returning it. To avoid this, a + // bool variable (IdentifierInfoInitialized) is used and the function will + // be run only once. + Guard = &Call.getCalleeAnalysisDeclContext()->getASTContext().Idents.get( + GuardName); + IdentifierInfoInitialized = true; + } + } + + template bool matchesImpl(const CallEvent &Call) const { + const T *C = dyn_cast(&Call); + if (!C) + return false; + const IdentifierInfo *II = + cast(C->getDecl()->getParent())->getIdentifier(); + return II == Guard; + } + +public: + RAIIMutexDescriptor(StringRef GuardName) : GuardName(GuardName) {} + [[nodiscard]] bool matches(const CallEvent &Call, bool IsLock) const { + initIdentifierInfo(Call); + if (IsLock) { + return matchesImpl(Call); + } + return matchesImpl(Call); + } + [[nodiscard]] const MemRegion *getRegion(const CallEvent &Call, + bool IsLock) const { + const MemRegion *LockRegion = nullptr; + if (IsLock) { + if (std::optional Object = Call.getReturnValueUnderConstruction()) { + LockRegion = Object->getAsRegion(); + } + } else { + LockRegion = cast(Call).getCXXThisVal().getAsRegion(); + } + return LockRegion; + } +}; + +using MutexDescriptor = + std::variant; + class BlockInCriticalSectionChecker : public Checker { - mutable IdentifierInfo *IILockGuard = nullptr; - mutable IdentifierInfo *IIUniqueLock = nullptr; - mutable bool IdentifierInfoInitialized = false; - - const CallDescription LockFn{{"lock"}}; - const CallDescription UnlockFn{{"unlock"}}; - const CallDescription SleepFn{{"sleep"}}; - const CallDescription GetcFn{{"getc"}}; - const CallDescription FgetsFn{{"fgets"}}; - const CallDescription ReadFn{{"read"}}; - const CallDescription RecvFn{{"recv"}}; - const CallDescription PthreadLockFn{{"pthread_mutex_lock"}}; - const CallDescription PthreadTryLockFn{{"pthread_mutex_trylock"}}; - const CallDescription PthreadUnlockFn{{"pthread_mutex_unlock"}}; - const CallDescription MtxLock{{"mtx_lock"}}; - const CallDescription MtxTimedLock{{"mtx_timedlock"}}; - const CallDescription MtxTryLock{{"mtx_trylock"}}; - const CallDescription MtxUnlock{{"mtx_unlock"}}; - - const llvm::StringLiteral ClassLockGuard{"lock_guard"}; - const llvm::StringLiteral ClassUniqueLock{"unique_lock"}; +private: + const std::array MutexDescriptors{ + MemberMutexDescriptor( + CallDescription(/*QualifiedName=*/{"std", "mutex", "lock"}, + /*RequiredArgs=*/0), + CallDescription({"std", "mutex", "unlock"}, 0)), + FirstArgMutexDescriptor(CallDescription({"pthread_mutex_lock"}, 1), + CallDescription({"pthread_mutex_unlock"}, 1)), + FirstArgMutexDescriptor(CallDescription({"mtx_lock"}, 1), + CallDescription({"mtx_unlock"}, 1)), + FirstArgMutexDescriptor(CallDescription({"pthread_mutex_trylock"}, 1), + CallDescription({"pthread_mutex_unlock"}, 1)), + FirstArgMutexDescriptor(CallDescription({"mtx_trylock"}, 1), + CallDescription({"mtx_unlock"}, 1)), + FirstArgMutexDescriptor(CallDescription({"mtx_timedlock"}, 1), + CallDescription({"mtx_unlock"}, 1)), + RAIIMutexDescriptor("lock_guard"), + RAIIMutexDescriptor("unique_lock")}; + + const std::array BlockingFunctions{ + ArrayRef{StringRef{"sleep"}}, ArrayRef{StringRef{"getc"}}, + ArrayRef{StringRef{"fgets"}}, ArrayRef{StringRef{"read"}}, + ArrayRef{StringRef{"recv"}}}; const BugType BlockInCritSectionBugType{ this, "Call to blocking function in critical section", "Blocking Error"}; - void initIdentifierInfo(ASTContext &Ctx) const; + void reportBlockInCritSection(const CallEvent &call, CheckerContext &C) const; - void reportBlockInCritSection(SymbolRef FileDescSym, - const CallEvent &call, - CheckerContext &C) const; + [[nodiscard]] const NoteTag *createCritSectionNote(CritSectionMarker M, + CheckerContext &C) const; -public: - bool isBlockingFunction(const CallEvent &Call) const; - bool isLockFunction(const CallEvent &Call) const; - bool isUnlockFunction(const CallEvent &Call) const; + [[nodiscard]] std::optional + checkDescriptorMatch(const CallEvent &Call, CheckerContext &C, + bool IsLock) const; + + void handleLock(const MutexDescriptor &Mutex, const CallEvent &Call, + CheckerContext &C) const; + void handleUnlock(const MutexDescriptor &Mutex, const CallEvent &Call, + CheckerContext &C) const; + + [[nodiscard]] bool isBlockingInCritSection(const CallEvent &Call, + CheckerContext &C) const; + +public: /// Process unlock. /// Process lock. /// Process blocking functions (sleep, getc, fgets, read, recv) @@ -70,73 +200,118 @@ public: } // end anonymous namespace -REGISTER_TRAIT_WITH_PROGRAMSTATE(MutexCounter, unsigned) - -void BlockInCriticalSectionChecker::initIdentifierInfo(ASTContext &Ctx) const { - if (!IdentifierInfoInitialized) { - /* In case of checking C code, or when the corresponding headers are not - * included, we might end up query the identifier table every time when this - * function is called instead of early returning it. To avoid this, a bool - * variable (IdentifierInfoInitialized) is used and the function will be run - * only once. */ - IILockGuard = &Ctx.Idents.get(ClassLockGuard); - IIUniqueLock = &Ctx.Idents.get(ClassUniqueLock); - IdentifierInfoInitialized = true; - } +REGISTER_LIST_WITH_PROGRAMSTATE(ActiveCritSections, CritSectionMarker) + +namespace std { +// Iterator traits for ImmutableList data structure +// that enable the use of STL algorithms. +// TODO: Move these to llvm::ImmutableList when overhauling immutable data +// structures for proper iterator concept support. +template <> +struct iterator_traits< + typename llvm::ImmutableList::iterator> { + using iterator_category = std::forward_iterator_tag; + using value_type = CritSectionMarker; + using difference_type = std::ptrdiff_t; + using reference = CritSectionMarker &; + using pointer = CritSectionMarker *; +}; +} // namespace std + +std::optional +BlockInCriticalSectionChecker::checkDescriptorMatch(const CallEvent &Call, + CheckerContext &C, + bool IsLock) const { + const auto Descriptor = + llvm::find_if(MutexDescriptors, [&Call, IsLock](auto &&Descriptor) { + return std::visit( + [&Call, IsLock](auto &&DescriptorImpl) { + return DescriptorImpl.matches(Call, IsLock); + }, + Descriptor); + }); + if (Descriptor != MutexDescriptors.end()) + return *Descriptor; + return std::nullopt; } -bool BlockInCriticalSectionChecker::isBlockingFunction(const CallEvent &Call) const { - return matchesAny(Call, SleepFn, GetcFn, FgetsFn, ReadFn, RecvFn); +static const MemRegion *getRegion(const CallEvent &Call, + const MutexDescriptor &Descriptor, + bool IsLock) { + return std::visit( + [&Call, IsLock](auto &&Descriptor) { + return Descriptor.getRegion(Call, IsLock); + }, + Descriptor); } -bool BlockInCriticalSectionChecker::isLockFunction(const CallEvent &Call) const { - if (const auto *Ctor = dyn_cast(&Call)) { - auto IdentifierInfo = Ctor->getDecl()->getParent()->getIdentifier(); - if (IdentifierInfo == IILockGuard || IdentifierInfo == IIUniqueLock) - return true; - } +void BlockInCriticalSectionChecker::handleLock( + const MutexDescriptor &LockDescriptor, const CallEvent &Call, + CheckerContext &C) const { + const MemRegion *MutexRegion = + getRegion(Call, LockDescriptor, /*IsLock=*/true); + if (!MutexRegion) + return; - return matchesAny(Call, LockFn, PthreadLockFn, PthreadTryLockFn, MtxLock, - MtxTimedLock, MtxTryLock); + const CritSectionMarker MarkToAdd{Call.getOriginExpr(), MutexRegion}; + ProgramStateRef StateWithLockEvent = + C.getState()->add(MarkToAdd); + C.addTransition(StateWithLockEvent, createCritSectionNote(MarkToAdd, C)); } -bool BlockInCriticalSectionChecker::isUnlockFunction(const CallEvent &Call) const { - if (const auto *Dtor = dyn_cast(&Call)) { - const auto *DRecordDecl = cast(Dtor->getDecl()->getParent()); - auto IdentifierInfo = DRecordDecl->getIdentifier(); - if (IdentifierInfo == IILockGuard || IdentifierInfo == IIUniqueLock) - return true; +void BlockInCriticalSectionChecker::handleUnlock( + const MutexDescriptor &UnlockDescriptor, const CallEvent &Call, + CheckerContext &C) const { + const MemRegion *MutexRegion = + getRegion(Call, UnlockDescriptor, /*IsLock=*/false); + if (!MutexRegion) + return; + + ProgramStateRef State = C.getState(); + const auto ActiveSections = State->get(); + const auto MostRecentLock = + llvm::find_if(ActiveSections, [MutexRegion](auto &&Marker) { + return Marker.LockReg == MutexRegion; + }); + if (MostRecentLock == ActiveSections.end()) + return; + + // Build a new ImmutableList without this element. + auto &Factory = State->get_context(); + llvm::ImmutableList NewList = Factory.getEmptyList(); + for (auto It = ActiveSections.begin(), End = ActiveSections.end(); It != End; + ++It) { + if (It != MostRecentLock) + NewList = Factory.add(*It, NewList); } - return matchesAny(Call, UnlockFn, PthreadUnlockFn, MtxUnlock); + State = State->set(NewList); + C.addTransition(State); +} + +bool BlockInCriticalSectionChecker::isBlockingInCritSection( + const CallEvent &Call, CheckerContext &C) const { + return llvm::any_of(BlockingFunctions, + [&Call](auto &&Fn) { return Fn.matches(Call); }) && + !C.getState()->get().isEmpty(); } void BlockInCriticalSectionChecker::checkPostCall(const CallEvent &Call, CheckerContext &C) const { - initIdentifierInfo(C.getASTContext()); - - if (!isBlockingFunction(Call) - && !isLockFunction(Call) - && !isUnlockFunction(Call)) - return; - - ProgramStateRef State = C.getState(); - unsigned mutexCount = State->get(); - if (isUnlockFunction(Call) && mutexCount > 0) { - State = State->set(--mutexCount); - C.addTransition(State); - } else if (isLockFunction(Call)) { - State = State->set(++mutexCount); - C.addTransition(State); - } else if (mutexCount > 0) { - SymbolRef BlockDesc = Call.getReturnValue().getAsSymbol(); - reportBlockInCritSection(BlockDesc, Call, C); + if (isBlockingInCritSection(Call, C)) { + reportBlockInCritSection(Call, C); + } else if (std::optional LockDesc = + checkDescriptorMatch(Call, C, /*IsLock=*/true)) { + handleLock(*LockDesc, Call, C); + } else if (std::optional UnlockDesc = + checkDescriptorMatch(Call, C, /*IsLock=*/false)) { + handleUnlock(*UnlockDesc, Call, C); } } void BlockInCriticalSectionChecker::reportBlockInCritSection( - SymbolRef BlockDescSym, const CallEvent &Call, CheckerContext &C) const { - ExplodedNode *ErrNode = C.generateNonFatalErrorNode(); + const CallEvent &Call, CheckerContext &C) const { + ExplodedNode *ErrNode = C.generateNonFatalErrorNode(C.getState()); if (!ErrNode) return; @@ -147,14 +322,63 @@ void BlockInCriticalSectionChecker::reportBlockInCritSection( auto R = std::make_unique(BlockInCritSectionBugType, os.str(), ErrNode); R->addRange(Call.getSourceRange()); - R->markInteresting(BlockDescSym); + R->markInteresting(Call.getReturnValue()); C.emitReport(std::move(R)); } +const NoteTag * +BlockInCriticalSectionChecker::createCritSectionNote(CritSectionMarker M, + CheckerContext &C) const { + const BugType *BT = &this->BlockInCritSectionBugType; + return C.getNoteTag([M, BT](PathSensitiveBugReport &BR, + llvm::raw_ostream &OS) { + if (&BR.getBugType() != BT) + return; + + // Get the lock events for the mutex of the current line's lock event. + const auto CritSectionBegins = + BR.getErrorNode()->getState()->get(); + llvm::SmallVector LocksForMutex; + llvm::copy_if( + CritSectionBegins, std::back_inserter(LocksForMutex), + [M](const auto &Marker) { return Marker.LockReg == M.LockReg; }); + if (LocksForMutex.empty()) + return; + + // As the ImmutableList builds the locks by prepending them, we + // reverse the list to get the correct order. + std::reverse(LocksForMutex.begin(), LocksForMutex.end()); + + // Find the index of the lock expression in the list of all locks for a + // given mutex (in acquisition order). + const auto Position = + llvm::find_if(std::as_const(LocksForMutex), [M](const auto &Marker) { + return Marker.LockExpr == M.LockExpr; + }); + if (Position == LocksForMutex.end()) + return; + + // If there is only one lock event, we don't need to specify how many times + // the critical section was entered. + if (LocksForMutex.size() == 1) { + OS << "Entering critical section here"; + return; + } + + const auto IndexOfLock = + std::distance(std::as_const(LocksForMutex).begin(), Position); + + const auto OrdinalOfLock = IndexOfLock + 1; + OS << "Entering critical section for the " << OrdinalOfLock + << llvm::getOrdinalSuffix(OrdinalOfLock) << " time here"; + }); +} + void ento::registerBlockInCriticalSectionChecker(CheckerManager &mgr) { mgr.registerChecker(); } -bool ento::shouldRegisterBlockInCriticalSectionChecker(const CheckerManager &mgr) { +bool ento::shouldRegisterBlockInCriticalSectionChecker( + const CheckerManager &mgr) { return true; } diff --git a/clang/lib/StaticAnalyzer/Core/CoreEngine.cpp b/clang/lib/StaticAnalyzer/Core/CoreEngine.cpp index 141d0cb320bffab360efd622b44ceb9229a94013..8605fa149e4f52c4a3f47bf56ec7c5af50698ee9 100644 --- a/clang/lib/StaticAnalyzer/Core/CoreEngine.cpp +++ b/clang/lib/StaticAnalyzer/Core/CoreEngine.cpp @@ -625,8 +625,8 @@ ExplodedNode* NodeBuilder::generateNodeImpl(const ProgramPoint &Loc, bool MarkAsSink) { HasGeneratedNodes = true; bool IsNew; - ExplodedNode *N = C.Eng.G.getNode(Loc, State, MarkAsSink, &IsNew); - N->addPredecessor(FromN, C.Eng.G); + ExplodedNode *N = C.getEngine().G.getNode(Loc, State, MarkAsSink, &IsNew); + N->addPredecessor(FromN, C.getEngine().G); Frontier.erase(FromN); if (!IsNew) @@ -655,7 +655,7 @@ ExplodedNode *BranchNodeBuilder::generateNode(ProgramStateRef State, if (!isFeasible(branch)) return nullptr; - ProgramPoint Loc = BlockEdge(C.Block, branch ? DstT:DstF, + ProgramPoint Loc = BlockEdge(C.getBlock(), branch ? DstT : DstF, NodePred->getLocationContext()); ExplodedNode *Succ = generateNodeImpl(Loc, State, NodePred); return Succ; diff --git a/clang/lib/StaticAnalyzer/Core/LoopUnrolling.cpp b/clang/lib/StaticAnalyzer/Core/LoopUnrolling.cpp index a80352816be6134337c81cde9c68343069a6e4d0..7042f1aeb803fcd66443ddd479f4f740ce1873f1 100644 --- a/clang/lib/StaticAnalyzer/Core/LoopUnrolling.cpp +++ b/clang/lib/StaticAnalyzer/Core/LoopUnrolling.cpp @@ -190,6 +190,17 @@ static bool isCapturedByReference(ExplodedNode *N, const DeclRefExpr *DR) { return FD->getType()->isReferenceType(); } +static bool isFoundInStmt(const Stmt *S, const VarDecl *VD) { + if (const DeclStmt *DS = dyn_cast(S)) { + for (const Decl *D : DS->decls()) { + // Once we reach the declaration of the VD we can return. + if (D->getCanonicalDecl() == VD) + return true; + } + } + return false; +} + // A loop counter is considered escaped if: // case 1: It is a global variable. // case 2: It is a reference parameter or a reference capture. @@ -219,13 +230,19 @@ static bool isPossiblyEscaped(ExplodedNode *N, const DeclRefExpr *DR) { continue; } - if (const DeclStmt *DS = dyn_cast(S)) { - for (const Decl *D : DS->decls()) { - // Once we reach the declaration of the VD we can return. - if (D->getCanonicalDecl() == VD) - return false; + if (isFoundInStmt(S, VD)) { + return false; + } + + if (const auto *SS = dyn_cast(S)) { + if (const auto *CST = dyn_cast(SS->getBody())) { + for (const Stmt *CB : CST->body()) { + if (isFoundInStmt(CB, VD)) + return false; + } } } + // Check the usage of the pass-by-ref function calls and adress-of operator // on VD and reference initialized by VD. ASTContext &ASTCtx = diff --git a/clang/lib/Tooling/DependencyScanning/DependencyScanningWorker.cpp b/clang/lib/Tooling/DependencyScanning/DependencyScanningWorker.cpp index 2b882f8a5e0793da3aba44ae0bcea4080e4fd9c3..76f3d950a13b8100f27642dd24be405709d29399 100644 --- a/clang/lib/Tooling/DependencyScanning/DependencyScanningWorker.cpp +++ b/clang/lib/Tooling/DependencyScanning/DependencyScanningWorker.cpp @@ -296,7 +296,7 @@ public: DisableFree(DisableFree), ModuleName(ModuleName) {} bool runInvocation(std::shared_ptr Invocation, - FileManager *FileMgr, + FileManager *DriverFileMgr, std::shared_ptr PCHContainerOps, DiagnosticConsumer *DiagConsumer) override { // Make a deep copy of the original Clang invocation. @@ -342,12 +342,13 @@ public: ScanInstance.getHeaderSearchOpts().ModulesIncludeVFSUsage = any(OptimizeArgs & ScanningOptimizations::VFS); - ScanInstance.setFileManager(FileMgr); // Support for virtual file system overlays. - FileMgr->setVirtualFileSystem(createVFSFromCompilerInvocation( + auto FS = createVFSFromCompilerInvocation( ScanInstance.getInvocation(), ScanInstance.getDiagnostics(), - FileMgr->getVirtualFileSystemPtr())); + DriverFileMgr->getVirtualFileSystemPtr()); + // Create a new FileManager to match the invocation's FileSystemOptions. + auto *FileMgr = ScanInstance.createFileManager(FS); ScanInstance.createSourceManager(*FileMgr); // Store the list of prebuilt module files into header search options. This @@ -624,9 +625,8 @@ bool DependencyScanningWorker::computeDependencies( ModifiedCommandLine ? *ModifiedCommandLine : CommandLine; auto &FinalFS = ModifiedFS ? ModifiedFS : BaseFS; - FileSystemOptions FSOpts; - FSOpts.WorkingDir = WorkingDirectory.str(); - auto FileMgr = llvm::makeIntrusiveRefCnt(FSOpts, FinalFS); + auto FileMgr = + llvm::makeIntrusiveRefCnt(FileSystemOptions{}, FinalFS); std::vector FinalCCommandLine(FinalCommandLine.size(), nullptr); llvm::transform(FinalCommandLine, FinalCCommandLine.begin(), diff --git a/clang/test/AST/Interp/arrays.cpp b/clang/test/AST/Interp/arrays.cpp index 4b112d7fdddfdb8cc68a4ddab3953e3dee31ff9d..2443992f75fb7d09705b6adff9cf2566832c6110 100644 --- a/clang/test/AST/Interp/arrays.cpp +++ b/clang/test/AST/Interp/arrays.cpp @@ -429,18 +429,13 @@ namespace Incomplete { // both-note {{array-to-pointer decay of array member without known bound}} /// These are from test/SemaCXX/constant-expression-cxx11.cpp - /// and are the only tests using the 'indexing of array without known bound' diagnostic. - /// We currently diagnose them differently. - extern int arr[]; // expected-note 3{{declared here}} + extern int arr[]; constexpr int *c = &arr[1]; // both-error {{must be initialized by a constant expression}} \ - // ref-note {{indexing of array without known bound}} \ - // expected-note {{read of non-constexpr variable 'arr'}} + // both-note {{indexing of array without known bound}} constexpr int *d = &arr[1]; // both-error {{must be initialized by a constant expression}} \ - // ref-note {{indexing of array without known bound}} \ - // expected-note {{read of non-constexpr variable 'arr'}} + // both-note {{indexing of array without known bound}} constexpr int *e = arr + 1; // both-error {{must be initialized by a constant expression}} \ - // ref-note {{indexing of array without known bound}} \ - // expected-note {{read of non-constexpr variable 'arr'}} + // both-note {{indexing of array without known bound}} } namespace GH69115 { diff --git a/clang/test/AST/Interp/builtin-functions.cpp b/clang/test/AST/Interp/builtin-functions.cpp index ab8abac4b36e34f684994a6b1d4471f0f9bc5a1c..2e9d1a831dcf6e26ad70291b2dadec1121906717 100644 --- a/clang/test/AST/Interp/builtin-functions.cpp +++ b/clang/test/AST/Interp/builtin-functions.cpp @@ -268,6 +268,24 @@ namespace popcount { static_assert(__builtin_popcountl(0) == 0, ""); static_assert(__builtin_popcountll(~0ull) == __CHAR_BIT__ * sizeof(unsigned long long), ""); static_assert(__builtin_popcountll(0) == 0, ""); + static_assert(__builtin_popcountg((unsigned char)~0) == __CHAR_BIT__ * sizeof(unsigned char), ""); + static_assert(__builtin_popcountg((unsigned char)0) == 0, ""); + static_assert(__builtin_popcountg((unsigned short)~0) == __CHAR_BIT__ * sizeof(unsigned short), ""); + static_assert(__builtin_popcountg((unsigned short)0) == 0, ""); + static_assert(__builtin_popcountg(~0u) == __CHAR_BIT__ * sizeof(unsigned int), ""); + static_assert(__builtin_popcountg(0u) == 0, ""); + static_assert(__builtin_popcountg(~0ul) == __CHAR_BIT__ * sizeof(unsigned long), ""); + static_assert(__builtin_popcountg(0ul) == 0, ""); + static_assert(__builtin_popcountg(~0ull) == __CHAR_BIT__ * sizeof(unsigned long long), ""); + static_assert(__builtin_popcountg(0ull) == 0, ""); +#ifdef __SIZEOF_INT128__ + static_assert(__builtin_popcountg(~(unsigned __int128)0) == __CHAR_BIT__ * sizeof(unsigned __int128), ""); + static_assert(__builtin_popcountg((unsigned __int128)0) == 0, ""); +#endif +#ifndef __AVR__ + static_assert(__builtin_popcountg(~(unsigned _BitInt(128))0) == __CHAR_BIT__ * sizeof(unsigned _BitInt(128)), ""); + static_assert(__builtin_popcountg((unsigned _BitInt(128))0) == 0, ""); +#endif /// From test/Sema/constant-builtins-2.c char popcount1[__builtin_popcount(0) == 0 ? 1 : -1]; @@ -280,6 +298,17 @@ namespace popcount { char popcount8[__builtin_popcountll(0LL) == 0 ? 1 : -1]; char popcount9[__builtin_popcountll(0xF0F0LL) == 8 ? 1 : -1]; char popcount10[__builtin_popcountll(~0LL) == BITSIZE(long long) ? 1 : -1]; + char popcount11[__builtin_popcountg(0U) == 0 ? 1 : -1]; + char popcount12[__builtin_popcountg(0xF0F0U) == 8 ? 1 : -1]; + char popcount13[__builtin_popcountg(~0U) == BITSIZE(int) ? 1 : -1]; + char popcount14[__builtin_popcountg(~0UL) == BITSIZE(long) ? 1 : -1]; + char popcount15[__builtin_popcountg(~0ULL) == BITSIZE(long long) ? 1 : -1]; +#ifdef __SIZEOF_INT128__ + char popcount16[__builtin_popcountg(~(unsigned __int128)0) == BITSIZE(__int128) ? 1 : -1]; +#endif +#ifndef __AVR__ + char popcount17[__builtin_popcountg(~(unsigned _BitInt(128))0) == BITSIZE(_BitInt(128)) ? 1 : -1]; +#endif } namespace parity { @@ -481,3 +510,14 @@ namespace bswap { int h4 = __builtin_bswap32(0x1234) == 0x34120000 ? 1 : f(); int h5 = __builtin_bswap64(0x1234) == 0x3412000000000000 ? 1 : f(); } + +#define CFSTR __builtin___CFStringMakeConstantString +void test7(void) { + const void *X; +#if !defined(_AIX) + X = CFSTR("\242"); // both-warning {{input conversion stopped}} + X = CFSTR("\0"); // no-warning + X = CFSTR(242); // both-error {{cannot initialize a parameter of type 'const char *' with an rvalue of type 'int'}} + X = CFSTR("foo", "bar"); // both-error {{too many arguments to function call}} +#endif +} diff --git a/clang/test/AST/Interp/builtins.cpp b/clang/test/AST/Interp/builtins.cpp index 06a22b16b2dcbb4c9bd2d177709ddb99bdcace09..9095d1bf8d6a3a8170c3b4b72f6287522f03d6cf 100644 --- a/clang/test/AST/Interp/builtins.cpp +++ b/clang/test/AST/Interp/builtins.cpp @@ -1,5 +1,5 @@ -// RUN: %clang_cc1 -fexperimental-new-constant-interpreter %s -verify -fms-extensions -// RUN: %clang_cc1 -fexperimental-new-constant-interpreter %s -fms-extensions -S -emit-llvm -o - | FileCheck %s +// RUN: %clang_cc1 -fexperimental-new-constant-interpreter %s -Wno-constant-evaluated -verify -fms-extensions +// RUN: %clang_cc1 -fexperimental-new-constant-interpreter %s -Wno-constant-evaluated -fms-extensions -S -emit-llvm -o - | FileCheck %s // RUN: %clang_cc1 -verify=ref %s -Wno-constant-evaluated -fms-extensions // RUN: %clang_cc1 -verify=ref %s -Wno-constant-evaluated %s -fms-extensions -S -emit-llvm -o - | FileCheck %s diff --git a/clang/test/AST/Interp/c.c b/clang/test/AST/Interp/c.c index 8de6139efbea09c620cc32fc44368129e96a7d84..10e23839f2ba2a889af774f49ecb03dd557da974 100644 --- a/clang/test/AST/Interp/c.c +++ b/clang/test/AST/Interp/c.c @@ -66,11 +66,11 @@ _Static_assert((&a - 100) != 0, ""); // pedantic-ref-warning {{is a GNU extensio // pedantic-ref-note {{-100 of non-array}} \ // pedantic-expected-note {{-100 of non-array}} /// extern variable of a composite type. -/// FIXME: The 'cast from void*' note is missing in the new interpreter. +/// FIXME: The 'this conversion is not allowed' note is missing in the new interpreter. extern struct Test50S Test50; _Static_assert(&Test50 != (void*)0, ""); // all-warning {{always true}} \ // pedantic-ref-warning {{is a GNU extension}} \ - // pedantic-ref-note {{cast from 'void *' is not allowed}} \ + // pedantic-ref-note {{this conversion is not allowed in a constant expression}} \ // pedantic-expected-warning {{is a GNU extension}} struct y {int x,y;}; @@ -201,3 +201,11 @@ void localCompoundLiteral(void) { // pedantic-ref-warning {{use of an empty initializer}} }; } + +/// struct copy +struct StrA {int a; }; +const struct StrA sa = { 12 }; +const struct StrA * const sb = &sa; +const struct StrA sc = *sb; +_Static_assert(sc.a == 12, ""); // pedantic-ref-warning {{GNU extension}} \ + // pedantic-expected-warning {{GNU extension}} diff --git a/clang/test/AST/Interp/c23.c b/clang/test/AST/Interp/c23.c new file mode 100644 index 0000000000000000000000000000000000000000..cf1bf4d4e7d9052520520a7c14e6a445ab78d9d8 --- /dev/null +++ b/clang/test/AST/Interp/c23.c @@ -0,0 +1,11 @@ +// RUN: %clang_cc1 -std=c23 -fexperimental-new-constant-interpreter -verify=expected,both %s +// RUN: %clang_cc1 -std=c23 -verify=ref,both %s + + + +const _Bool inf1 = (1.0/0.0 == __builtin_inf()); +constexpr _Bool inf2 = (1.0/0.0 == __builtin_inf()); // both-error {{must be initialized by a constant expression}} \ + // both-note {{division by zero}} +constexpr _Bool inf3 = __builtin_inf() == __builtin_inf(); + + diff --git a/clang/test/AST/Interp/complex.c b/clang/test/AST/Interp/complex.c index c9c2efb59745311f394deb336dcc755fb06f083c..a39f83160ef8ca449b0d0931fe6825c4294ccaba 100644 --- a/clang/test/AST/Interp/complex.c +++ b/clang/test/AST/Interp/complex.c @@ -14,3 +14,17 @@ void blah() { _Static_assert((0.0 + 0.0j) == (0.0 + 0.0j), ""); _Static_assert((0.0 + 0.0j) != (0.0 + 0.0j), ""); // both-error {{static assertion}} \ // both-note {{evaluates to}} + +const _Complex float FC = {0.0f, 0.0f}; +_Static_assert(!FC, ""); +const _Complex float FI = {0, 0}; +_Static_assert(!FI, ""); + + +/// Make sure we're stripping the _Atomic part from the +/// complex type. +void testComplexFloat(_Atomic(_Complex float) *fp) { + _Atomic(_Complex float) x = 2.0f; + _Complex float f = *fp; + *fp = f; +} diff --git a/clang/test/AST/Interp/complex.cpp b/clang/test/AST/Interp/complex.cpp index 6a42afc68d26c78b1c016a0430839c8a763af5ac..09cb620d7b7c398cf1e51312a2ff64af3adc48cf 100644 --- a/clang/test/AST/Interp/complex.cpp +++ b/clang/test/AST/Interp/complex.cpp @@ -9,6 +9,9 @@ static_assert(&__imag z1 == &__real z1 + 1, ""); static_assert((*(&__imag z1)) == __imag z1, ""); static_assert((*(&__real z1)) == __real z1, ""); +constexpr _Complex int Comma1 = {1, 2}; +constexpr _Complex int Comma2 = (0, Comma1); +static_assert(Comma1 == Comma1, ""); constexpr double setter() { _Complex float d = {1.0, 2.0}; @@ -313,3 +316,53 @@ namespace Cmp { static_assert((0.0 + 0.0j) > (0.0 + 0.0j)); // both-error {{invalid operands to binary expression}} static_assert((0.0 + 0.0j) ^ (0.0 + 0.0j)); // both-error {{invalid operands to binary expression}} } + +/// From test/SemaCXX/constant-expression-cxx11.cpp +/// +/// Some of the diagnostics we emit are different than the one of the +/// current interpreter. +/// +/// FIXME: For the '&test3 + 1' test, we are _not_ creating an explicit pointer variable +/// anywhere and so the &test3+1 is the same as __imag(test3) for us. +namespace ComplexConstexpr { + constexpr _Complex float test1 = {}; + constexpr _Complex float test2 = {1}; + constexpr _Complex double test3 = {1,2}; + constexpr _Complex int test4 = {4}; + constexpr _Complex int test5 = 4; + constexpr _Complex int test6 = {5,6}; + typedef _Complex float fcomplex; + constexpr fcomplex test7 = fcomplex(); + + constexpr const double &t2r = __real test3; + constexpr const double &t2i = __imag test3; + static_assert(&t2r + 1 == &t2i, ""); + static_assert(t2r == 1.0, ""); + static_assert(t2i == 2.0, ""); + constexpr const double *t2p = &t2r; + static_assert(t2p[-1] == 0.0, ""); // both-error {{constant expr}} \ + // both-note {{cannot refer to element -1 of array of 2 elements}} + static_assert(t2p[0] == 1.0, ""); + static_assert(t2p[1] == 2.0, ""); + static_assert(t2p[2] == 0.0, ""); // both-error {{constant expr}} \ + // both-note {{one-past-the-end pointer}} + static_assert(t2p[3] == 0.0, ""); // both-error {{constant expr}} \ + // both-note {{cannot refer to element 3 of array of 2 elements}} + constexpr _Complex float *p = 0; + constexpr float pr = __real *p; // both-error {{constant expr}} \ + // ref-note {{cannot access real component of null}} \ + // expected-note {{read of dereferenced null pointer}} + constexpr float pi = __imag *p; // both-error {{constant expr}} \ + // ref-note {{cannot access imaginary component of null}} \ + // expected-note {{cannot perform pointer arithmetic on null pointer}} + constexpr const _Complex double *q = &test3 + 1; + constexpr double qr = __real *q; // ref-error {{constant expr}} \ + // ref-note {{cannot access real component of pointer past the end}} + constexpr double qi = __imag *q; // both-error {{constant expr}} \ + // ref-note {{cannot access imaginary component of pointer past the end}} \ + // expected-note {{read of dereferenced one-past-the-end pointer}} + + static_assert(__real test6 == 5, ""); + static_assert(__imag test6 == 6, ""); + static_assert(&__imag test6 == &__real test6 + 1, ""); +} diff --git a/clang/test/AST/Interp/cxx23.cpp b/clang/test/AST/Interp/cxx23.cpp index 127b58915127cf2d07307052e4056600f7593eb6..042e29613aa75301bc6a0b8eb584ad34187d204b 100644 --- a/clang/test/AST/Interp/cxx23.cpp +++ b/clang/test/AST/Interp/cxx23.cpp @@ -1,6 +1,6 @@ -// RUN: %clang_cc1 -std=c++20 -fsyntax-only -fcxx-exceptions -verify=ref20,all,all-20 %s +// RUN: %clang_cc1 -std=c++20 -fsyntax-only -fcxx-exceptions -verify=ref20,all,all20 %s // RUN: %clang_cc1 -std=c++23 -fsyntax-only -fcxx-exceptions -verify=ref23,all %s -// RUN: %clang_cc1 -std=c++20 -fsyntax-only -fcxx-exceptions -verify=expected20,all,all-20 %s -fexperimental-new-constant-interpreter +// RUN: %clang_cc1 -std=c++20 -fsyntax-only -fcxx-exceptions -verify=expected20,all,all20 %s -fexperimental-new-constant-interpreter // RUN: %clang_cc1 -std=c++23 -fsyntax-only -fcxx-exceptions -verify=expected23,all %s -fexperimental-new-constant-interpreter /// FIXME: The new interpreter is missing all the 'control flows through...' diagnostics. @@ -108,9 +108,9 @@ namespace StaticOperators { static_assert(f2() == 3); struct S1 { - constexpr S1() { // all-20-error {{never produces a constant expression}} + constexpr S1() { // all20-error {{never produces a constant expression}} throw; // all-note {{not valid in a constant expression}} \ - // all-20-note {{not valid in a constant expression}} + // all20-note {{not valid in a constant expression}} } static constexpr int operator()() { return 3; } // ref20-warning {{C++23 extension}} \ // expected20-warning {{C++23 extension}} @@ -121,3 +121,28 @@ namespace StaticOperators { } + +int test_in_lambdas() { + auto c = [](int n) constexpr { + if (n == 0) + return 0; + else + goto test; // all-note {{subexpression not valid in a constant expression}} \ + // all20-warning {{use of this statement in a constexpr function is a C++23 extension}} + test: + return 1; + }; + c(0); + constexpr auto A = c(1); // all-error {{must be initialized by a constant expression}} \ + // all-note {{in call to}} + return 0; +} + +/// PackIndexExpr. +template +struct check_ice { + enum e { + x = p...[0] // all-warning {{is a C++2c extension}} + }; +}; +static_assert(check_ice<42>::x == 42); diff --git a/clang/test/AST/Interp/cxx98.cpp b/clang/test/AST/Interp/cxx98.cpp index 73e45372066334a862c8426f9383f4a2d4dd5eea..ba6bcd97d920dd4767ee2afff4bcee75b3c85cc7 100644 --- a/clang/test/AST/Interp/cxx98.cpp +++ b/clang/test/AST/Interp/cxx98.cpp @@ -18,13 +18,12 @@ template struct C; /// FIXME: This example does not get properly diagnosed in the new interpreter. extern const int recurse1; -const int recurse2 = recurse1; // both-note {{declared here}} +const int recurse2 = recurse1; // ref-note {{declared here}} const int recurse1 = 1; int array1[recurse1]; int array2[recurse2]; // ref-warning 2{{variable length array}} \ // ref-note {{initializer of 'recurse2' is not a constant expression}} \ // expected-warning {{variable length array}} \ - // expected-note {{read of non-const variable 'recurse2'}} \ // expected-error {{variable length array}} int NCI; // both-note {{declared here}} @@ -39,3 +38,10 @@ struct V { // both-error {{constructor cannot have a return type}} }; _Static_assert(V().c[0], ""); // both-error {{is not an integral constant expression}} + +struct C0 { + template static U Data; // both-warning {{C++14 extension}} + template static const U Data = U(); +}; +const int c0_test = C0::Data; +_Static_assert(c0_test == 0, ""); diff --git a/clang/test/AST/Interp/if.cpp b/clang/test/AST/Interp/if.cpp index 86ae8de6f73ebb7ec321c402320cd83e7cc9ac1b..37289d69d3255499b73236dcb09e25aa03d47b82 100644 --- a/clang/test/AST/Interp/if.cpp +++ b/clang/test/AST/Interp/if.cpp @@ -1,8 +1,5 @@ -// RUN: %clang_cc1 -std=c++23 -fsyntax-only -fexperimental-new-constant-interpreter %s -verify -// RUN: %clang_cc1 -std=c++23 -fsyntax-only %s -verify=ref - -// expected-no-diagnostics -// ref-no-diagnostics +// RUN: %clang_cc1 -std=c++23 -fsyntax-only -fexperimental-new-constant-interpreter %s -verify=expected,both +// RUN: %clang_cc1 -std=c++23 -fsyntax-only %s -verify=ref,both namespace ConstEval { constexpr int f() { @@ -51,3 +48,13 @@ namespace InitDecl { } static_assert(attrs() == 1, ""); }; + +/// The faulty if statement creates a RecoveryExpr with contains-errors, +/// but the execution will never reach that. +constexpr char g(char const (&x)[2]) { + return 'x'; + if (auto [a, b] = x) // both-error {{an array type is not allowed here}} \ + // both-warning {{ISO C++17 does not permit structured binding declaration in a condition}} + ; +} +static_assert(g("x") == 'x'); diff --git a/clang/test/AST/Interp/literals.cpp b/clang/test/AST/Interp/literals.cpp index 7ae8499b1156dd2c2fbe9be4d81ccb6120a3ce4e..277438d2e6311431e60bb3c81a08261cf568e17a 100644 --- a/clang/test/AST/Interp/literals.cpp +++ b/clang/test/AST/Interp/literals.cpp @@ -910,6 +910,18 @@ namespace TypeTraits { struct U {}; static_assert(S3{}.foo(), ""); static_assert(!S3{}.foo(), ""); + + typedef int Int; + typedef Int IntAr[10]; + typedef const IntAr ConstIntAr; + typedef ConstIntAr ConstIntArAr[4]; + + static_assert(__array_rank(IntAr) == 1, ""); + static_assert(__array_rank(ConstIntArAr) == 2, ""); + + static_assert(__array_extent(IntAr, 0) == 10, ""); + static_assert(__array_extent(ConstIntArAr, 0) == 4, ""); + static_assert(__array_extent(ConstIntArAr, 1) == 10, ""); } #if __cplusplus >= 201402L @@ -1113,6 +1125,9 @@ namespace InvalidDeclRefs { int b03 = 3; // both-note {{declared here}} static_assert(b03, ""); // both-error {{not an integral constant expression}} \ // both-note {{read of non-const variable}} + + extern int var; + constexpr int *varp = &var; // Ok. } namespace NonConstReads { @@ -1182,8 +1197,16 @@ namespace incdecbool { } #if __cplusplus >= 201402L +/// NOTE: The diagnostics of the two interpreters are a little +/// different here, but they both make sense. constexpr int externvar1() { // both-error {{never produces a constant expression}} - extern char arr[]; // both-note {{declared here}} - return arr[0]; // both-note {{read of non-constexpr variable 'arr'}} + extern char arr[]; // ref-note {{declared here}} + return arr[0]; // ref-note {{read of non-constexpr variable 'arr'}} \ + // expected-note {{array-to-pointer decay of array member without known bound is not supported}} } #endif + +namespace Extern { + constexpr extern char Oops = 1; + static_assert(Oops == 1, ""); +} diff --git a/clang/test/AST/Interp/ms.cpp b/clang/test/AST/Interp/ms.cpp new file mode 100644 index 0000000000000000000000000000000000000000..99716e90c7a1db9054a01fc2fb50fac271463193 --- /dev/null +++ b/clang/test/AST/Interp/ms.cpp @@ -0,0 +1,8 @@ +// RUN: %clang_cc1 -verify=ref,both %s -fms-extensions +// RUN: %clang_cc1 -verify=expected,both %s -fexperimental-new-constant-interpreter -fms-extensions + +// ref-no-diagnostics +// expected-no-diagnostics + +/// Used to assert because the two parameters to _rotl do not have the same type. +static_assert(_rotl(0x01, 5) == 32); diff --git a/clang/test/AST/Interp/records.cpp b/clang/test/AST/Interp/records.cpp index 7ddc56c9b5dfc4f2a34025b0959c8397202c0fef..0f76e0cfe99277386fa395f669c834e02a7dcc2e 100644 --- a/clang/test/AST/Interp/records.cpp +++ b/clang/test/AST/Interp/records.cpp @@ -1238,3 +1238,50 @@ namespace InvalidCtorInitializer { // no crash on evaluating the constexpr ctor. constexpr int Z = X().Y; // both-error {{constexpr variable 'Z' must be initialized by a constant expression}} } + +extern int f(); // both-note {{here}} +struct HasNonConstExprMemInit { + int x = f(); // both-note {{non-constexpr function}} + constexpr HasNonConstExprMemInit() {} // both-error {{never produces a constant expression}} +}; + +namespace { + template + struct integral_constant { + static const Tp value = v; + }; + + template + const Tp integral_constant::value; + + typedef integral_constant true_type; + typedef integral_constant false_type; + + /// This might look innocent, but we get an evaluateAsInitializer call for the + /// static bool member before evaluating the first static_assert, but we do NOT + /// get such a call for the second one. So the second one needs to lazily visit + /// the data member itself. + static_assert(true_type::value, ""); + static_assert(true_type::value, ""); +} + +#if __cplusplus >= 202002L +namespace { + /// Used to crash because the CXXDefaultInitExpr is of compound type. + struct A { + int &x; + constexpr ~A() { --x; } + }; + struct B { + int &x; + const A &a = A{x}; + }; + constexpr int a() { + int x = 1; + int f = B{x}.x; + B{x}; // both-warning {{expression result unused}} + + return 1; + } +} +#endif diff --git a/clang/test/AST/ast-dump-concepts.cpp b/clang/test/AST/ast-dump-concepts.cpp index 06518a71987a2251f10ff27a6fafdefd326052e6..5bb174e3548ed2f28e8497537ab68f4a1873df38 100644 --- a/clang/test/AST/ast-dump-concepts.cpp +++ b/clang/test/AST/ast-dump-concepts.cpp @@ -57,3 +57,53 @@ struct Foo { template ... Ts> Foo(); }; + +namespace GH82628 { +namespace ns { + +template +concept C = true; + +} // namespace ns + +using ns::C; + +// CHECK: ConceptDecl {{.*}} Foo +// CHECK-NEXT: |-TemplateTypeParmDecl {{.*}} typename depth 0 index 0 T +// CHECK-NEXT: `-ConceptSpecializationExpr {{.*}} UsingShadow {{.*}} 'C' +template +concept Foo = C; + +// CHECK: TemplateTypeParmDecl {{.*}} Concept {{.*}} 'C' (UsingShadow {{.*}} 'C') +template +constexpr bool FooVar = false; + +// CHECK: ConceptSpecializationExpr {{.*}} UsingShadow {{.*}} 'C' +template requires C +constexpr bool FooVar2 = true; + +// CHECK: SimpleRequirement +// CHECK-NEXT: `-ConceptSpecializationExpr {{.*}} UsingShadow {{.*}} 'C' +template requires requires (T) { C; } +constexpr bool FooVar3 = true; + +// CHECK: NonTypeTemplateParmDecl +// CHECK-NEXT: `-ConceptSpecializationExpr {{.*}} UsingShadow {{.*}} 'C' +template +constexpr bool FooVar4 = bool(T()); + +// CHECK: FunctionTemplateDecl +// CHECK-NEXT: |-TemplateTypeParmDecl {{.*}} Concept {{.*}} 'C' (UsingShadow {{.*}} 'C') depth 0 index 0 ... T +// CHECK: NonTypeTemplateParmDecl {{.*}} depth 0 index 1 U +// CHECK-NEXT: `-ConceptSpecializationExpr {{.*}} UsingShadow {{.*}} 'C' +// CHECK: |-TemplateTypeParmDecl {{.*}} Concept {{.*}} 'C' (UsingShadow {{.*}} 'C') depth 0 index 2 V:auto + +template +auto FooFunc(C auto V) -> C decltype(auto) { + // FIXME: TypeLocs inside of the function body cannot be dumped via -ast-dump for now. + // See clang-tools-extra/clangd/unittests/SelectionTests.cpp:SelectionTest.UsingConcepts for their checkings. + C auto W = V; + return W; +} + +} diff --git a/clang/test/AST/ast-print-objectivec.m b/clang/test/AST/ast-print-objectivec.m index 05a0a5d4aa74c47fb7592dd0b08b6d796733d8ae..a0652f38e713fa87e5b0dfddbc722d866c1eba51 100644 --- a/clang/test/AST/ast-print-objectivec.m +++ b/clang/test/AST/ast-print-objectivec.m @@ -21,6 +21,10 @@ - (void)methodWithArg:(int)x andAnotherOne:(int)y { } @end +__attribute__((availability(macosx,introduced=10.1.0,deprecated=10.2))) +@interface InterfaceWithAttribute +@end + // CHECK: @protocol P // CHECK: - (void)MethP __attribute__((availability(macos, introduced=10.1.0, deprecated=10.2))); // CHECK: @end @@ -45,6 +49,10 @@ // CHECK: @end +// CHECK: __attribute__((availability(macos, introduced=10.1.0, deprecated=10.2))) +// CHECK: @interface InterfaceWithAttribute +// CHECK: @end + @class C1; struct __attribute__((objc_bridge_related(C1,,))) S1; diff --git a/clang/test/AST/coroutine-locals-cleanup.cpp b/clang/test/AST/coroutine-locals-cleanup.cpp index ce106b8e230a10ede5b14118a7766e8b5ef38219..6264df01fa2acb299b579f738c73ba1edfa33e8a 100644 --- a/clang/test/AST/coroutine-locals-cleanup.cpp +++ b/clang/test/AST/coroutine-locals-cleanup.cpp @@ -90,10 +90,7 @@ Task bar() { // CHECK: ExprWithCleanups {{.*}} 'bool' // CHECK-NEXT: CXXMemberCallExpr {{.*}} 'bool' // CHECK-NEXT: MemberExpr {{.*}} .await_ready -// CHECK: CallExpr {{.*}} 'void' -// CHECK-NEXT: ImplicitCastExpr {{.*}} 'void (*)(void *)' -// CHECK-NEXT: DeclRefExpr {{.*}} '__builtin_coro_resume' 'void (void *)' -// CHECK-NEXT: ExprWithCleanups {{.*}} 'void *' +// CHECK: ExprWithCleanups {{.*}} 'void *' // CHECK: CaseStmt // CHECK: ExprWithCleanups {{.*}} 'void' @@ -103,7 +100,4 @@ Task bar() { // CHECK: ExprWithCleanups {{.*}} 'bool' // CHECK-NEXT: CXXMemberCallExpr {{.*}} 'bool' // CHECK-NEXT: MemberExpr {{.*}} .await_ready -// CHECK: CallExpr {{.*}} 'void' -// CHECK-NEXT: ImplicitCastExpr {{.*}} 'void (*)(void *)' -// CHECK-NEXT: DeclRefExpr {{.*}} '__builtin_coro_resume' 'void (void *)' -// CHECK-NEXT: ExprWithCleanups {{.*}} 'void *' +// CHECK: ExprWithCleanups {{.*}} 'void *' diff --git a/clang/test/Analysis/block-in-critical-section.cpp b/clang/test/Analysis/block-in-critical-section.cpp index fcf6188fc033ec8f4f6f7990916003427b26a63b..87c26b9f1b5209fe72c4675f76117cd3a08e6c58 100644 --- a/clang/test/Analysis/block-in-critical-section.cpp +++ b/clang/test/Analysis/block-in-critical-section.cpp @@ -1,4 +1,8 @@ -// RUN: %clang_analyze_cc1 -analyzer-checker=alpha.unix.BlockInCriticalSection -std=c++11 -verify %s +// RUN: %clang_analyze_cc1 \ +// RUN: -analyzer-checker=alpha.unix.BlockInCriticalSection \ +// RUN: -std=c++11 \ +// RUN: -analyzer-output text \ +// RUN: -verify %s void sleep(int x) {} @@ -21,108 +25,242 @@ template struct not_real_lock { not_real_lock(std::mutex) {} }; -} +} // namespace std + +struct FILE; +int getc(FILE *stream); +char* fgets(char *str, FILE *stream); +using ssize_t = long long; +using size_t = unsigned long long; +ssize_t read(int fd, void *buf, size_t count); +ssize_t recv(int sockfd, void *buf, size_t len, int flags); -void getc() {} -void fgets() {} -void read() {} -void recv() {} +struct pthread_mutex_t; +void pthread_mutex_lock(pthread_mutex_t *mutex); +void pthread_mutex_trylock(pthread_mutex_t *mutex); +void pthread_mutex_unlock(pthread_mutex_t *mutex); -void pthread_mutex_lock() {} -void pthread_mutex_trylock() {} -void pthread_mutex_unlock() {} +struct mtx_t; +void mtx_lock(mtx_t *mutex); +void mtx_timedlock(mtx_t *mutex); +void mtx_trylock(mtx_t *mutex); +void mtx_unlock(mtx_t *mutex); -void mtx_lock() {} -void mtx_timedlock() {} -void mtx_trylock() {} -void mtx_unlock() {} +// global params for dummy function calls +FILE *stream; +char *str; +int fd; +void *buf; +size_t count; +int sockfd; +size_t len; +int flags; void testBlockInCriticalSectionWithStdMutex() { std::mutex m; - m.lock(); + m.lock(); // expected-note 5{{Entering critical section here}} sleep(3); // expected-warning {{Call to blocking function 'sleep' inside of critical section}} - getc(); // expected-warning {{Call to blocking function 'getc' inside of critical section}} - fgets(); // expected-warning {{Call to blocking function 'fgets' inside of critical section}} - read(); // expected-warning {{Call to blocking function 'read' inside of critical section}} - recv(); // expected-warning {{Call to blocking function 'recv' inside of critical section}} + // expected-note@-1 {{Call to blocking function 'sleep' inside of critical section}} + getc(stream); // expected-warning {{Call to blocking function 'getc' inside of critical section}} + // expected-note@-1 {{Call to blocking function 'getc' inside of critical section}} + fgets(str, stream); // expected-warning {{Call to blocking function 'fgets' inside of critical section}} + // expected-note@-1 {{Call to blocking function 'fgets' inside of critical section}} + read(fd, buf, count); // expected-warning {{Call to blocking function 'read' inside of critical section}} + // expected-note@-1 {{Call to blocking function 'read' inside of critical section}} + recv(sockfd, buf, count, flags); // expected-warning {{Call to blocking function 'recv' inside of critical section}} + // expected-note@-1 {{Call to blocking function 'recv' inside of critical section}} m.unlock(); } -void testBlockInCriticalSectionWithPthreadMutex() { - pthread_mutex_lock(); +void testBlockInCriticalSectionWithPthreadMutex(pthread_mutex_t *mutex) { + pthread_mutex_lock(mutex); // expected-note 5{{Entering critical section here}} sleep(3); // expected-warning {{Call to blocking function 'sleep' inside of critical section}} - getc(); // expected-warning {{Call to blocking function 'getc' inside of critical section}} - fgets(); // expected-warning {{Call to blocking function 'fgets' inside of critical section}} - read(); // expected-warning {{Call to blocking function 'read' inside of critical section}} - recv(); // expected-warning {{Call to blocking function 'recv' inside of critical section}} - pthread_mutex_unlock(); + // expected-note@-1 {{Call to blocking function 'sleep' inside of critical section}} + getc(stream); // expected-warning {{Call to blocking function 'getc' inside of critical section}} + // expected-note@-1 {{Call to blocking function 'getc' inside of critical section}} + fgets(str, stream); // expected-warning {{Call to blocking function 'fgets' inside of critical section}} + // expected-note@-1 {{Call to blocking function 'fgets' inside of critical section}} + read(fd, buf, count); // expected-warning {{Call to blocking function 'read' inside of critical section}} + // expected-note@-1 {{Call to blocking function 'read' inside of critical section}} + recv(sockfd, buf, count, flags); // expected-warning {{Call to blocking function 'recv' inside of critical section}} + // expected-note@-1 {{Call to blocking function 'recv' inside of critical section}} + pthread_mutex_unlock(mutex); - pthread_mutex_trylock(); + pthread_mutex_trylock(mutex); // expected-note 5{{Entering critical section here}} sleep(3); // expected-warning {{Call to blocking function 'sleep' inside of critical section}} - getc(); // expected-warning {{Call to blocking function 'getc' inside of critical section}} - fgets(); // expected-warning {{Call to blocking function 'fgets' inside of critical section}} - read(); // expected-warning {{Call to blocking function 'read' inside of critical section}} - recv(); // expected-warning {{Call to blocking function 'recv' inside of critical section}} - pthread_mutex_unlock(); + // expected-note@-1 {{Call to blocking function 'sleep' inside of critical section}} + getc(stream); // expected-warning {{Call to blocking function 'getc' inside of critical section}} + // expected-note@-1 {{Call to blocking function 'getc' inside of critical section}} + fgets(str, stream); // expected-warning {{Call to blocking function 'fgets' inside of critical section}} + // expected-note@-1 {{Call to blocking function 'fgets' inside of critical section}} + read(fd, buf, count); // expected-warning {{Call to blocking function 'read' inside of critical section}} + // expected-note@-1 {{Call to blocking function 'read' inside of critical section}} + recv(sockfd, buf, count, flags); // expected-warning {{Call to blocking function 'recv' inside of critical section}} + // expected-note@-1 {{Call to blocking function 'recv' inside of critical section}} + pthread_mutex_unlock(mutex); } -void testBlockInCriticalSectionC11Locks() { - mtx_lock(); +void testBlockInCriticalSectionC11Locks(mtx_t *mutex) { + mtx_lock(mutex); // expected-note 5{{Entering critical section here}} sleep(3); // expected-warning {{Call to blocking function 'sleep' inside of critical section}} - getc(); // expected-warning {{Call to blocking function 'getc' inside of critical section}} - fgets(); // expected-warning {{Call to blocking function 'fgets' inside of critical section}} - read(); // expected-warning {{Call to blocking function 'read' inside of critical section}} - recv(); // expected-warning {{Call to blocking function 'recv' inside of critical section}} - mtx_unlock(); + // expected-note@-1 {{Call to blocking function 'sleep' inside of critical section}} + getc(stream); // expected-warning {{Call to blocking function 'getc' inside of critical section}} + // expected-note@-1 {{Call to blocking function 'getc' inside of critical section}} + fgets(str, stream); // expected-warning {{Call to blocking function 'fgets' inside of critical section}} + // expected-note@-1 {{Call to blocking function 'fgets' inside of critical section}} + read(fd, buf, count); // expected-warning {{Call to blocking function 'read' inside of critical section}} + // expected-note@-1 {{Call to blocking function 'read' inside of critical section}} + recv(sockfd, buf, count, flags); // expected-warning {{Call to blocking function 'recv' inside of critical section}} + // expected-note@-1 {{Call to blocking function 'recv' inside of critical section}} + mtx_unlock(mutex); - mtx_timedlock(); + mtx_timedlock(mutex); // expected-note 5{{Entering critical section here}} sleep(3); // expected-warning {{Call to blocking function 'sleep' inside of critical section}} - getc(); // expected-warning {{Call to blocking function 'getc' inside of critical section}} - fgets(); // expected-warning {{Call to blocking function 'fgets' inside of critical section}} - read(); // expected-warning {{Call to blocking function 'read' inside of critical section}} - recv(); // expected-warning {{Call to blocking function 'recv' inside of critical section}} - mtx_unlock(); + // expected-note@-1 {{Call to blocking function 'sleep' inside of critical section}} + getc(stream); // expected-warning {{Call to blocking function 'getc' inside of critical section}} + // expected-note@-1 {{Call to blocking function 'getc' inside of critical section}} + fgets(str, stream); // expected-warning {{Call to blocking function 'fgets' inside of critical section}} + // expected-note@-1 {{Call to blocking function 'fgets' inside of critical section}} + read(fd, buf, count); // expected-warning {{Call to blocking function 'read' inside of critical section}} + // expected-note@-1 {{Call to blocking function 'read' inside of critical section}} + recv(sockfd, buf, count, flags); // expected-warning {{Call to blocking function 'recv' inside of critical section}} + // expected-note@-1 {{Call to blocking function 'recv' inside of critical section}} + mtx_unlock(mutex); - mtx_trylock(); + mtx_trylock(mutex); // expected-note 5{{Entering critical section here}} sleep(3); // expected-warning {{Call to blocking function 'sleep' inside of critical section}} - getc(); // expected-warning {{Call to blocking function 'getc' inside of critical section}} - fgets(); // expected-warning {{Call to blocking function 'fgets' inside of critical section}} - read(); // expected-warning {{Call to blocking function 'read' inside of critical section}} - recv(); // expected-warning {{Call to blocking function 'recv' inside of critical section}} - mtx_unlock(); + // expected-note@-1 {{Call to blocking function 'sleep' inside of critical section}} + getc(stream); // expected-warning {{Call to blocking function 'getc' inside of critical section}} + // expected-note@-1 {{Call to blocking function 'getc' inside of critical section}} + fgets(str, stream); // expected-warning {{Call to blocking function 'fgets' inside of critical section}} + // expected-note@-1 {{Call to blocking function 'fgets' inside of critical section}} + read(fd, buf, count); // expected-warning {{Call to blocking function 'read' inside of critical section}} + // expected-note@-1 {{Call to blocking function 'read' inside of critical section}} + recv(sockfd, buf, count, flags); // expected-warning {{Call to blocking function 'recv' inside of critical section}} + // expected-note@-1 {{Call to blocking function 'recv' inside of critical section}} + mtx_unlock(mutex); +} + +void testMultipleBlockingCalls() { + std::mutex m; + m.lock(); // expected-note 1{{Entering critical section here}} + sleep(1); // expected-warning {{Call to blocking function 'sleep' inside of critical section}} + // expected-note@-1 {{Call to blocking function 'sleep' inside of critical section}} + m.unlock(); + sleep(2); // no-warning } -void testBlockInCriticalSectionWithNestedMutexes() { +void testMultipleMutexesMultipleBlockingCalls() { std::mutex m, n, k; - m.lock(); - n.lock(); - k.lock(); - sleep(3); // expected-warning {{Call to blocking function 'sleep' inside of critical section}} + m.lock(); // expected-note 2{{Entering critical section here}} + n.lock(); // expected-note 2{{Entering critical section here}} + k.lock(); // expected-note 1{{Entering critical section here}} + sleep(1); // expected-warning {{Call to blocking function 'sleep' inside of critical section}} + // expected-note@-1 {{Call to blocking function 'sleep' inside of critical section}} k.unlock(); - sleep(5); // expected-warning {{Call to blocking function 'sleep' inside of critical section}} + sleep(2); // expected-warning {{Call to blocking function 'sleep' inside of critical section}} + // expected-note@-1 {{Call to blocking function 'sleep' inside of critical section}} +} + + +void testRecursiveAcquisition() { + std::mutex m; + m.lock(); // expected-note {{Entering critical section for the 1st time here}} + m.lock(); // expected-note {{Entering critical section for the 2nd time here}} + sleep(1); // expected-warning {{Call to blocking function 'sleep' inside of critical section}} + // expected-note@-1 {{Call to blocking function 'sleep' inside of critical section}} + m.unlock(); + m.unlock(); +} + +void testRecursiveAcquisitionWithMultipleBlockingCalls() { + std::mutex m; + m.lock(); // expected-note 1{{Entering critical section for the 1st time here}} + // expected-note@-1 {{Entering critical section here}} + m.lock(); // expected-note 1{{Entering critical section for the 2nd time here}} + sleep(1); // expected-warning {{Call to blocking function 'sleep' inside of critical section}} + // expected-note@-1 {{Call to blocking function 'sleep' inside of critical section}} + m.unlock(); + // this next 'sleep' call is only in the critical section of the first lock + sleep(2); // expected-warning {{Call to blocking function 'sleep' inside of critical section}} + // expected-note@-1 {{Call to blocking function 'sleep' inside of critical section}} + m.unlock(); +} + +void testRecursiveAcquisitionWithMultipleMutexes() { + std::mutex m, n; + m.lock(); // expected-note 1{{Entering critical section here}} + n.lock(); // expected-note 2{{Entering critical section here}} + sleep(1); // expected-warning {{Call to blocking function 'sleep' inside of critical section}} + // expected-note@-1 {{Call to blocking function 'sleep' inside of critical section}} + m.unlock(); + // this next 'sleep' call is only in the critical section of mutex 'n' + sleep(2); // expected-warning {{Call to blocking function 'sleep' inside of critical section}} + // expected-note@-1 {{Call to blocking function 'sleep' inside of critical section}} + n.unlock(); +} + + +void testNestedMutexes() { + std::mutex m, n, k; + m.lock(); // expected-note 3{{Entering critical section here}} + n.lock(); // expected-note 2{{Entering critical section here}} + k.lock(); // expected-note 1{{Entering critical section here}} + sleep(1); // expected-warning {{Call to blocking function 'sleep' inside of critical section}} + // expected-note@-1 {{Call to blocking function 'sleep' inside of critical section}} + k.unlock(); + sleep(2); // expected-warning {{Call to blocking function 'sleep' inside of critical section}} + // expected-note@-1 {{Call to blocking function 'sleep' inside of critical section}} n.unlock(); sleep(3); // expected-warning {{Call to blocking function 'sleep' inside of critical section}} + // expected-note@-1 {{Call to blocking function 'sleep' inside of critical section}} + m.unlock(); + sleep(4); // no-warning +} + +void testNonOverlappingMutexes() { + std::mutex m; + m.lock(); // There should be no warning here + m.unlock(); + m.lock(); // expected-note {{Entering critical section here}} + sleep(1); // expected-warning {{Call to blocking function 'sleep' inside of critical section}} + // expected-note@-1 {{Call to blocking function 'sleep' inside of critical section}} + m.unlock(); +} + +void testMixedMutexLocksWithIntermittentUnlock() { + std::mutex m, n, k; + m.lock(); // expected-note {{Entering critical section here}} + n.lock(); // the problem is not is this lock's critical section + n.unlock(); + k.lock(); // same as for n.lock() + k.unlock(); + sleep(1); // expected-warning {{Call to blocking function 'sleep' inside of critical section}} + // expected-note@-1 {{Call to blocking function 'sleep' inside of critical section}} m.unlock(); - sleep(3); // no-warning } void f() { sleep(1000); // expected-warning {{Call to blocking function 'sleep' inside of critical section}} + // expected-note@-1 {{Call to blocking function 'sleep' inside of critical section}} } void testBlockInCriticalSectionInterProcedural() { std::mutex m; - m.lock(); - f(); + m.lock(); // expected-note {{Entering critical section here}} + f(); // expected-note {{Calling 'f'}} m.unlock(); } +void unknown_function_that_may_lock(std::mutex &); void testBlockInCriticalSectionUnexpectedUnlock() { std::mutex m; + unknown_function_that_may_lock(m); m.unlock(); sleep(1); // no-warning - m.lock(); - sleep(1); // expected-warning {{Call to blocking function 'sleep' inside of critical section}} + m.lock(); // expected-note {{Entering critical section here}} + sleep(2); // expected-warning {{Call to blocking function 'sleep' inside of critical section}} + // expected-note@-1 {{Call to blocking function 'sleep' inside of critical section}} } void testBlockInCriticalSectionLockGuard() { @@ -130,12 +268,13 @@ void testBlockInCriticalSectionLockGuard() { std::not_real_lock not_real_lock(g_mutex); sleep(1); // no-warning - std::lock_guard lock(g_mutex); + std::lock_guard lock(g_mutex); // expected-note {{Entering critical section here}} sleep(1); // expected-warning {{Call to blocking function 'sleep' inside of critical section}} + // expected-note@-1 {{Call to blocking function 'sleep' inside of critical section}} } void testBlockInCriticalSectionLockGuardNested() { - testBlockInCriticalSectionLockGuard(); + testBlockInCriticalSectionLockGuard(); // expected-note {{Calling 'testBlockInCriticalSectionLockGuard'}} sleep(1); // no-warning } @@ -144,11 +283,12 @@ void testBlockInCriticalSectionUniqueLock() { std::not_real_lock not_real_lock(g_mutex); sleep(1); // no-warning - std::unique_lock lock(g_mutex); + std::unique_lock lock(g_mutex); // expected-note {{Entering critical section here}} sleep(1); // expected-warning {{Call to blocking function 'sleep' inside of critical section}} + // expected-note@-1 {{Call to blocking function 'sleep' inside of critical section}} } void testBlockInCriticalSectionUniqueLockNested() { - testBlockInCriticalSectionUniqueLock(); + testBlockInCriticalSectionUniqueLock(); // expected-note {{Calling 'testBlockInCriticalSectionUniqueLock'}} sleep(1); // no-warning } diff --git a/clang/test/Analysis/loop-unrolling.cpp b/clang/test/Analysis/loop-unrolling.cpp index fc1fb06cdc014ef57e5f9ef85aa142091a5c8a06..66a828abfb5133924015e7bd2c6e19a39fff49d0 100644 --- a/clang/test/Analysis/loop-unrolling.cpp +++ b/clang/test/Analysis/loop-unrolling.cpp @@ -547,3 +547,15 @@ void capture_implicitly_by_ref_as_loop_counter() { } }; } + + +void test_escaping_on_var_before_switch_case_no_crash(int c) { + // https://github.com/llvm/llvm-project/issues/68819 + switch (c) { + int i; // no-crash: The declaration of `i` is found here. + case 0: { + for (i = 0; i < 16; i++) {} + break; + } + } +} diff --git a/clang/test/CXX/module/dcl.dcl/dcl.module/dcl.module.interface/p1.cppm b/clang/test/CXX/module/dcl.dcl/dcl.module/dcl.module.interface/p1.cppm index 3072b760f9d7dd1101d9657e72b2c6295f7a2bf0..1a01ffac0154aefd35842b16ecb911c4074f19cb 100644 --- a/clang/test/CXX/module/dcl.dcl/dcl.module/dcl.module.interface/p1.cppm +++ b/clang/test/CXX/module/dcl.dcl/dcl.module/dcl.module.interface/p1.cppm @@ -15,10 +15,6 @@ module A; // #module-decl // expected-error@-2 {{missing 'export' specifier in module declaration while building module interface}} #define INTERFACE #endif -#else - #ifdef BUILT_AS_INTERFACE - // expected-error@1 {{missing 'export module' declaration in module interface unit}} - #endif #endif #ifndef INTERFACE diff --git a/clang/test/ClangScanDeps/working-directory-option.c b/clang/test/ClangScanDeps/working-directory-option.c new file mode 100644 index 0000000000000000000000000000000000000000..d57497d405d30f242c5e40000183d1a9d6c139ae --- /dev/null +++ b/clang/test/ClangScanDeps/working-directory-option.c @@ -0,0 +1,30 @@ +// Test that -working-directory works even when it differs from the working +// directory of the filesystem. + +// RUN: rm -rf %t +// RUN: mkdir -p %t/other +// RUN: split-file %s %t +// RUN: sed -e "s|DIR|%/t|g" %t/cdb.json.template > %t/cdb.json + +// RUN: clang-scan-deps -compilation-database %t/cdb.json -format experimental-full \ +// RUN: > %t/deps.json + +// RUN: cat %t/deps.json | sed 's:\\\\\?:/:g' | FileCheck %s -DPREFIX=%/t + +// CHECK: "file-deps": [ +// CHECK-NEXT: "[[PREFIX]]/cwd/t.c" +// CHECK-NEXT: "[[PREFIX]]/cwd/relative/h1.h" +// CHECK-NEXT: ] +// CHECK-NEXT: "input-file": "[[PREFIX]]/cwd/t.c" + +//--- cdb.json.template +[{ + "directory": "DIR/other", + "command": "clang -c t.c -I relative -working-directory DIR/cwd", + "file": "DIR/cwd/t.c" +}] + +//--- cwd/relative/h1.h + +//--- cwd/t.c +#include "h1.h" diff --git a/clang/test/CodeCompletion/ordinary-name.c b/clang/test/CodeCompletion/ordinary-name.c index c8181a248daa2fae964aca9ae337c731392deb0b..9398561920617308f921c61f2abb5a0910f8abc8 100644 --- a/clang/test/CodeCompletion/ordinary-name.c +++ b/clang/test/CodeCompletion/ordinary-name.c @@ -5,6 +5,7 @@ typedef struct t _TYPEDEF; void foo() { int y; // RUN: %clang_cc1 -isystem %S/Inputs -fsyntax-only -code-completion-at=%s:%(line-1):9 %s -o - | FileCheck -check-prefix=CHECK-CC1 %s + // CHECK-CC1-NOT: __builtin_va_list // CHECK-CC1-NOT: __INTEGER_TYPE // CHECK-CC1: _Imaginary // CHECK-CC1: _MyPrivateType @@ -15,4 +16,8 @@ void foo() { // CHECK-CC1: y // PR8744 - // RUN: %clang_cc1 -isystem %S/Inputs -fsyntax-only -code-completion-at=%s:%(line-17):11 %s + // RUN: %clang_cc1 -isystem %S/Inputs -fsyntax-only -code-completion-at=%s:%(line-18):11 %s + + // RUN: %clang_cc1 -isystem %S/Inputs -fsyntax-only -fdebugger-support -code-completion-at=%s:%(line-15):9 %s -o - | FileCheck -check-prefix=CHECK-DBG %s + // CHECK-DBG: __builtin_va_list + // CHECK-DBG: __INTEGER_TYPE diff --git a/clang/test/CodeGen/PowerPC/builtins-ppc-xlcompat-error.c b/clang/test/CodeGen/PowerPC/builtins-ppc-xlcompat-error.c index 5f57d7575c859abba0b8fc083d38ceb397bc11be..272e0222dc9e41f9e078a0cf0e723fd8ca0be3b8 100644 --- a/clang/test/CodeGen/PowerPC/builtins-ppc-xlcompat-error.c +++ b/clang/test/CodeGen/PowerPC/builtins-ppc-xlcompat-error.c @@ -24,13 +24,16 @@ void test_trap(void) { __tw(ia, ib, 0); //expected-error {{argument value 0 is outside the valid range [1, 31]}} } +#ifdef __PPC64__ void test_builtin_ppc_rldimi() { unsigned int shift; unsigned long long mask; unsigned long long res = __builtin_ppc_rldimi(ull, ull, shift, 7); // expected-error {{argument to '__builtin_ppc_rldimi' must be a constant integer}} res = __builtin_ppc_rldimi(ull, ull, 63, mask); // expected-error {{argument to '__builtin_ppc_rldimi' must be a constant integer}} res = __builtin_ppc_rldimi(ull, ull, 63, 0xFFFF000000000F00); // expected-error {{argument 3 value should represent a contiguous bit field}} + res = __builtin_ppc_rldimi(ull, ull, 64, 0xFFFF000000000000); // expected-error {{argument value 64 is outside the valid range [0, 63]}} } +#endif void test_builtin_ppc_rlwimi() { unsigned int shift; @@ -83,6 +86,10 @@ void testalignx(const void *pointer, unsigned int alignment) { } #ifndef __PPC64__ +unsigned long long testrldimi32() { + return __rldimi(ull, ui, 3, 0x7ffff8ULL); //expected-error {{this builtin is only available on 64-bit targets}} +} + long long testbpermd(long long bit_selector, long long source) { return __bpermd(bit_selector, source); //expected-error {{this builtin is only available on 64-bit targets}} } diff --git a/clang/test/CodeGen/PowerPC/builtins-ppc-xlcompat-rotate.c b/clang/test/CodeGen/PowerPC/builtins-ppc-xlcompat-rotate.c index b218547c00d93111d25c25b0e7967590a784819a..4773d6cb1a0cfdfc0c05ae491589b1ee7e56293b 100644 --- a/clang/test/CodeGen/PowerPC/builtins-ppc-xlcompat-rotate.c +++ b/clang/test/CodeGen/PowerPC/builtins-ppc-xlcompat-rotate.c @@ -1,8 +1,10 @@ // REQUIRES: powerpc-registered-target // RUN: %clang_cc1 -triple powerpc64-unknown-linux-gnu \ -// RUN: -emit-llvm %s -o - -target-cpu pwr7 | FileCheck %s +// RUN: -emit-llvm %s -o - -target-cpu pwr7 | FileCheck %s \ +// RUN: -check-prefixes=PPC64,CHECK // RUN: %clang_cc1 -triple powerpc64le-unknown-linux-gnu \ -// RUN: -emit-llvm %s -o - -target-cpu pwr8 | FileCheck %s +// RUN: -emit-llvm %s -o - -target-cpu pwr8 | FileCheck %s \ +// RUN: -check-prefixes=PPC64,CHECK // RUN: %clang_cc1 -triple powerpc-unknown-aix \ // RUN: -emit-llvm %s -o - -target-cpu pwr7 | FileCheck %s // RUN: %clang_cc1 -triple powerpc64-unknown-aix \ @@ -11,18 +13,20 @@ extern unsigned int ui; extern unsigned long long ull; +#ifdef __PPC64__ void test_builtin_ppc_rldimi() { - // CHECK-LABEL: test_builtin_ppc_rldimi - // CHECK: %res = alloca i64, align 8 - // CHECK-NEXT: [[RA:%[0-9]+]] = load i64, ptr @ull, align 8 - // CHECK-NEXT: [[RB:%[0-9]+]] = load i64, ptr @ull, align 8 - // CHECK-NEXT: [[RC:%[0-9]+]] = call i64 @llvm.ppc.rldimi(i64 [[RA]], i64 [[RB]], i32 63, i64 72057593769492480) - // CHECK-NEXT: store i64 [[RC]], ptr %res, align 8 - // CHECK-NEXT: ret void + // PPC64-LABEL: test_builtin_ppc_rldimi + // PPC64: %res = alloca i64, align 8 + // PPC64-NEXT: [[RA:%[0-9]+]] = load i64, ptr @ull, align 8 + // PPC64-NEXT: [[RB:%[0-9]+]] = load i64, ptr @ull, align 8 + // PPC64-NEXT: [[RC:%[0-9]+]] = call i64 @llvm.ppc.rldimi(i64 [[RA]], i64 [[RB]], i32 63, i64 72057593769492480) + // PPC64-NEXT: store i64 [[RC]], ptr %res, align 8 + // PPC64-NEXT: ret void /*shift = 63, mask = 0x00FFFFFFF0000000 = 72057593769492480, ~mask = 0xFF0000000FFFFFFF = -72057593769492481*/ unsigned long long res = __builtin_ppc_rldimi(ull, ull, 63, 0x00FFFFFFF0000000); } +#endif void test_builtin_ppc_rlwimi() { // CHECK-LABEL: test_builtin_ppc_rlwimi diff --git a/clang/test/CodeGen/PowerPC/toc-data-attribute.c b/clang/test/CodeGen/PowerPC/toc-data-attribute.c new file mode 100644 index 0000000000000000000000000000000000000000..db23d74759eeff873e623ca3759708001ab93a58 --- /dev/null +++ b/clang/test/CodeGen/PowerPC/toc-data-attribute.c @@ -0,0 +1,50 @@ +// RUN: %clang_cc1 %s -triple powerpc-ibm-aix-xcoff -S -mtocdata=f,g,h,i,j,k,l,m,n,o,p -emit-llvm -o - 2>&1 | FileCheck %s -check-prefixes=COMMON,CHECK32 --match-full-lines +// RUN: %clang_cc1 %s -triple powerpc-ibm-aix-xcoff -S -mtocdata -emit-llvm -o - 2>&1 | FileCheck %s -check-prefixes=COMMON,CHECK32 --match-full-lines + +// RUN: %clang_cc1 %s -triple powerpc64-ibm-aix-xcoff -S -mtocdata=f,g,h,i,j,k,l,m,n,o,p -emit-llvm -o - 2>&1 | FileCheck %s -check-prefixes=COMMON,CHECK64 --match-full-lines +// RUN: %clang_cc1 %s -triple powerpc64-ibm-aix-xcoff -S -mtocdata -emit-llvm -o - 2>&1 | FileCheck %s -check-prefixes=COMMON,CHECK64 --match-full-lines + +extern int f; +long long g = 5; +const char *h = "h"; +int *i; +int __attribute__((aligned(128))) j = 0; +float k = 100.00; +double l = 2.5; +int m __attribute__((section("foo"))) = 10; +__thread int n; + +extern int p[]; + +struct SomeStruct; +extern struct SomeStruct o; + +static int func_a() { + return g+(int)h[0]+*i+j+k+l+m+n+p[0]; +} + +int func_b() { + f = 1; + return func_a(); +} + +struct SomeStruct* getAddress(void) { + return &o; +} + +// CHECK32: @g = global i64 5, align 8 +// CHECK64: @g = global i64 5, align 8 #0 +// COMMON: {{.*}} = private unnamed_addr constant [2 x i8] c"h\00", align 1 +// COMMON: @h = global {{...*}} #0 +// COMMON: @j = global i32 0, align 128 +// COMMON: @k = global float 1.000000e+02, align 4 #0 +// CHECK32: @l = global double 2.500000e+00, align 8 +// CHECK64: @l = global double 2.500000e+00, align 8 #0 +// COMMON: @m = global i32 10, section "foo", align 4 +// COMMON: @f = external global i32, align 4 #0 +// COMMON: @o = external global %struct.SomeStruct, align 1 +// CHECK32: @i = global ptr null, align 4 #0 +// CHECK64: @i = global ptr null, align 8 #0 +// COMMON: @n = thread_local global i32 0, align 4 +// COMMON: @p = external global [0 x i32], align 4 +// COMMON: attributes #0 = { "toc-data" } diff --git a/clang/test/CodeGen/PowerPC/toc-data-attribute.cpp b/clang/test/CodeGen/PowerPC/toc-data-attribute.cpp new file mode 100644 index 0000000000000000000000000000000000000000..8183e3b727e7b369fcf98ceca9ef20789bcf4516 --- /dev/null +++ b/clang/test/CodeGen/PowerPC/toc-data-attribute.cpp @@ -0,0 +1,39 @@ +// RUN: %clang_cc1 %s -triple powerpc-ibm-aix-xcoff -S -mtocdata -emit-llvm -o - 2>&1 | FileCheck %s -check-prefixes=COMMON,ALLTOC +// RUN: %clang_cc1 %s -triple powerpc-ibm-aix-xcoff -S -mtocdata=n,_ZN11MyNamespace10myVariableE,_ZL1s,_ZZ4testvE7counter -emit-llvm -o - 2>&1 | FileCheck %s -check-prefixes=COMMON,TOCLIST +// RUN: %clang_cc1 %s -triple powerpc64-ibm-aix-xcoff -S -mtocdata -emit-llvm -o - 2>&1 | FileCheck %s -check-prefixes=COMMON,ALLTOC +// RUN: %clang_cc1 %s -triple powerpc64-ibm-aix-xcoff -S -mtocdata=n,_ZN11MyNamespace10myVariableE,_ZL1s,_ZZ4testvE7counter -emit-llvm -o - 2>&1 | FileCheck %s -check-prefixes=COMMON,TOCLIST + +extern int n; +static int s = 100; + +inline int test() { + static int counter = 0; + counter++; + return counter; +} + +int a () { + n = test(); + return 0; +} + +namespace MyNamespace { + int myVariable = 10; +} + +int b(int x) { + using namespace MyNamespace; + return x + myVariable; +} + +int c(int x) { + s += x; + return s; +} + +// COMMON: @n = external global i32, align 4 #0 +// COMMON: @_ZN11MyNamespace10myVariableE = global i32 10, align 4 #0 +// COMMON-NOT: @_ZL1s = internal global i32 100, align 4 #0 +// ALLTOC: @_ZZ4testvE7counter = linkonce_odr global i32 0, align 4 #0 +// TOCLIST-NOT: @_ZZ4testvE7counter = linkonce_odr global i32 0, align 4 #0 +// COMMON: attributes #0 = { "toc-data" } diff --git a/clang/test/CodeGen/PowerPC/toc-data-diagnostics.c b/clang/test/CodeGen/PowerPC/toc-data-diagnostics.c new file mode 100644 index 0000000000000000000000000000000000000000..ba8955530e46700bba5875fae6dc62f614a04a14 --- /dev/null +++ b/clang/test/CodeGen/PowerPC/toc-data-diagnostics.c @@ -0,0 +1,68 @@ +// RUN: %clang_cc1 %s -triple=powerpc-ibm-aix-xcoff -S -mtocdata=h,g,f,e,d,c,b,a,globalOneWithAlias,globalTwoWithAlias,ll,t3 -verify -emit-llvm -o - | FileCheck %s -check-prefix=CHECK --match-full-lines +// RUN: %clang_cc1 %s -triple=powerpc-ibm-aix-xcoff -S -mtocdata -verify=none -emit-llvm -o - | FileCheck %s -check-prefix=CHECK --match-full-lines + +// none-no-diagnostics + +struct large_struct { + int x; + short y; + short z; + char c; +}; + +struct large_struct a; // expected-warning {{-mtocdata option is ignored for a because variable is larger than a pointer}} +long long b = 5; // expected-warning {{-mtocdata option is ignored for b because variable is larger than a pointer}} +int __attribute__((aligned(128))) c = 0; // expected-warning {{-mtocdata option is ignored for c because variable is aligned wider than a pointer}} +double d = 2.5; // expected-warning {{-mtocdata option is ignored for d because variable is larger than a pointer}} +int e __attribute__((section("foo"))) = 10; // expected-warning {{-mtocdata option is ignored for e because variable has a section attribute}} +__thread int f; // expected-warning {{-mtocdata option is ignored for f because of thread local storage}} + +struct SomeStruct; +extern struct SomeStruct g; // expected-warning {{-mtocdata option is ignored for g because of incomplete type}} + +extern int h[]; // expected-warning {{-mtocdata option is ignored for h because of incomplete type}} + +struct ty3 { + int A; + char C[]; +}; +struct ty3 t3 = { 4, "fo" }; // expected-warning {{-mtocdata option is ignored for t3 because it contains a flexible array member}} + +int globalOneWithAlias = 10; +__attribute__((__alias__("globalOneWithAlias"))) extern int aliasOne; // expected-warning {{-mtocdata option is ignored for globalOneWithAlias because the variable has an alias}} +__attribute__((__alias__("globalTwoWithAlias"))) extern int aliasTwo; // expected-warning {{-mtocdata option is ignored for globalTwoWithAlias because the variable has an alias}} +int globalTwoWithAlias = 20; + + +int func() { + return a.x+b+c+d+e+f+h[0]; +} + +struct SomeStruct* getAddress(void) { + return &g; +} + +int test() { + return globalOneWithAlias + globalTwoWithAlias + aliasOne + aliasTwo; +} + +long long test2() { + static long long ll = 5; + ll++; + return ll; +} + +// CHECK: @b = global i64 5, align 8 +// CHECK: @c = global i32 0, align 128 +// CHECK: @d = global double 2.500000e+00, align 8 +// CHECK: @e = global i32 10, section "foo", align 4 +// CHECK: @globalOneWithAlias = global i32 10, align 4 +// CHECK: @globalTwoWithAlias = global i32 20, align 4 +// CHECK: @a = global %struct.large_struct zeroinitializer, align 4 +// CHECK: @f = thread_local global i32 0, align 4 +// CHECK: @h = external global [0 x i32], align 4 +// CHECK: @g = external global %struct.SomeStruct, align 1 +// CHECK: @test2.ll = internal global i64 5, align 8 +// CHECK: @aliasOne = alias i32, ptr @globalOneWithAlias +// CHECK: @aliasTwo = alias i32, ptr @globalTwoWithAlias +// CHECK-NOT: attributes #0 = { "toc-data" } diff --git a/clang/test/CodeGen/PowerPC/toc-data-structs-arrays.cpp b/clang/test/CodeGen/PowerPC/toc-data-structs-arrays.cpp new file mode 100644 index 0000000000000000000000000000000000000000..a717995cdceb1989be06ac8a1a072351aff18bb8 --- /dev/null +++ b/clang/test/CodeGen/PowerPC/toc-data-structs-arrays.cpp @@ -0,0 +1,65 @@ +// RUN: %clang_cc1 %s -triple powerpc-ibm-aix-xcoff -S -mtocdata=a4,a5,a8,a9,b,c,d,e,v -emit-llvm -o - 2>&1 \ +// RUN: | FileCheck %s -check-prefixes=CHECK32 --match-full-lines +// RUN: %clang_cc1 %s -triple powerpc-ibm-aix-xcoff -S -mtocdata -emit-llvm -o - 2>&1 \ +// RUN: | FileCheck %s -check-prefixes=CHECK32 --match-full-lines + +// RUN: %clang_cc1 %s -triple powerpc64-ibm-aix-xcoff -S -mtocdata=a4,a5,a8,a9,b,c,d,e,v -emit-llvm -o - 2>&1 \ +// RUN: | FileCheck %s -check-prefixes=CHECK64 --match-full-lines +// RUN: %clang_cc1 %s -triple powerpc64-ibm-aix-xcoff -S -mtocdata -emit-llvm -o - 2>&1 \ +// RUN: | FileCheck %s -check-prefixes=CHECK64 --match-full-lines + +struct size4_struct { + int x; +}; + +struct size5_struct { + int x; + char c; +}; + +struct size8_struct { + int x; + short y; + short z; +}; + +struct size9_struct { + int x; + short y; + short z; + char c; +}; + +struct size4_struct a4; +struct size5_struct a5; +struct size8_struct a8; +struct size9_struct a9; + +short b[2]; +short c[3]; +short d[4]; +short e[5]; + +int func_a() { + return a4.x+a5.x+a8.x+a9.x+b[0]+c[0]+d[0]+e[0]; +} + +// CHECK32: @a4 = global %struct.size4_struct zeroinitializer, align 4 #0 +// CHECK32: @a5 = global %struct.size5_struct zeroinitializer, align 4 +// CHECK32: @a8 = global %struct.size8_struct zeroinitializer, align 4 +// CHECK32: @a9 = global %struct.size9_struct zeroinitializer, align 4 +// CHECK32: @b = global [2 x i16] zeroinitializer, align 2 #0 +// CHECK32: @c = global [3 x i16] zeroinitializer, align 2 +// CHECK32: @d = global [4 x i16] zeroinitializer, align 2 +// CHECK32: @e = global [5 x i16] zeroinitializer, align 2 +// CHECK32: attributes #0 = { "toc-data" } + +// CHECK64: @a4 = global %struct.size4_struct zeroinitializer, align 4 #0 +// CHECK64: @a5 = global %struct.size5_struct zeroinitializer, align 4 #0 +// CHECK64: @a8 = global %struct.size8_struct zeroinitializer, align 4 #0 +// CHECK64: @a9 = global %struct.size9_struct zeroinitializer, align 4 +// CHECK64: @b = global [2 x i16] zeroinitializer, align 2 #0 +// CHECK64: @c = global [3 x i16] zeroinitializer, align 2 #0 +// CHECK64: @d = global [4 x i16] zeroinitializer, align 2 #0 +// CHECK64: @e = global [5 x i16] zeroinitializer, align 2 +// CHECK64: attributes #0 = { "toc-data" } diff --git a/clang/test/CodeGen/SystemZ/atomic_fp_load_store.c b/clang/test/CodeGen/SystemZ/atomic_fp_load_store.c new file mode 100644 index 0000000000000000000000000000000000000000..8a4383e92a1e50699b162ea783bffe4d6f4cad54 --- /dev/null +++ b/clang/test/CodeGen/SystemZ/atomic_fp_load_store.c @@ -0,0 +1,164 @@ +// RUN: %clang_cc1 -triple s390x-linux-gnu -O1 -emit-llvm %s -o - | FileCheck %s +// +// Test that floating point atomic stores and loads do not get casted to/from +// integer. + +#include + +_Atomic float Af; +_Atomic double Ad; +_Atomic long double Ald; + +//// Atomic stores of floating point values. +void fun0(float Arg) { +// CHECK-LABEL: @fun0 +// CHECK: store atomic float %Arg, ptr @Af seq_cst, align 4 + Af = Arg; +} + +void fun1(double Arg) { +// CHECK-LABEL: @fun1 +// CHECK: store atomic double %Arg, ptr @Ad seq_cst, align 8 + Ad = Arg; +} + +void fun2(long double Arg) { +// CHECK-LABEL: @fun2 +// CHECK: store atomic fp128 %Arg, ptr @Ald seq_cst, align 16 + Ald = Arg; +} + +void fun3(_Atomic float *Dst, float Arg) { +// CHECK-LABEL: @fun +// CHECK: store atomic float %Arg, ptr %Dst seq_cst, align 4 + *Dst = Arg; +} + +void fun4(_Atomic double *Dst, double Arg) { +// CHECK-LABEL: @fun4 +// CHECK: store atomic double %Arg, ptr %Dst seq_cst, align 8 + *Dst = Arg; +} + +void fun5(_Atomic long double *Dst, long double Arg) { +// CHECK-LABEL: @fun5 +// CHECK: store atomic fp128 %Arg, ptr %Dst seq_cst, align 16 + *Dst = Arg; +} + +//// Atomic loads of floating point values. +float fun6() { +// CHECK-LABEL: @fun6 +// CHECK: %atomic-load = load atomic float, ptr @Af seq_cst, align 4 + return Af; +} + +float fun7() { +// CHECK-LABEL: @fun7 +// CHECK: %atomic-load = load atomic double, ptr @Ad seq_cst, align 8 + return Ad; +} + +float fun8() { +// CHECK-LABEL: @fun8 +// CHECK: %atomic-load = load atomic fp128, ptr @Ald seq_cst, align 16 + return Ald; +} + +float fun9(_Atomic float *Src) { +// CHECK-LABEL: @fun9 +// CHECK: %atomic-load = load atomic float, ptr %Src seq_cst, align 4 + return *Src; +} + +double fun10(_Atomic double *Src) { +// CHECK-LABEL: @fun10 +// CHECK: %atomic-load = load atomic double, ptr %Src seq_cst, align 8 + return *Src; +} + +long double fun11(_Atomic long double *Src) { +// CHECK-LABEL: @fun11 +// CHECK: %atomic-load = load atomic fp128, ptr %Src seq_cst, align 16 + return *Src; +} + +//// Same, but with 'volatile' as well: + +_Atomic volatile float Af_vol; +_Atomic volatile double Ad_vol; +_Atomic volatile long double Ald_vol; + +//// Atomic volatile stores of floating point values. +void fun0_vol(float Arg) { +// CHECK-LABEL: @fun0_vol +// CHECK: store atomic volatile float %Arg, ptr @Af_vol seq_cst, align 4 + Af_vol = Arg; +} + +void fun1_vol(double Arg) { +// CHECK-LABEL: @fun1_vol +// CHECK: store atomic volatile double %Arg, ptr @Ad_vol seq_cst, align 8 + Ad_vol = Arg; +} + +void fun2_vol(long double Arg) { +// CHECK-LABEL: @fun2_vol +// CHECK: store atomic volatile fp128 %Arg, ptr @Ald_vol seq_cst, align 16 + Ald_vol = Arg; +} + +void fun3_vol(_Atomic volatile float *Dst, float Arg) { +// CHECK-LABEL: @fun3_vol +// CHECK: store atomic volatile float %Arg, ptr %Dst seq_cst, align 4 + *Dst = Arg; +} + +void fun4_vol(_Atomic volatile double *Dst, double Arg) { +// CHECK-LABEL: @fun4_vol +// CHECK: store atomic volatile double %Arg, ptr %Dst seq_cst, align 8 + *Dst = Arg; +} + +void fun5_vol(_Atomic volatile long double *Dst, long double Arg) { +// CHECK-LABEL: @fun5_vol +// CHECK: store atomic volatile fp128 %Arg, ptr %Dst seq_cst, align 16 + *Dst = Arg; +} + +//// Atomic volatile loads of floating point values. +float fun6_vol() { +// CHECK-LABEL: @fun6_vol +// CHECK: %atomic-load = load atomic volatile float, ptr @Af_vol seq_cst, align 4 + return Af_vol; +} + +float fun7_vol() { +// CHECK-LABEL: @fun7_vol +// CHECK: %atomic-load = load atomic volatile double, ptr @Ad_vol seq_cst, align 8 + return Ad_vol; +} + +float fun8_vol() { +// CHECK-LABEL: @fun8_vol +// CHECK: %atomic-load = load atomic volatile fp128, ptr @Ald_vol seq_cst, align 16 + return Ald_vol; +} + +float fun9_vol(_Atomic volatile float *Src) { +// CHECK-LABEL: @fun9_vol +// CHECK: %atomic-load = load atomic volatile float, ptr %Src seq_cst, align 4 + return *Src; +} + +double fun10_vol(_Atomic volatile double *Src) { +// CHECK-LABEL: @fun10_vol +// CHECK: %atomic-load = load atomic volatile double, ptr %Src seq_cst, align 8 + return *Src; +} + +long double fun11_vol(_Atomic volatile long double *Src) { +// CHECK-LABEL: @fun11_vol +// CHECK: %atomic-load = load atomic volatile fp128, ptr %Src seq_cst, align 16 + return *Src; +} diff --git a/clang/test/CodeGen/X86/attribute-cmpsd-no-error.c b/clang/test/CodeGen/X86/attribute-cmpsd-no-error.c new file mode 100644 index 0000000000000000000000000000000000000000..a73d998155d0963c4fb3e987c83272cf78b634fe --- /dev/null +++ b/clang/test/CodeGen/X86/attribute-cmpsd-no-error.c @@ -0,0 +1,11 @@ +// RUN: %clang_cc1 %s -ffreestanding -triple=x86_64-unknown-unknown-emit-llvm -o /dev/null -verify +// RUN: %clang_cc1 %s -ffreestanding -triple=i386-unknown-unknown-emit-llvm -o /dev/null -verify + +// expected-no-diagnostics + +#include + +__attribute__((target("avx"))) +__m128 test(__m128 a, __m128 b) { + return _mm_cmp_ps(a, b, 14); +} diff --git a/clang/test/CodeGen/X86/avx-builtins.c b/clang/test/CodeGen/X86/avx-builtins.c index d50366c3a022ccaf64bbc0eb1186e156e376b689..4bf1213d9fca97a9d59c7ff904631fde2e8f80ff 100644 --- a/clang/test/CodeGen/X86/avx-builtins.c +++ b/clang/test/CodeGen/X86/avx-builtins.c @@ -596,54 +596,6 @@ __m256 test_mm256_cmp_ps_true_us(__m256 a, __m256 b) { return _mm256_cmp_ps(a, b, _CMP_TRUE_US); } -__m128d test_mm_cmp_pd_eq_oq(__m128d a, __m128d b) { - // CHECK-LABEL: test_mm_cmp_pd_eq_oq - // CHECK: fcmp oeq <2 x double> %{{.*}}, %{{.*}} - return _mm_cmp_pd(a, b, _CMP_EQ_OQ); -} - -__m128d test_mm_cmp_pd_lt_os(__m128d a, __m128d b) { - // CHECK-LABEL: test_mm_cmp_pd_lt_os - // CHECK: fcmp olt <2 x double> %{{.*}}, %{{.*}} - return _mm_cmp_pd(a, b, _CMP_LT_OS); -} - -__m128d test_mm_cmp_pd_le_os(__m128d a, __m128d b) { - // CHECK-LABEL: test_mm_cmp_pd_le_os - // CHECK: fcmp ole <2 x double> %{{.*}}, %{{.*}} - return _mm_cmp_pd(a, b, _CMP_LE_OS); -} - -__m128d test_mm_cmp_pd_unord_q(__m128d a, __m128d b) { - // CHECK-LABEL: test_mm_cmp_pd_unord_q - // CHECK: fcmp uno <2 x double> %{{.*}}, %{{.*}} - return _mm_cmp_pd(a, b, _CMP_UNORD_Q); -} - -__m128d test_mm_cmp_pd_neq_uq(__m128d a, __m128d b) { - // CHECK-LABEL: test_mm_cmp_pd_neq_uq - // CHECK: fcmp une <2 x double> %{{.*}}, %{{.*}} - return _mm_cmp_pd(a, b, _CMP_NEQ_UQ); -} - -__m128d test_mm_cmp_pd_nlt_us(__m128d a, __m128d b) { - // CHECK-LABEL: test_mm_cmp_pd_nlt_us - // CHECK: fcmp uge <2 x double> %{{.*}}, %{{.*}} - return _mm_cmp_pd(a, b, _CMP_NLT_US); -} - -__m128d test_mm_cmp_pd_nle_us(__m128d a, __m128d b) { - // CHECK-LABEL: test_mm_cmp_pd_nle_us - // CHECK: fcmp ugt <2 x double> %{{.*}}, %{{.*}} - return _mm_cmp_pd(a, b, _CMP_NLE_US); -} - -__m128d test_mm_cmp_pd_ord_q(__m128d a, __m128d b) { - // CHECK-LABEL: test_mm_cmp_pd_ord_q - // CHECK: fcmp ord <2 x double> %{{.*}}, %{{.*}} - return _mm_cmp_pd(a, b, _CMP_ORD_Q); -} - __m128d test_mm_cmp_pd_eq_uq(__m128d a, __m128d b) { // CHECK-LABEL: test_mm_cmp_pd_eq_uq // CHECK: fcmp ueq <2 x double> %{{.*}}, %{{.*}} @@ -788,54 +740,6 @@ __m128d test_mm_cmp_pd_true_us(__m128d a, __m128d b) { return _mm_cmp_pd(a, b, _CMP_TRUE_US); } -__m128 test_mm_cmp_ps_eq_oq(__m128 a, __m128 b) { - // CHECK-LABEL: test_mm_cmp_ps_eq_oq - // CHECK: fcmp oeq <4 x float> %{{.*}}, %{{.*}} - return _mm_cmp_ps(a, b, _CMP_EQ_OQ); -} - -__m128 test_mm_cmp_ps_lt_os(__m128 a, __m128 b) { - // CHECK-LABEL: test_mm_cmp_ps_lt_os - // CHECK: fcmp olt <4 x float> %{{.*}}, %{{.*}} - return _mm_cmp_ps(a, b, _CMP_LT_OS); -} - -__m128 test_mm_cmp_ps_le_os(__m128 a, __m128 b) { - // CHECK-LABEL: test_mm_cmp_ps_le_os - // CHECK: fcmp ole <4 x float> %{{.*}}, %{{.*}} - return _mm_cmp_ps(a, b, _CMP_LE_OS); -} - -__m128 test_mm_cmp_ps_unord_q(__m128 a, __m128 b) { - // CHECK-LABEL: test_mm_cmp_ps_unord_q - // CHECK: fcmp uno <4 x float> %{{.*}}, %{{.*}} - return _mm_cmp_ps(a, b, _CMP_UNORD_Q); -} - -__m128 test_mm_cmp_ps_neq_uq(__m128 a, __m128 b) { - // CHECK-LABEL: test_mm_cmp_ps_neq_uq - // CHECK: fcmp une <4 x float> %{{.*}}, %{{.*}} - return _mm_cmp_ps(a, b, _CMP_NEQ_UQ); -} - -__m128 test_mm_cmp_ps_nlt_us(__m128 a, __m128 b) { - // CHECK-LABEL: test_mm_cmp_ps_nlt_us - // CHECK: fcmp uge <4 x float> %{{.*}}, %{{.*}} - return _mm_cmp_ps(a, b, _CMP_NLT_US); -} - -__m128 test_mm_cmp_ps_nle_us(__m128 a, __m128 b) { - // CHECK-LABEL: test_mm_cmp_ps_nle_us - // CHECK: fcmp ugt <4 x float> %{{.*}}, %{{.*}} - return _mm_cmp_ps(a, b, _CMP_NLE_US); -} - -__m128 test_mm_cmp_ps_ord_q(__m128 a, __m128 b) { - // CHECK-LABEL: test_mm_cmp_ps_ord_q - // CHECK: fcmp ord <4 x float> %{{.*}}, %{{.*}} - return _mm_cmp_ps(a, b, _CMP_ORD_Q); -} - __m128 test_mm_cmp_ps_eq_uq(__m128 a, __m128 b) { // CHECK-LABEL: test_mm_cmp_ps_eq_uq // CHECK: fcmp ueq <4 x float> %{{.*}}, %{{.*}} diff --git a/clang/test/CodeGen/X86/cmp-avx-builtins-error.c b/clang/test/CodeGen/X86/cmp-avx-builtins-error.c new file mode 100644 index 0000000000000000000000000000000000000000..bad2606021b69e6e0f0ad19982d3eee17b517236 --- /dev/null +++ b/clang/test/CodeGen/X86/cmp-avx-builtins-error.c @@ -0,0 +1,22 @@ +// RUN: %clang_cc1 %s -ffreestanding -triple=x86_64-unknown-unknown \ +// RUN: -target-feature +avx -emit-llvm -fsyntax-only -verify +// RUN: %clang_cc1 %s -ffreestanding -triple=i386-unknown-unknown \ +// RUN: -target-feature +avx -emit-llvm -fsyntax-only -verify + +#include + +__m128d test_mm_cmp_pd(__m128d a, __m128d b) { + return _mm_cmp_pd(a, b, 32); // expected-error {{argument value 32 is outside the valid range [0, 31]}} +} + +__m128d test_mm_cmp_sd(__m128d a, __m128d b) { + return _mm_cmp_sd(a, b, 32); // expected-error {{argument value 32 is outside the valid range [0, 31]}} +} + +__m128 test_mm_cmp_ps(__m128 a, __m128 b) { + return _mm_cmp_ps(a, b, 32); // expected-error {{argument value 32 is outside the valid range [0, 31]}} +} + +__m128 test_mm_cmp_ss(__m128 a, __m128 b) { + return _mm_cmp_ss(a, b, 32); // expected-error {{argument value 32 is outside the valid range [0, 31]}} +} diff --git a/clang/test/CodeGen/X86/sse-builtins.c b/clang/test/CodeGen/X86/sse-builtins.c index 830081296e52fb839738d9da3079596e9b765aea..aae5cfb8bb1d99376db66102dbe0480b998222d3 100644 --- a/clang/test/CodeGen/X86/sse-builtins.c +++ b/clang/test/CodeGen/X86/sse-builtins.c @@ -34,6 +34,60 @@ __m128 test_mm_andnot_ps(__m128 A, __m128 B) { return _mm_andnot_ps(A, B); } +__m128 test_mm_cmp_ps_eq_oq(__m128 a, __m128 b) { + // CHECK-LABEL: test_mm_cmp_ps_eq_oq + // CHECK: fcmp oeq <4 x float> %{{.*}}, %{{.*}} + return _mm_cmp_ps(a, b, _CMP_EQ_OQ); +} + +__m128 test_mm_cmp_ps_lt_os(__m128 a, __m128 b) { + // CHECK-LABEL: test_mm_cmp_ps_lt_os + // CHECK: fcmp olt <4 x float> %{{.*}}, %{{.*}} + return _mm_cmp_ps(a, b, _CMP_LT_OS); +} + +__m128 test_mm_cmp_ps_le_os(__m128 a, __m128 b) { + // CHECK-LABEL: test_mm_cmp_ps_le_os + // CHECK: fcmp ole <4 x float> %{{.*}}, %{{.*}} + return _mm_cmp_ps(a, b, _CMP_LE_OS); +} + +__m128 test_mm_cmp_ps_unord_q(__m128 a, __m128 b) { + // CHECK-LABEL: test_mm_cmp_ps_unord_q + // CHECK: fcmp uno <4 x float> %{{.*}}, %{{.*}} + return _mm_cmp_ps(a, b, _CMP_UNORD_Q); +} + +__m128 test_mm_cmp_ps_neq_uq(__m128 a, __m128 b) { + // CHECK-LABEL: test_mm_cmp_ps_neq_uq + // CHECK: fcmp une <4 x float> %{{.*}}, %{{.*}} + return _mm_cmp_ps(a, b, _CMP_NEQ_UQ); +} + +__m128 test_mm_cmp_ps_nlt_us(__m128 a, __m128 b) { + // CHECK-LABEL: test_mm_cmp_ps_nlt_us + // CHECK: fcmp uge <4 x float> %{{.*}}, %{{.*}} + return _mm_cmp_ps(a, b, _CMP_NLT_US); +} + +__m128 test_mm_cmp_ps_nle_us(__m128 a, __m128 b) { + // CHECK-LABEL: test_mm_cmp_ps_nle_us + // CHECK: fcmp ugt <4 x float> %{{.*}}, %{{.*}} + return _mm_cmp_ps(a, b, _CMP_NLE_US); +} + +__m128 test_mm_cmp_ps_ord_q(__m128 a, __m128 b) { + // CHECK-LABEL: test_mm_cmp_ps_ord_q + // CHECK: fcmp ord <4 x float> %{{.*}}, %{{.*}} + return _mm_cmp_ps(a, b, _CMP_ORD_Q); +} + +__m128 test_mm_cmp_ss(__m128 A, __m128 B) { + // CHECK-LABEL: test_mm_cmp_ss + // CHECK: call <4 x float> @llvm.x86.sse.cmp.ss(<4 x float> %{{.*}}, <4 x float> %{{.*}}, i8 7) + return _mm_cmp_ss(A, B, _CMP_ORD_Q); +} + __m128 test_mm_cmpeq_ps(__m128 __a, __m128 __b) { // CHECK-LABEL: test_mm_cmpeq_ps // CHECK: [[CMP:%.*]] = fcmp oeq <4 x float> diff --git a/clang/test/CodeGen/X86/sse2-builtins.c b/clang/test/CodeGen/X86/sse2-builtins.c index 44b2e485a5bd85eeead9be1e261676c893f93bc1..3ca7777e763359ede47544926149b77e9ec42d0f 100644 --- a/clang/test/CodeGen/X86/sse2-builtins.c +++ b/clang/test/CodeGen/X86/sse2-builtins.c @@ -160,6 +160,60 @@ void test_mm_clflush(void* A) { _mm_clflush(A); } +__m128d test_mm_cmp_pd_eq_oq(__m128d a, __m128d b) { + // CHECK-LABEL: test_mm_cmp_pd_eq_oq + // CHECK: fcmp oeq <2 x double> %{{.*}}, %{{.*}} + return _mm_cmp_pd(a, b, _CMP_EQ_OQ); +} + +__m128d test_mm_cmp_pd_lt_os(__m128d a, __m128d b) { + // CHECK-LABEL: test_mm_cmp_pd_lt_os + // CHECK: fcmp olt <2 x double> %{{.*}}, %{{.*}} + return _mm_cmp_pd(a, b, _CMP_LT_OS); +} + +__m128d test_mm_cmp_pd_le_os(__m128d a, __m128d b) { + // CHECK-LABEL: test_mm_cmp_pd_le_os + // CHECK: fcmp ole <2 x double> %{{.*}}, %{{.*}} + return _mm_cmp_pd(a, b, _CMP_LE_OS); +} + +__m128d test_mm_cmp_pd_unord_q(__m128d a, __m128d b) { + // CHECK-LABEL: test_mm_cmp_pd_unord_q + // CHECK: fcmp uno <2 x double> %{{.*}}, %{{.*}} + return _mm_cmp_pd(a, b, _CMP_UNORD_Q); +} + +__m128d test_mm_cmp_pd_neq_uq(__m128d a, __m128d b) { + // CHECK-LABEL: test_mm_cmp_pd_neq_uq + // CHECK: fcmp une <2 x double> %{{.*}}, %{{.*}} + return _mm_cmp_pd(a, b, _CMP_NEQ_UQ); +} + +__m128d test_mm_cmp_pd_nlt_us(__m128d a, __m128d b) { + // CHECK-LABEL: test_mm_cmp_pd_nlt_us + // CHECK: fcmp uge <2 x double> %{{.*}}, %{{.*}} + return _mm_cmp_pd(a, b, _CMP_NLT_US); +} + +__m128d test_mm_cmp_pd_nle_us(__m128d a, __m128d b) { + // CHECK-LABEL: test_mm_cmp_pd_nle_us + // CHECK: fcmp ugt <2 x double> %{{.*}}, %{{.*}} + return _mm_cmp_pd(a, b, _CMP_NLE_US); +} + +__m128d test_mm_cmp_pd_ord_q(__m128d a, __m128d b) { + // CHECK-LABEL: test_mm_cmp_pd_ord_q + // CHECK: fcmp ord <2 x double> %{{.*}}, %{{.*}} + return _mm_cmp_pd(a, b, _CMP_ORD_Q); +} + +__m128d test_mm_cmp_sd(__m128d A, __m128d B) { + // CHECK-LABEL: test_mm_cmp_sd + // CHECK: call <2 x double> @llvm.x86.sse2.cmp.sd(<2 x double> %{{.*}}, <2 x double> %{{.*}}, i8 7) + return _mm_cmp_sd(A, B, _CMP_ORD_Q); +} + __m128i test_mm_cmpeq_epi8(__m128i A, __m128i B) { // CHECK-LABEL: test_mm_cmpeq_epi8 // CHECK: icmp eq <16 x i8> diff --git a/clang/test/CodeGen/atomic.c b/clang/test/CodeGen/atomic.c index 9143bedab906160ddc792c1e489c308adc5548d2..af5c056bbfe6e8ad4cb4679a35c70796d5267584 100644 --- a/clang/test/CodeGen/atomic.c +++ b/clang/test/CodeGen/atomic.c @@ -145,6 +145,5 @@ void force_global_uses(void) { (void)glob_int; // CHECK: load atomic i32, ptr @[[GLOB_INT]] seq_cst (void)glob_flt; - // CHECK: %[[LOCAL_FLT:.+]] = load atomic i32, ptr @[[GLOB_FLT]] seq_cst - // CHECK-NEXT: bitcast i32 %[[LOCAL_FLT]] to float + // CHECK: load atomic float, ptr @[[GLOB_FLT]] seq_cst } diff --git a/clang/test/CodeGen/builtins-arm64.c b/clang/test/CodeGen/builtins-arm64.c index 05ea1c719edff3651d5a4dbe848e7088a3abb780..8bd68d9ceb48ec90a43295c8092e096a33ac3148 100644 --- a/clang/test/CodeGen/builtins-arm64.c +++ b/clang/test/CodeGen/builtins-arm64.c @@ -156,4 +156,10 @@ int rndrrs(uint64_t *__addr) { return __builtin_arm_rndrrs(__addr); } +// CHECK-LABEL: @trap( +// CHECK: call void @llvm.aarch64.break(i32 42) +void trap() { + __builtin_arm_trap(42); +} + // CHECK: ![[M0]] = !{!"1:2:3:4:5"} diff --git a/clang/test/CodeGen/c11atomics-ios.c b/clang/test/CodeGen/c11atomics-ios.c index bcb6519ab0dc818a622f710aa1ab8f213051d353..811820b67fbdbf23d1073a37f8671fb82294c82a 100644 --- a/clang/test/CodeGen/c11atomics-ios.c +++ b/clang/test/CodeGen/c11atomics-ios.c @@ -19,15 +19,13 @@ void testFloat(_Atomic(float) *fp) { _Atomic(float) x = 2.0f; // CHECK-NEXT: [[T0:%.*]] = load ptr, ptr [[FP]] -// CHECK-NEXT: [[T2:%.*]] = load atomic i32, ptr [[T0]] seq_cst, align 4 -// CHECK-NEXT: [[T3:%.*]] = bitcast i32 [[T2]] to float -// CHECK-NEXT: store float [[T3]], ptr [[F]] +// CHECK-NEXT: [[T2:%.*]] = load atomic float, ptr [[T0]] seq_cst, align 4 +// CHECK-NEXT: store float [[T2]], ptr [[F]] float f = *fp; // CHECK-NEXT: [[T0:%.*]] = load float, ptr [[F]], align 4 // CHECK-NEXT: [[T1:%.*]] = load ptr, ptr [[FP]], align 4 -// CHECK-NEXT: [[T2:%.*]] = bitcast float [[T0]] to i32 -// CHECK-NEXT: store atomic i32 [[T2]], ptr [[T1]] seq_cst, align 4 +// CHECK-NEXT: store atomic float [[T0]], ptr [[T1]] seq_cst, align 4 *fp = f; // CHECK-NEXT: ret void diff --git a/clang/test/CodeGen/complex-math-mixed.c b/clang/test/CodeGen/complex-math-mixed.c new file mode 100644 index 0000000000000000000000000000000000000000..050163cca80aab4bb8a6ea1178e44c8f7f44f2f6 --- /dev/null +++ b/clang/test/CodeGen/complex-math-mixed.c @@ -0,0 +1,146 @@ +// RUN: %clang_cc1 %s -O0 -emit-llvm -triple x86_64-unknown-unknown -o - | FileCheck %s --check-prefix=X86 +// RUN: %clang_cc1 %s -O0 -triple x86_64-unknown-unknown -fsyntax-only -ast-dump | FileCheck %s --check-prefix=AST + +// Check that for 'F _Complex + int' (F = real floating-point type), we emit an +// implicit cast from 'int' to 'F', but NOT to 'F _Complex' (i.e. that we do +// 'F _Complex + F', NOT 'F _Complex + F _Complex'), and likewise for -/*. + +// AST-NOT: FloatingRealToComplex + +float _Complex add_float_ci(float _Complex a, int b) { + // X86-LABEL: @add_float_ci + // X86: [[I:%.*]] = sitofp i32 {{%.*}} to float + // X86: fadd float {{.*}}, [[I]] + // X86-NOT: fadd + return a + b; +} + +float _Complex add_float_ic(int a, float _Complex b) { + // X86-LABEL: @add_float_ic + // X86: [[I:%.*]] = sitofp i32 {{%.*}} to float + // X86: fadd float [[I]] + // X86-NOT: fadd + return a + b; +} + +float _Complex sub_float_ci(float _Complex a, int b) { + // X86-LABEL: @sub_float_ci + // X86: [[I:%.*]] = sitofp i32 {{%.*}} to float + // X86: fsub float {{.*}}, [[I]] + // X86-NOT: fsub + return a - b; +} + +float _Complex sub_float_ic(int a, float _Complex b) { + // X86-LABEL: @sub_float_ic + // X86: [[I:%.*]] = sitofp i32 {{%.*}} to float + // X86: fsub float [[I]] + // X86: fneg + // X86-NOT: fsub + return a - b; +} + +float _Complex mul_float_ci(float _Complex a, int b) { + // X86-LABEL: @mul_float_ci + // X86: [[I:%.*]] = sitofp i32 {{%.*}} to float + // X86: fmul float {{.*}}, [[I]] + // X86: fmul float {{.*}}, [[I]] + // X86-NOT: fmul + return a * b; +} + +float _Complex mul_float_ic(int a, float _Complex b) { + // X86-LABEL: @mul_float_ic + // X86: [[I:%.*]] = sitofp i32 {{%.*}} to float + // X86: fmul float [[I]] + // X86: fmul float [[I]] + // X86-NOT: fmul + return a * b; +} + +float _Complex div_float_ci(float _Complex a, int b) { + // X86-LABEL: @div_float_ci + // X86: [[I:%.*]] = sitofp i32 {{%.*}} to float + // X86: fdiv float {{.*}}, [[I]] + // X86: fdiv float {{.*}}, [[I]] + // X86-NOT: @__divsc3 + return a / b; +} + +// There is no good way of doing this w/o converting the 'int' to a complex +// number, so we expect complex division here. +float _Complex div_float_ic(int a, float _Complex b) { + // X86-LABEL: @div_float_ic + // X86: [[I:%.*]] = sitofp i32 {{%.*}} to float + // X86: call {{.*}} @__divsc3(float {{.*}} [[I]], float noundef 0.{{0+}}e+00, float {{.*}}, float {{.*}}) + return a / b; +} + +double _Complex add_double_ci(double _Complex a, int b) { + // X86-LABEL: @add_double_ci + // X86: [[I:%.*]] = sitofp i32 {{%.*}} to double + // X86: fadd double {{.*}}, [[I]] + // X86-NOT: fadd + return a + b; +} + +double _Complex add_double_ic(int a, double _Complex b) { + // X86-LABEL: @add_double_ic + // X86: [[I:%.*]] = sitofp i32 {{%.*}} to double + // X86: fadd double [[I]] + // X86-NOT: fadd + return a + b; +} + +double _Complex sub_double_ci(double _Complex a, int b) { + // X86-LABEL: @sub_double_ci + // X86: [[I:%.*]] = sitofp i32 {{%.*}} to double + // X86: fsub double {{.*}}, [[I]] + // X86-NOT: fsub + return a - b; +} + +double _Complex sub_double_ic(int a, double _Complex b) { + // X86-LABEL: @sub_double_ic + // X86: [[I:%.*]] = sitofp i32 {{%.*}} to double + // X86: fsub double [[I]] + // X86: fneg + // X86-NOT: fsub + return a - b; +} + +double _Complex mul_double_ci(double _Complex a, int b) { + // X86-LABEL: @mul_double_ci + // X86: [[I:%.*]] = sitofp i32 {{%.*}} to double + // X86: fmul double {{.*}}, [[I]] + // X86: fmul double {{.*}}, [[I]] + // X86-NOT: fmul + return a * b; +} + +double _Complex mul_double_ic(int a, double _Complex b) { + // X86-LABEL: @mul_double_ic + // X86: [[I:%.*]] = sitofp i32 {{%.*}} to double + // X86: fmul double [[I]] + // X86: fmul double [[I]] + // X86-NOT: fmul + return a * b; +} + +double _Complex div_double_ci(double _Complex a, int b) { + // X86-LABEL: @div_double_ci + // X86: [[I:%.*]] = sitofp i32 {{%.*}} to double + // X86: fdiv double {{.*}}, [[I]] + // X86: fdiv double {{.*}}, [[I]] + // X86-NOT: @__divdc3 + return a / b; +} + +// There is no good way of doing this w/o converting the 'int' to a complex +// number, so we expect complex division here. +double _Complex div_double_ic(int a, double _Complex b) { + // X86-LABEL: @div_double_ic + // X86: [[I:%.*]] = sitofp i32 {{%.*}} to double + // X86: call {{.*}} @__divdc3(double {{.*}} [[I]], double noundef 0.{{0+}}e+00, double {{.*}}, double {{.*}}) + return a / b; +} diff --git a/clang/test/CodeGen/const-init.c b/clang/test/CodeGen/const-init.c index 0e4fc4ad48af8dba4bdc5c2d4e6f9f10724a4965..ad3e9551199ac25622463d335ef4964db2b25951 100644 --- a/clang/test/CodeGen/const-init.c +++ b/clang/test/CodeGen/const-init.c @@ -216,3 +216,6 @@ int PR4517_x2 = PR4517_arrc[PR4517_idx]; // CHECK: @PR4517_x = global i32 42, align 4 // CHECK: @PR4517_idx = constant i32 1, align 4 // CHECK: @PR4517_x2 = global i32 42, align 4 + +// CHECK: @GH84784_inf = constant i8 1 +_Bool const GH84784_inf = (1.0/0.0); diff --git a/clang/test/CodeGen/ptrauth-intrinsics.c b/clang/test/CodeGen/ptrauth-intrinsics.c new file mode 100644 index 0000000000000000000000000000000000000000..17f28dddb380153685416f0d497c49fb417847bc --- /dev/null +++ b/clang/test/CodeGen/ptrauth-intrinsics.c @@ -0,0 +1,73 @@ +// RUN: %clang_cc1 -triple arm64-apple-ios -fptrauth-intrinsics -emit-llvm %s -o - | FileCheck %s + +void (*fnptr)(void); +long int_discriminator; +void *ptr_discriminator; +long signature; + +// CHECK-LABEL: define void @test_auth() +void test_auth() { + // CHECK: [[PTR:%.*]] = load ptr, ptr @fnptr, + // CHECK-NEXT: [[DISC0:%.*]] = load ptr, ptr @ptr_discriminator, + // CHECK-NEXT: [[T0:%.*]] = ptrtoint ptr [[PTR]] to i64 + // CHECK-NEXT: [[DISC:%.*]] = ptrtoint ptr [[DISC0]] to i64 + // CHECK-NEXT: [[T1:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[T0]], i32 0, i64 [[DISC]]) + // CHECK-NEXT: [[RESULT:%.*]] = inttoptr i64 [[T1]] to ptr + // CHECK-NEXT: store ptr [[RESULT]], ptr @fnptr, + fnptr = __builtin_ptrauth_auth(fnptr, 0, ptr_discriminator); +} + +// CHECK-LABEL: define void @test_strip() +void test_strip() { + // CHECK: [[PTR:%.*]] = load ptr, ptr @fnptr, + // CHECK-NEXT: [[T0:%.*]] = ptrtoint ptr [[PTR]] to i64 + // CHECK-NEXT: [[T1:%.*]] = call i64 @llvm.ptrauth.strip(i64 [[T0]], i32 0) + // CHECK-NEXT: [[RESULT:%.*]] = inttoptr i64 [[T1]] to ptr + // CHECK-NEXT: store ptr [[RESULT]], ptr @fnptr, + fnptr = __builtin_ptrauth_strip(fnptr, 0); +} + +// CHECK-LABEL: define void @test_sign_unauthenticated() +void test_sign_unauthenticated() { + // CHECK: [[PTR:%.*]] = load ptr, ptr @fnptr, + // CHECK-NEXT: [[DISC0:%.*]] = load ptr, ptr @ptr_discriminator, + // CHECK-NEXT: [[T0:%.*]] = ptrtoint ptr [[PTR]] to i64 + // CHECK-NEXT: [[DISC:%.*]] = ptrtoint ptr [[DISC0]] to i64 + // CHECK-NEXT: [[T1:%.*]] = call i64 @llvm.ptrauth.sign(i64 [[T0]], i32 0, i64 [[DISC]]) + // CHECK-NEXT: [[RESULT:%.*]] = inttoptr i64 [[T1]] to ptr + // CHECK-NEXT: store ptr [[RESULT]], ptr @fnptr, + fnptr = __builtin_ptrauth_sign_unauthenticated(fnptr, 0, ptr_discriminator); +} + +// CHECK-LABEL: define void @test_auth_and_resign() +void test_auth_and_resign() { + // CHECK: [[PTR:%.*]] = load ptr, ptr @fnptr, + // CHECK-NEXT: [[DISC0:%.*]] = load ptr, ptr @ptr_discriminator, + // CHECK-NEXT: [[T0:%.*]] = ptrtoint ptr [[PTR]] to i64 + // CHECK-NEXT: [[DISC:%.*]] = ptrtoint ptr [[DISC0]] to i64 + // CHECK-NEXT: [[T1:%.*]] = call i64 @llvm.ptrauth.resign(i64 [[T0]], i32 0, i64 [[DISC]], i32 3, i64 15) + // CHECK-NEXT: [[RESULT:%.*]] = inttoptr i64 [[T1]] to ptr + // CHECK-NEXT: store ptr [[RESULT]], ptr @fnptr, + fnptr = __builtin_ptrauth_auth_and_resign(fnptr, 0, ptr_discriminator, 3, 15); +} + +// CHECK-LABEL: define void @test_blend_discriminator() +void test_blend_discriminator() { + // CHECK: [[PTR:%.*]] = load ptr, ptr @fnptr, + // CHECK-NEXT: [[DISC:%.*]] = load i64, ptr @int_discriminator, + // CHECK-NEXT: [[T0:%.*]] = ptrtoint ptr [[PTR]] to i64 + // CHECK-NEXT: [[RESULT:%.*]] = call i64 @llvm.ptrauth.blend(i64 [[T0]], i64 [[DISC]]) + // CHECK-NEXT: store i64 [[RESULT]], ptr @int_discriminator, + int_discriminator = __builtin_ptrauth_blend_discriminator(fnptr, int_discriminator); +} + +// CHECK-LABEL: define void @test_sign_generic_data() +void test_sign_generic_data() { + // CHECK: [[PTR:%.*]] = load ptr, ptr @fnptr, + // CHECK-NEXT: [[DISC0:%.*]] = load ptr, ptr @ptr_discriminator, + // CHECK-NEXT: [[T0:%.*]] = ptrtoint ptr [[PTR]] to i64 + // CHECK-NEXT: [[DISC:%.*]] = ptrtoint ptr [[DISC0]] to i64 + // CHECK-NEXT: [[RESULT:%.*]] = call i64 @llvm.ptrauth.sign.generic(i64 [[T0]], i64 [[DISC]]) + // CHECK-NEXT: store i64 [[RESULT]], ptr @signature, + signature = __builtin_ptrauth_sign_generic_data(fnptr, ptr_discriminator); +} diff --git a/clang/test/CodeGen/remote-traps.c b/clang/test/CodeGen/remote-traps.c new file mode 100644 index 0000000000000000000000000000000000000000..6751afb96d25f2572f456c52d3f291b205e8d74e --- /dev/null +++ b/clang/test/CodeGen/remote-traps.c @@ -0,0 +1,15 @@ +// RUN: %clang_cc1 -O1 -emit-llvm -fsanitize=signed-integer-overflow -fsanitize-trap=signed-integer-overflow %s -o - | FileCheck %s +// RUN: %clang_cc1 -O1 -emit-llvm -fsanitize=signed-integer-overflow -fsanitize-trap=signed-integer-overflow -mllvm -clang-remove-traps -mllvm -remove-traps-random-rate=1 %s -o - | FileCheck %s --implicit-check-not="call void @llvm.ubsantrap" --check-prefixes=REMOVE + +int test(int x) { + return x + 123; +} + +// CHECK-LABEL: define {{.*}}i32 @test( +// CHECK: call { i32, i1 } @llvm.sadd.with.overflow.i32( +// CHECK: trap: +// CHECK-NEXT: call void @llvm.ubsantrap(i8 0) +// CHECK-NEXT: unreachable + +// REMOVE-LABEL: define {{.*}}i32 @test( +// REMOVE: call { i32, i1 } @llvm.sadd.with.overflow.i32( diff --git a/clang/test/CodeGen/target-features-error-2.c b/clang/test/CodeGen/target-features-error-2.c index 60586fb57f1c04486ab72032c89bfc21187af12e..1599b0135b747f981da0c4a9c05a2c3e67b51a5d 100644 --- a/clang/test/CodeGen/target-features-error-2.c +++ b/clang/test/CodeGen/target-features-error-2.c @@ -15,7 +15,7 @@ int baz(__m256i a) { #if NEED_AVX_2 __m128 need_avx(__m128 a, __m128 b) { - return _mm_cmp_ps(a, b, 0); // expected-error {{'__builtin_ia32_cmpps' needs target feature avx}} + return _mm_cmp_ps(a, b, 8); // expected-error {{'__builtin_ia32_cmpps' needs target feature avx}} } #endif diff --git a/clang/test/CodeGen/tbaa-struct.cpp b/clang/test/CodeGen/tbaa-struct.cpp index 63e4097946448e5ed56ef76f1181416666b242de..9b4b7415142d933be0a89e1a87520dc4d5a726bd 100644 --- a/clang/test/CodeGen/tbaa-struct.cpp +++ b/clang/test/CodeGen/tbaa-struct.cpp @@ -191,7 +191,7 @@ void copy12(UnionMember2 *a1, UnionMember2 *a2) { // (offset, size) = (0,1) char; (4,2) short; (8,4) int; (12,1) char; (16,4) int; (20,4) int // CHECK-OLD: [[TS2]] = !{i64 0, i64 1, !{{.*}}, i64 4, i64 2, !{{.*}}, i64 8, i64 4, !{{.*}}, i64 12, i64 1, !{{.*}}, i64 16, i64 4, {{.*}}, i64 20, i64 4, {{.*}}} // (offset, size) = (0,8) char; (0,2) char; (4,8) char -// CHECK-OLD: [[TS3]] = !{i64 0, i64 8, !{{.*}}, i64 0, i64 2, !{{.*}}, i64 4, i64 8, !{{.*}}} +// CHECK-OLD: [[TS3]] = !{i64 0, i64 12, [[TAG_CHAR]]} // CHECK-OLD: [[TS4]] = !{i64 0, i64 1, [[TAG_CHAR]], i64 1, i64 1, [[TAG_CHAR]], i64 2, i64 1, [[TAG_CHAR]]} // CHECK-OLD: [[TS5]] = !{i64 0, i64 1, [[TAG_CHAR]], i64 4, i64 1, [[TAG_CHAR]], i64 5, i64 1, [[TAG_CHAR]]} // CHECK-OLD: [[TS6]] = !{i64 0, i64 2, [[TAG_CHAR]], i64 2, i64 1, [[TAG_CHAR]], i64 8, i64 8, [[TAG_DOUBLE:!.+]]} @@ -199,10 +199,8 @@ void copy12(UnionMember2 *a1, UnionMember2 *a2) { // CHECK-OLD [[DOUBLE]] = !{!"double", [[CHAR]], i64 0} // CHECK-OLD: [[TS7]] = !{i64 0, i64 1, [[TAG_CHAR]], i64 1, i64 1, [[TAG_CHAR]], i64 2, i64 1, [[TAG_CHAR]], i64 3, i64 1, [[TAG_CHAR]], i64 4, i64 1, [[TAG_CHAR]], i64 8, i64 8, [[TAG_DOUBLE]], i64 16, i64 1, [[TAG_CHAR]]} // CHECK-OLD: [[TS8]] = !{i64 0, i64 4, [[TAG_CHAR]], i64 8, i64 8, [[TAG_DOUBLE]]} -// CHECK-OLD: [[TS9]] = !{i64 0, i64 8, [[TAG_DOUBLE]], i64 0, i64 4, [[TAG_FLOAT:!.+]], i64 8, i64 4, [[TAG_INT]]} -// CHECK-OLD: [[TAG_FLOAT]] = !{[[FLOAT:!.+]], [[FLOAT]], i64 0} -// CHECK-OLD: [[FLOAT]] = !{!"float", [[CHAR]], i64 0} -// CHECK-OLD: [[TS10]] = !{i64 0, i64 4, [[TAG_INT]], i64 8, i64 8, [[TAG_DOUBLE]], i64 8, i64 4, [[TAG_FLOAT:!.+]]} +// CHECK-OLD: [[TS9]] = !{i64 0, i64 8, [[TAG_CHAR]], i64 8, i64 4, [[TAG_INT]]} +// CHECK-OLD: [[TS10]] = !{i64 0, i64 4, [[TAG_INT]], i64 8, i64 8, [[TAG_CHAR]]} // CHECK-NEW-DAG: [[TYPE_char:!.*]] = !{{{.*}}, i64 1, !"omnipotent char"} // CHECK-NEW-DAG: [[TAG_char]] = !{[[TYPE_char]], [[TYPE_char]], i64 0, i64 0} diff --git a/clang/test/CodeGen/volatile.cpp b/clang/test/CodeGen/volatile.cpp index 38724659ad8a3557cad7ad6b44e4f6cdfbeb5649..70f523b93852ed16875effc915f4289f1e9ff0f6 100644 --- a/clang/test/CodeGen/volatile.cpp +++ b/clang/test/CodeGen/volatile.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -O2 -triple=x86_64-unknown-linux-gnu -emit-llvm %s -o - | FileCheck %s -check-prefix CHECK +// RUN: %clang_cc1 -O2 -triple=x86_64-unknown-linux-gnu -emit-llvm %s -o - | FileCheck %s struct agg { int a ; @@ -10,34 +10,32 @@ _Complex float cf; int volatile vol =10; void f0() { const_cast(cf) = const_cast(cf) + 1; -// CHECK: %cf.real = load volatile float, ptr @cf -// CHECK: %cf.imag = load volatile float, ptr getelementptr -// CHECK: %add.r = fadd float %cf.real, 1.000000e+00 -// CHECK: %add.i = fadd float %cf.imag, 0.000000e+00 -// CHECK: store volatile float %add.r -// CHECK: store volatile float %add.i, ptr getelementptr +// CHECK: [[Re1:%.*]] = load volatile float, ptr @cf +// CHECK: [[Im1:%.*]] = load volatile float, ptr getelementptr +// CHECK: [[Add1:%.*]] = fadd float [[Re1]], 1.000000e+00 +// CHECK: store volatile float [[Add1]], ptr @cf +// CHECK: store volatile float [[Im1]], ptr getelementptr static_cast(cf) = static_cast(cf) + 1; -// CHECK: %cf.real1 = load volatile float, ptr @cf -// CHECK: %cf.imag2 = load volatile float, ptr getelementptr -// CHECK: %add.r3 = fadd float %cf.real1, 1.000000e+00 -// CHECK: %add.i4 = fadd float %cf.imag2, 0.000000e+00 -// CHECK: store volatile float %add.r3, ptr @cf -// CHECK: store volatile float %add.i4, ptr getelementptr +// CHECK: [[Re2:%.*]] = load volatile float, ptr @cf +// CHECK: [[Im2:%.*]] = load volatile float, ptr getelementptr +// CHECK: [[Add2:%.*]] = fadd float [[Re2]], 1.000000e+00 +// CHECK: store volatile float [[Add2]], ptr @cf +// CHECK: store volatile float [[Im2]], ptr getelementptr const_cast(a.a) = const_cast(t.a) ; -// CHECK: %0 = load volatile i32, ptr @t -// CHECK: store volatile i32 %0, ptr @a +// CHECK: [[I1:%.*]] = load volatile i32, ptr @t +// CHECK: store volatile i32 [[I1]], ptr @a static_cast(a.b) = static_cast(t.a) ; -// CHECK: %1 = load volatile i32, ptr @t -// CHECK: store volatile i32 %1, ptr getelementptr +// CHECK: [[I2:%.*]] = load volatile i32, ptr @t +// CHECK: store volatile i32 [[I2]], ptr getelementptr const_cast(vt) = const_cast(vt) + 1; -// CHECK: %2 = load volatile i32, ptr @vt -// CHECK: %add = add nsw i32 %2, 1 -// CHECK: store volatile i32 %add, ptr @vt +// CHECK: [[I3:%.*]] = load volatile i32, ptr @vt +// CHECK: [[Add3:%.*]] = add nsw i32 [[I3]], 1 +// CHECK: store volatile i32 [[Add3]], ptr @vt static_cast(vt) = static_cast(vt) + 1; -// CHECK: %3 = load volatile i32, ptr @vt -// CHECK: %add5 = add nsw i32 %3, 1 -// CHECK: store volatile i32 %add5, ptr @vt +// CHECK: [[I4:%.*]] = load volatile i32, ptr @vt +// CHECK: [[Add4:%.*]] = add nsw i32 [[I4]], 1 +// CHECK: store volatile i32 [[Add4]], ptr @vt vt = const_cast(vol); -// %4 = load i32, ptr @vol -// store i32 %4, ptr @vt +// [[I5:%.*]] = load i32, ptr @vol +// store i32 [[I5]], ptr @vt } diff --git a/clang/test/CodeGenCUDA/amdgpu-kernel-attrs.cu b/clang/test/CodeGenCUDA/amdgpu-kernel-attrs.cu index a1642421af2c8c096cbeb15354d3d46bf42bc859..11a133fd1351d2ba76180947ac2010b42df28cb8 100644 --- a/clang/test/CodeGenCUDA/amdgpu-kernel-attrs.cu +++ b/clang/test/CodeGenCUDA/amdgpu-kernel-attrs.cu @@ -40,12 +40,45 @@ __attribute__((amdgpu_num_vgpr(64))) // expected-no-diagnostics __global__ void num_vgpr_64() { // CHECK: define{{.*}} amdgpu_kernel void @_Z11num_vgpr_64v() [[NUM_VGPR_64:#[0-9]+]] } +__attribute__((amdgpu_max_num_work_groups(32, 4, 2))) // expected-no-diagnostics +__global__ void max_num_work_groups_32_4_2() { +// CHECK: define{{.*}} amdgpu_kernel void @_Z26max_num_work_groups_32_4_2v() [[MAX_NUM_WORK_GROUPS_32_4_2:#[0-9]+]] +} +__attribute__((amdgpu_max_num_work_groups(32))) // expected-no-diagnostics +__global__ void max_num_work_groups_32() { +// CHECK: define{{.*}} amdgpu_kernel void @_Z22max_num_work_groups_32v() [[MAX_NUM_WORK_GROUPS_32_1_1:#[0-9]+]] +} +__attribute__((amdgpu_max_num_work_groups(32,1))) // expected-no-diagnostics +__global__ void max_num_work_groups_32_1() { +// CHECK: define{{.*}} amdgpu_kernel void @_Z24max_num_work_groups_32_1v() [[MAX_NUM_WORK_GROUPS_32_1_1:#[0-9]+]] +} + + + +template +__attribute__((amdgpu_max_num_work_groups(a, 4, 2))) +__global__ void template_a_4_2_max_num_work_groups() {} +template __global__ void template_a_4_2_max_num_work_groups<32>(); +// CHECK: define{{.*}} amdgpu_kernel void @_Z34template_a_4_2_max_num_work_groupsILj32EEvv() [[MAX_NUM_WORK_GROUPS_32_4_2:#[0-9]+]] + +template +__attribute__((amdgpu_max_num_work_groups(32, a, 2))) +__global__ void template_32_a_2_max_num_work_groups() {} +template __global__ void template_32_a_2_max_num_work_groups<4>(); +// CHECK: define{{.*}} amdgpu_kernel void @_Z35template_32_a_2_max_num_work_groupsILj4EEvv() [[MAX_NUM_WORK_GROUPS_32_4_2:#[0-9]+]] + +template +__attribute__((amdgpu_max_num_work_groups(32, 4, a))) +__global__ void template_32_4_a_max_num_work_groups() {} +template __global__ void template_32_4_a_max_num_work_groups<2>(); +// CHECK: define{{.*}} amdgpu_kernel void @_Z35template_32_4_a_max_num_work_groupsILj2EEvv() [[MAX_NUM_WORK_GROUPS_32_4_2:#[0-9]+]] // Make sure this is silently accepted on other targets. // NAMD-NOT: "amdgpu-flat-work-group-size" // NAMD-NOT: "amdgpu-waves-per-eu" // NAMD-NOT: "amdgpu-num-vgpr" // NAMD-NOT: "amdgpu-num-sgpr" +// NAMD-NOT: "amdgpu-max-num-work-groups" // DEFAULT-DAG: attributes [[FLAT_WORK_GROUP_SIZE_DEFAULT]] = {{.*}}"amdgpu-flat-work-group-size"="1,1024"{{.*}}"uniform-work-group-size"="true" // MAX1024-DAG: attributes [[FLAT_WORK_GROUP_SIZE_DEFAULT]] = {{.*}}"amdgpu-flat-work-group-size"="1,1024" @@ -53,5 +86,7 @@ __global__ void num_vgpr_64() { // CHECK-DAG: attributes [[WAVES_PER_EU_2]] = {{.*}}"amdgpu-waves-per-eu"="2" // CHECK-DAG: attributes [[NUM_SGPR_32]] = {{.*}}"amdgpu-num-sgpr"="32" // CHECK-DAG: attributes [[NUM_VGPR_64]] = {{.*}}"amdgpu-num-vgpr"="64" +// CHECK-DAG: attributes [[MAX_NUM_WORK_GROUPS_32_4_2]] = {{.*}}"amdgpu-max-num-workgroups"="32,4,2" +// CHECK-DAG: attributes [[MAX_NUM_WORK_GROUPS_32_1_1]] = {{.*}}"amdgpu-max-num-workgroups"="32,1,1" // NOUB-NOT: "uniform-work-group-size"="true" diff --git a/clang/test/CodeGenCXX/arm-swiftcall.cpp b/clang/test/CodeGenCXX/arm-swiftcall.cpp index e60c1482700a4b9ffcf80b5043be71d7eb8ae6ae..45eea7bfd853b992f9f88b8394676abd494aad1b 100644 --- a/clang/test/CodeGenCXX/arm-swiftcall.cpp +++ b/clang/test/CodeGenCXX/arm-swiftcall.cpp @@ -1,5 +1,9 @@ // RUN: %clang_cc1 -triple armv7-apple-darwin9 -emit-llvm -o - %s -Wno-return-type-c-linkage -std=c++03 | FileCheck %s -check-prefixes=CHECK +// For now just check that the RISC-V triples are accepted, but don't check the IR, as swiftcall is not yet supported. +// RUN: %clang_cc1 -triple riscv32-unknown-linux-gnu -emit-llvm -o - %s -Wno-return-type-c-linkage -std=c++03 +// RUN: %clang_cc1 -triple riscv64-unknown-linux-gnu -emit-llvm -o - %s -Wno-return-type-c-linkage -std=c++03 + // This isn't really testing anything ARM-specific; it's just a convenient // 32-bit platform. diff --git a/clang/test/CodeGenCXX/cxx23-assume.cpp b/clang/test/CodeGenCXX/cxx23-assume.cpp new file mode 100644 index 0000000000000000000000000000000000000000..a1fa6b30b2f0e112298fe0433c3efc2d21260632 --- /dev/null +++ b/clang/test/CodeGenCXX/cxx23-assume.cpp @@ -0,0 +1,50 @@ +// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -std=c++23 %s -emit-llvm -o - | FileCheck %s +// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -std=c++23 -fno-assumptions %s -emit-llvm -o - | FileCheck %s --check-prefix=DISABLED + +// DISABLED-NOT: @llvm.assume + +bool f(); + +template +void f2() { + [[assume(sizeof(T) == sizeof(int))]]; +} + +// CHECK: @_Z1gii(i32 noundef [[X:%.*]], i32 noundef [[Y:%.*]]) +// CHECK-NEXT: entry: +// CHECK-NEXT: [[X_ADDR:%.*]] = alloca i32 +// CHECK-NEXT: [[Y_ADDR:%.*]] = alloca i32 +// CHECK-NEXT: store i32 [[X]], ptr [[X_ADDR]] +// CHECK-NEXT: store i32 [[Y]], ptr [[Y_ADDR]] +void g(int x, int y) { + // Not emitted because it has side-effects. + [[assume(f())]]; + + // CHECK-NEXT: call void @llvm.assume(i1 true) + [[assume((1, 2))]]; + + // CHECK-NEXT: [[X1:%.*]] = load i32, ptr [[X_ADDR]] + // CHECK-NEXT: [[CMP1:%.*]] = icmp ne i32 [[X1]], 27 + // CHECK-NEXT: call void @llvm.assume(i1 [[CMP1]]) + [[assume(x != 27)]]; + + // CHECK-NEXT: [[X2:%.*]] = load i32, ptr [[X_ADDR]] + // CHECK-NEXT: [[Y2:%.*]] = load i32, ptr [[Y_ADDR]] + // CHECK-NEXT: [[CMP2:%.*]] = icmp eq i32 [[X2]], [[Y2]] + // CHECK-NEXT: call void @llvm.assume(i1 [[CMP2]]) + [[assume(x == y)]]; + + // CHECK-NEXT: call void @_Z2f2IiEvv() + f2(); + + // CHECK-NEXT: call void @_Z2f2IdEvv() + f2(); +} + +// CHECK: void @_Z2f2IiEvv() +// CHECK-NEXT: entry: +// CHECK-NEXT: call void @llvm.assume(i1 true) + +// CHECK: void @_Z2f2IdEvv() +// CHECK-NEXT: entry: +// CHECK-NEXT: call void @llvm.assume(i1 false) diff --git a/clang/test/CodeGenCXX/mangle-ms-back-references.cpp b/clang/test/CodeGenCXX/mangle-ms-back-references.cpp index cb95c100b3d22e0fe8500c8a87f5c9543eac36b4..b27a9c5acacb777513efca00e1a072e9acf15190 100644 --- a/clang/test/CodeGenCXX/mangle-ms-back-references.cpp +++ b/clang/test/CodeGenCXX/mangle-ms-back-references.cpp @@ -83,3 +83,20 @@ class H; void ManyParams(T01 &, T02 &, T03 &, T04 &, T05 &, T06 &, T07 &, T08 &, T09 &, T10 &, H &, H &) {} // CHECK: "?ManyParams@@YAXAAVT01@@AAVT02@@AAVT03@@AAVT04@@AAVT05@@AAVT06@@AAVT07@@AAVT08@@AAVT09@@AAVT10@@AAV?$H@VT11@@@@AAV?$H@VT11@@@@@Z" + +namespace NS { +// The name "TSS0" for the name of the class below has been specifically +// chosen to ensure that back reference lookup does not match against the +// implicitly generated "$TSS0" name of the thread safe static initialization +// variable. +struct __declspec(dllexport) TSS0 { + static TSS0& get(); + __forceinline static TSS0& singleton() { + static TSS0& lsv = get(); + return lsv; + } +}; +} +// CHECK: "?singleton@TSS0@NS@@SAAAU12@XZ" +// CHECK: "?lsv@?1??singleton@TSS0@NS@@SAAAU23@XZ@4AAU23@A" +// CHECK: "?$TSS0@?1??singleton@TSS0@NS@@SAAAU23@XZ@4HA" diff --git a/clang/test/CodeGenCoroutines/coro-always-inline.cpp b/clang/test/CodeGenCoroutines/coro-always-inline.cpp index 6e13a62fbd98659f0fb3c940fe2aeeb578a6a0ae..d4f67a73f517268aa810a406148dcc2bd537b041 100644 --- a/clang/test/CodeGenCoroutines/coro-always-inline.cpp +++ b/clang/test/CodeGenCoroutines/coro-always-inline.cpp @@ -34,7 +34,7 @@ struct coroutine_traits { // CHECK-LABEL: @_Z3foov // CHECK-LABEL: entry: // CHECK: %ref.tmp.reload.addr = getelementptr -// CHECK: %ref.tmp4.reload.addr = getelementptr +// CHECK: %ref.tmp3.reload.addr = getelementptr void foo() { co_return; } // Check that bar is not inlined even it's marked as always_inline. diff --git a/clang/test/CodeGenCoroutines/coro-await.cpp b/clang/test/CodeGenCoroutines/coro-await.cpp index dc5a765ccb83d782c10add7d6977b5f756fc5067..75851d8805bb6e37d1308bcf7e6b03c112f87137 100644 --- a/clang/test/CodeGenCoroutines/coro-await.cpp +++ b/clang/test/CodeGenCoroutines/coro-await.cpp @@ -71,16 +71,13 @@ extern "C" void f0() { // CHECK: [[SUSPEND_BB]]: // CHECK: %[[SUSPEND_ID:.+]] = call token @llvm.coro.save( // --------------------------- - // Build the coroutine handle and pass it to await_suspend + // Call coro.await.suspend // --------------------------- - // CHECK: call ptr @_ZNSt16coroutine_handleINSt16coroutine_traitsIJvEE12promise_typeEE12from_addressEPv(ptr %[[FRAME]]) - // ... many lines of code to coerce coroutine_handle into an ptr scalar - // CHECK: %[[CH:.+]] = load ptr, ptr %{{.+}} - // CHECK: call void @_ZN14suspend_always13await_suspendESt16coroutine_handleIvE(ptr {{[^,]*}} %[[AWAITABLE]], ptr %[[CH]]) + // CHECK-NEXT: call void @llvm.coro.await.suspend.void(ptr %[[AWAITABLE]], ptr %[[FRAME]], ptr @__await_suspend_wrapper_f0_await) // ------------------------- // Generate a suspend point: // ------------------------- - // CHECK: %[[OUTCOME:.+]] = call i8 @llvm.coro.suspend(token %[[SUSPEND_ID]], i1 false) + // CHECK-NEXT: %[[OUTCOME:.+]] = call i8 @llvm.coro.suspend(token %[[SUSPEND_ID]], i1 false) // CHECK: switch i8 %[[OUTCOME]], label %[[RET_BB:.+]] [ // CHECK: i8 0, label %[[READY_BB]] // CHECK: i8 1, label %[[CLEANUP_BB:.+]] @@ -101,6 +98,17 @@ extern "C" void f0() { // CHECK-NEXT: call zeroext i1 @_ZN10final_susp11await_readyEv(ptr // CHECK: %[[FINALSP_ID:.+]] = call token @llvm.coro.save( // CHECK: call i8 @llvm.coro.suspend(token %[[FINALSP_ID]], i1 true) + + // Await suspend wrapper + // CHECK: define{{.*}} @__await_suspend_wrapper_f0_await(ptr {{[^,]*}} %[[AWAITABLE_ARG:.+]], ptr {{[^,]*}} %[[FRAME_ARG:.+]]) + // CHECK: store ptr %[[AWAITABLE_ARG]], ptr %[[AWAITABLE_TMP:.+]], + // CHECK: store ptr %[[FRAME_ARG]], ptr %[[FRAME_TMP:.+]], + // CHECK: %[[AWAITABLE:.+]] = load ptr, ptr %[[AWAITABLE_TMP]] + // CHECK: %[[FRAME:.+]] = load ptr, ptr %[[FRAME_TMP]] + // CHECK: call ptr @_ZNSt16coroutine_handleINSt16coroutine_traitsIJvEE12promise_typeEE12from_addressEPv(ptr %[[FRAME]]) + // ... many lines of code to coerce coroutine_handle into an ptr scalar + // CHECK: %[[CH:.+]] = load ptr, ptr %{{.+}} + // CHECK: call void @_ZN14suspend_always13await_suspendESt16coroutine_handleIvE(ptr {{[^,]*}} %[[AWAITABLE]], ptr %[[CH]]) } struct suspend_maybe { @@ -131,7 +139,7 @@ extern "C" void f1(int) { // See if we need to suspend: // -------------------------- - // CHECK: %[[READY:.+]] = call zeroext i1 @_ZN13suspend_maybe11await_readyEv(ptr {{[^,]*}} %[[AWAITABLE]]) + // CHECK: %[[READY:.+]] = call zeroext i1 @_ZN13suspend_maybe11await_readyEv(ptr {{[^,]*}} %[[AWAITABLE:.+]]) // CHECK: br i1 %[[READY]], label %[[READY_BB:.+]], label %[[SUSPEND_BB:.+]] // If we are suspending: @@ -139,12 +147,9 @@ extern "C" void f1(int) { // CHECK: [[SUSPEND_BB]]: // CHECK: %[[SUSPEND_ID:.+]] = call token @llvm.coro.save( // --------------------------- - // Build the coroutine handle and pass it to await_suspend + // Call coro.await.suspend // --------------------------- - // CHECK: call ptr @_ZNSt16coroutine_handleINSt16coroutine_traitsIJviEE12promise_typeEE12from_addressEPv(ptr %[[FRAME]]) - // ... many lines of code to coerce coroutine_handle into an ptr scalar - // CHECK: %[[CH:.+]] = load ptr, ptr %{{.+}} - // CHECK: %[[YES:.+]] = call zeroext i1 @_ZN13suspend_maybe13await_suspendESt16coroutine_handleIvE(ptr {{[^,]*}} %[[AWAITABLE]], ptr %[[CH]]) + // CHECK-NEXT: %[[YES:.+]] = call i1 @llvm.coro.await.suspend.bool(ptr %[[AWAITABLE]], ptr %[[FRAME]], ptr @__await_suspend_wrapper_f1_yield) // ------------------------------------------- // See if await_suspend decided not to suspend // ------------------------------------------- @@ -155,6 +160,18 @@ extern "C" void f1(int) { // CHECK: [[READY_BB]]: // CHECK: call void @_ZN13suspend_maybe12await_resumeEv(ptr {{[^,]*}} %[[AWAITABLE]]) + + // Await suspend wrapper + // CHECK: define {{.*}} i1 @__await_suspend_wrapper_f1_yield(ptr {{[^,]*}} %[[AWAITABLE_ARG:.+]], ptr {{[^,]*}} %[[FRAME_ARG:.+]]) + // CHECK: store ptr %[[AWAITABLE_ARG]], ptr %[[AWAITABLE_TMP:.+]], + // CHECK: store ptr %[[FRAME_ARG]], ptr %[[FRAME_TMP:.+]], + // CHECK: %[[AWAITABLE:.+]] = load ptr, ptr %[[AWAITABLE_TMP]] + // CHECK: %[[FRAME:.+]] = load ptr, ptr %[[FRAME_TMP]] + // CHECK: call ptr @_ZNSt16coroutine_handleINSt16coroutine_traitsIJviEE12promise_typeEE12from_addressEPv(ptr %[[FRAME]]) + // ... many lines of code to coerce coroutine_handle into an ptr scalar + // CHECK: %[[CH:.+]] = load ptr, ptr %{{.+}} + // CHECK: %[[YES:.+]] = call zeroext i1 @_ZN13suspend_maybe13await_suspendESt16coroutine_handleIvE(ptr {{[^,]*}} %[[AWAITABLE]], ptr %[[CH]]) + // CHECK-NEXT: ret i1 %[[YES]] } struct ComplexAwaiter { @@ -340,11 +357,39 @@ struct TailCallAwait { // CHECK-LABEL: @TestTailcall( extern "C" void TestTailcall() { + // CHECK: %[[PROMISE:.+]] = alloca %"struct.std::coroutine_traits::promise_type" + // CHECK: %[[FRAME:.+]] = call ptr @llvm.coro.begin( co_await TailCallAwait{}; + // CHECK: %[[READY:.+]] = call zeroext i1 @_ZN13TailCallAwait11await_readyEv(ptr {{[^,]*}} %[[AWAITABLE:.+]]) + // CHECK: br i1 %[[READY]], label %[[READY_BB:.+]], label %[[SUSPEND_BB:.+]] - // CHECK: %[[RESULT:.+]] = call ptr @_ZN13TailCallAwait13await_suspendESt16coroutine_handleIvE(ptr - // CHECK: %[[COERCE:.+]] = getelementptr inbounds %"struct.std::coroutine_handle", ptr %[[TMP:.+]], i32 0, i32 0 - // CHECK: store ptr %[[RESULT]], ptr %[[COERCE]] - // CHECK: %[[ADDR:.+]] = call ptr @_ZNSt16coroutine_handleIvE7addressEv(ptr {{[^,]*}} %[[TMP]]) - // CHECK: call void @llvm.coro.resume(ptr %[[ADDR]]) + // If we are suspending: + // --------------------- + // CHECK: [[SUSPEND_BB]]: + // CHECK: %[[SUSPEND_ID:.+]] = call token @llvm.coro.save( + // --------------------------- + // Call coro.await.suspend + // --------------------------- + // CHECK-NEXT: %[[RESUMED:.+]] = call ptr @llvm.coro.await.suspend.handle(ptr %[[AWAITABLE]], ptr %[[FRAME]], ptr @__await_suspend_wrapper_TestTailcall_await) + // CHECK-NEXT: call void @llvm.coro.resume(ptr %[[RESUMED]]) + // CHECK-NEXT: %[[OUTCOME:.+]] = call i8 @llvm.coro.suspend(token %[[SUSPEND_ID]], i1 false) + // CHECK-NEXT: switch i8 %[[OUTCOME]], label %[[RET_BB:.+]] [ + // CHECK-NEXT: i8 0, label %[[READY_BB]] + // CHECK-NEXT: i8 1, label %{{.+}} + // CHECK-NEXT: ] + + // Await suspend wrapper + // CHECK: define {{.*}} ptr @__await_suspend_wrapper_TestTailcall_await(ptr {{[^,]*}} %[[AWAITABLE_ARG:.+]], ptr {{[^,]*}} %[[FRAME_ARG:.+]]) + // CHECK: store ptr %[[AWAITABLE_ARG]], ptr %[[AWAITABLE_TMP:.+]], + // CHECK: store ptr %[[FRAME_ARG]], ptr %[[FRAME_TMP:.+]], + // CHECK: %[[AWAITABLE:.+]] = load ptr, ptr %[[AWAITABLE_TMP]] + // CHECK: %[[FRAME:.+]] = load ptr, ptr %[[FRAME_TMP]] + // CHECK: call ptr @_ZNSt16coroutine_handleINSt16coroutine_traitsIJvEE12promise_typeEE12from_addressEPv(ptr %[[FRAME]]) + // ... many lines of code to coerce coroutine_handle into an ptr scalar + // CHECK: %[[CH:.+]] = load ptr, ptr %{{.+}} + // CHECK-NEXT: %[[RESULT:.+]] = call ptr @_ZN13TailCallAwait13await_suspendESt16coroutine_handleIvE(ptr {{[^,]*}} %[[AWAITABLE]], ptr %[[CH]]) + // CHECK-NEXT: %[[COERCE:.+]] = getelementptr inbounds %"struct.std::coroutine_handle", ptr %[[TMP:.+]], i32 0, i32 0 + // CHECK-NEXT: store ptr %[[RESULT]], ptr %[[COERCE]] + // CHECK-NEXT: %[[ADDR:.+]] = call ptr @_ZNSt16coroutine_handleIvE7addressEv(ptr {{[^,]*}} %[[TMP]]) + // CHECK-NEXT: ret ptr %[[ADDR]] } diff --git a/clang/test/CodeGenCoroutines/coro-awaiter-noinline-suspend.cpp b/clang/test/CodeGenCoroutines/coro-awaiter-noinline-suspend.cpp deleted file mode 100644 index f95286faf46ec8ddc317723e72d104401406e004..0000000000000000000000000000000000000000 --- a/clang/test/CodeGenCoroutines/coro-awaiter-noinline-suspend.cpp +++ /dev/null @@ -1,168 +0,0 @@ -// Tests that we can mark await-suspend as noinline correctly. -// -// RUN: %clang_cc1 -std=c++20 -triple x86_64-unknown-linux-gnu -emit-llvm -o - %s \ -// RUN: -O1 -disable-llvm-passes | FileCheck %s - -#include "Inputs/coroutine.h" - -struct Task { - struct promise_type { - struct FinalAwaiter { - bool await_ready() const noexcept { return false; } - template - std::coroutine_handle<> await_suspend(std::coroutine_handle h) noexcept { - return h.promise().continuation; - } - void await_resume() noexcept {} - }; - - Task get_return_object() noexcept { - return std::coroutine_handle::from_promise(*this); - } - - std::suspend_always initial_suspend() noexcept { return {}; } - FinalAwaiter final_suspend() noexcept { return {}; } - void unhandled_exception() noexcept {} - void return_void() noexcept {} - - std::coroutine_handle<> continuation; - }; - - Task(std::coroutine_handle handle); - ~Task(); - -private: - std::coroutine_handle handle; -}; - -struct StatefulAwaiter { - int value; - bool await_ready() const noexcept { return false; } - template - void await_suspend(std::coroutine_handle h) noexcept {} - void await_resume() noexcept {} -}; - -typedef std::suspend_always NoStateAwaiter; -using AnotherStatefulAwaiter = StatefulAwaiter; - -template -struct TemplatedAwaiter { - T value; - bool await_ready() const noexcept { return false; } - template - void await_suspend(std::coroutine_handle h) noexcept {} - void await_resume() noexcept {} -}; - - -class Awaitable {}; -StatefulAwaiter operator co_await(Awaitable) { - return StatefulAwaiter{}; -} - -StatefulAwaiter GlobalAwaiter; -class Awaitable2 {}; -StatefulAwaiter& operator co_await(Awaitable2) { - return GlobalAwaiter; -} - -struct AlwaysInlineStatefulAwaiter { - void* value; - bool await_ready() const noexcept { return false; } - - template - __attribute__((always_inline)) - void await_suspend(std::coroutine_handle h) noexcept {} - - void await_resume() noexcept {} -}; - -Task testing() { - co_await std::suspend_always{}; - co_await StatefulAwaiter{}; - co_await AnotherStatefulAwaiter{}; - - // Test lvalue case. - StatefulAwaiter awaiter; - co_await awaiter; - - // The explicit call to await_suspend is not considered suspended. - awaiter.await_suspend(std::coroutine_handle::from_address(nullptr)); - - co_await TemplatedAwaiter{}; - TemplatedAwaiter TemplatedAwaiterInstace; - co_await TemplatedAwaiterInstace; - - co_await Awaitable{}; - co_await Awaitable2{}; - - co_await AlwaysInlineStatefulAwaiter{}; -} - -struct AwaitTransformTask { - struct promise_type { - struct FinalAwaiter { - bool await_ready() const noexcept { return false; } - template - std::coroutine_handle<> await_suspend(std::coroutine_handle h) noexcept { - return h.promise().continuation; - } - void await_resume() noexcept {} - }; - - AwaitTransformTask get_return_object() noexcept { - return std::coroutine_handle::from_promise(*this); - } - - std::suspend_always initial_suspend() noexcept { return {}; } - FinalAwaiter final_suspend() noexcept { return {}; } - void unhandled_exception() noexcept {} - void return_void() noexcept {} - - template - auto await_transform(Awaitable &&awaitable) { - return awaitable; - } - - std::coroutine_handle<> continuation; - }; - - AwaitTransformTask(std::coroutine_handle handle); - ~AwaitTransformTask(); - -private: - std::coroutine_handle handle; -}; - -struct awaitableWithGetAwaiter { - bool await_ready() const noexcept { return false; } - template - void await_suspend(std::coroutine_handle h) noexcept {} - void await_resume() noexcept {} -}; - -AwaitTransformTask testingWithAwaitTransform() { - co_await awaitableWithGetAwaiter{}; -} - -// CHECK: define{{.*}}@_ZNSt14suspend_always13await_suspendESt16coroutine_handleIvE{{.*}}#[[NORMAL_ATTR:[0-9]+]] - -// CHECK: define{{.*}}@_ZN15StatefulAwaiter13await_suspendIN4Task12promise_typeEEEvSt16coroutine_handleIT_E{{.*}}#[[NOINLINE_ATTR:[0-9]+]] - -// CHECK: define{{.*}}@_ZN15StatefulAwaiter13await_suspendIvEEvSt16coroutine_handleIT_E{{.*}}#[[NORMAL_ATTR]] - -// CHECK: define{{.*}}@_ZN16TemplatedAwaiterIiE13await_suspendIN4Task12promise_typeEEEvSt16coroutine_handleIT_E{{.*}}#[[NOINLINE_ATTR]] - -// CHECK: define{{.*}}@_ZN27AlwaysInlineStatefulAwaiter13await_suspendIN4Task12promise_typeEEEvSt16coroutine_handleIT_E{{.*}}#[[ALWAYS_INLINE_ATTR:[0-9]+]] - -// CHECK: define{{.*}}@_ZN4Task12promise_type12FinalAwaiter13await_suspendIS0_EESt16coroutine_handleIvES3_IT_E{{.*}}#[[NORMAL_ATTR]] - -// CHECK: define{{.*}}@_ZN23awaitableWithGetAwaiter13await_suspendIN18AwaitTransformTask12promise_typeEEEvSt16coroutine_handleIT_E{{.*}}#[[NORMAL_ATTR]] - -// CHECK: define{{.*}}@_ZN18AwaitTransformTask12promise_type12FinalAwaiter13await_suspendIS0_EESt16coroutine_handleIvES3_IT_E{{.*}}#[[NORMAL_ATTR]] - -// CHECK-NOT: attributes #[[NORMAL_ATTR]] = noinline -// CHECK: attributes #[[NOINLINE_ATTR]] = {{.*}}noinline -// CHECK-NOT: attributes #[[ALWAYS_INLINE_ATTR]] = {{.*}}noinline -// CHECK: attributes #[[ALWAYS_INLINE_ATTR]] = {{.*}}alwaysinline diff --git a/clang/test/CodeGenCoroutines/coro-dwarf.cpp b/clang/test/CodeGenCoroutines/coro-dwarf.cpp index 7914babe5483a4597d9c954b9c26759b82ffa45b..2c9c827e6753d68e8a0e71449b896ab2df1ee453 100644 --- a/clang/test/CodeGenCoroutines/coro-dwarf.cpp +++ b/clang/test/CodeGenCoroutines/coro-dwarf.cpp @@ -70,3 +70,15 @@ void f_coro(int val, MoveOnly moParam, MoveAndCopy mcParam) { // CHECK: !{{[0-9]+}} = !DILocalVariable(name: "moParam", arg: 2, scope: ![[SP]], file: !{{[0-9]+}}, line: {{[0-9]+}}, type: !{{[0-9]+}}) // CHECK: !{{[0-9]+}} = !DILocalVariable(name: "mcParam", arg: 3, scope: ![[SP]], file: !{{[0-9]+}}, line: {{[0-9]+}}, type: !{{[0-9]+}}) // CHECK: !{{[0-9]+}} = !DILocalVariable(name: "__promise", + +// CHECK: !{{[0-9]+}} = distinct !DISubprogram(linkageName: "__await_suspend_wrapper__Z6f_coroi8MoveOnly11MoveAndCopy_init" +// CHECK-NEXT: !{{[0-9]+}} = !DIFile +// CHECK-NEXT: !{{[0-9]+}} = !DISubroutineType +// CHECK-NEXT: !{{[0-9]+}} = !DILocalVariable(arg: 1, +// CHECK-NEXT: !{{[0-9]+}} = !DILocation +// CHECK-NEXT: !{{[0-9]+}} = !DILocalVariable(arg: 2, + +// CHECK: !{{[0-9]+}} = distinct !DISubprogram(linkageName: "__await_suspend_wrapper__Z6f_coroi8MoveOnly11MoveAndCopy_final" +// CHECK-NEXT: !{{[0-9]+}} = !DILocalVariable(arg: 1, +// CHECK-NEXT: !{{[0-9]+}} = !DILocation +// CHECK-NEXT: !{{[0-9]+}} = !DILocalVariable(arg: 2, diff --git a/clang/test/CodeGenCoroutines/coro-function-try-block.cpp b/clang/test/CodeGenCoroutines/coro-function-try-block.cpp index f609eb55b8e771ffd64a1629e5c97f03e7f9c2b4..b7a796cc241af4bca3d378d0095843e0463fe281 100644 --- a/clang/test/CodeGenCoroutines/coro-function-try-block.cpp +++ b/clang/test/CodeGenCoroutines/coro-function-try-block.cpp @@ -19,5 +19,5 @@ task f() try { } // CHECK-LABEL: define{{.*}} void @_Z1fv( -// CHECK: call void @_ZNSt13suspend_never13await_suspendESt16coroutine_handleIvE( +// CHECK: call void @llvm.coro.await.suspend.void( // CHECK: call void @_ZN4task12promise_type11return_voidEv( diff --git a/clang/test/CodeGenCoroutines/coro-symmetric-transfer-01.cpp b/clang/test/CodeGenCoroutines/coro-symmetric-transfer-01.cpp index c0b9e9ee2c55818fcc8189e2611ba91ff4a706d5..da30e12c63cffb2d1e3038969ba03087d633d7d5 100644 --- a/clang/test/CodeGenCoroutines/coro-symmetric-transfer-01.cpp +++ b/clang/test/CodeGenCoroutines/coro-symmetric-transfer-01.cpp @@ -50,10 +50,5 @@ detached_task foo() { // check that the lifetime of the coroutine handle used to obtain the address is contained within single basic block, and hence does not live across suspension points. // CHECK-LABEL: final.suspend: // CHECK: %{{.+}} = call token @llvm.coro.save(ptr null) -// CHECK: call void @llvm.lifetime.start.p0(i64 8, ptr %[[HDL:.+]]) -// CHECK: %[[CALL:.+]] = call ptr @_ZN13detached_task12promise_type13final_awaiter13await_suspendESt16coroutine_handleIS0_E( -// CHECK: %[[HDL_CAST2:.+]] = getelementptr inbounds %"struct.std::coroutine_handle.0", ptr %[[HDL]], i32 0, i32 0 -// CHECK: store ptr %[[CALL]], ptr %[[HDL_CAST2]], align 8 -// CHECK: %[[HDL_TRANSFER:.+]] = call noundef ptr @_ZNKSt16coroutine_handleIvE7addressEv(ptr noundef {{.*}}%[[HDL]]) -// CHECK: call void @llvm.lifetime.end.p0(i64 8, ptr %[[HDL]]) +// CHECK: %[[HDL_TRANSFER:.+]] = call ptr @llvm.coro.await.suspend.handle // CHECK: call void @llvm.coro.resume(ptr %[[HDL_TRANSFER]]) diff --git a/clang/test/CodeGenCoroutines/coro-symmetric-transfer-02.cpp b/clang/test/CodeGenCoroutines/coro-symmetric-transfer-02.cpp index 890d55e41de95380c7ad53265d19af2a1de79f4a..ca6cf74115a3b1e434e9c2b95b17be8c856f76fb 100644 --- a/clang/test/CodeGenCoroutines/coro-symmetric-transfer-02.cpp +++ b/clang/test/CodeGenCoroutines/coro-symmetric-transfer-02.cpp @@ -89,10 +89,8 @@ Task bar() { // CHECK: br i1 %{{.+}}, label %[[CASE1_AWAIT_READY:.+]], label %[[CASE1_AWAIT_SUSPEND:.+]] // CHECK: [[CASE1_AWAIT_SUSPEND]]: // CHECK-NEXT: %{{.+}} = call token @llvm.coro.save(ptr null) -// CHECK-NEXT: call void @llvm.lifetime.start.p0(i64 8, ptr %[[TMP1:.+]]) - -// CHECK: call void @llvm.lifetime.end.p0(i64 8, ptr %[[TMP1]]) -// CHECK-NEXT: call void @llvm.coro.resume +// CHECK-NEXT: %[[HANDLE1_PTR:.+]] = call ptr @llvm.coro.await.suspend.handle +// CHECK-NEXT: call void @llvm.coro.resume(ptr %[[HANDLE1_PTR]]) // CHECK-NEXT: %{{.+}} = call i8 @llvm.coro.suspend // CHECK-NEXT: switch i8 %{{.+}}, label %coro.ret [ // CHECK-NEXT: i8 0, label %[[CASE1_AWAIT_READY]] @@ -106,10 +104,8 @@ Task bar() { // CHECK: br i1 %{{.+}}, label %[[CASE2_AWAIT_READY:.+]], label %[[CASE2_AWAIT_SUSPEND:.+]] // CHECK: [[CASE2_AWAIT_SUSPEND]]: // CHECK-NEXT: %{{.+}} = call token @llvm.coro.save(ptr null) -// CHECK-NEXT: call void @llvm.lifetime.start.p0(i64 8, ptr %[[TMP2:.+]]) - -// CHECK: call void @llvm.lifetime.end.p0(i64 8, ptr %[[TMP2]]) -// CHECK-NEXT: call void @llvm.coro.resume +// CHECK-NEXT: %[[HANDLE2_PTR:.+]] = call ptr @llvm.coro.await.suspend.handle +// CHECK-NEXT: call void @llvm.coro.resume(ptr %[[HANDLE2_PTR]]) // CHECK-NEXT: %{{.+}} = call i8 @llvm.coro.suspend // CHECK-NEXT: switch i8 %{{.+}}, label %coro.ret [ // CHECK-NEXT: i8 0, label %[[CASE2_AWAIT_READY]] diff --git a/clang/test/CodeGenCoroutines/pr56329.cpp b/clang/test/CodeGenCoroutines/pr56329.cpp index 31d4849af4e71efd00ccb985d74e09d02d8f2579..ad8b1b990179c949207803ca457fda14d6e313e9 100644 --- a/clang/test/CodeGenCoroutines/pr56329.cpp +++ b/clang/test/CodeGenCoroutines/pr56329.cpp @@ -115,5 +115,9 @@ Task Outer() { // CHECK-NOT: _exit // CHECK: musttail call // CHECK: musttail call +// CHECK: musttail call // CHECK-NEXT: ret void +// CHECK-EMPTY: +// CHECK-NEXT: unreachable: +// CHECK-NEXT: unreachable // CHECK-NEXT: } diff --git a/clang/test/CodeGenCoroutines/pr59181.cpp b/clang/test/CodeGenCoroutines/pr59181.cpp index 80f4634db25214663eb7af7cd8b8bdd9e71252d8..21e784e0031de33d52357982086907514039fcf3 100644 --- a/clang/test/CodeGenCoroutines/pr59181.cpp +++ b/clang/test/CodeGenCoroutines/pr59181.cpp @@ -52,9 +52,8 @@ void foo() { // CHECK-NEXT: load i8 // CHECK-NEXT: trunc // CHECK-NEXT: store i1 false -// CHECK-NEXT: call void @llvm.lifetime.start.p0(i64 8, ptr [[REF:%ref.tmp[0-9]+]]) // CHECK: await.suspend:{{.*}} -// CHECK-NOT: call void @llvm.lifetime.start.p0(i64 8, ptr [[REF]]) -// CHECK: call void @_ZZN4Task12promise_type15await_transformES_EN10Suspension13await_suspendESt16coroutine_handleIvE -// CHECK-NEXT: call void @llvm.lifetime.end.p0(i64 8, ptr [[REF]]) +// CHECK-NOT: call void @llvm.lifetime +// CHECK: call void @llvm.coro.await.suspend.void( +// CHECK-NEXT: %{{[0-9]+}} = call i8 @llvm.coro.suspend( diff --git a/clang/test/CodeGenCoroutines/pr65054.cpp b/clang/test/CodeGenCoroutines/pr65054.cpp index 834b71050f59ffaf66ad7c2967077ee04c20d6bb..7af9c04fca180e725cdf8fe58bf47d60416e1bcf 100644 --- a/clang/test/CodeGenCoroutines/pr65054.cpp +++ b/clang/test/CodeGenCoroutines/pr65054.cpp @@ -1,7 +1,3 @@ -// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -std=c++20 \ -// RUN: -O0 -disable-llvm-passes -emit-llvm %s -o - \ -// RUN: | FileCheck %s --check-prefix=FRONTEND - // The output of O0 is highly redundant and hard to test. Also it is not good // limit the output of O0. So we test the optimized output from O0. The idea // is the optimizations shouldn't change the semantics of the program. @@ -51,10 +47,7 @@ MyTask FooBar() { } } -// FRONTEND: define{{.*}}@_ZNKSt16coroutine_handleIvE7addressEv{{.*}}#[[address_attr:[0-9]+]] -// FRONTEND: attributes #[[address_attr]] = {{.*}}alwaysinline - // CHECK-O0: define{{.*}}@_Z6FooBarv.resume -// CHECK-O0: call{{.*}}@_ZN7Awaiter13await_suspendESt16coroutine_handleIvE +// CHECK-O0: call{{.*}}@__await_suspend_wrapper__Z6FooBarv_await( // CHECK-O0-NOT: store // CHECK-O0: ret void diff --git a/clang/test/CodeGenHLSL/builtins/clamp-builtin.hlsl b/clang/test/CodeGenHLSL/builtins/clamp-builtin.hlsl new file mode 100644 index 0000000000000000000000000000000000000000..e3ef26429e7e40f00d2dc482a521d4f71d5218b8 --- /dev/null +++ b/clang/test/CodeGenHLSL/builtins/clamp-builtin.hlsl @@ -0,0 +1,8 @@ +// RUN: %clang_cc1 -finclude-default-header -x hlsl -triple dxil-pc-shadermodel6.3-library %s -fnative-half-type -emit-llvm -disable-llvm-passes -o - | FileCheck %s + +// CHECK-LABEL: builtin_test_clamp_int4 +// CHECK: %dx.clamp = call <4 x i32> @llvm.dx.clamp.v4i32(<4 x i32> %0, <4 x i32> %1, <4 x i32> %2) +// CHECK: ret <4 x i32> %dx.clamp +int4 builtin_test_clamp_int4(int4 p0, int4 p1, int4 p2) { + return __builtin_hlsl_elementwise_clamp(p0, p1, p2); +} diff --git a/clang/test/CodeGenHLSL/builtins/clamp.hlsl b/clang/test/CodeGenHLSL/builtins/clamp.hlsl new file mode 100644 index 0000000000000000000000000000000000000000..029e48ffe25865fb51a0872b2a7be93375e52a3f --- /dev/null +++ b/clang/test/CodeGenHLSL/builtins/clamp.hlsl @@ -0,0 +1,134 @@ +// RUN: %clang_cc1 -std=hlsl2021 -finclude-default-header -x hlsl -triple \ +// RUN: dxil-pc-shadermodel6.3-library %s -fnative-half-type \ +// RUN: -emit-llvm -disable-llvm-passes -o - | FileCheck %s \ +// RUN: --check-prefixes=CHECK,NATIVE_HALF +// RUN: %clang_cc1 -std=hlsl2021 -finclude-default-header -x hlsl -triple \ +// RUN: dxil-pc-shadermodel6.3-library %s -emit-llvm -disable-llvm-passes \ +// RUN: -o - | FileCheck %s --check-prefixes=CHECK,NO_HALF + +#ifdef __HLSL_ENABLE_16_BIT +// NATIVE_HALF: define noundef i16 @ +// NATIVE_HALF: call i16 @llvm.dx.clamp.i16( +int16_t test_clamp_short(int16_t p0, int16_t p1) { return clamp(p0, p1,p1); } +// NATIVE_HALF: define noundef <2 x i16> @ +// NATIVE_HALF: call <2 x i16> @llvm.dx.clamp.v2i16( +int16_t2 test_clamp_short2(int16_t2 p0, int16_t2 p1) { return clamp(p0, p1,p1); } +// NATIVE_HALF: define noundef <3 x i16> @ +// NATIVE_HALF: call <3 x i16> @llvm.dx.clamp.v3i16 +int16_t3 test_clamp_short3(int16_t3 p0, int16_t3 p1) { return clamp(p0, p1,p1); } +// NATIVE_HALF: define noundef <4 x i16> @ +// NATIVE_HALF: call <4 x i16> @llvm.dx.clamp.v4i16 +int16_t4 test_clamp_short4(int16_t4 p0, int16_t4 p1) { return clamp(p0, p1,p1); } + +// NATIVE_HALF: define noundef i16 @ +// NATIVE_HALF: call i16 @llvm.dx.uclamp.i16( +uint16_t test_clamp_ushort(uint16_t p0, uint16_t p1) { return clamp(p0, p1,p1); } +// NATIVE_HALF: define noundef <2 x i16> @ +// NATIVE_HALF: call <2 x i16> @llvm.dx.uclamp.v2i16 +uint16_t2 test_clamp_ushort2(uint16_t2 p0, uint16_t2 p1) { return clamp(p0, p1,p1); } +// NATIVE_HALF: define noundef <3 x i16> @ +// NATIVE_HALF: call <3 x i16> @llvm.dx.uclamp.v3i16 +uint16_t3 test_clamp_ushort3(uint16_t3 p0, uint16_t3 p1) { return clamp(p0, p1,p1); } +// NATIVE_HALF: define noundef <4 x i16> @ +// NATIVE_HALF: call <4 x i16> @llvm.dx.uclamp.v4i16 +uint16_t4 test_clamp_ushort4(uint16_t4 p0, uint16_t4 p1) { return clamp(p0, p1,p1); } +#endif + +// CHECK: define noundef i32 @ +// CHECK: call i32 @llvm.dx.clamp.i32( +int test_clamp_int(int p0, int p1) { return clamp(p0, p1,p1); } +// CHECK: define noundef <2 x i32> @ +// CHECK: call <2 x i32> @llvm.dx.clamp.v2i32 +int2 test_clamp_int2(int2 p0, int2 p1) { return clamp(p0, p1,p1); } +// CHECK: define noundef <3 x i32> @ +// CHECK: call <3 x i32> @llvm.dx.clamp.v3i32 +int3 test_clamp_int3(int3 p0, int3 p1) { return clamp(p0, p1,p1); } +// CHECK: define noundef <4 x i32> @ +// CHECK: call <4 x i32> @llvm.dx.clamp.v4i32 +int4 test_clamp_int4(int4 p0, int4 p1) { return clamp(p0, p1,p1); } + +// CHECK: define noundef i32 @ +// CHECK: call i32 @llvm.dx.uclamp.i32( +int test_clamp_uint(uint p0, uint p1) { return clamp(p0, p1,p1); } +// CHECK: define noundef <2 x i32> @ +// CHECK: call <2 x i32> @llvm.dx.uclamp.v2i32 +uint2 test_clamp_uint2(uint2 p0, uint2 p1) { return clamp(p0, p1,p1); } +// CHECK: define noundef <3 x i32> @ +// CHECK: call <3 x i32> @llvm.dx.uclamp.v3i32 +uint3 test_clamp_uint3(uint3 p0, uint3 p1) { return clamp(p0, p1,p1); } +// CHECK: define noundef <4 x i32> @ +// CHECK: call <4 x i32> @llvm.dx.uclamp.v4i32 +uint4 test_clamp_uint4(uint4 p0, uint4 p1) { return clamp(p0, p1,p1); } + +// CHECK: define noundef i64 @ +// CHECK: call i64 @llvm.dx.clamp.i64( +int64_t test_clamp_long(int64_t p0, int64_t p1) { return clamp(p0, p1,p1); } +// CHECK: define noundef <2 x i64> @ +// CHECK: call <2 x i64> @llvm.dx.clamp.v2i64 +int64_t2 test_clamp_long2(int64_t2 p0, int64_t2 p1) { return clamp(p0, p1,p1); } +// CHECK: define noundef <3 x i64> @ +// CHECK: call <3 x i64> @llvm.dx.clamp.v3i64 +int64_t3 test_clamp_long3(int64_t3 p0, int64_t3 p1) { return clamp(p0, p1,p1); } +// CHECK: define noundef <4 x i64> @ +// CHECK: call <4 x i64> @llvm.dx.clamp.v4i64 +int64_t4 test_clamp_long4(int64_t4 p0, int64_t4 p1) { return clamp(p0, p1,p1); } + +// CHECK: define noundef i64 @ +// CHECK: call i64 @llvm.dx.uclamp.i64( +uint64_t test_clamp_long(uint64_t p0, uint64_t p1) { return clamp(p0, p1,p1); } +// CHECK: define noundef <2 x i64> @ +// CHECK: call <2 x i64> @llvm.dx.uclamp.v2i64 +uint64_t2 test_clamp_long2(uint64_t2 p0, uint64_t2 p1) { return clamp(p0, p1,p1); } +// CHECK: define noundef <3 x i64> @ +// CHECK: call <3 x i64> @llvm.dx.uclamp.v3i64 +uint64_t3 test_clamp_long3(uint64_t3 p0, uint64_t3 p1) { return clamp(p0, p1,p1); } +// CHECK: define noundef <4 x i64> @ +// CHECK: call <4 x i64> @llvm.dx.uclamp.v4i64 +uint64_t4 test_clamp_long4(uint64_t4 p0, uint64_t4 p1) { return clamp(p0, p1,p1); } + +// NATIVE_HALF: define noundef half @ +// NATIVE_HALF: call half @llvm.dx.clamp.f16( +// NO_HALF: define noundef float @"?test_clamp_half +// NO_HALF: call float @llvm.dx.clamp.f32( +half test_clamp_half(half p0, half p1) { return clamp(p0, p1,p1); } +// NATIVE_HALF: define noundef <2 x half> @ +// NATIVE_HALF: call <2 x half> @llvm.dx.clamp.v2f16 +// NO_HALF: define noundef <2 x float> @"?test_clamp_half2 +// NO_HALF: call <2 x float> @llvm.dx.clamp.v2f32( +half2 test_clamp_half2(half2 p0, half2 p1) { return clamp(p0, p1,p1); } +// NATIVE_HALF: define noundef <3 x half> @ +// NATIVE_HALF: call <3 x half> @llvm.dx.clamp.v3f16 +// NO_HALF: define noundef <3 x float> @"?test_clamp_half3 +// NO_HALF: call <3 x float> @llvm.dx.clamp.v3f32( +half3 test_clamp_half3(half3 p0, half3 p1) { return clamp(p0, p1,p1); } +// NATIVE_HALF: define noundef <4 x half> @ +// NATIVE_HALF: call <4 x half> @llvm.dx.clamp.v4f16 +// NO_HALF: define noundef <4 x float> @"?test_clamp_half4 +// NO_HALF: call <4 x float> @llvm.dx.clamp.v4f32( +half4 test_clamp_half4(half4 p0, half4 p1) { return clamp(p0, p1,p1); } + +// CHECK: define noundef float @"?test_clamp_float +// CHECK: call float @llvm.dx.clamp.f32( +float test_clamp_float(float p0, float p1) { return clamp(p0, p1,p1); } +// CHECK: define noundef <2 x float> @"?test_clamp_float2 +// CHECK: call <2 x float> @llvm.dx.clamp.v2f32 +float2 test_clamp_float2(float2 p0, float2 p1) { return clamp(p0, p1,p1); } +// CHECK: define noundef <3 x float> @"?test_clamp_float3 +// CHECK: call <3 x float> @llvm.dx.clamp.v3f32 +float3 test_clamp_float3(float3 p0, float3 p1) { return clamp(p0, p1,p1); } +// CHECK: define noundef <4 x float> @"?test_clamp_float4 +// CHECK: call <4 x float> @llvm.dx.clamp.v4f32 +float4 test_clamp_float4(float4 p0, float4 p1) { return clamp(p0, p1,p1); } + +// CHECK: define noundef double @ +// CHECK: call double @llvm.dx.clamp.f64( +double test_clamp_double(double p0, double p1) { return clamp(p0, p1,p1); } +// CHECK: define noundef <2 x double> @ +// CHECK: call <2 x double> @llvm.dx.clamp.v2f64 +double2 test_clamp_double2(double2 p0, double2 p1) { return clamp(p0, p1,p1); } +// CHECK: define noundef <3 x double> @ +// CHECK: call <3 x double> @llvm.dx.clamp.v3f64 +double3 test_clamp_double3(double3 p0, double3 p1) { return clamp(p0, p1,p1); } +// CHECK: define noundef <4 x double> @ +// CHECK: call <4 x double> @llvm.dx.clamp.v4f64 +double4 test_clamp_double4(double4 p0, double4 p1) { return clamp(p0, p1,p1); } diff --git a/clang/test/CodeGenHLSL/builtins/isinf.hlsl b/clang/test/CodeGenHLSL/builtins/isinf.hlsl new file mode 100644 index 0000000000000000000000000000000000000000..df44fc4a91dfd014d6dc91e8e6aacd3bff5846cf --- /dev/null +++ b/clang/test/CodeGenHLSL/builtins/isinf.hlsl @@ -0,0 +1,45 @@ +// RUN: %clang_cc1 -finclude-default-header -x hlsl -triple \ +// RUN: dxil-pc-shadermodel6.3-library %s -fnative-half-type \ +// RUN: -emit-llvm -disable-llvm-passes -o - | FileCheck %s \ +// RUN: --check-prefixes=CHECK,NATIVE_HALF +// RUN: %clang_cc1 -finclude-default-header -x hlsl -triple \ +// RUN: dxil-pc-shadermodel6.3-library %s -emit-llvm -disable-llvm-passes \ +// RUN: -o - | FileCheck %s --check-prefixes=CHECK,NO_HALF + +// CHECK: define noundef i1 @ +// NATIVE_HALF: %dx.isinf = call i1 @llvm.dx.isinf.f16( +// NO_HALF: %dx.isinf = call i1 @llvm.dx.isinf.f32( +// CHECK: ret i1 %dx.isinf +bool test_isinf_half(half p0) { return isinf(p0); } +// CHECK: define noundef <2 x i1> @ +// NATIVE_HALF: %dx.isinf = call <2 x i1> @llvm.dx.isinf.v2f16 +// NO_HALF: %dx.isinf = call <2 x i1> @llvm.dx.isinf.v2f32( +// CHECK: ret <2 x i1> %dx.isinf +bool2 test_isinf_half2(half2 p0) { return isinf(p0); } +// NATIVE_HALF: define noundef <3 x i1> @ +// NATIVE_HALF: %dx.isinf = call <3 x i1> @llvm.dx.isinf.v3f16 +// NO_HALF: %dx.isinf = call <3 x i1> @llvm.dx.isinf.v3f32( +// CHECK: ret <3 x i1> %dx.isinf +bool3 test_isinf_half3(half3 p0) { return isinf(p0); } +// NATIVE_HALF: define noundef <4 x i1> @ +// NATIVE_HALF: %dx.isinf = call <4 x i1> @llvm.dx.isinf.v4f16 +// NO_HALF: %dx.isinf = call <4 x i1> @llvm.dx.isinf.v4f32( +// CHECK: ret <4 x i1> %dx.isinf +bool4 test_isinf_half4(half4 p0) { return isinf(p0); } + +// CHECK: define noundef i1 @ +// CHECK: %dx.isinf = call i1 @llvm.dx.isinf.f32( +// CHECK: ret i1 %dx.isinf +bool test_isinf_float(float p0) { return isinf(p0); } +// CHECK: define noundef <2 x i1> @ +// CHECK: %dx.isinf = call <2 x i1> @llvm.dx.isinf.v2f32 +// CHECK: ret <2 x i1> %dx.isinf +bool2 test_isinf_float2(float2 p0) { return isinf(p0); } +// CHECK: define noundef <3 x i1> @ +// CHECK: %dx.isinf = call <3 x i1> @llvm.dx.isinf.v3f32 +// CHECK: ret <3 x i1> %dx.isinf +bool3 test_isinf_float3(float3 p0) { return isinf(p0); } +// CHECK: define noundef <4 x i1> @ +// CHECK: %dx.isinf = call <4 x i1> @llvm.dx.isinf.v4f32 +// CHECK: ret <4 x i1> %dx.isinf +bool4 test_isinf_float4(float4 p0) { return isinf(p0); } diff --git a/clang/test/CodeGenHLSL/builtins/lerp-builtin.hlsl b/clang/test/CodeGenHLSL/builtins/lerp-builtin.hlsl index 1f16dec68212e49051ec86d7bec55220760c5cb9..2fd5a19fc33521641ef04a378b33eef7586f36a6 100644 --- a/clang/test/CodeGenHLSL/builtins/lerp-builtin.hlsl +++ b/clang/test/CodeGenHLSL/builtins/lerp-builtin.hlsl @@ -1,27 +1,5 @@ // RUN: %clang_cc1 -finclude-default-header -x hlsl -triple dxil-pc-shadermodel6.3-library %s -fnative-half-type -emit-llvm -disable-llvm-passes -o - | FileCheck %s - - -// CHECK-LABEL: builtin_lerp_half_scalar -// CHECK: %3 = fsub double %conv1, %conv -// CHECK: %4 = fmul double %conv2, %3 -// CHECK: %dx.lerp = fadd double %conv, %4 -// CHECK: %conv3 = fptrunc double %dx.lerp to half -// CHECK: ret half %conv3 -half builtin_lerp_half_scalar (half p0) { - return __builtin_hlsl_lerp ( p0, p0, p0 ); -} - -// CHECK-LABEL: builtin_lerp_float_scalar -// CHECK: %3 = fsub double %conv1, %conv -// CHECK: %4 = fmul double %conv2, %3 -// CHECK: %dx.lerp = fadd double %conv, %4 -// CHECK: %conv3 = fptrunc double %dx.lerp to float -// CHECK: ret float %conv3 -float builtin_lerp_float_scalar ( float p0) { - return __builtin_hlsl_lerp ( p0, p0, p0 ); -} - // CHECK-LABEL: builtin_lerp_half_vector // CHECK: %dx.lerp = call <3 x half> @llvm.dx.lerp.v3f16(<3 x half> %0, <3 x half> %1, <3 x half> %2) // CHECK: ret <3 x half> %dx.lerp diff --git a/clang/test/CodeGenHLSL/builtins/lerp.hlsl b/clang/test/CodeGenHLSL/builtins/lerp.hlsl index a6b3d9643d674ca840dcc317223f6d00251a8dc3..49cd04a10115aee13f70700baddee400b6013d62 100644 --- a/clang/test/CodeGenHLSL/builtins/lerp.hlsl +++ b/clang/test/CodeGenHLSL/builtins/lerp.hlsl @@ -6,13 +6,10 @@ // RUN: dxil-pc-shadermodel6.3-library %s -emit-llvm -disable-llvm-passes \ // RUN: -o - | FileCheck %s --check-prefixes=CHECK,NO_HALF -// NATIVE_HALF: %3 = fsub half %1, %0 -// NATIVE_HALF: %4 = fmul half %2, %3 -// NATIVE_HALF: %dx.lerp = fadd half %0, %4 + +// NATIVE_HALF: %dx.lerp = call half @llvm.dx.lerp.f16(half %0, half %1, half %2) // NATIVE_HALF: ret half %dx.lerp -// NO_HALF: %3 = fsub float %1, %0 -// NO_HALF: %4 = fmul float %2, %3 -// NO_HALF: %dx.lerp = fadd float %0, %4 +// NO_HALF: %dx.lerp = call float @llvm.dx.lerp.f32(float %0, float %1, float %2) // NO_HALF: ret float %dx.lerp half test_lerp_half(half p0) { return lerp(p0, p0, p0); } @@ -20,37 +17,35 @@ half test_lerp_half(half p0) { return lerp(p0, p0, p0); } // NATIVE_HALF: ret <2 x half> %dx.lerp // NO_HALF: %dx.lerp = call <2 x float> @llvm.dx.lerp.v2f32(<2 x float> %0, <2 x float> %1, <2 x float> %2) // NO_HALF: ret <2 x float> %dx.lerp -half2 test_lerp_half2(half2 p0, half2 p1) { return lerp(p0, p0, p0); } +half2 test_lerp_half2(half2 p0) { return lerp(p0, p0, p0); } // NATIVE_HALF: %dx.lerp = call <3 x half> @llvm.dx.lerp.v3f16(<3 x half> %0, <3 x half> %1, <3 x half> %2) // NATIVE_HALF: ret <3 x half> %dx.lerp // NO_HALF: %dx.lerp = call <3 x float> @llvm.dx.lerp.v3f32(<3 x float> %0, <3 x float> %1, <3 x float> %2) // NO_HALF: ret <3 x float> %dx.lerp -half3 test_lerp_half3(half3 p0, half3 p1) { return lerp(p0, p0, p0); } +half3 test_lerp_half3(half3 p0) { return lerp(p0, p0, p0); } // NATIVE_HALF: %dx.lerp = call <4 x half> @llvm.dx.lerp.v4f16(<4 x half> %0, <4 x half> %1, <4 x half> %2) // NATIVE_HALF: ret <4 x half> %dx.lerp // NO_HALF: %dx.lerp = call <4 x float> @llvm.dx.lerp.v4f32(<4 x float> %0, <4 x float> %1, <4 x float> %2) // NO_HALF: ret <4 x float> %dx.lerp -half4 test_lerp_half4(half4 p0, half4 p1) { return lerp(p0, p0, p0); } +half4 test_lerp_half4(half4 p0) { return lerp(p0, p0, p0); } -// CHECK: %3 = fsub float %1, %0 -// CHECK: %4 = fmul float %2, %3 -// CHECK: %dx.lerp = fadd float %0, %4 +// CHECK: %dx.lerp = call float @llvm.dx.lerp.f32(float %0, float %1, float %2) // CHECK: ret float %dx.lerp -float test_lerp_float(float p0, float p1) { return lerp(p0, p0, p0); } +float test_lerp_float(float p0) { return lerp(p0, p0, p0); } // CHECK: %dx.lerp = call <2 x float> @llvm.dx.lerp.v2f32(<2 x float> %0, <2 x float> %1, <2 x float> %2) // CHECK: ret <2 x float> %dx.lerp -float2 test_lerp_float2(float2 p0, float2 p1) { return lerp(p0, p0, p0); } +float2 test_lerp_float2(float2 p0) { return lerp(p0, p0, p0); } // CHECK: %dx.lerp = call <3 x float> @llvm.dx.lerp.v3f32(<3 x float> %0, <3 x float> %1, <3 x float> %2) // CHECK: ret <3 x float> %dx.lerp -float3 test_lerp_float3(float3 p0, float3 p1) { return lerp(p0, p0, p0); } +float3 test_lerp_float3(float3 p0) { return lerp(p0, p0, p0); } // CHECK: %dx.lerp = call <4 x float> @llvm.dx.lerp.v4f32(<4 x float> %0, <4 x float> %1, <4 x float> %2) // CHECK: ret <4 x float> %dx.lerp -float4 test_lerp_float4(float4 p0, float4 p1) { return lerp(p0, p0, p0); } +float4 test_lerp_float4(float4 p0) { return lerp(p0, p0, p0); } // CHECK: %dx.lerp = call <2 x float> @llvm.dx.lerp.v2f32(<2 x float> %splat.splat, <2 x float> %1, <2 x float> %2) // CHECK: ret <2 x float> %dx.lerp diff --git a/clang/test/CodeGenHLSL/builtins/rsqrt.hlsl b/clang/test/CodeGenHLSL/builtins/rsqrt.hlsl new file mode 100644 index 0000000000000000000000000000000000000000..c87a8c404b08e1e6eafaefcc01bbb8f65e9b0381 --- /dev/null +++ b/clang/test/CodeGenHLSL/builtins/rsqrt.hlsl @@ -0,0 +1,53 @@ +// RUN: %clang_cc1 -finclude-default-header -x hlsl -triple \ +// RUN: dxil-pc-shadermodel6.3-library %s -fnative-half-type \ +// RUN: -emit-llvm -disable-llvm-passes -o - | FileCheck %s \ +// RUN: --check-prefixes=CHECK,NATIVE_HALF +// RUN: %clang_cc1 -finclude-default-header -x hlsl -triple \ +// RUN: dxil-pc-shadermodel6.3-library %s -emit-llvm -disable-llvm-passes \ +// RUN: -o - | FileCheck %s --check-prefixes=CHECK,NO_HALF + +// NATIVE_HALF: define noundef half @ +// NATIVE_HALF: %dx.rsqrt = call half @llvm.dx.rsqrt.f16( +// NATIVE_HALF: ret half %dx.rsqrt +// NO_HALF: define noundef float @"?test_rsqrt_half@@YA$halff@$halff@@Z"( +// NO_HALF: %dx.rsqrt = call float @llvm.dx.rsqrt.f32( +// NO_HALF: ret float %dx.rsqrt +half test_rsqrt_half(half p0) { return rsqrt(p0); } +// NATIVE_HALF: define noundef <2 x half> @ +// NATIVE_HALF: %dx.rsqrt = call <2 x half> @llvm.dx.rsqrt.v2f16 +// NATIVE_HALF: ret <2 x half> %dx.rsqrt +// NO_HALF: define noundef <2 x float> @ +// NO_HALF: %dx.rsqrt = call <2 x float> @llvm.dx.rsqrt.v2f32( +// NO_HALF: ret <2 x float> %dx.rsqrt +half2 test_rsqrt_half2(half2 p0) { return rsqrt(p0); } +// NATIVE_HALF: define noundef <3 x half> @ +// NATIVE_HALF: %dx.rsqrt = call <3 x half> @llvm.dx.rsqrt.v3f16 +// NATIVE_HALF: ret <3 x half> %dx.rsqrt +// NO_HALF: define noundef <3 x float> @ +// NO_HALF: %dx.rsqrt = call <3 x float> @llvm.dx.rsqrt.v3f32( +// NO_HALF: ret <3 x float> %dx.rsqrt +half3 test_rsqrt_half3(half3 p0) { return rsqrt(p0); } +// NATIVE_HALF: define noundef <4 x half> @ +// NATIVE_HALF: %dx.rsqrt = call <4 x half> @llvm.dx.rsqrt.v4f16 +// NATIVE_HALF: ret <4 x half> %dx.rsqrt +// NO_HALF: define noundef <4 x float> @ +// NO_HALF: %dx.rsqrt = call <4 x float> @llvm.dx.rsqrt.v4f32( +// NO_HALF: ret <4 x float> %dx.rsqrt +half4 test_rsqrt_half4(half4 p0) { return rsqrt(p0); } + +// CHECK: define noundef float @ +// CHECK: %dx.rsqrt = call float @llvm.dx.rsqrt.f32( +// CHECK: ret float %dx.rsqrt +float test_rsqrt_float(float p0) { return rsqrt(p0); } +// CHECK: define noundef <2 x float> @ +// CHECK: %dx.rsqrt = call <2 x float> @llvm.dx.rsqrt.v2f32 +// CHECK: ret <2 x float> %dx.rsqrt +float2 test_rsqrt_float2(float2 p0) { return rsqrt(p0); } +// CHECK: define noundef <3 x float> @ +// CHECK: %dx.rsqrt = call <3 x float> @llvm.dx.rsqrt.v3f32 +// CHECK: ret <3 x float> %dx.rsqrt +float3 test_rsqrt_float3(float3 p0) { return rsqrt(p0); } +// CHECK: define noundef <4 x float> @ +// CHECK: %dx.rsqrt = call <4 x float> @llvm.dx.rsqrt.v4f32 +// CHECK: ret <4 x float> %dx.rsqrt +float4 test_rsqrt_float4(float4 p0) { return rsqrt(p0); } diff --git a/clang/test/CodeGenObjC/debug-info-blocks.m b/clang/test/CodeGenObjC/debug-info-blocks.m index 14b29f222fbe8ed31488092380e5e8c350c31929..59171da016da1e248efe05fc7a81732f4beb62d2 100644 --- a/clang/test/CodeGenObjC/debug-info-blocks.m +++ b/clang/test/CodeGenObjC/debug-info-blocks.m @@ -5,8 +5,8 @@ // CHECK: define {{.*}}_block_invoke // CHECK: store ptr %.block_descriptor, ptr %[[ALLOCA:block.addr]], align -// CHECK-NEXT: call void @llvm.dbg.declare(metadata ptr %[[ALLOCA]], metadata ![[SELF:[0-9]+]], metadata !{{.*}}) // CHECK-NEXT: call void @llvm.dbg.declare(metadata ptr %d, metadata ![[D:[0-9]+]], metadata !{{.*}}) +// CHECK-NEXT: call void @llvm.dbg.declare(metadata ptr %[[ALLOCA]], metadata ![[SELF:[0-9]+]], metadata !{{.*}}) // Test that we do emit scope info for the helper functions, and that the // parameters to these functions are marked as artificial (so the debugger diff --git a/clang/test/CodeGenOpenCL/amdgpu-attrs.cl b/clang/test/CodeGenOpenCL/amdgpu-attrs.cl index b0dfc97b53b2c5345773e8205bb87fcdf3685bf7..5648bc13458e1a09bfde3ba77a490e6e000ad037 100644 --- a/clang/test/CodeGenOpenCL/amdgpu-attrs.cl +++ b/clang/test/CodeGenOpenCL/amdgpu-attrs.cl @@ -139,6 +139,46 @@ kernel void reqd_work_group_size_32_2_1_flat_work_group_size_16_128() { // CHECK: define{{.*}} amdgpu_kernel void @reqd_work_group_size_32_2_1_flat_work_group_size_16_128() [[FLAT_WORK_GROUP_SIZE_16_128:#[0-9]+]] } +__attribute__((amdgpu_max_num_work_groups(1, 1, 1))) // expected-no-diagnostics +kernel void max_num_work_groups_1_1_1() { +// CHECK: define{{.*}} amdgpu_kernel void @max_num_work_groups_1_1_1() [[MAX_NUM_WORK_GROUPS_1_1_1:#[0-9]+]] +} + +__attribute__((amdgpu_max_num_work_groups(32, 1, 1))) // expected-no-diagnostics +kernel void max_num_work_groups_32_1_1() { +// CHECK: define{{.*}} amdgpu_kernel void @max_num_work_groups_32_1_1() [[MAX_NUM_WORK_GROUPS_32_1_1:#[0-9]+]] +} + +__attribute__((amdgpu_max_num_work_groups(32, 8, 1))) // expected-no-diagnostics +kernel void max_num_work_groups_32_8_1() { +// CHECK: define{{.*}} amdgpu_kernel void @max_num_work_groups_32_8_1() [[MAX_NUM_WORK_GROUPS_32_8_1:#[0-9]+]] +} + +__attribute__((amdgpu_max_num_work_groups(1, 1, 32))) // expected-no-diagnostics +kernel void max_num_work_groups_1_1_32() { +// CHECK: define{{.*}} amdgpu_kernel void @max_num_work_groups_1_1_32() [[MAX_NUM_WORK_GROUPS_1_1_32:#[0-9]+]] +} + +__attribute__((amdgpu_max_num_work_groups(1, 8, 32))) // expected-no-diagnostics +kernel void max_num_work_groups_1_8_32() { +// CHECK: define{{.*}} amdgpu_kernel void @max_num_work_groups_1_8_32() [[MAX_NUM_WORK_GROUPS_1_8_32:#[0-9]+]] +} + +__attribute__((amdgpu_max_num_work_groups(4, 8, 32))) // expected-no-diagnostics +kernel void max_num_work_groups_4_8_32() { +// CHECK: define{{.*}} amdgpu_kernel void @max_num_work_groups_4_8_32() [[MAX_NUM_WORK_GROUPS_4_8_32:#[0-9]+]] +} + +__attribute__((amdgpu_max_num_work_groups(32))) // expected-no-diagnostics +kernel void max_num_work_groups_32() { +// CHECK: define{{.*}} amdgpu_kernel void @max_num_work_groups_32() [[MAX_NUM_WORK_GROUPS_32_1_1:#[0-9]+]] +} + +__attribute__((amdgpu_max_num_work_groups(32,1))) // expected-no-diagnostics +kernel void max_num_work_groups_32_1() { +// CHECK: define{{.*}} amdgpu_kernel void @max_num_work_groups_32_1() [[MAX_NUM_WORK_GROUPS_32_1_1:#[0-9]+]] +} + void a_function() { // CHECK: define{{.*}} void @a_function() [[A_FUNCTION:#[0-9]+]] } @@ -189,5 +229,12 @@ kernel void default_kernel() { // CHECK-DAG: attributes [[FLAT_WORK_GROUP_SIZE_32_64_WAVES_PER_EU_2_NUM_SGPR_32_NUM_VGPR_64]] = {{.*}} "amdgpu-flat-work-group-size"="32,64" "amdgpu-num-sgpr"="32" "amdgpu-num-vgpr"="64" "amdgpu-waves-per-eu"="2" // CHECK-DAG: attributes [[FLAT_WORK_GROUP_SIZE_32_64_WAVES_PER_EU_2_4_NUM_SGPR_32_NUM_VGPR_64]] = {{.*}} "amdgpu-flat-work-group-size"="32,64" "amdgpu-num-sgpr"="32" "amdgpu-num-vgpr"="64" "amdgpu-waves-per-eu"="2,4" +// CHECK-DAG: attributes [[MAX_NUM_WORK_GROUPS_1_1_1]] = {{.*}} "amdgpu-max-num-workgroups"="1,1,1" +// CHECK-DAG: attributes [[MAX_NUM_WORK_GROUPS_32_1_1]] = {{.*}} "amdgpu-max-num-workgroups"="32,1,1" +// CHECK-DAG: attributes [[MAX_NUM_WORK_GROUPS_32_8_1]] = {{.*}} "amdgpu-max-num-workgroups"="32,8,1" +// CHECK-DAG: attributes [[MAX_NUM_WORK_GROUPS_1_1_32]] = {{.*}} "amdgpu-max-num-workgroups"="1,1,32" +// CHECK-DAG: attributes [[MAX_NUM_WORK_GROUPS_1_8_32]] = {{.*}} "amdgpu-max-num-workgroups"="1,8,32" +// CHECK-DAG: attributes [[MAX_NUM_WORK_GROUPS_4_8_32]] = {{.*}} "amdgpu-max-num-workgroups"="4,8,32" + // CHECK-DAG: attributes [[A_FUNCTION]] = {{.*}} // CHECK-DAG: attributes [[DEFAULT_KERNEL_ATTRS]] = {{.*}} "amdgpu-flat-work-group-size"="1,256" diff --git a/clang/test/Driver/apple-kext-mkernel.c b/clang/test/Driver/apple-kext-mkernel.c index f03ed4a09b47d3558fed7312b1ffa108df8cabfc..de905e169c139e4f9b177b4410952b1604ce0fde 100644 --- a/clang/test/Driver/apple-kext-mkernel.c +++ b/clang/test/Driver/apple-kext-mkernel.c @@ -13,8 +13,8 @@ // CHECK-X86-2: "-fno-rtti" // CHECK-X86-2-NOT: "-fno-common" -// RUN: not %clang -target x86_64-apple-darwin11 -arch armv7 -mkernel -mstrict-align -### -fsyntax-only %s 2>&1 | FileCheck --check-prefix=CHECK-ARM %s -// RUN: not %clang -target x86_64-apple-darwin11 -arch armv7 -mkernel -mstrict-align -### -fsyntax-only -fbuiltin -fno-builtin -fcommon -fno-common %s 2>&1 | FileCheck --check-prefix=CHECK-ARM %s +// RUN: %clang --target=x86_64-apple-darwin11 -arch armv7 -mkernel -mstrict-align -### -fsyntax-only %s 2>&1 | FileCheck --check-prefix=CHECK-ARM %s +// RUN: %clang --target=x86_64-apple-darwin11 -arch armv7 -mkernel -mstrict-align -### -fsyntax-only -fbuiltin -fno-builtin -fcommon -fno-common %s 2>&1 | FileCheck --check-prefix=CHECK-ARM %s // CHECK-ARM: "-target-feature" "+long-calls" // CHECK-ARM: "-target-feature" "+strict-align" diff --git a/clang/test/Driver/clang-g-opts.c b/clang/test/Driver/clang-g-opts.c index b73602a155b00947043731d9678d17d813a7e41d..fdbe0b96420c5193925567f4426a2de6add0ae5f 100644 --- a/clang/test/Driver/clang-g-opts.c +++ b/clang/test/Driver/clang-g-opts.c @@ -42,8 +42,3 @@ // CHECK-WITH-G-STANDALONE: "-debug-info-kind=standalone" // CHECK-WITH-G-STANDALONE: "-dwarf-version=2" - -/// TODO: Special case before R_RISCV_SET_ULEB128 linker support becomes more widely available. -// RUN: %clang -### -S %s -g --target=riscv64-linux-gnu 2>&1 | FileCheck --check-prefix=VERSION4 %s -// RUN: %clang -### -S %s -g --target=riscv64-unknown-elf 2>&1 | FileCheck --check-prefix=VERSION4 %s -// VERSION4: "-dwarf-version=4" diff --git a/clang/test/Driver/clang-offload-bundler-zlib.c b/clang/test/Driver/clang-offload-bundler-zlib.c index a57ee6da9a86a6d31ecb1091335a0acbb5ce8929..15b60341a8dbde372d010514a201a01a6fd609eb 100644 --- a/clang/test/Driver/clang-offload-bundler-zlib.c +++ b/clang/test/Driver/clang-offload-bundler-zlib.c @@ -1,4 +1,4 @@ -// REQUIRES: zlib +// REQUIRES: zlib && !zstd // REQUIRES: x86-registered-target // UNSUPPORTED: target={{.*}}-darwin{{.*}}, target={{.*}}-aix{{.*}} @@ -34,13 +34,28 @@ // RUN: diff %t.tgt2 %t.res.tgt2 // -// COMPRESS: Compression method used: -// DECOMPRESS: Decompression method: +// COMPRESS: Compression method used: zlib +// COMPRESS: Compression level: 6 +// DECOMPRESS: Decompression method: zlib +// DECOMPRESS: Hashes match: Yes // NOHOST-NOT: host- // NOHOST-DAG: hip-amdgcn-amd-amdhsa--gfx900 // NOHOST-DAG: hip-amdgcn-amd-amdhsa--gfx906 // +// Check -compression-level= option + +// RUN: clang-offload-bundler -type=bc -targets=hip-amdgcn-amd-amdhsa--gfx900,hip-amdgcn-amd-amdhsa--gfx906 \ +// RUN: -input=%t.tgt1 -input=%t.tgt2 -output=%t.hip.bundle.bc -compress -verbose -compression-level=9 2>&1 | \ +// RUN: FileCheck -check-prefix=LEVEL %s +// RUN: clang-offload-bundler -type=bc -targets=hip-amdgcn-amd-amdhsa--gfx900,hip-amdgcn-amd-amdhsa--gfx906 \ +// RUN: -output=%t.res.tgt1 -output=%t.res.tgt2 -input=%t.hip.bundle.bc -unbundle +// RUN: diff %t.tgt1 %t.res.tgt1 +// RUN: diff %t.tgt2 %t.res.tgt2 +// +// LEVEL: Compression method used: zlib +// LEVEL: Compression level: 9 + // // Check -bundle-align option. // diff --git a/clang/test/Driver/clang-offload-bundler-zstd.c b/clang/test/Driver/clang-offload-bundler-zstd.c index 3b577d4d166a3f5e8b6162d67bcb3f981ad4f9ae..4485e57309bbbc5b9489b496d5751b3ed783862a 100644 --- a/clang/test/Driver/clang-offload-bundler-zstd.c +++ b/clang/test/Driver/clang-offload-bundler-zstd.c @@ -31,13 +31,28 @@ // RUN: diff %t.tgt1 %t.res.tgt1 // RUN: diff %t.tgt2 %t.res.tgt2 // -// COMPRESS: Compression method used -// DECOMPRESS: Decompression method +// COMPRESS: Compression method used: zstd +// COMPRESS: Compression level: 3 +// DECOMPRESS: Decompression method: zstd +// DECOMPRESS: Hashes match: Yes // NOHOST-NOT: host- // NOHOST-DAG: hip-amdgcn-amd-amdhsa--gfx900 // NOHOST-DAG: hip-amdgcn-amd-amdhsa--gfx906 // +// Check -compression-level= option + +// RUN: clang-offload-bundler -type=bc -targets=hip-amdgcn-amd-amdhsa--gfx900,hip-amdgcn-amd-amdhsa--gfx906 \ +// RUN: -input=%t.tgt1 -input=%t.tgt2 -output=%t.hip.bundle.bc -compress -verbose -compression-level=9 2>&1 | \ +// RUN: FileCheck -check-prefix=LEVEL %s +// RUN: clang-offload-bundler -type=bc -targets=hip-amdgcn-amd-amdhsa--gfx900,hip-amdgcn-amd-amdhsa--gfx906 \ +// RUN: -output=%t.res.tgt1 -output=%t.res.tgt2 -input=%t.hip.bundle.bc -unbundle +// RUN: diff %t.tgt1 %t.res.tgt1 +// RUN: diff %t.tgt2 %t.res.tgt2 +// +// LEVEL: Compression method used: zstd +// LEVEL: Compression level: 9 + // // Check -bundle-align option. // diff --git a/clang/test/Driver/cuda-cross-compiling.c b/clang/test/Driver/cuda-cross-compiling.c index 086840accebe7f5623fd322e26927de323fa2b33..a1719a6fbe042b5f3b48bfaa4acc5e56ee69d9c6 100644 --- a/clang/test/Driver/cuda-cross-compiling.c +++ b/clang/test/Driver/cuda-cross-compiling.c @@ -80,11 +80,15 @@ // // RUN: not %clang -target nvptx64-nvidia-cuda %s -### 2>&1 \ // RUN: | FileCheck -check-prefix=MISSING %s +// 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' // RUN: %clang -target nvptx64-nvidia-cuda -flto -c %s -### 2>&1 \ // RUN: | FileCheck -check-prefix=GENERIC %s +// RUN: %clang -target nvptx64-nvidia-cuda -march=sm_52 -march=generic -flto -c %s -### 2>&1 \ +// RUN: | FileCheck -check-prefix=GENERIC %s // GENERIC-NOT: -cc1" "-triple" "nvptx64-nvidia-cuda" {{.*}} "-target-cpu" diff --git a/clang/test/Driver/hip-binding.hip b/clang/test/Driver/hip-binding.hip index 79ec2039edb74c573be10c77b99b757cab0a57e7..c116ad80a8ad80e53efa939e84f57f0662a62a34 100644 --- a/clang/test/Driver/hip-binding.hip +++ b/clang/test/Driver/hip-binding.hip @@ -65,9 +65,18 @@ // MULTI-D-ONLY-NEXT: # "amdgcn-amd-amdhsa" - "AMDGCN::Linker", inputs: ["[[GFX90a]]"], output: "[[GFX90a_OUT:.+]]" // // RUN: not %clang -### --target=x86_64-linux-gnu --offload-new-driver -ccc-print-bindings -nogpulib -nogpuinc \ -// RUN: --offload-arch=gfx90a --offload-arch=gfx908 --offload-device-only -c -o %t %s 2>&1 \ +// RUN: --no-gpu-bundle-output --offload-arch=gfx90a --offload-arch=gfx908 --offload-device-only -c -o %t %s 2>&1 \ +// RUN: | FileCheck -check-prefix=MULTI-D-ONLY-NO-BUNDLE-O %s +// MULTI-D-ONLY-NO-BUNDLE-O: error: cannot specify -o when generating multiple output files + +// RUN: %clang -### --target=x86_64-linux-gnu --offload-new-driver -ccc-print-bindings -nogpulib -nogpuinc \ +// RUN: --gpu-bundle-output --offload-arch=gfx90a --offload-arch=gfx908 --offload-device-only -c -o a.out %s 2>&1 \ // RUN: | FileCheck -check-prefix=MULTI-D-ONLY-O %s -// MULTI-D-ONLY-O: error: cannot specify -o when generating multiple output files +// MULTI-D-ONLY-O: "amdgcn-amd-amdhsa" - "clang", inputs: ["[[INPUT:.+]]"], output: "[[GFX908_OBJ:.+]]" +// MULTI-D-ONLY-O-NEXT: "amdgcn-amd-amdhsa" - "AMDGCN::Linker", inputs: ["[[GFX908_OBJ]]"], output: "[[GFX908:.+]]" +// MULTI-D-ONLY-O-NEXT: "amdgcn-amd-amdhsa" - "clang", inputs: ["[[INPUT]]"], output: "[[GFX90A_OBJ:.+]]" +// MULTI-D-ONLY-O-NEXT: "amdgcn-amd-amdhsa" - "AMDGCN::Linker", inputs: ["[[GFX90A_OBJ]]"], output: "[[GFX90A:.+]]" +// MULTI-D-ONLY-O-NEXT: "amdgcn-amd-amdhsa" - "AMDGCN::Linker", inputs: ["[[GFX908]]", "[[GFX90A]]"], output: "a.out" // // Check to ensure that we can use '-fsyntax-only' for HIP output with the new diff --git a/clang/test/Driver/hip-offload-compress-zlib.hip b/clang/test/Driver/hip-offload-compress-zlib.hip index 7a269c566bb93c183badbc2480edb8043bfb852b..c1566c5f192c2d5593e257917667b38ad40f3a4c 100644 --- a/clang/test/Driver/hip-offload-compress-zlib.hip +++ b/clang/test/Driver/hip-offload-compress-zlib.hip @@ -1,4 +1,4 @@ -// REQUIRES: zlib +// REQUIRES: zlib && !zstd // REQUIRES: x86-registered-target // REQUIRES: amdgpu-registered-target @@ -9,13 +9,14 @@ // RUN: -x hip --offload-arch=gfx1100 --offload-arch=gfx1101 \ // RUN: --no-offload-new-driver -fgpu-rdc -nogpuinc -nogpulib \ // RUN: %S/Inputs/hip_multiple_inputs/a.cu \ -// RUN: --offload-compress --offload-device-only --gpu-bundle-output \ +// RUN: --offload-compress --offload-compression-level=9 \ +// RUN: --offload-device-only --gpu-bundle-output \ // RUN: -o %t.bc \ // RUN: 2>&1 | FileCheck %s // CHECK: clang-offload-bundler{{.*}} -type=bc // CHECK-SAME: -targets={{.*}}hip-amdgcn-amd-amdhsa-gfx1100,hip-amdgcn-amd-amdhsa-gfx1101 -// CHECK-SAME: -compress -verbose +// CHECK-SAME: -compress -verbose -compression-level=9 // CHECK: Compressed bundle format // Test uncompress of bundled bitcode. diff --git a/clang/test/Driver/hip-offload-compress-zstd.hip b/clang/test/Driver/hip-offload-compress-zstd.hip index fa7fb3b6d5b5cb9fdd6904adeb44edef59ce8037..ede7d59f113c863dc2ecaee922d47fdade1179b7 100644 --- a/clang/test/Driver/hip-offload-compress-zstd.hip +++ b/clang/test/Driver/hip-offload-compress-zstd.hip @@ -9,13 +9,14 @@ // RUN: -x hip --offload-arch=gfx1100 --offload-arch=gfx1101 \ // RUN: --no-offload-new-driver -fgpu-rdc -nogpuinc -nogpulib \ // RUN: %S/Inputs/hip_multiple_inputs/a.cu \ -// RUN: --offload-compress --offload-device-only --gpu-bundle-output \ +// RUN: --offload-compress --offload-compression-level=9 \ +// RUN: --offload-device-only --gpu-bundle-output \ // RUN: -o %t.bc \ // RUN: 2>&1 | FileCheck %s // CHECK: clang-offload-bundler{{.*}} -type=bc // CHECK-SAME: -targets={{.*}}hip-amdgcn-amd-amdhsa-gfx1100,hip-amdgcn-amd-amdhsa-gfx1101 -// CHECK-SAME: -compress -verbose +// CHECK-SAME: -compress -verbose -compression-level=9 // CHECK: Compressed bundle format // Test uncompress of bundled bitcode. diff --git a/clang/test/Driver/linker-wrapper.c b/clang/test/Driver/linker-wrapper.c index 0e6fd80b4298465539a755ff6061535b36c8ca9f..cbf24d4ce3a8245c83204ee6e3eb637dd71169b1 100644 --- a/clang/test/Driver/linker-wrapper.c +++ b/clang/test/Driver/linker-wrapper.c @@ -114,12 +114,13 @@ __attribute__((visibility("protected"), used)) int x; // RUN: --image=file=%t.elf.o,kind=hip,triple=amdgcn-amd-amdhsa,arch=gfx908 // RUN: %clang -cc1 %s -triple x86_64-unknown-linux-gnu -emit-obj -o %t.o \ // RUN: -fembed-offload-object=%t.out -// RUN: clang-linker-wrapper --dry-run --host-triple=x86_64-unknown-linux-gnu --compress \ +// RUN: clang-linker-wrapper --dry-run --host-triple=x86_64-unknown-linux-gnu \ +// RUN: --compress --compression-level=6 \ // RUN: --linker-path=/usr/bin/ld %t.o -o a.out 2>&1 | FileCheck %s --check-prefix=HIP // HIP: clang{{.*}} -o [[IMG_GFX908:.+]] --target=amdgcn-amd-amdhsa -mcpu=gfx908 // HIP: clang{{.*}} -o [[IMG_GFX90A:.+]] --target=amdgcn-amd-amdhsa -mcpu=gfx90a -// HIP: clang-offload-bundler{{.*}}-type=o -bundle-align=4096 -compress -targets=host-x86_64-unknown-linux,hipv4-amdgcn-amd-amdhsa--gfx90a,hipv4-amdgcn-amd-amdhsa--gfx908 -input=/dev/null -input=[[IMG_GFX90A]] -input=[[IMG_GFX908]] -output={{.*}}.hipfb +// HIP: clang-offload-bundler{{.*}}-type=o -bundle-align=4096 -compress -compression-level=6 -targets=host-x86_64-unknown-linux,hipv4-amdgcn-amd-amdhsa--gfx90a,hipv4-amdgcn-amd-amdhsa--gfx908 -input=/dev/null -input=[[IMG_GFX90A]] -input=[[IMG_GFX908]] -output={{.*}}.hipfb // RUN: clang-offload-packager -o %t.out \ // RUN: --image=file=%t.elf.o,kind=openmp,triple=amdgcn-amd-amdhsa,arch=gfx908 \ diff --git a/clang/test/Driver/loongarch-munaligned-access.c b/clang/test/Driver/loongarch-munaligned-access.c index 44edb2eb17e6ab603136b1e0db795562194e0693..a545679949973a6e94910e9c1d8e0a79bfb173e6 100644 --- a/clang/test/Driver/loongarch-munaligned-access.c +++ b/clang/test/Driver/loongarch-munaligned-access.c @@ -1,54 +1,25 @@ /// Test -m[no-]unaligned-access and -m[no-]strict-align options. -// RUN: %clang --target=loongarch64 -munaligned-access -fsyntax-only %s -### 2>&1 | \ -// RUN: FileCheck %s --check-prefix=CC1-UNALIGNED -// RUN: %clang --target=loongarch64 -mno-unaligned-access -fsyntax-only %s -### 2>&1 | \ -// RUN: FileCheck %s --check-prefix=CC1-NO-UNALIGNED // RUN: %clang --target=loongarch64 -mstrict-align -fsyntax-only %s -### 2>&1 | \ // RUN: FileCheck %s --check-prefix=CC1-NO-UNALIGNED // RUN: %clang --target=loongarch64 -mno-strict-align -fsyntax-only %s -### 2>&1 | \ // RUN: FileCheck %s --check-prefix=CC1-UNALIGNED -// RUN: %clang --target=loongarch64 -munaligned-access -mno-unaligned-access -fsyntax-only %s -### 2>&1 | \ -// RUN: FileCheck %s --check-prefix=CC1-NO-UNALIGNED -// RUN: %clang --target=loongarch64 -mno-unaligned-access -munaligned-access -fsyntax-only %s -### 2>&1 | \ -// RUN: FileCheck %s --check-prefix=CC1-UNALIGNED // RUN: %clang --target=loongarch64 -mstrict-align -mno-strict-align -fsyntax-only %s -### 2>&1 | \ // RUN: FileCheck %s --check-prefix=CC1-UNALIGNED // RUN: %clang --target=loongarch64 -mno-strict-align -mstrict-align -fsyntax-only %s -### 2>&1 | \ // RUN: FileCheck %s --check-prefix=CC1-NO-UNALIGNED -// RUN: %clang --target=loongarch64 -munaligned-access -mstrict-align -fsyntax-only %s -### 2>&1 | \ -// RUN: FileCheck %s --check-prefix=CC1-NO-UNALIGNED -// RUN: %clang --target=loongarch64 -mstrict-align -munaligned-access -fsyntax-only %s -### 2>&1 | \ -// RUN: FileCheck %s --check-prefix=CC1-UNALIGNED -// RUN: %clang --target=loongarch64 -mno-unaligned-access -mno-strict-align -fsyntax-only %s -### 2>&1 | \ -// RUN: FileCheck %s --check-prefix=CC1-UNALIGNED -// RUN: %clang --target=loongarch64 -mno-strict-align -mno-unaligned-access -fsyntax-only %s -### 2>&1 | \ -// RUN: FileCheck %s --check-prefix=CC1-NO-UNALIGNED -// RUN: %clang --target=loongarch64 -munaligned-access -S -emit-llvm %s -o - | \ -// RUN: FileCheck %s --check-prefix=IR-UNALIGNED -// RUN: %clang --target=loongarch64 -mno-unaligned-access -S -emit-llvm %s -o - | \ -// RUN: FileCheck %s --check-prefix=IR-NO-UNALIGNED // RUN: %clang --target=loongarch64 -mstrict-align -S -emit-llvm %s -o - | \ // RUN: FileCheck %s --check-prefix=IR-NO-UNALIGNED // RUN: %clang --target=loongarch64 -mno-strict-align -S -emit-llvm %s -o - | \ // RUN: FileCheck %s --check-prefix=IR-UNALIGNED -// RUN: %clang --target=loongarch64 -munaligned-access -mno-unaligned-access -S -emit-llvm %s -o - | \ -// RUN: FileCheck %s --check-prefix=IR-NO-UNALIGNED -// RUN: %clang --target=loongarch64 -mno-unaligned-access -munaligned-access -S -emit-llvm %s -o - | \ -// RUN: FileCheck %s --check-prefix=IR-UNALIGNED // RUN: %clang --target=loongarch64 -mstrict-align -mno-strict-align -S -emit-llvm %s -o - | \ // RUN: FileCheck %s --check-prefix=IR-UNALIGNED // RUN: %clang --target=loongarch64 -mno-strict-align -mstrict-align -S -emit-llvm %s -o - | \ // RUN: FileCheck %s --check-prefix=IR-NO-UNALIGNED -// RUN: %clang --target=loongarch64 -munaligned-access -mstrict-align -S -emit-llvm %s -o - | \ -// RUN: FileCheck %s --check-prefix=IR-NO-UNALIGNED -// RUN: %clang --target=loongarch64 -mstrict-align -munaligned-access -S -emit-llvm %s -o - | \ -// RUN: FileCheck %s --check-prefix=IR-UNALIGNED -// RUN: %clang --target=loongarch64 -mno-unaligned-access -mno-strict-align -S -emit-llvm %s -o - | \ -// RUN: FileCheck %s --check-prefix=IR-UNALIGNED -// RUN: %clang --target=loongarch64 -mno-strict-align -mno-unaligned-access -S -emit-llvm %s -o - | \ -// RUN: FileCheck %s --check-prefix=IR-NO-UNALIGNED + +// RUN: not %clang -### --target=loongarch64 -mno-unaligned-access -munaligned-access %s 2>&1 | \ +// RUN: FileCheck %s --check-prefix=ERR // CC1-UNALIGNED: "-target-feature" "+ual" // CC1-NO-UNALIGNED: "-target-feature" "-ual" @@ -56,6 +27,9 @@ // IR-UNALIGNED: attributes #[[#]] ={{.*}}"target-features"="{{(.*,)?}}+ual{{(,.*)?}}" // IR-NO-UNALIGNED: attributes #[[#]] ={{.*}}"target-features"="{{(.*,)?}}-ual{{(,.*)?}}" +// ERR: error: unsupported option '-mno-unaligned-access' for target 'loongarch64' +// ERR: error: unsupported option '-munaligned-access' for target 'loongarch64' + int foo(void) { return 3; } diff --git a/clang/test/Driver/modules-print-library-module-manifest-path.cpp b/clang/test/Driver/modules-print-library-module-manifest-path.cpp new file mode 100644 index 0000000000000000000000000000000000000000..24797002b80f5303366ad9e8417d4f5b29e645a6 --- /dev/null +++ b/clang/test/Driver/modules-print-library-module-manifest-path.cpp @@ -0,0 +1,36 @@ +// Test that -print-library-module-manifest-path finds the correct file. + +// RUN: rm -rf %t && split-file %s %t && cd %t +// RUN: mkdir -p %t/Inputs/usr/lib/x86_64-linux-gnu +// RUN: touch %t/Inputs/usr/lib/x86_64-linux-gnu/libc++.so + +// RUN: %clang -print-library-module-manifest-path \ +// RUN: -stdlib=libc++ \ +// RUN: -resource-dir=%t/Inputs/usr/lib/x86_64-linux-gnu \ +// RUN: --target=x86_64-linux-gnu 2>&1 \ +// RUN: | FileCheck libcxx-no-module-json.cpp + +// RUN: touch %t/Inputs/usr/lib/x86_64-linux-gnu/modules.json +// RUN: %clang -print-library-module-manifest-path \ +// RUN: -stdlib=libc++ \ +// RUN: -resource-dir=%t/Inputs/usr/lib/x86_64-linux-gnu \ +// RUN: --target=x86_64-linux-gnu 2>&1 \ +// RUN: | FileCheck libcxx.cpp + +// RUN: %clang -print-library-module-manifest-path \ +// RUN: -stdlib=libstdc++ \ +// RUN: -resource-dir=%t/Inputs/usr/lib/x86_64-linux-gnu \ +// RUN: --target=x86_64-linux-gnu 2>&1 \ +// RUN: | FileCheck libstdcxx.cpp + +//--- libcxx-no-module-json.cpp + +// CHECK: + +//--- libcxx.cpp + +// CHECK: {{.*}}/Inputs/usr/lib/x86_64-linux-gnu{{/|\\}}modules.json + +//--- libstdcxx.cpp + +// CHECK: diff --git a/clang/test/Driver/munaligned-access-unused.c b/clang/test/Driver/munaligned-access-unused.c index 1d86edb798ef2dc232350e30e212e5aaf6fd10a8..4060b53c42fe5f478e6c9efc2b15308046baedf0 100644 --- a/clang/test/Driver/munaligned-access-unused.c +++ b/clang/test/Driver/munaligned-access-unused.c @@ -1,8 +1,9 @@ -/// Check -m[no-]unaligned-access and -m[no-]strict-align are warned unused on a target that does not support them. +/// Check -m[no-]unaligned-access and -m[no-]strict-align are errored on a target that does not support them. // RUN: not %clang --target=x86_64 -munaligned-access -fsyntax-only %s -### 2>&1 | FileCheck %s -DOPTION=unaligned-access // RUN: not %clang --target=x86_64 -mno-unaligned-access -fsyntax-only %s -### 2>&1 | FileCheck %s -DOPTION=no-unaligned-access -// RUN: not %clang --target=x86_64 -mstrict-align -fsyntax-only %s -### 2>&1 | FileCheck %s -DOPTION=strict-align -// RUN: not %clang --target=x86_64 -mno-strict-align -fsyntax-only %s -### 2>&1 | FileCheck %s -DOPTION=no-strict-align +// RUN: not %clang --target=x86_64 -mno-strict-align -mstrict-align -fsyntax-only %s -### 2>&1 | FileCheck %s --check-prefix=ALIGN // CHECK: error: unsupported option '-m{{(no-)?}}unaligned-access' for target '{{.*}}' +// ALIGN: error: unsupported option '-mno-strict-align' for target '{{.*}}' +// ALIGN: error: unsupported option '-mstrict-align' for target '{{.*}}' diff --git a/clang/test/Driver/range.c b/clang/test/Driver/range.c index 49116df2f4480ed002fca71a3ec934814dbcaef9..2d1fd7f9f1a9d53d573b30eed2b275263e704581 100644 --- a/clang/test/Driver/range.c +++ b/clang/test/Driver/range.c @@ -12,12 +12,23 @@ // RUN: %clang -### -target x86_64 -fcx-fortran-rules -c %s 2>&1 \ // RUN: | FileCheck --check-prefix=FRTRN %s +// RUN: %clang -### -target x86_64 -fcx-fortran-rules -c %s 2>&1 \ +// RUN: -fno-cx-fortran-rules | FileCheck --check-prefix=FULL %s + +// RUN: %clang -### -target x86_64 -fcx-fortran-rules -fno-cx-limited-range \ +// RUN: -c %s 2>&1 | FileCheck --check-prefix=WARN3 %s + // RUN: %clang -### -target x86_64 -fno-cx-fortran-rules -c %s 2>&1 \ // RUN: | FileCheck %s -// RUN: %clang -### -target x86_64 -fcx-limited-range \ -// RUN: -fcx-fortran-rules -c %s 2>&1 \ -// RUN: | FileCheck --check-prefix=WARN1 %s +// RUN: %clang -### -target x86_64 -fcx-limited-range -fcx-fortran-rules \ +// RUN: -c %s 2>&1 | FileCheck --check-prefix=WARN1 %s + +// RUN: %clang -### -target x86_64 -fcx-limited-range -fno-cx-fortran-rules \ +// RUN: -c %s 2>&1 | FileCheck --check-prefix=WARN4 %s + +// RUN: %clang -### -target x86_64 -fcx-limited-range -fno-cx-limited-range \ +// RUN: -c %s 2>&1 | FileCheck --check-prefix=FULL %s // RUN: %clang -### -target x86_64 -fcx-fortran-rules \ // RUN: -fcx-limited-range -c %s 2>&1 \ @@ -32,8 +43,8 @@ // RUN: %clang -### -target x86_64 -fcx-limited-range -ffast-math -c %s 2>&1 \ // RUN: | FileCheck --check-prefix=LMTD %s -// RUN: %clang -### -target x86_64 -ffast-math -fno-cx-limited-range -c %s 2>&1 \ -// RUN: | FileCheck --check-prefix=FULL %s +// RUN: %clang -### -target x86_64 -ffast-math -fno-cx-limited-range \ +// RUN: -c %s 2>&1 | FileCheck --check-prefix=FULL %s // RUN: %clang -### -Werror -target x86_64 -fcx-limited-range -c %s 2>&1 \ // RUN: | FileCheck --check-prefix=LMTD %s @@ -50,3 +61,5 @@ // CHECK-NOT: -complex-range=fortran // WARN1: warning: overriding '-fcx-limited-range' option with '-fcx-fortran-rules' [-Woverriding-option] // WARN2: warning: overriding '-fcx-fortran-rules' option with '-fcx-limited-range' [-Woverriding-option] +// WARN3: warning: overriding '-fcx-fortran-rules' option with '-fno-cx-limited-range' [-Woverriding-option] +// WARN4: warning: overriding '-fcx-limited-range' option with '-fno-cx-fortran-rules' [-Woverriding-option] diff --git a/clang/test/Driver/riscv-features.c b/clang/test/Driver/riscv-features.c index fc5fb0f27e3af4393f432fcb91e86676522c74fa..fe74ac773ef8ca8b064da87ffac1cb0d707baeea 100644 --- a/clang/test/Driver/riscv-features.c +++ b/clang/test/Driver/riscv-features.c @@ -33,8 +33,6 @@ // NO-FORCE-SW-SCS: "-target-feature" "-forced-sw-shadow-stack" // DEFAULT-NOT: "-target-feature" "+forced-sw-shadow-stack" -// RUN: %clang --target=riscv32-unknown-elf -### %s -munaligned-access 2>&1 | FileCheck %s -check-prefix=FAST-UNALIGNED-ACCESS -// RUN: %clang --target=riscv32-unknown-elf -### %s -mno-unaligned-access 2>&1 | FileCheck %s -check-prefix=NO-FAST-UNALIGNED-ACCESS // RUN: %clang --target=riscv32-unknown-elf -### %s -mno-strict-align 2>&1 | FileCheck %s -check-prefix=FAST-UNALIGNED-ACCESS // RUN: %clang --target=riscv32-unknown-elf -### %s -mstrict-align 2>&1 | FileCheck %s -check-prefix=NO-FAST-UNALIGNED-ACCESS diff --git a/clang/test/Driver/tls-dialect.c b/clang/test/Driver/tls-dialect.c index f73915b28ec2a301f8b8f32ece70e605cf0f80ca..a808dd81531ce72fe7bd61a8eefdac398ad03450 100644 --- a/clang/test/Driver/tls-dialect.c +++ b/clang/test/Driver/tls-dialect.c @@ -2,6 +2,7 @@ // RUN: %clang -### --target=riscv64-linux -mtls-dialect=trad %s 2>&1 | FileCheck --check-prefix=NODESC %s // RUN: %clang -### --target=riscv64-linux %s 2>&1 | FileCheck --check-prefix=NODESC %s // RUN: %clang -### --target=x86_64-linux -mtls-dialect=gnu %s 2>&1 | FileCheck --check-prefix=NODESC %s +// RUN: %clang -### --target=x86_64-linux -mtls-dialect=gnu2 %s 2>&1 | FileCheck --check-prefix=DESC %s /// Android supports TLSDESC by default on RISC-V /// TLSDESC is not on by default in Linux, even on RISC-V, and is covered above @@ -18,7 +19,6 @@ /// Unsupported argument // RUN: not %clang -### --target=riscv64-linux -mtls-dialect=gnu2 %s 2>&1 | FileCheck --check-prefix=UNSUPPORTED-ARG %s -// RUN: not %clang -### --target=x86_64-linux -mtls-dialect=gnu2 %s 2>&1 | FileCheck --check-prefix=UNSUPPORTED-ARG %s // DESC: "-cc1" {{.*}}"-enable-tlsdesc" // NODESC-NOT: "-enable-tlsdesc" diff --git a/clang/test/Driver/toc-conf.c b/clang/test/Driver/toc-conf.c new file mode 100644 index 0000000000000000000000000000000000000000..80d92ee1a90b4bcb29312613b20601e019ff229a --- /dev/null +++ b/clang/test/Driver/toc-conf.c @@ -0,0 +1,30 @@ +// RUN: %clang %s --target=powerpc-unknown-aix -mno-tocdata -mtocdata -mno-tocdata -### 2>&1 | FileCheck %s -check-prefix=CHECK-FLAG1 +// RUN: %clang %s --target=powerpc-unknown-aix -mno-tocdata -mtocdata -mno-tocdata -mtocdata -### 2>&1 | FileCheck %s -check-prefix=CHECK-FLAG2 +// RUN: %clang %s --target=powerpc-unknown-aix -mtocdata=g1,g2 -mno-tocdata=g2 -mtocdata=g3,g4 -mno-tocdata=g5,g1 -### 2>&1 | FileCheck %s -check-prefix=CHECK-EQCONF +// RUN: %clang %s --target=powerpc-unknown-aix -mtocdata=g1 -mtocdata -mno-tocdata -mtocdata=g2,g3 -mno-tocdata=g4,g5,g3 -### 2>&1 | FileCheck %s -check-prefix=CHECK-CONF1 +// RUN: %clang %s --target=powerpc-unknown-aix -mno-tocdata=g1 -mno-tocdata -mtocdata -### 2>&1 | FileCheck %s -check-prefix=CHECK-CONF2 + +int g1, g4, g5; +extern int g2; +int g3 = 0; +void func() { + g2 = 0; +} + +// CHECK-FLAG1-NOT: warning: +// CHECK-FLAG1: "-cc1"{{.*}}" "-mno-tocdata" + +// CHECK-FLAG2-NOT: warning: +// CHECK-FLAG2: "-cc1"{{.*}}" "-mtocdata" + +// CHECK-EQCONF-NOT: warning: +// CHECK-EQCONF: "-cc1"{{.*}}" "-mno-tocdata" +// CHECK-EQCONF: "-mtocdata=g3,g4" + +// CHECK-CONF1-NOT: warning: +// CHECK-CONF1: "-cc1"{{.*}}" "-mno-tocdata" +// CHECK-CONF1: "-mtocdata=g2,g1" + +// CHECK-CONF2-NOT: warning: +// CHECK-CONF2: "-cc1"{{.*}}" "-mtocdata" +// CHECK-CONF2: "-mno-tocdata=g1" diff --git a/clang/test/Driver/tocdata-cc1.c b/clang/test/Driver/tocdata-cc1.c new file mode 100644 index 0000000000000000000000000000000000000000..fe0d97ea02db1f549af1b1e81655593c3c0a5ffc --- /dev/null +++ b/clang/test/Driver/tocdata-cc1.c @@ -0,0 +1,16 @@ +// RUN: %clang -### --target=powerpc-ibm-aix-xcoff -mcmodel=medium -mtocdata %s 2>&1 \ +// RUN: | FileCheck -check-prefix=CHECK-NOTOC %s +// RUN: %clang -### --target=powerpc-ibm-aix-xcoff -mcmodel=large -mtocdata %s 2>&1 \ +// RUN: | FileCheck -check-prefix=CHECK-NOTOC %s +// RUN: %clang -### --target=powerpc-ibm-aix-xcoff -mtocdata %s 2>&1 \ +// RUN: | FileCheck -check-prefix=CHECK-TOC %s +// RUN: %clang -### --target=powerpc64-ibm-aix-xcoff -mcmodel=medium -mtocdata %s 2>&1 \ +// RUN: | FileCheck -check-prefix=CHECK-NOTOC %s +// RUN: %clang -### --target=powerpc64-ibm-aix-xcoff -mcmodel=large -mtocdata %s 2>&1 \ +// RUN: | FileCheck -check-prefix=CHECK-NOTOC %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 diff --git a/clang/test/Headers/__clang_hip_math.hip b/clang/test/Headers/__clang_hip_math.hip index 37099de74fb8ecf29d2bc69b9ee469573ee3c2ff..701f93853ab93c5b82bdca90d81cee469d776bb7 100644 --- a/clang/test/Headers/__clang_hip_math.hip +++ b/clang/test/Headers/__clang_hip_math.hip @@ -1685,7 +1685,7 @@ extern "C" __device__ double test_j1(double x) { // DEFAULT-NEXT: [[__X1_0_I3:%.*]] = phi float [ [[SUB_I:%.*]], [[FOR_BODY_I]] ], [ [[CALL_I21_I]], [[IF_END4_I]] ] // DEFAULT-NEXT: [[__X0_0_I2:%.*]] = phi float [ [[__X1_0_I3]], [[FOR_BODY_I]] ], [ [[CALL_I_I]], [[IF_END4_I]] ] // DEFAULT-NEXT: [[MUL_I:%.*]] = shl nuw nsw i32 [[__I_0_I4]], 1 -// DEFAULT-NEXT: [[CONV_I:%.*]] = sitofp i32 [[MUL_I]] to float +// DEFAULT-NEXT: [[CONV_I:%.*]] = uitofp i32 [[MUL_I]] to float // DEFAULT-NEXT: [[DIV_I:%.*]] = fdiv contract float [[CONV_I]], [[Y]] // DEFAULT-NEXT: [[MUL8_I:%.*]] = fmul contract float [[__X1_0_I3]], [[DIV_I]] // DEFAULT-NEXT: [[SUB_I]] = fsub contract float [[MUL8_I]], [[__X0_0_I2]] @@ -1718,7 +1718,7 @@ extern "C" __device__ double test_j1(double x) { // FINITEONLY-NEXT: [[__X1_0_I3:%.*]] = phi float [ [[SUB_I:%.*]], [[FOR_BODY_I]] ], [ [[CALL_I21_I]], [[IF_END4_I]] ] // FINITEONLY-NEXT: [[__X0_0_I2:%.*]] = phi float [ [[__X1_0_I3]], [[FOR_BODY_I]] ], [ [[CALL_I_I]], [[IF_END4_I]] ] // FINITEONLY-NEXT: [[MUL_I:%.*]] = shl nuw nsw i32 [[__I_0_I4]], 1 -// FINITEONLY-NEXT: [[CONV_I:%.*]] = sitofp i32 [[MUL_I]] to float +// FINITEONLY-NEXT: [[CONV_I:%.*]] = uitofp i32 [[MUL_I]] to float // FINITEONLY-NEXT: [[DIV_I:%.*]] = fdiv nnan ninf contract float [[CONV_I]], [[Y]] // FINITEONLY-NEXT: [[MUL8_I:%.*]] = fmul nnan ninf contract float [[__X1_0_I3]], [[DIV_I]] // FINITEONLY-NEXT: [[SUB_I]] = fsub nnan ninf contract float [[MUL8_I]], [[__X0_0_I2]] @@ -1751,7 +1751,7 @@ extern "C" __device__ double test_j1(double x) { // APPROX-NEXT: [[__X1_0_I3:%.*]] = phi float [ [[SUB_I:%.*]], [[FOR_BODY_I]] ], [ [[CALL_I21_I]], [[IF_END4_I]] ] // APPROX-NEXT: [[__X0_0_I2:%.*]] = phi float [ [[__X1_0_I3]], [[FOR_BODY_I]] ], [ [[CALL_I_I]], [[IF_END4_I]] ] // APPROX-NEXT: [[MUL_I:%.*]] = shl nuw nsw i32 [[__I_0_I4]], 1 -// APPROX-NEXT: [[CONV_I:%.*]] = sitofp i32 [[MUL_I]] to float +// APPROX-NEXT: [[CONV_I:%.*]] = uitofp i32 [[MUL_I]] to float // APPROX-NEXT: [[DIV_I:%.*]] = fdiv contract float [[CONV_I]], [[Y]] // APPROX-NEXT: [[MUL8_I:%.*]] = fmul contract float [[__X1_0_I3]], [[DIV_I]] // APPROX-NEXT: [[SUB_I]] = fsub contract float [[MUL8_I]], [[__X0_0_I2]] @@ -1788,7 +1788,7 @@ extern "C" __device__ float test_jnf(int x, float y) { // DEFAULT-NEXT: [[__X1_0_I3:%.*]] = phi double [ [[SUB_I:%.*]], [[FOR_BODY_I]] ], [ [[CALL_I21_I]], [[IF_END4_I]] ] // DEFAULT-NEXT: [[__X0_0_I2:%.*]] = phi double [ [[__X1_0_I3]], [[FOR_BODY_I]] ], [ [[CALL_I_I]], [[IF_END4_I]] ] // DEFAULT-NEXT: [[MUL_I:%.*]] = shl nuw nsw i32 [[__I_0_I4]], 1 -// DEFAULT-NEXT: [[CONV_I:%.*]] = sitofp i32 [[MUL_I]] to double +// DEFAULT-NEXT: [[CONV_I:%.*]] = uitofp i32 [[MUL_I]] to double // DEFAULT-NEXT: [[DIV_I:%.*]] = fdiv contract double [[CONV_I]], [[Y]] // DEFAULT-NEXT: [[MUL8_I:%.*]] = fmul contract double [[__X1_0_I3]], [[DIV_I]] // DEFAULT-NEXT: [[SUB_I]] = fsub contract double [[MUL8_I]], [[__X0_0_I2]] @@ -1821,7 +1821,7 @@ extern "C" __device__ float test_jnf(int x, float y) { // FINITEONLY-NEXT: [[__X1_0_I3:%.*]] = phi double [ [[SUB_I:%.*]], [[FOR_BODY_I]] ], [ [[CALL_I21_I]], [[IF_END4_I]] ] // FINITEONLY-NEXT: [[__X0_0_I2:%.*]] = phi double [ [[__X1_0_I3]], [[FOR_BODY_I]] ], [ [[CALL_I_I]], [[IF_END4_I]] ] // FINITEONLY-NEXT: [[MUL_I:%.*]] = shl nuw nsw i32 [[__I_0_I4]], 1 -// FINITEONLY-NEXT: [[CONV_I:%.*]] = sitofp i32 [[MUL_I]] to double +// FINITEONLY-NEXT: [[CONV_I:%.*]] = uitofp i32 [[MUL_I]] to double // FINITEONLY-NEXT: [[DIV_I:%.*]] = fdiv nnan ninf contract double [[CONV_I]], [[Y]] // FINITEONLY-NEXT: [[MUL8_I:%.*]] = fmul nnan ninf contract double [[__X1_0_I3]], [[DIV_I]] // FINITEONLY-NEXT: [[SUB_I]] = fsub nnan ninf contract double [[MUL8_I]], [[__X0_0_I2]] @@ -1854,7 +1854,7 @@ extern "C" __device__ float test_jnf(int x, float y) { // APPROX-NEXT: [[__X1_0_I3:%.*]] = phi double [ [[SUB_I:%.*]], [[FOR_BODY_I]] ], [ [[CALL_I21_I]], [[IF_END4_I]] ] // APPROX-NEXT: [[__X0_0_I2:%.*]] = phi double [ [[__X1_0_I3]], [[FOR_BODY_I]] ], [ [[CALL_I_I]], [[IF_END4_I]] ] // APPROX-NEXT: [[MUL_I:%.*]] = shl nuw nsw i32 [[__I_0_I4]], 1 -// APPROX-NEXT: [[CONV_I:%.*]] = sitofp i32 [[MUL_I]] to double +// APPROX-NEXT: [[CONV_I:%.*]] = uitofp i32 [[MUL_I]] to double // APPROX-NEXT: [[DIV_I:%.*]] = fdiv contract double [[CONV_I]], [[Y]] // APPROX-NEXT: [[MUL8_I:%.*]] = fmul contract double [[__X1_0_I3]], [[DIV_I]] // APPROX-NEXT: [[SUB_I]] = fsub contract double [[MUL8_I]], [[__X0_0_I2]] @@ -4222,7 +4222,7 @@ extern "C" __device__ double test_y1(double x) { // DEFAULT-NEXT: [[__X1_0_I3:%.*]] = phi float [ [[SUB_I:%.*]], [[FOR_BODY_I]] ], [ [[CALL_I21_I]], [[IF_END4_I]] ] // DEFAULT-NEXT: [[__X0_0_I2:%.*]] = phi float [ [[__X1_0_I3]], [[FOR_BODY_I]] ], [ [[CALL_I_I]], [[IF_END4_I]] ] // DEFAULT-NEXT: [[MUL_I:%.*]] = shl nuw nsw i32 [[__I_0_I4]], 1 -// DEFAULT-NEXT: [[CONV_I:%.*]] = sitofp i32 [[MUL_I]] to float +// DEFAULT-NEXT: [[CONV_I:%.*]] = uitofp i32 [[MUL_I]] to float // DEFAULT-NEXT: [[DIV_I:%.*]] = fdiv contract float [[CONV_I]], [[Y]] // DEFAULT-NEXT: [[MUL8_I:%.*]] = fmul contract float [[__X1_0_I3]], [[DIV_I]] // DEFAULT-NEXT: [[SUB_I]] = fsub contract float [[MUL8_I]], [[__X0_0_I2]] @@ -4255,7 +4255,7 @@ extern "C" __device__ double test_y1(double x) { // FINITEONLY-NEXT: [[__X1_0_I3:%.*]] = phi float [ [[SUB_I:%.*]], [[FOR_BODY_I]] ], [ [[CALL_I21_I]], [[IF_END4_I]] ] // FINITEONLY-NEXT: [[__X0_0_I2:%.*]] = phi float [ [[__X1_0_I3]], [[FOR_BODY_I]] ], [ [[CALL_I_I]], [[IF_END4_I]] ] // FINITEONLY-NEXT: [[MUL_I:%.*]] = shl nuw nsw i32 [[__I_0_I4]], 1 -// FINITEONLY-NEXT: [[CONV_I:%.*]] = sitofp i32 [[MUL_I]] to float +// FINITEONLY-NEXT: [[CONV_I:%.*]] = uitofp i32 [[MUL_I]] to float // FINITEONLY-NEXT: [[DIV_I:%.*]] = fdiv nnan ninf contract float [[CONV_I]], [[Y]] // FINITEONLY-NEXT: [[MUL8_I:%.*]] = fmul nnan ninf contract float [[__X1_0_I3]], [[DIV_I]] // FINITEONLY-NEXT: [[SUB_I]] = fsub nnan ninf contract float [[MUL8_I]], [[__X0_0_I2]] @@ -4288,7 +4288,7 @@ extern "C" __device__ double test_y1(double x) { // APPROX-NEXT: [[__X1_0_I3:%.*]] = phi float [ [[SUB_I:%.*]], [[FOR_BODY_I]] ], [ [[CALL_I21_I]], [[IF_END4_I]] ] // APPROX-NEXT: [[__X0_0_I2:%.*]] = phi float [ [[__X1_0_I3]], [[FOR_BODY_I]] ], [ [[CALL_I_I]], [[IF_END4_I]] ] // APPROX-NEXT: [[MUL_I:%.*]] = shl nuw nsw i32 [[__I_0_I4]], 1 -// APPROX-NEXT: [[CONV_I:%.*]] = sitofp i32 [[MUL_I]] to float +// APPROX-NEXT: [[CONV_I:%.*]] = uitofp i32 [[MUL_I]] to float // APPROX-NEXT: [[DIV_I:%.*]] = fdiv contract float [[CONV_I]], [[Y]] // APPROX-NEXT: [[MUL8_I:%.*]] = fmul contract float [[__X1_0_I3]], [[DIV_I]] // APPROX-NEXT: [[SUB_I]] = fsub contract float [[MUL8_I]], [[__X0_0_I2]] @@ -4325,7 +4325,7 @@ extern "C" __device__ float test_ynf(int x, float y) { // DEFAULT-NEXT: [[__X1_0_I3:%.*]] = phi double [ [[SUB_I:%.*]], [[FOR_BODY_I]] ], [ [[CALL_I21_I]], [[IF_END4_I]] ] // DEFAULT-NEXT: [[__X0_0_I2:%.*]] = phi double [ [[__X1_0_I3]], [[FOR_BODY_I]] ], [ [[CALL_I_I]], [[IF_END4_I]] ] // DEFAULT-NEXT: [[MUL_I:%.*]] = shl nuw nsw i32 [[__I_0_I4]], 1 -// DEFAULT-NEXT: [[CONV_I:%.*]] = sitofp i32 [[MUL_I]] to double +// DEFAULT-NEXT: [[CONV_I:%.*]] = uitofp i32 [[MUL_I]] to double // DEFAULT-NEXT: [[DIV_I:%.*]] = fdiv contract double [[CONV_I]], [[Y]] // DEFAULT-NEXT: [[MUL8_I:%.*]] = fmul contract double [[__X1_0_I3]], [[DIV_I]] // DEFAULT-NEXT: [[SUB_I]] = fsub contract double [[MUL8_I]], [[__X0_0_I2]] @@ -4358,7 +4358,7 @@ extern "C" __device__ float test_ynf(int x, float y) { // FINITEONLY-NEXT: [[__X1_0_I3:%.*]] = phi double [ [[SUB_I:%.*]], [[FOR_BODY_I]] ], [ [[CALL_I21_I]], [[IF_END4_I]] ] // FINITEONLY-NEXT: [[__X0_0_I2:%.*]] = phi double [ [[__X1_0_I3]], [[FOR_BODY_I]] ], [ [[CALL_I_I]], [[IF_END4_I]] ] // FINITEONLY-NEXT: [[MUL_I:%.*]] = shl nuw nsw i32 [[__I_0_I4]], 1 -// FINITEONLY-NEXT: [[CONV_I:%.*]] = sitofp i32 [[MUL_I]] to double +// FINITEONLY-NEXT: [[CONV_I:%.*]] = uitofp i32 [[MUL_I]] to double // FINITEONLY-NEXT: [[DIV_I:%.*]] = fdiv nnan ninf contract double [[CONV_I]], [[Y]] // FINITEONLY-NEXT: [[MUL8_I:%.*]] = fmul nnan ninf contract double [[__X1_0_I3]], [[DIV_I]] // FINITEONLY-NEXT: [[SUB_I]] = fsub nnan ninf contract double [[MUL8_I]], [[__X0_0_I2]] @@ -4391,7 +4391,7 @@ extern "C" __device__ float test_ynf(int x, float y) { // APPROX-NEXT: [[__X1_0_I3:%.*]] = phi double [ [[SUB_I:%.*]], [[FOR_BODY_I]] ], [ [[CALL_I21_I]], [[IF_END4_I]] ] // APPROX-NEXT: [[__X0_0_I2:%.*]] = phi double [ [[__X1_0_I3]], [[FOR_BODY_I]] ], [ [[CALL_I_I]], [[IF_END4_I]] ] // APPROX-NEXT: [[MUL_I:%.*]] = shl nuw nsw i32 [[__I_0_I4]], 1 -// APPROX-NEXT: [[CONV_I:%.*]] = sitofp i32 [[MUL_I]] to double +// APPROX-NEXT: [[CONV_I:%.*]] = uitofp i32 [[MUL_I]] to double // APPROX-NEXT: [[DIV_I:%.*]] = fdiv contract double [[CONV_I]], [[Y]] // APPROX-NEXT: [[MUL8_I:%.*]] = fmul contract double [[__X1_0_I3]], [[DIV_I]] // APPROX-NEXT: [[SUB_I]] = fsub contract double [[MUL8_I]], [[__X0_0_I2]] diff --git a/clang/test/InstallAPI/asm.test b/clang/test/InstallAPI/asm.test new file mode 100644 index 0000000000000000000000000000000000000000..b6af7f643d72f2253bcd3420323838b68996130b --- /dev/null +++ b/clang/test/InstallAPI/asm.test @@ -0,0 +1,90 @@ +// RUN: rm -rf %t +// RUN: split-file %s %t +// RUN: sed -e "s|DSTROOT|%/t|g" %t/inputs.json.in > %t/inputs.json + +// RUN: clang-installapi -target arm64-apple-macos13.1 \ +// RUN: -I%t/usr/include \ +// RUN: -install_name @rpath/lib/libasm.dylib \ +// RUN: %t/inputs.json -o %t/output.tbd 2>&1 | FileCheck %s --allow-empty +// RUN: llvm-readtapi -compare %t/output.tbd %t/expected.tbd 2>&1 | FileCheck %s --allow-empty + +// CHECK-NOT: error: +// CHECK-NOT: warning: + +//--- usr/include/asm.h +#ifndef ASM_H +#define ASM_H + +extern int ivar __asm("_OBJC_IVAR_$_SomeClass._ivar1"); +extern int objcClass1 __asm("_OBJC_CLASS_$_SomeClass"); +extern int objcClass2 __asm("_OBJC_METACLASS_$_SomeClass"); +extern int objcClass3 __asm("_OBJC_EHTYPE_$_SomeClass"); +extern int objcClass4 __asm(".objc_class_name_SomeClass"); + +__attribute__((visibility("hidden"))) +@interface NSString { +} +@end + +extern int ivarExtra __asm("_OBJC_IVAR_$_NSString._ivar1"); +#endif // ASM_H + +//--- inputs.json.in +{ + "headers": [ { + "path" : "DSTROOT/usr/include/asm.h", + "type" : "public" + }], + "version": "3" +} + +//--- expected.tbd +{ + "main_library": { + "compatibility_versions": [ + { + "version": "0" + } + ], + "current_versions": [ + { + "version": "0" + } + ], + "exported_symbols": [ + { + "data": { + "objc_class": [ + "SomeClass" + ], + "objc_eh_type": [ + "SomeClass" + ], + "objc_ivar": [ + "NSString._ivar1", + "SomeClass._ivar1" + ] + } + } + ], + "flags": [ + { + "attributes": [ + "not_app_extension_safe" + ] + } + ], + "install_names": [ + { + "name": "@rpath/lib/libasm.dylib" + } + ], + "target_info": [ + { + "min_deployment": "13.1", + "target": "arm64-macos" + } + ] + }, + "tapi_tbd_version": 5 +} diff --git a/clang/test/InstallAPI/basic.test b/clang/test/InstallAPI/basic.test index 5b41ccd517b0afe667b08b6a52b892f61b96fa05..096911039d114e4fceed2e681a43634bd8b7c258 100644 --- a/clang/test/InstallAPI/basic.test +++ b/clang/test/InstallAPI/basic.test @@ -2,7 +2,8 @@ // RUN: split-file %s %t /// Check basic arguments are captured. // RUN: clang-installapi -x objective-c -target arm64-apple-ios13.0.0 \ -// RUN: -fapplication-extension -current_version 1 -install_name /usr/lib/basic.dylib \ +// RUN: -fapplication-extension -current_version 1 -compatibility_version 1 \ +// RUN: -install_name /usr/lib/basic.dylib \ // RUN: %t/basic_inputs.json -o %t/basic.tbd 2>&1 | FileCheck %s --allow-empty // RUN: llvm-readtapi -compare %t/basic.tbd %t/expected.tbd 2>&1 | FileCheck %s --allow-empty @@ -25,11 +26,6 @@ //--- expected.tbd { "main_library": { - "compatibility_versions": [ - { - "version": "0" - } - ], "install_names": [ { "name": "/usr/lib/basic.dylib" diff --git a/clang/test/InstallAPI/cpp.test b/clang/test/InstallAPI/cpp.test new file mode 100644 index 0000000000000000000000000000000000000000..4817899095302b2ca46370abc87d4bb78da3449f --- /dev/null +++ b/clang/test/InstallAPI/cpp.test @@ -0,0 +1,530 @@ +// RUN: rm -rf %t +// RUN: split-file %s %t +// RUN: sed -e "s|DSTROOT|%/t|g" %t/inputs.json.in > %t/inputs.json + +// Invoke C++ with no-rtti. +// RUN: clang-installapi -target arm64-apple-macos13.1 \ +// RUN: -I%t/usr/include -I%t/usr/local/include -x c++ \ +// RUN: -install_name @rpath/lib/libcpp.dylib -fno-rtti \ +// RUN: %t/inputs.json -o %t/no-rtti.tbd 2>&1 | FileCheck %s --allow-empty + +// RUN: llvm-readtapi -compare %t/no-rtti.tbd \ +// RUN: %t/expected-no-rtti.tbd 2>&1 | FileCheck %s --allow-empty + +// Invoke C++ with rtti. +// RUN: clang-installapi -target arm64-apple-macos13.1 \ +// RUN: -I%t/usr/include -I%t/usr/local/include -x c++ \ +// RUN: -install_name @rpath/lib/libcpp.dylib -frtti \ +// RUN: %t/inputs.json -o %t/rtti.tbd 2>&1 | FileCheck %s --allow-empty +// RUN: llvm-readtapi -compare %t/rtti.tbd \ +// RUN: %t/expected-rtti.tbd 2>&1 | FileCheck %s --allow-empty + +// CHECK-NOT: error: +// CHECK-NOT: warning: + +//--- usr/include/basic.h +#ifndef CPP_H +#define CPP_H + +inline int foo(int x) { return x + 1; } + +extern int bar(int x) { return x + 1; } + +inline int baz(int x) { + static const int a[] = {1, 2, 3}; + return a[x]; +} + +extern "C" { + int cFunc(const char*); +} + +class Bar { +public: + static const int x = 0; + static int y; + + inline int func1(int x) { return x + 2; } + inline int func2(int x); + int func3(int x); +}; + +class __attribute__((visibility("hidden"))) BarI { + static const int x = 0; + static int y; + + inline int func1(int x) { return x + 2; } + inline int func2(int x); + int func3(int x); +}; + +int Bar::func2(int x) { return x + 3; } +inline int Bar::func3(int x) { return x + 4; } + +int BarI::func2(int x) { return x + 3; } +inline int BarI::func3(int x) { return x + 4; } +#endif + +//--- usr/local/include/vtable.h +// Simple test class with no virtual functions. There should be no vtable or +// RTTI. +namespace test1 { +class Simple { +public: + void run(); +}; +} // end namespace test1 + +// Simple test class with virtual function. There should be an external vtable +// and RTTI. +namespace test2 { +class Simple { +public: + virtual void run(); +}; +} // end namespace test2 + +// Abstract class with no sub classes. There should be no vtable or RTTI. +namespace test3 { +class Abstract { +public: + virtual ~Abstract() {} + virtual void run() = 0; +}; +} // end namespace test3 + +// Abstract base class with a sub class. There should be weak-def RTTI for the +// abstract base class. +// The sub-class should have vtable and RTTI. +namespace test4 { +class Base { +public: + virtual ~Base() {} + virtual void run() = 0; +}; + +class Sub : public Base { +public: + void run() override; +}; +} // end namespace test4 + +// Abstract base class with a sub class. Same as above, but with a user defined +// inlined destructor. +namespace test5 { +class Base { +public: + virtual ~Base() {} + virtual void run() = 0; +}; + +class Sub : public Base { +public: + virtual ~Sub() {} + void run() override; +}; +} // end namespace test5 + +// Abstract base class with a sub class. Same as above, but with a different +// inlined key method. +namespace test6 { +class Base { +public: + virtual ~Base() {} + virtual void run() = 0; +}; + +class Sub : public Base { +public: + virtual void foo() {} + void run() override; +}; +} // end namespace test6 + +// Abstract base class with a sub class. Overloaded method is implemented +// inline. No vtable or RTTI. +namespace test7 { +class Base { +public: + virtual ~Base() {} + virtual bool run() = 0; +}; + +class Sub : public Base { +public: + bool run() override { return true; } +}; +} // end namespace test7 + +// Abstract base class with a sub class. Overloaded method has no inline +// attribute and is recognized as key method, +// but is later implemented inline. Weak-def RTTI only. +namespace test8 { +class Base { +public: + virtual ~Base() {} + virtual void run() = 0; +}; + +class Sub : public Base { +public: + void run() override; +}; + +inline void Sub::run() {} +} // end namespace test8 + +namespace test9 { +class Base { +public: + virtual ~Base() {} + virtual void run1() = 0; + virtual void run2() = 0; +}; + +class Sub : public Base { +public: + void run1() override {} + void run2() override; +}; + +inline void Sub::run2() {} +} // end namespace test9 + +namespace test10 { +class Base { +public: + virtual ~Base() {} + virtual void run1() = 0; + virtual void run2() = 0; +}; + +class Sub : public Base { +public: + void run1() override {} + inline void run2() override; +}; + +void Sub::run2() {} +} // end namespace test10 + +namespace test11 { +class Base { +public: + virtual ~Base() {} + virtual void run1() = 0; + virtual void run2() = 0; + virtual void run3() = 0; +}; + +class Sub : public Base { +public: + void run1() override {} + void run2() override; + void run3() override; +}; + +inline void Sub::run2() {} +} // end namespace test11 + +namespace test12 { +template class Simple { +public: + virtual void foo() {} +}; +extern template class Simple; +} // end namespace test12 + +namespace test13 { +class Base { +public: + virtual ~Base() {} + virtual void run1() = 0; + virtual void run2() {}; + virtual void run3(); // key function. +}; + +class Sub : public Base { +public: + void run1() override {} + void run2() override {} +}; + +} // end namespace test13 + +namespace test14 { + +class __attribute__((visibility("hidden"))) Base +{ +public: + Base() {} + virtual ~Base(); // keyfunction. + virtual void run1() const = 0; +}; + +class Sub : public Base +{ +public: + Sub(); + virtual ~Sub(); + virtual void run1() const; + void run2() const {} +}; + +} // end namespace test14 + +namespace test15 { + +class Base { +public: + virtual ~Base() {} + virtual void run() {}; +}; + +class Base1 { +public: + virtual ~Base1() {} + virtual void run1() {}; +}; + +class Sub : public Base, public Base1 { +public: + Sub() {} + ~Sub(); + void run() override; + void run1() override; +}; + +class Sub1 : public Base, public Base1 { +public: + Sub1() {} + ~Sub1() = default; + void run() override; + void run1() override; +}; + +} // end namespace test15 + +//--- usr/local/include/templates.h +#ifndef TEMPLATES_H +#define TEMPLATES_H + +namespace templates { + +// Full specialization. +template int foo1(T a) { return 1; } +template <> int foo1(int a); +extern template int foo1(short a); + +template int foo2(T a); + +// Partial specialization. +template class Partial { + static int run(A a, B b) { return a + b; } +}; + +template class Partial { + static int run(A a, int b) { return a - b; } +}; + +template class Foo { +public: + Foo(); + ~Foo(); +}; + +template class Bar { +public: + Bar(); + ~Bar() {} + + inline int bazinga() { return 7; } +}; + +extern template class Bar; + +class Bazz { +public: + Bazz() {} + + template int buzz(T a); + + float implicit() const { return foo1(0.0f); } +}; + +template int Bazz::buzz(T a) { return sizeof(T); } + +template struct S { static int x; }; + +template int S::x = 0; + +} // end namespace templates. + +#endif + + +//--- inputs.json.in +{ + "headers": [ { + "path" : "DSTROOT/usr/include/basic.h", + "type" : "public" + }, + { + "path" : "DSTROOT/usr/local/include/vtable.h", + "type" : "private" + }, + { + "path" : "DSTROOT/usr/local/include/templates.h", + "type" : "private" + } + ], + "version": "3" +} + +//--- expected-no-rtti.tbd +{ + "main_library": { + "compatibility_versions": [ + { + "version": "0" + } + ], + "current_versions": [ + { + "version": "0" + } + ], + "exported_symbols": [ + { + "data": { + "global": [ + "__ZTVN6test143SubE", "__ZTVN6test113SubE", "__ZTVN5test26SimpleE", + "__ZTVN5test53SubE", "__ZTVN6test154Sub1E", "__ZTVN6test153SubE", + "__ZN3Bar1yE", "__ZTVN5test43SubE", "__ZTVN5test63SubE", + "__ZTVN6test134BaseE" + ], + "weak": [ + "__ZTVN6test126SimpleIiEE" + ] + }, + "text": { + "global": [ + "__ZN6test153Sub3runEv", "__ZN6test154Sub13runEv", + "__Z3bari", "__ZThn8_N6test153SubD1Ev", + "__ZNK6test143Sub4run1Ev", "__ZN6test154Sub14run1Ev", + "__ZThn8_N6test153Sub4run1Ev", "__ZN6test143SubD1Ev", + "__ZN6test134Base4run3Ev", "__ZN5test16Simple3runEv", + "__ZN5test43Sub3runEv", "__ZN6test113Sub4run3Ev", "__ZN6test153SubD2Ev", + "__ZN5test53Sub3runEv", "__ZN6test153SubD1Ev", "__ZN6test143SubC1Ev", + "__ZN9templates4foo1IiEEiT_", "__ZN6test143SubC2Ev", "__ZN5test63Sub3runEv", + "__ZN5test26Simple3runEv", "__ZN6test153SubD0Ev", + "__ZN6test143SubD2Ev", "__ZN6test153Sub4run1Ev", "__ZN6test143SubD0Ev", + "__ZThn8_N6test153SubD0Ev", "__ZThn8_N6test154Sub14run1Ev", "_cFunc" + ], + "weak": [ + "__ZN9templates3BarIiED2Ev", "__ZN9templates3BarIiEC2Ev", + "__ZN9templates3BarIiEC1Ev", "__ZN9templates3BarIiED1Ev", + "__ZN6test126SimpleIiE3fooEv", "__ZN9templates3BarIiE7bazingaEv", + "__ZN9templates4foo1IsEEiT_" + ] + } + } + ], + "flags": [ + { + "attributes": [ + "not_app_extension_safe" + ] + } + ], + "install_names": [ + { + "name": "@rpath/lib/libcpp.dylib" + } + ], + "target_info": [ + { + "min_deployment": "13.1", + "target": "arm64-macos" + } + ] + }, + "tapi_tbd_version": 5 +} + +//--- expected-rtti.tbd +{ + "main_library": { + "compatibility_versions": [ + { + "version": "0" + } + ], + "current_versions": [ + { + "version": "0" + } + ], + "exported_symbols": [ + { + "data": { + "global": [ + "__ZTVN6test143SubE", "__ZTIN5test63SubE", "__ZTSN5test26SimpleE", + "__ZTIN6test153SubE", "__ZTVN6test113SubE", "__ZTIN5test43SubE", + "__ZTIN6test134BaseE", "__ZTVN5test26SimpleE", "__ZTIN5test26SimpleE", + "__ZTSN6test134BaseE", "__ZTVN6test154Sub1E", "__ZTVN5test43SubE", + "__ZTVN5test63SubE", "__ZTSN5test43SubE", "__ZTSN6test113SubE", + "__ZTIN6test154Sub1E", "__ZTSN6test153SubE", "__ZTSN5test63SubE", + "__ZTSN6test154Sub1E", "__ZTIN6test113SubE", "__ZTSN6test143SubE", + "__ZTVN5test53SubE", "__ZTIN6test143SubE", "__ZTVN6test153SubE", + "__ZTIN5test53SubE", "__ZN3Bar1yE", "__ZTVN6test134BaseE", + "__ZTSN5test53SubE" + ], + "weak": [ + "__ZTVN6test126SimpleIiEE" + ] + }, + "text": { + "global": [ + "__ZN6test154Sub13runEv", "__ZN6test153Sub3runEv", "__ZNK6test143Sub4run1Ev", + "__ZN6test134Base4run3Ev", "__ZN5test16Simple3runEv", "__ZN6test153SubD2Ev", + "__ZN6test143SubC2Ev", "__ZN5test63Sub3runEv", "__ZN6test153SubD0Ev", + "__ZN6test143SubD2Ev", "__ZThn8_N6test154Sub14run1Ev", + "__ZThn8_N6test153SubD0Ev", "__Z3bari", "__ZThn8_N6test153SubD1Ev", + "__ZN6test154Sub14run1Ev", "__ZThn8_N6test153Sub4run1Ev", + "__ZN6test143SubD1Ev", "__ZN5test43Sub3runEv", + "__ZN6test113Sub4run3Ev", "__ZN5test53Sub3runEv", "__ZN6test143SubC1Ev", + "__ZN6test153SubD1Ev", "__ZN9templates4foo1IiEEiT_", "__ZN5test26Simple3runEv", + "__ZN6test153Sub4run1Ev", "__ZN6test143SubD0Ev", "_cFunc" + ], + "weak": [ + "__ZN9templates3BarIiEC2Ev", "__ZN9templates3BarIiEC1Ev", + "__ZN9templates3BarIiED1Ev", "__ZN6test126SimpleIiE3fooEv", + "__ZN9templates4foo1IsEEiT_", "__ZN9templates3BarIiED2Ev", + "__ZN9templates3BarIiE7bazingaEv" + ] + } + } + ], + "flags": [ + { + "attributes": [ + "not_app_extension_safe" + ] + } + ], + "install_names": [ + { + "name": "@rpath/lib/libcpp.dylib" + } + ], + "target_info": [ + { + "min_deployment": "13.1", + "target": "arm64-macos" + } + ] + }, + "tapi_tbd_version": 5 +} + diff --git a/clang/test/InstallAPI/driver-invalid-options.test b/clang/test/InstallAPI/driver-invalid-options.test index a2e008e1eb03e7adc40bc58e242208570fd78414..69f3b2d66ab8b6f78741487344aeb0b2e44fb285 100644 --- a/clang/test/InstallAPI/driver-invalid-options.test +++ b/clang/test/InstallAPI/driver-invalid-options.test @@ -1,4 +1,9 @@ /// Check non-darwin triple is rejected. -// RUN: not clang-installapi -target x86_64-unknown-unknown %s 2> %t +// RUN: not clang-installapi -target x86_64-unknown-unknown %s -o tmp.tbd 2> %t // RUN: FileCheck --check-prefix INVALID_INSTALLAPI -input-file %t %s // INVALID_INSTALLAPI: error: unsupported option 'installapi' for target 'x86_64-unknown-unknown' + +/// Check that missing install_name is reported. +// RUN: not clang-installapi -target x86_64-apple-ios-simulator %s -o tmp.tbd 2> %t +// RUN: FileCheck --check-prefix INVALID_INSTALL_NAME -input-file %t %s +// INVALID_INSTALL_NAME: error: no install name specified: add -install_name diff --git a/clang/test/InstallAPI/functions.test b/clang/test/InstallAPI/functions.test index 527965303cb351f4a8422e1ced40cf502c401f10..5b5fd1308842ede729da85e428919a7103170f5a 100644 --- a/clang/test/InstallAPI/functions.test +++ b/clang/test/InstallAPI/functions.test @@ -4,7 +4,7 @@ // RUN: clang-installapi -target arm64-apple-macos13.1 \ // RUN: -I%t/usr/include -I%t/usr/local/include \ -// RUN: -install_name @rpath/lib/libfunctions.dylib \ +// RUN: -install_name @rpath/lib/libfunctions.dylib --filetype=tbd-v4 \ // RUN: %t/inputs.json -o %t/outputs.tbd 2>&1 | FileCheck %s --allow-empty // RUN: llvm-readtapi -compare %t/outputs.tbd %t/expected.tbd 2>&1 | FileCheck %s --allow-empty diff --git a/clang/test/Misc/pragma-attribute-supported-attributes-list.test b/clang/test/Misc/pragma-attribute-supported-attributes-list.test index 1528388e3298ebcc7b3b5e9f3674de582bb8d174..318bfb2df2a7aaf0838579cbdc91d438dc87b03e 100644 --- a/clang/test/Misc/pragma-attribute-supported-attributes-list.test +++ b/clang/test/Misc/pragma-attribute-supported-attributes-list.test @@ -4,6 +4,7 @@ // CHECK: #pragma clang attribute supports the following attributes: // CHECK-NEXT: AMDGPUFlatWorkGroupSize (SubjectMatchRule_function) +// CHECK-NEXT: AMDGPUMaxNumWorkGroups (SubjectMatchRule_function) // CHECK-NEXT: AMDGPUNumSGPR (SubjectMatchRule_function) // CHECK-NEXT: AMDGPUNumVGPR (SubjectMatchRule_function) // CHECK-NEXT: AMDGPUWavesPerEU (SubjectMatchRule_function) @@ -19,7 +20,6 @@ // CHECK-NEXT: ArcWeakrefUnavailable (SubjectMatchRule_objc_interface) // CHECK-NEXT: ArmBuiltinAlias (SubjectMatchRule_function) // CHECK-NEXT: AssumeAligned (SubjectMatchRule_objc_method, SubjectMatchRule_function) -// CHECK-NEXT: Assumption (SubjectMatchRule_function, SubjectMatchRule_objc_method) // CHECK-NEXT: Availability ((SubjectMatchRule_record, SubjectMatchRule_enum, SubjectMatchRule_enum_constant, SubjectMatchRule_field, SubjectMatchRule_function, SubjectMatchRule_namespace, SubjectMatchRule_objc_category, SubjectMatchRule_objc_implementation, SubjectMatchRule_objc_interface, SubjectMatchRule_objc_method, SubjectMatchRule_objc_property, SubjectMatchRule_objc_protocol, SubjectMatchRule_record, SubjectMatchRule_type_alias, SubjectMatchRule_variable)) // CHECK-NEXT: AvailableOnlyInDefaultEvalMethod (SubjectMatchRule_type_alias) // CHECK-NEXT: BPFPreserveAccessIndex (SubjectMatchRule_record) @@ -127,6 +127,7 @@ // CHECK-NEXT: NoThrow (SubjectMatchRule_hasType_functionType) // CHECK-NEXT: NoUwtable (SubjectMatchRule_hasType_functionType) // CHECK-NEXT: NotTailCalled (SubjectMatchRule_function) +// CHECK-NEXT: OMPAssume (SubjectMatchRule_function, SubjectMatchRule_objc_method) // CHECK-NEXT: OSConsumed (SubjectMatchRule_variable_is_parameter) // CHECK-NEXT: OSReturnsNotRetained (SubjectMatchRule_function, SubjectMatchRule_objc_method, SubjectMatchRule_objc_property, SubjectMatchRule_variable_is_parameter) // CHECK-NEXT: OSReturnsRetained (SubjectMatchRule_function, SubjectMatchRule_objc_method, SubjectMatchRule_objc_property, SubjectMatchRule_variable_is_parameter) diff --git a/clang/test/Misc/warning-wall.c b/clang/test/Misc/warning-wall.c index 05a82770e26de69595374a64b25a81cea43b6e2c..4909ab034ef30aa3bd005b92032c5a780981889f 100644 --- a/clang/test/Misc/warning-wall.c +++ b/clang/test/Misc/warning-wall.c @@ -44,6 +44,7 @@ CHECK-NEXT: -Wreorder-ctor CHECK-NEXT: -Wreorder-init-list CHECK-NEXT: -Wreturn-type CHECK-NEXT: -Wreturn-type-c-linkage +CHECK-NEXT: -Wreturn-mismatch CHECK-NEXT: -Wself-assign CHECK-NEXT: -Wself-assign-overloaded CHECK-NEXT: -Wself-assign-field diff --git a/clang/test/Modules/hashing-decls-in-exprs-from-gmf.cppm b/clang/test/Modules/hashing-decls-in-exprs-from-gmf.cppm new file mode 100644 index 0000000000000000000000000000000000000000..8db53c0ace8796971b763d9ceebd11e2fee62936 --- /dev/null +++ b/clang/test/Modules/hashing-decls-in-exprs-from-gmf.cppm @@ -0,0 +1,67 @@ +// RUN: rm -rf %t +// RUN: mkdir -p %t +// RUN: split-file %s %t +// +// RUN: %clang_cc1 -std=c++20 -fskip-odr-check-in-gmf %t/A.cppm -emit-module-interface -o %t/A.pcm +// RUN: %clang_cc1 -std=c++20 -fskip-odr-check-in-gmf %t/B.cppm -emit-module-interface -o %t/B.pcm +// RUN: %clang_cc1 -std=c++20 -fskip-odr-check-in-gmf %t/test.cpp -fprebuilt-module-path=%t -fsyntax-only -verify + +//--- header.h +#pragma once +template +class Optional {}; + +template +concept C = requires(const _Tp& __t) { + [](const Optional<_Up>&) {}(__t); +}; + +//--- func.h +#include "header.h" +template +void func() {} + +//--- duplicated_func.h +#include "header.h" +template +void duplicated_func() {} + +//--- test_func.h +#include "func.h" + +void test_func() { + func>(); +} + +//--- test_duplicated_func.h +#include "duplicated_func.h" + +void test_duplicated_func() { + duplicated_func>(); +} + +//--- A.cppm +module; +#include "header.h" +#include "test_duplicated_func.h" +export module A; +export using ::test_duplicated_func; + +//--- B.cppm +module; +#include "header.h" +#include "test_func.h" +#include "test_duplicated_func.h" +export module B; +export using ::test_func; +export using ::test_duplicated_func; + +//--- test.cpp +// expected-no-diagnostics +import A; +import B; + +void test() { + test_func(); + test_duplicated_func(); +} diff --git a/clang/test/Modules/missing-module-declaration.cppm b/clang/test/Modules/missing-module-declaration.cppm deleted file mode 100644 index d52f6639fe4f6484cd5a0925f8a5ad5e3898d478..0000000000000000000000000000000000000000 --- a/clang/test/Modules/missing-module-declaration.cppm +++ /dev/null @@ -1,13 +0,0 @@ -// RUN: rm -rf %t -// RUN: split-file %s %t -// RUN: cd %t -// -// RUN: %clang_cc1 -std=c++20 %t/B.cppm -I%t -emit-module-interface -o %t/B.pcm -// RUN: %clang_cc1 -std=c++20 %t/A.cppm -I%t -fprebuilt-module-path=%t -emit-module-interface -verify - -//--- A.cppm -import B; // expected-error{{missing 'export module' declaration in module interface unit}} - -//--- B.cppm -module; -export module B; diff --git a/clang/test/Modules/no-undeclared-includes-builtins.cpp b/clang/test/Modules/no-undeclared-includes-builtins.cpp index c9bffc55619905303d0b2669f196cafca722c8a1..f9eefd24a33c7d8903c5d20151ed1bccc716f6af 100644 --- a/clang/test/Modules/no-undeclared-includes-builtins.cpp +++ b/clang/test/Modules/no-undeclared-includes-builtins.cpp @@ -8,7 +8,7 @@ // headers. // RUN: rm -rf %t -// RUN: %clang_cc1 -fmodules-cache-path=%t -fmodules -fimplicit-module-maps -I %S/Inputs/no-undeclared-includes-builtins/libcxx -I %S/Inputs/no-undeclared-includes-builtins/glibc %s +// RUN: %clang_cc1 -fmodules-cache-path=%t -fmodules -fbuiltin-headers-in-system-modules -fimplicit-module-maps -I %S/Inputs/no-undeclared-includes-builtins/libcxx -I %S/Inputs/no-undeclared-includes-builtins/glibc %s // expected-no-diagnostics #include diff --git a/clang/test/Modules/pr72828.cppm b/clang/test/Modules/pr72828.cppm index 574523188507a17e1804cc70f173f2f0d3dde7eb..7432f2831f248a69a5967c3f1b07c753d1b76cd4 100644 --- a/clang/test/Modules/pr72828.cppm +++ b/clang/test/Modules/pr72828.cppm @@ -17,7 +17,7 @@ struct s { void f() { auto [x] = s(); - [x] {}; + (void) [x] {}; } // Check that we can generate the LLVM IR expectedly. diff --git a/clang/test/Modules/reduced-bmi-generating-codes.cppm b/clang/test/Modules/reduced-bmi-generating-codes.cppm new file mode 100644 index 0000000000000000000000000000000000000000..13dcda06437b29df26956b90950b3727ec5b0488 --- /dev/null +++ b/clang/test/Modules/reduced-bmi-generating-codes.cppm @@ -0,0 +1,40 @@ +// Although the reduced BMI are not designed to be generated, +// it is helpful for testing whether we've reduced the definitions. +// +// RUN: rm -rf %t +// RUN: mkdir -p %t +// RUN: split-file %s %t +// +// RUN: %clang_cc1 -std=c++20 -triple %itanium_abi_triple %t/a.cppm \ +// RUN: -emit-reduced-module-interface -o %t/a.pcm +// RUN: %clang_cc1 -std=c++20 -triple %itanium_abi_triple %t/b.cpp \ +// RUN: -fmodule-file=a=%t/a.pcm -S -emit-llvm -o - \ +// RUN: | FileCheck %t/b.cpp + +//--- a.cppm +export module a; + +export template +class A { +public: + int member() { + return 43; + } +}; + +// Instantiate `A::member()`. +export int a_member = A().member(); + +export const int a = 43; + +//--- b.cpp +import a; + +static_assert(a == 43); + +int b() { + A a; + return a.member(); +} + +// CHECK: define{{.*}}@_ZNW1a1AIiE6memberEv diff --git a/clang/test/Modules/stddef.c b/clang/test/Modules/stddef.c index 5bc0d1e44c8563fc3e254e9fb5b84790bea3da75..7623982614681009cf6fefd358916f67f1e2ae0b 100644 --- a/clang/test/Modules/stddef.c +++ b/clang/test/Modules/stddef.c @@ -1,29 +1,33 @@ // RUN: rm -rf %t -// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -fbuiltin-headers-in-system-modules -fmodules-cache-path=%t -I%S/Inputs/StdDef %s -verify -fno-modules-error-recovery +// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -fbuiltin-headers-in-system-modules -fmodules-cache-path=%t -I%S/Inputs/StdDef %s -verify=builtin-headers-in-system-modules -fno-modules-error-recovery // RUN: rm -rf %t -// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t -I%S/Inputs/StdDef %s -verify -fno-modules-error-recovery +// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t -I%S/Inputs/StdDef %s -verify=no-builtin-headers-in-system-modules -fno-modules-error-recovery #include "ptrdiff_t.h" ptrdiff_t pdt; -// size_t is declared in both size_t.h and __stddef_size_t.h, both of which are -// modular headers. Regardless of whether stddef.h joins the StdDef test module -// or is in its _Builtin_stddef module, __stddef_size_t.h will be in -// _Builtin_stddef.size_t. It's not defined which module will win as the expected -// provider of size_t. For the purposes of this test it doesn't matter which header -// gets reported, just as long as it isn't other.h or include_again.h. -size_t st; // expected-error-re {{missing '#include "{{size_t|__stddef_size_t}}.h"'; 'size_t' must be declared before it is used}} -// expected-note@size_t.h:* 0+ {{here}} -// expected-note@__stddef_size_t.h:* 0+ {{here}} +// size_t is declared in both size_t.h and __stddef_size_t.h. If +// -fbuiltin-headers-in-system-modules is set, then __stddef_size_t.h is a +// non-modular header that will be transitively pulled in the StdDef test module +// by include_again.h. Otherwise it will be in the _Builtin_stddef module. In +// any case it's not defined which module will win as the expected provider of +// size_t. For the purposes of this test it doesn't matter which of the two +// providing headers get reported. +size_t st; // builtin-headers-in-system-modules-error-re {{missing '#include "{{size_t|include_again}}.h"'; 'size_t' must be declared before it is used}} \ + no-builtin-headers-in-system-modules-error-re {{missing '#include "{{size_t|__stddef_size_t}}.h"'; 'size_t' must be declared before it is used}} +// builtin-headers-in-system-modules-note@size_t.h:* 0+ {{here}} \ + no-builtin-headers-in-system-modules-note@size_t.h:* 0+ {{here}} +// builtin-headers-in-system-modules-note@__stddef_size_t.h:* 0+ {{here}} \ + no-builtin-headers-in-system-modules-note@__stddef_size_t.h:* 0+ {{here}} #include "include_again.h" -// Includes which includes <__stddef_size_t.h> which imports the -// _Builtin_stddef.size_t module. +// Includes which includes <__stddef_size_t.h>. size_t st2; #include "size_t.h" -// Redeclares size_t, but the type merger should figure it out. +// Redeclares size_t when -fbuiltin-headers-in-system-modules is not passed, but +// the type merger should figure it out. size_t st3; diff --git a/clang/test/OpenMP/amdgcn_target_device_vla.cpp b/clang/test/OpenMP/amdgcn_target_device_vla.cpp index de150a0fcb4afd23854ac78630b72d5b9c864bb9..58fef517a9e72d2eaeb8aff57355697b9af2f458 100644 --- a/clang/test/OpenMP/amdgcn_target_device_vla.cpp +++ b/clang/test/OpenMP/amdgcn_target_device_vla.cpp @@ -539,7 +539,7 @@ int main() { // CHECK: omp.loop.exit: // CHECK-NEXT: [[TMP34:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR_ASCAST]], align 8 // CHECK-NEXT: [[TMP35:%.*]] = load i32, ptr [[TMP34]], align 4 -// CHECK-NEXT: call void @__kmpc_distribute_static_fini(ptr addrspacecast (ptr addrspace(1) @[[GLOB2]] to ptr), i32 [[TMP35]]) +// CHECK-NEXT: call void @__kmpc_for_static_fini(ptr addrspacecast (ptr addrspace(1) @[[GLOB3]] to ptr), i32 [[TMP35]]) // CHECK-NEXT: br label [[OMP_PRECOND_END]] // CHECK: omp.precond.end: // CHECK-NEXT: ret void diff --git a/clang/test/OpenMP/amdgpu_target_with_aligned_attribute.c b/clang/test/OpenMP/amdgpu_target_with_aligned_attribute.c index dd33e8405c34247ee1eb17e3284626e56f789ba5..cc0cc0def48b8111fbb4437e6dac8fd44d59f824 100644 --- a/clang/test/OpenMP/amdgpu_target_with_aligned_attribute.c +++ b/clang/test/OpenMP/amdgpu_target_with_aligned_attribute.c @@ -301,7 +301,7 @@ void write_to_aligned_array(int *a, int N) { // CHECK-AMD: omp.loop.exit: // CHECK-AMD-NEXT: [[TMP17:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR_ASCAST]], align 8 // CHECK-AMD-NEXT: [[TMP18:%.*]] = load i32, ptr [[TMP17]], align 4 -// CHECK-AMD-NEXT: call void @__kmpc_distribute_static_fini(ptr addrspacecast (ptr addrspace(1) @[[GLOB2]] to ptr), i32 [[TMP18]]) +// CHECK-AMD-NEXT: call void @__kmpc_for_static_fini(ptr addrspacecast (ptr addrspace(1) @[[GLOB3]] to ptr), i32 [[TMP18]]) // CHECK-AMD-NEXT: br label [[OMP_PRECOND_END]] // CHECK-AMD: omp.precond.end: // CHECK-AMD-NEXT: ret void diff --git a/clang/test/OpenMP/atomic_read_codegen.c b/clang/test/OpenMP/atomic_read_codegen.c index b60e1686d4dab0b05d340c8dce078e4de44168cc..0a68c8e2c35a5636f4ccb80be25fd6bd21394a8d 100644 --- a/clang/test/OpenMP/atomic_read_codegen.c +++ b/clang/test/OpenMP/atomic_read_codegen.c @@ -128,13 +128,11 @@ int main(void) { // CHECK: store i64 #pragma omp atomic read ullv = ullx; -// CHECK: load atomic i32, ptr {{.*}} monotonic, align 4 -// CHECK: bitcast i32 {{.*}} to float +// CHECK: load atomic float, ptr {{.*}} monotonic, align 4 // CHECK: store float #pragma omp atomic read fv = fx; -// CHECK: load atomic i64, ptr {{.*}} monotonic, align 8 -// CHECK: bitcast i64 {{.*}} to double +// CHECK: load atomic double, ptr {{.*}} monotonic, align 8 // CHECK: store double #pragma omp atomic read dv = dx; @@ -194,11 +192,11 @@ int main(void) { // CHECK: store i64 #pragma omp atomic read lv = cix; -// CHECK: load atomic i32, ptr {{.*}} monotonic, align 4 +// CHECK: load atomic float, ptr {{.*}} monotonic, align 4 // CHECK: store i64 #pragma omp atomic read ulv = fx; -// CHECK: load atomic i64, ptr {{.*}} monotonic, align 8 +// CHECK: load atomic double, ptr {{.*}} monotonic, align 8 // CHECK: store i64 #pragma omp atomic read llv = dx; diff --git a/clang/test/OpenMP/atomic_write_codegen.c b/clang/test/OpenMP/atomic_write_codegen.c index 24dfbf9c0e8fc78d8e16219ccbc3c1538bd0570c..afe8737d30b06584fe1ac28eab8914be184698d3 100644 --- a/clang/test/OpenMP/atomic_write_codegen.c +++ b/clang/test/OpenMP/atomic_write_codegen.c @@ -131,13 +131,11 @@ int main(void) { #pragma omp atomic write ullx = ullv; // CHECK: load float, ptr -// CHECK: bitcast float {{.*}} to i32 -// CHECK: store atomic i32 {{.*}}, ptr {{.*}} monotonic, align 4 +// CHECK: store atomic float {{.*}}, ptr {{.*}} monotonic, align 4 #pragma omp atomic write fx = fv; // CHECK: load double, ptr -// CHECK: bitcast double {{.*}} to i64 -// CHECK: store atomic i64 {{.*}}, ptr {{.*}} monotonic, align 8 +// CHECK: store atomic double {{.*}}, ptr {{.*}} monotonic, align 8 #pragma omp atomic write dx = dv; // CHECK: [[LD:%.+]] = load x86_fp80, ptr @@ -215,11 +213,11 @@ int main(void) { #pragma omp atomic write cix = lv; // CHECK: load i64, ptr -// CHECK: store atomic i32 %{{.+}}, ptr {{.*}} monotonic, align 4 +// CHECK: store atomic float %{{.+}}, ptr {{.*}} monotonic, align 4 #pragma omp atomic write fx = ulv; // CHECK: load i64, ptr -// CHECK: store atomic i64 %{{.+}}, ptr {{.*}} monotonic, align 8 +// CHECK: store atomic double %{{.+}}, ptr {{.*}} monotonic, align 8 #pragma omp atomic write dx = llv; // CHECK: load i64, ptr @@ -491,8 +489,7 @@ int main(void) { float2x.x = ulv; // CHECK: call i32 @llvm.read_register.i32( // CHECK: sitofp i32 %{{.+}} to double -// CHECK: bitcast double %{{.+}} to i64 -// CHECK: store atomic i64 %{{.+}}, ptr @{{.+}} seq_cst, align 8 +// CHECK: store atomic double %{{.+}}, ptr @{{.+}} seq_cst, align 8 // CHECK: call{{.*}} @__kmpc_flush( #pragma omp atomic write seq_cst dv = rix; diff --git a/clang/test/OpenMP/attr-assume.cpp b/clang/test/OpenMP/attr-assume.cpp new file mode 100644 index 0000000000000000000000000000000000000000..09c22f98d1e299ab3220d2e75d8d2b489a25b1e1 --- /dev/null +++ b/clang/test/OpenMP/attr-assume.cpp @@ -0,0 +1,13 @@ +// RUN: %clang_cc1 -fsyntax-only -fopenmp -verify %s +[[omp::assume(3)]] void f1(); // expected-error {{expected string literal as argument of 'assume' attribute}} +[[omp::assume(int)]] void f2(); // expected-error {{expected string literal as argument of 'assume' attribute}} +[[omp::assume(for)]] void f3(); // expected-error {{expected string literal as argument of 'assume' attribute}} +[[omp::assume("QQQQ")]] void f4(); // expected-warning {{unknown assumption string 'QQQQ'; attribute is potentially ignored}} +[[omp::assume("omp_no_openmp")]] void f5(); +[[omp::assume("omp_noopenmp")]] void f6(); // expected-warning {{unknown assumption string 'omp_noopenmp' may be misspelled; attribute is potentially ignored, did you mean 'omp_no_openmp'?}} +[[omp::assume("omp_no_openmp_routine")]] void f7(); // expected-warning {{unknown assumption string 'omp_no_openmp_routine' may be misspelled; attribute is potentially ignored, did you mean 'omp_no_openmp_routines'?}} +[[omp::assume("omp_no_openmp1")]] void f8(); // expected-warning {{unknown assumption string 'omp_no_openmp1' may be misspelled; attribute is potentially ignored, did you mean 'omp_no_openmp'?}} +[[omp::assume("omp_no_openmp", "omp_no_openmp")]] void f9(); // expected-error {{'assume' attribute takes one argument}} + +[[omp::assume(3)]] int g1; // expected-error {{expected string literal as argument of 'assume' attribute}} +[[omp::assume("omp_no_openmp")]] int g2; // expected-warning {{'assume' attribute only applies to functions and Objective-C methods}} diff --git a/clang/test/OpenMP/bug60602.cpp b/clang/test/OpenMP/bug60602.cpp index 3ecc70cab778a1823905283e0acab8e363d017ae..48dc341a08224ec9d0483262536e2e564f824e7a 100644 --- a/clang/test/OpenMP/bug60602.cpp +++ b/clang/test/OpenMP/bug60602.cpp @@ -564,7 +564,7 @@ int kernel_within_loop(int *a, int *b, int N, int num_iters) { // CHECK: omp.loop.exit: // CHECK-NEXT: [[TMP22:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 // CHECK-NEXT: [[TMP23:%.*]] = load i32, ptr [[TMP22]], align 4 -// CHECK-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB3]], i32 [[TMP23]]) +// CHECK-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP23]]) // CHECK-NEXT: br label [[OMP_PRECOND_END]] // CHECK: omp.precond.end: // CHECK-NEXT: ret void diff --git a/clang/test/OpenMP/distribute_parallel_for_codegen.cpp b/clang/test/OpenMP/distribute_parallel_for_codegen.cpp index 95adefa8020f6267ce6210bab6491f60ddbddbf2..9cb0a15530651b4a2f0c5043a431a2023e93b1d8 100644 --- a/clang/test/OpenMP/distribute_parallel_for_codegen.cpp +++ b/clang/test/OpenMP/distribute_parallel_for_codegen.cpp @@ -1027,7 +1027,7 @@ int main() { // CHECK1: omp.loop.exit: // CHECK1-NEXT: [[TMP33:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 // CHECK1-NEXT: [[TMP34:%.*]] = load i32, ptr [[TMP33]], align 4 -// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP34]]) +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP34]]) // CHECK1-NEXT: br label [[OMP_PRECOND_END]] // CHECK1: omp.precond.end: // CHECK1-NEXT: ret void @@ -1266,7 +1266,7 @@ int main() { // CHECK1: omp.loop.exit: // CHECK1-NEXT: [[TMP33:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 // CHECK1-NEXT: [[TMP34:%.*]] = load i32, ptr [[TMP33]], align 4 -// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP34]]) +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP34]]) // CHECK1-NEXT: br label [[OMP_PRECOND_END]] // CHECK1: omp.precond.end: // CHECK1-NEXT: ret void @@ -1535,7 +1535,7 @@ int main() { // CHECK1: omp.loop.exit: // CHECK1-NEXT: [[TMP33:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 // CHECK1-NEXT: [[TMP34:%.*]] = load i32, ptr [[TMP33]], align 4 -// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP34]]) +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP34]]) // CHECK1-NEXT: br label [[OMP_PRECOND_END]] // CHECK1: omp.precond.end: // CHECK1-NEXT: ret void @@ -1774,7 +1774,7 @@ int main() { // CHECK1: omp.loop.exit: // CHECK1-NEXT: [[TMP33:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 // CHECK1-NEXT: [[TMP34:%.*]] = load i32, ptr [[TMP33]], align 4 -// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP34]]) +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP34]]) // CHECK1-NEXT: br label [[OMP_PRECOND_END]] // CHECK1: omp.precond.end: // CHECK1-NEXT: ret void @@ -2047,7 +2047,7 @@ int main() { // CHECK1: omp.dispatch.end: // CHECK1-NEXT: [[TMP40:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 // CHECK1-NEXT: [[TMP41:%.*]] = load i32, ptr [[TMP40]], align 4 -// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP41]]) +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP41]]) // CHECK1-NEXT: br label [[OMP_PRECOND_END]] // CHECK1: omp.precond.end: // CHECK1-NEXT: ret void @@ -2791,7 +2791,7 @@ int main() { // CHECK3: omp.loop.exit: // CHECK3-NEXT: [[TMP33:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 4 // CHECK3-NEXT: [[TMP34:%.*]] = load i32, ptr [[TMP33]], align 4 -// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP34]]) +// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP34]]) // CHECK3-NEXT: br label [[OMP_PRECOND_END]] // CHECK3: omp.precond.end: // CHECK3-NEXT: ret void @@ -3023,7 +3023,7 @@ int main() { // CHECK3: omp.loop.exit: // CHECK3-NEXT: [[TMP33:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 4 // CHECK3-NEXT: [[TMP34:%.*]] = load i32, ptr [[TMP33]], align 4 -// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP34]]) +// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP34]]) // CHECK3-NEXT: br label [[OMP_PRECOND_END]] // CHECK3: omp.precond.end: // CHECK3-NEXT: ret void @@ -3285,7 +3285,7 @@ int main() { // CHECK3: omp.loop.exit: // CHECK3-NEXT: [[TMP33:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 4 // CHECK3-NEXT: [[TMP34:%.*]] = load i32, ptr [[TMP33]], align 4 -// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP34]]) +// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP34]]) // CHECK3-NEXT: br label [[OMP_PRECOND_END]] // CHECK3: omp.precond.end: // CHECK3-NEXT: ret void @@ -3517,7 +3517,7 @@ int main() { // CHECK3: omp.loop.exit: // CHECK3-NEXT: [[TMP33:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 4 // CHECK3-NEXT: [[TMP34:%.*]] = load i32, ptr [[TMP33]], align 4 -// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP34]]) +// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP34]]) // CHECK3-NEXT: br label [[OMP_PRECOND_END]] // CHECK3: omp.precond.end: // CHECK3-NEXT: ret void @@ -3781,7 +3781,7 @@ int main() { // CHECK3: omp.dispatch.end: // CHECK3-NEXT: [[TMP40:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 4 // CHECK3-NEXT: [[TMP41:%.*]] = load i32, ptr [[TMP40]], align 4 -// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP41]]) +// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP41]]) // CHECK3-NEXT: br label [[OMP_PRECOND_END]] // CHECK3: omp.precond.end: // CHECK3-NEXT: ret void @@ -5108,7 +5108,7 @@ int main() { // CHECK9: omp.loop.exit: // CHECK9-NEXT: [[TMP29:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 // CHECK9-NEXT: [[TMP30:%.*]] = load i32, ptr [[TMP29]], align 4 -// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP30]]) +// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP30]]) // CHECK9-NEXT: br label [[OMP_PRECOND_END]] // CHECK9: omp.precond.end: // CHECK9-NEXT: ret void @@ -5337,7 +5337,7 @@ int main() { // CHECK9: omp.loop.exit: // CHECK9-NEXT: [[TMP29:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 // CHECK9-NEXT: [[TMP30:%.*]] = load i32, ptr [[TMP29]], align 4 -// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP30]]) +// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP30]]) // CHECK9-NEXT: br label [[OMP_PRECOND_END]] // CHECK9: omp.precond.end: // CHECK9-NEXT: ret void @@ -5596,7 +5596,7 @@ int main() { // CHECK9: omp.loop.exit: // CHECK9-NEXT: [[TMP29:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 // CHECK9-NEXT: [[TMP30:%.*]] = load i32, ptr [[TMP29]], align 4 -// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP30]]) +// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP30]]) // CHECK9-NEXT: br label [[OMP_PRECOND_END]] // CHECK9: omp.precond.end: // CHECK9-NEXT: ret void @@ -5825,7 +5825,7 @@ int main() { // CHECK9: omp.loop.exit: // CHECK9-NEXT: [[TMP29:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 // CHECK9-NEXT: [[TMP30:%.*]] = load i32, ptr [[TMP29]], align 4 -// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP30]]) +// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP30]]) // CHECK9-NEXT: br label [[OMP_PRECOND_END]] // CHECK9: omp.precond.end: // CHECK9-NEXT: ret void @@ -6088,7 +6088,7 @@ int main() { // CHECK9: omp.dispatch.end: // CHECK9-NEXT: [[TMP36:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 // CHECK9-NEXT: [[TMP37:%.*]] = load i32, ptr [[TMP36]], align 4 -// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP37]]) +// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP37]]) // CHECK9-NEXT: br label [[OMP_PRECOND_END]] // CHECK9: omp.precond.end: // CHECK9-NEXT: ret void @@ -7414,12 +7414,12 @@ int main() { // CHECK9: omp.loop.exit: // CHECK9-NEXT: [[TMP33:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 // CHECK9-NEXT: [[TMP34:%.*]] = load i32, ptr [[TMP33]], align 4 -// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP34]]) +// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP34]]) // CHECK9-NEXT: br label [[OMP_PRECOND_END]] // CHECK9: cancel.exit: // CHECK9-NEXT: [[TMP35:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 // CHECK9-NEXT: [[TMP36:%.*]] = load i32, ptr [[TMP35]], align 4 -// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP36]]) +// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP36]]) // CHECK9-NEXT: br label [[CANCEL_CONT:%.*]] // CHECK9: omp.precond.end: // CHECK9-NEXT: br label [[CANCEL_CONT]] @@ -7650,7 +7650,7 @@ int main() { // CHECK9: omp.loop.exit: // CHECK9-NEXT: [[TMP29:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 // CHECK9-NEXT: [[TMP30:%.*]] = load i32, ptr [[TMP29]], align 4 -// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP30]]) +// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP30]]) // CHECK9-NEXT: br label [[OMP_PRECOND_END]] // CHECK9: omp.precond.end: // CHECK9-NEXT: ret void @@ -7909,7 +7909,7 @@ int main() { // CHECK9: omp.loop.exit: // CHECK9-NEXT: [[TMP29:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 // CHECK9-NEXT: [[TMP30:%.*]] = load i32, ptr [[TMP29]], align 4 -// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP30]]) +// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP30]]) // CHECK9-NEXT: br label [[OMP_PRECOND_END]] // CHECK9: omp.precond.end: // CHECK9-NEXT: ret void @@ -8138,7 +8138,7 @@ int main() { // CHECK9: omp.loop.exit: // CHECK9-NEXT: [[TMP29:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 // CHECK9-NEXT: [[TMP30:%.*]] = load i32, ptr [[TMP29]], align 4 -// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP30]]) +// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP30]]) // CHECK9-NEXT: br label [[OMP_PRECOND_END]] // CHECK9: omp.precond.end: // CHECK9-NEXT: ret void @@ -8401,7 +8401,7 @@ int main() { // CHECK9: omp.dispatch.end: // CHECK9-NEXT: [[TMP36:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 // CHECK9-NEXT: [[TMP37:%.*]] = load i32, ptr [[TMP36]], align 4 -// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP37]]) +// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP37]]) // CHECK9-NEXT: br label [[OMP_PRECOND_END]] // CHECK9: omp.precond.end: // CHECK9-NEXT: ret void @@ -9715,7 +9715,7 @@ int main() { // CHECK11: omp.loop.exit: // CHECK11-NEXT: [[TMP29:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 4 // CHECK11-NEXT: [[TMP30:%.*]] = load i32, ptr [[TMP29]], align 4 -// CHECK11-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP30]]) +// CHECK11-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP30]]) // CHECK11-NEXT: br label [[OMP_PRECOND_END]] // CHECK11: omp.precond.end: // CHECK11-NEXT: ret void @@ -9937,7 +9937,7 @@ int main() { // CHECK11: omp.loop.exit: // CHECK11-NEXT: [[TMP29:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 4 // CHECK11-NEXT: [[TMP30:%.*]] = load i32, ptr [[TMP29]], align 4 -// CHECK11-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP30]]) +// CHECK11-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP30]]) // CHECK11-NEXT: br label [[OMP_PRECOND_END]] // CHECK11: omp.precond.end: // CHECK11-NEXT: ret void @@ -10189,7 +10189,7 @@ int main() { // CHECK11: omp.loop.exit: // CHECK11-NEXT: [[TMP29:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 4 // CHECK11-NEXT: [[TMP30:%.*]] = load i32, ptr [[TMP29]], align 4 -// CHECK11-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP30]]) +// CHECK11-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP30]]) // CHECK11-NEXT: br label [[OMP_PRECOND_END]] // CHECK11: omp.precond.end: // CHECK11-NEXT: ret void @@ -10411,7 +10411,7 @@ int main() { // CHECK11: omp.loop.exit: // CHECK11-NEXT: [[TMP29:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 4 // CHECK11-NEXT: [[TMP30:%.*]] = load i32, ptr [[TMP29]], align 4 -// CHECK11-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP30]]) +// CHECK11-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP30]]) // CHECK11-NEXT: br label [[OMP_PRECOND_END]] // CHECK11: omp.precond.end: // CHECK11-NEXT: ret void @@ -10665,7 +10665,7 @@ int main() { // CHECK11: omp.dispatch.end: // CHECK11-NEXT: [[TMP36:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 4 // CHECK11-NEXT: [[TMP37:%.*]] = load i32, ptr [[TMP36]], align 4 -// CHECK11-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP37]]) +// CHECK11-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP37]]) // CHECK11-NEXT: br label [[OMP_PRECOND_END]] // CHECK11: omp.precond.end: // CHECK11-NEXT: ret void @@ -11970,12 +11970,12 @@ int main() { // CHECK11: omp.loop.exit: // CHECK11-NEXT: [[TMP33:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 4 // CHECK11-NEXT: [[TMP34:%.*]] = load i32, ptr [[TMP33]], align 4 -// CHECK11-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP34]]) +// CHECK11-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP34]]) // CHECK11-NEXT: br label [[OMP_PRECOND_END]] // CHECK11: cancel.exit: // CHECK11-NEXT: [[TMP35:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 4 // CHECK11-NEXT: [[TMP36:%.*]] = load i32, ptr [[TMP35]], align 4 -// CHECK11-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP36]]) +// CHECK11-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP36]]) // CHECK11-NEXT: br label [[CANCEL_CONT:%.*]] // CHECK11: omp.precond.end: // CHECK11-NEXT: br label [[CANCEL_CONT]] @@ -12199,7 +12199,7 @@ int main() { // CHECK11: omp.loop.exit: // CHECK11-NEXT: [[TMP29:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 4 // CHECK11-NEXT: [[TMP30:%.*]] = load i32, ptr [[TMP29]], align 4 -// CHECK11-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP30]]) +// CHECK11-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP30]]) // CHECK11-NEXT: br label [[OMP_PRECOND_END]] // CHECK11: omp.precond.end: // CHECK11-NEXT: ret void @@ -12451,7 +12451,7 @@ int main() { // CHECK11: omp.loop.exit: // CHECK11-NEXT: [[TMP29:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 4 // CHECK11-NEXT: [[TMP30:%.*]] = load i32, ptr [[TMP29]], align 4 -// CHECK11-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP30]]) +// CHECK11-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP30]]) // CHECK11-NEXT: br label [[OMP_PRECOND_END]] // CHECK11: omp.precond.end: // CHECK11-NEXT: ret void @@ -12673,7 +12673,7 @@ int main() { // CHECK11: omp.loop.exit: // CHECK11-NEXT: [[TMP29:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 4 // CHECK11-NEXT: [[TMP30:%.*]] = load i32, ptr [[TMP29]], align 4 -// CHECK11-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP30]]) +// CHECK11-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP30]]) // CHECK11-NEXT: br label [[OMP_PRECOND_END]] // CHECK11: omp.precond.end: // CHECK11-NEXT: ret void @@ -12927,7 +12927,7 @@ int main() { // CHECK11: omp.dispatch.end: // CHECK11-NEXT: [[TMP36:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 4 // CHECK11-NEXT: [[TMP37:%.*]] = load i32, ptr [[TMP36]], align 4 -// CHECK11-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP37]]) +// CHECK11-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP37]]) // CHECK11-NEXT: br label [[OMP_PRECOND_END]] // CHECK11: omp.precond.end: // CHECK11-NEXT: ret void diff --git a/clang/test/OpenMP/distribute_parallel_for_firstprivate_codegen.cpp b/clang/test/OpenMP/distribute_parallel_for_firstprivate_codegen.cpp index 46c115e40e4356fa6a3de92441cdf3684754de7a..6084a9a6cf931457adf3a907d3e46a2fcdde62a2 100644 --- a/clang/test/OpenMP/distribute_parallel_for_firstprivate_codegen.cpp +++ b/clang/test/OpenMP/distribute_parallel_for_firstprivate_codegen.cpp @@ -500,7 +500,7 @@ int main() { // CHECK1: omp.inner.for.end: // CHECK1-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK1: omp.loop.exit: -// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP3]]) +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) // CHECK1-NEXT: ret void // // @@ -748,7 +748,7 @@ int main() { // CHECK3: omp.inner.for.end: // CHECK3-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK3: omp.loop.exit: -// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP5]]) +// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP5]]) // CHECK3-NEXT: ret void // // @@ -1167,7 +1167,7 @@ int main() { // CHECK8: omp.loop.exit: // CHECK8-NEXT: [[TMP20:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 // CHECK8-NEXT: [[TMP21:%.*]] = load i32, ptr [[TMP20]], align 4 -// CHECK8-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP21]]) +// CHECK8-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP21]]) // CHECK8-NEXT: call void @_ZN1SIfED1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[VAR6]]) #[[ATTR4]] // CHECK8-NEXT: [[ARRAY_BEGIN12:%.*]] = getelementptr inbounds [2 x %struct.S], ptr [[S_ARR4]], i32 0, i32 0 // CHECK8-NEXT: [[TMP22:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[ARRAY_BEGIN12]], i64 2 @@ -1612,7 +1612,7 @@ int main() { // CHECK8: omp.loop.exit: // CHECK8-NEXT: [[TMP20:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 // CHECK8-NEXT: [[TMP21:%.*]] = load i32, ptr [[TMP20]], align 4 -// CHECK8-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP21]]) +// CHECK8-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP21]]) // CHECK8-NEXT: call void @_ZN1SIiED1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[VAR6]]) #[[ATTR4]] // CHECK8-NEXT: [[ARRAY_BEGIN12:%.*]] = getelementptr inbounds [2 x %struct.S.0], ptr [[S_ARR4]], i32 0, i32 0 // CHECK8-NEXT: [[TMP22:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[ARRAY_BEGIN12]], i64 2 @@ -2080,7 +2080,7 @@ int main() { // CHECK10: omp.loop.exit: // CHECK10-NEXT: [[TMP20:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 4 // CHECK10-NEXT: [[TMP21:%.*]] = load i32, ptr [[TMP20]], align 4 -// CHECK10-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP21]]) +// CHECK10-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP21]]) // CHECK10-NEXT: call void @_ZN1SIfED1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[VAR5]]) #[[ATTR4]] // CHECK10-NEXT: [[ARRAY_BEGIN10:%.*]] = getelementptr inbounds [2 x %struct.S], ptr [[S_ARR3]], i32 0, i32 0 // CHECK10-NEXT: [[TMP22:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[ARRAY_BEGIN10]], i32 2 @@ -2519,7 +2519,7 @@ int main() { // CHECK10: omp.loop.exit: // CHECK10-NEXT: [[TMP20:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 4 // CHECK10-NEXT: [[TMP21:%.*]] = load i32, ptr [[TMP20]], align 4 -// CHECK10-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP21]]) +// CHECK10-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP21]]) // CHECK10-NEXT: call void @_ZN1SIiED1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[VAR5]]) #[[ATTR4]] // CHECK10-NEXT: [[ARRAY_BEGIN10:%.*]] = getelementptr inbounds [2 x %struct.S.0], ptr [[S_ARR3]], i32 0, i32 0 // CHECK10-NEXT: [[TMP22:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[ARRAY_BEGIN10]], i32 2 diff --git a/clang/test/OpenMP/distribute_parallel_for_if_codegen.cpp b/clang/test/OpenMP/distribute_parallel_for_if_codegen.cpp index 846e7beb5d92ffe476373a37082ebb7a0644b618..d3b6654e57e2c99e76564e487d0ef5ce2d618eba 100644 --- a/clang/test/OpenMP/distribute_parallel_for_if_codegen.cpp +++ b/clang/test/OpenMP/distribute_parallel_for_if_codegen.cpp @@ -329,7 +329,7 @@ int main() { // CHECK1: omp.inner.for.end: // CHECK1-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK1: omp.loop.exit: -// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP3]]) +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) // CHECK1-NEXT: ret void // // @@ -472,7 +472,7 @@ int main() { // CHECK1: omp.inner.for.end: // CHECK1-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK1: omp.loop.exit: -// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP3]]) +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) // CHECK1-NEXT: ret void // // @@ -740,7 +740,7 @@ int main() { // CHECK1: omp.inner.for.end: // CHECK1-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK1: omp.loop.exit: -// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP3]]) +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) // CHECK1-NEXT: ret void // // @@ -883,7 +883,7 @@ int main() { // CHECK1: omp.inner.for.end: // CHECK1-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK1: omp.loop.exit: -// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP3]]) +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) // CHECK1-NEXT: ret void // // @@ -1040,7 +1040,7 @@ int main() { // CHECK1: omp.inner.for.end: // CHECK1-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK1: omp.loop.exit: -// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP3]]) +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) // CHECK1-NEXT: ret void // // @@ -1306,7 +1306,7 @@ int main() { // CHECK1: omp.inner.for.end: // CHECK1-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK1: omp.loop.exit: -// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP3]]) +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) // CHECK1-NEXT: ret void // // @@ -1449,7 +1449,7 @@ int main() { // CHECK1: omp.inner.for.end: // CHECK1-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK1: omp.loop.exit: -// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP3]]) +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) // CHECK1-NEXT: ret void // // @@ -1606,6 +1606,6 @@ int main() { // CHECK1: omp.inner.for.end: // CHECK1-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK1: omp.loop.exit: -// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP3]]) +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) // CHECK1-NEXT: ret void // diff --git a/clang/test/OpenMP/distribute_parallel_for_lastprivate_codegen.cpp b/clang/test/OpenMP/distribute_parallel_for_lastprivate_codegen.cpp index aa981f606cc876200d170967622dec73704e76f4..1f069c4070aecfa81c4a4ff68cca35117a3ec905 100644 --- a/clang/test/OpenMP/distribute_parallel_for_lastprivate_codegen.cpp +++ b/clang/test/OpenMP/distribute_parallel_for_lastprivate_codegen.cpp @@ -443,7 +443,7 @@ int main() { // CHECK1: omp.inner.for.end: // CHECK1-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK1: omp.loop.exit: -// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP8]]) +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP8]]) // CHECK1-NEXT: [[TMP22:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK1-NEXT: [[TMP23:%.*]] = icmp ne i32 [[TMP22]], 0 // CHECK1-NEXT: br i1 [[TMP23]], label [[DOTOMP_LASTPRIVATE_THEN:%.*]], label [[DOTOMP_LASTPRIVATE_DONE:%.*]] @@ -708,7 +708,7 @@ int main() { // CHECK3: omp.inner.for.end: // CHECK3-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK3: omp.loop.exit: -// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP8]]) +// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP8]]) // CHECK3-NEXT: [[TMP22:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK3-NEXT: [[TMP23:%.*]] = icmp ne i32 [[TMP22]], 0 // CHECK3-NEXT: br i1 [[TMP23]], label [[DOTOMP_LASTPRIVATE_THEN:%.*]], label [[DOTOMP_LASTPRIVATE_DONE:%.*]] @@ -1153,7 +1153,7 @@ int main() { // CHECK9: omp.loop.exit: // CHECK9-NEXT: [[TMP21:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 // CHECK9-NEXT: [[TMP22:%.*]] = load i32, ptr [[TMP21]], align 4 -// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP22]]) +// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP22]]) // CHECK9-NEXT: [[TMP23:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK9-NEXT: [[TMP24:%.*]] = icmp ne i32 [[TMP23]], 0 // CHECK9-NEXT: br i1 [[TMP24]], label [[DOTOMP_LASTPRIVATE_THEN:%.*]], label [[DOTOMP_LASTPRIVATE_DONE:%.*]] @@ -1636,7 +1636,7 @@ int main() { // CHECK9: omp.loop.exit: // CHECK9-NEXT: [[TMP20:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 // CHECK9-NEXT: [[TMP21:%.*]] = load i32, ptr [[TMP20]], align 4 -// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP21]]) +// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP21]]) // CHECK9-NEXT: [[TMP22:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK9-NEXT: [[TMP23:%.*]] = icmp ne i32 [[TMP22]], 0 // CHECK9-NEXT: br i1 [[TMP23]], label [[DOTOMP_LASTPRIVATE_THEN:%.*]], label [[DOTOMP_LASTPRIVATE_DONE:%.*]] @@ -2139,7 +2139,7 @@ int main() { // CHECK11: omp.loop.exit: // CHECK11-NEXT: [[TMP21:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 4 // CHECK11-NEXT: [[TMP22:%.*]] = load i32, ptr [[TMP21]], align 4 -// CHECK11-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP22]]) +// CHECK11-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP22]]) // CHECK11-NEXT: [[TMP23:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK11-NEXT: [[TMP24:%.*]] = icmp ne i32 [[TMP23]], 0 // CHECK11-NEXT: br i1 [[TMP24]], label [[DOTOMP_LASTPRIVATE_THEN:%.*]], label [[DOTOMP_LASTPRIVATE_DONE:%.*]] @@ -2616,7 +2616,7 @@ int main() { // CHECK11: omp.loop.exit: // CHECK11-NEXT: [[TMP20:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 4 // CHECK11-NEXT: [[TMP21:%.*]] = load i32, ptr [[TMP20]], align 4 -// CHECK11-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP21]]) +// CHECK11-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP21]]) // CHECK11-NEXT: [[TMP22:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK11-NEXT: [[TMP23:%.*]] = icmp ne i32 [[TMP22]], 0 // CHECK11-NEXT: br i1 [[TMP23]], label [[DOTOMP_LASTPRIVATE_THEN:%.*]], label [[DOTOMP_LASTPRIVATE_DONE:%.*]] diff --git a/clang/test/OpenMP/distribute_parallel_for_num_threads_codegen.cpp b/clang/test/OpenMP/distribute_parallel_for_num_threads_codegen.cpp index 5d9244268d5546bf3a2e23507a8fef56a1d36bc0..b6ae783b74d049cf833e4849bcab1ae5096046ef 100644 --- a/clang/test/OpenMP/distribute_parallel_for_num_threads_codegen.cpp +++ b/clang/test/OpenMP/distribute_parallel_for_num_threads_codegen.cpp @@ -386,7 +386,7 @@ int main() { // CHECK1: omp.inner.for.end: // CHECK1-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK1: omp.loop.exit: -// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP3]]) +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) // CHECK1-NEXT: ret void // CHECK1: terminate.lpad: // CHECK1-NEXT: [[TMP11:%.*]] = landingpad { ptr, i32 } @@ -547,7 +547,7 @@ int main() { // CHECK1: omp.inner.for.end: // CHECK1-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK1: omp.loop.exit: -// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP3]]) +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) // CHECK1-NEXT: ret void // CHECK1: terminate.lpad: // CHECK1-NEXT: [[TMP11:%.*]] = landingpad { ptr, i32 } @@ -879,7 +879,7 @@ int main() { // CHECK1: omp.inner.for.end: // CHECK1-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK1: omp.loop.exit: -// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP3]]) +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) // CHECK1-NEXT: ret void // CHECK1: terminate.lpad: // CHECK1-NEXT: [[TMP11:%.*]] = landingpad { ptr, i32 } @@ -1026,7 +1026,7 @@ int main() { // CHECK1: omp.inner.for.end: // CHECK1-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK1: omp.loop.exit: -// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP3]]) +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) // CHECK1-NEXT: ret void // CHECK1: terminate.lpad: // CHECK1-NEXT: [[TMP11:%.*]] = landingpad { ptr, i32 } @@ -1173,7 +1173,7 @@ int main() { // CHECK1: omp.inner.for.end: // CHECK1-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK1: omp.loop.exit: -// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP3]]) +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) // CHECK1-NEXT: ret void // CHECK1: terminate.lpad: // CHECK1-NEXT: [[TMP11:%.*]] = landingpad { ptr, i32 } @@ -1335,7 +1335,7 @@ int main() { // CHECK1: omp.inner.for.end: // CHECK1-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK1: omp.loop.exit: -// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP3]]) +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) // CHECK1-NEXT: ret void // CHECK1: terminate.lpad: // CHECK1-NEXT: [[TMP11:%.*]] = landingpad { ptr, i32 } @@ -1638,7 +1638,7 @@ int main() { // CHECK5: omp.inner.for.end: // CHECK5-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK5: omp.loop.exit: -// CHECK5-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP3]]) +// CHECK5-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) // CHECK5-NEXT: ret void // CHECK5: terminate.lpad: // CHECK5-NEXT: [[TMP11:%.*]] = landingpad { ptr, i32 } @@ -1799,7 +1799,7 @@ int main() { // CHECK5: omp.inner.for.end: // CHECK5-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK5: omp.loop.exit: -// CHECK5-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP3]]) +// CHECK5-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) // CHECK5-NEXT: ret void // CHECK5: terminate.lpad: // CHECK5-NEXT: [[TMP11:%.*]] = landingpad { ptr, i32 } @@ -2122,7 +2122,7 @@ int main() { // CHECK5: omp.inner.for.end: // CHECK5-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK5: omp.loop.exit: -// CHECK5-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP3]]) +// CHECK5-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) // CHECK5-NEXT: ret void // CHECK5: terminate.lpad: // CHECK5-NEXT: [[TMP11:%.*]] = landingpad { ptr, i32 } @@ -2269,7 +2269,7 @@ int main() { // CHECK5: omp.inner.for.end: // CHECK5-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK5: omp.loop.exit: -// CHECK5-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP3]]) +// CHECK5-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) // CHECK5-NEXT: ret void // CHECK5: terminate.lpad: // CHECK5-NEXT: [[TMP11:%.*]] = landingpad { ptr, i32 } @@ -2416,7 +2416,7 @@ int main() { // CHECK5: omp.inner.for.end: // CHECK5-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK5: omp.loop.exit: -// CHECK5-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP3]]) +// CHECK5-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) // CHECK5-NEXT: ret void // CHECK5: terminate.lpad: // CHECK5-NEXT: [[TMP11:%.*]] = landingpad { ptr, i32 } @@ -2578,7 +2578,7 @@ int main() { // CHECK5: omp.inner.for.end: // CHECK5-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK5: omp.loop.exit: -// CHECK5-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP3]]) +// CHECK5-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) // CHECK5-NEXT: ret void // CHECK5: terminate.lpad: // CHECK5-NEXT: [[TMP11:%.*]] = landingpad { ptr, i32 } @@ -2890,7 +2890,7 @@ int main() { // CHECK9: omp.inner.for.end: // CHECK9-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK9: omp.loop.exit: -// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP3]]) +// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) // CHECK9-NEXT: ret void // CHECK9: terminate.lpad: // CHECK9-NEXT: [[TMP11:%.*]] = landingpad { ptr, i32 } @@ -3051,7 +3051,7 @@ int main() { // CHECK9: omp.inner.for.end: // CHECK9-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK9: omp.loop.exit: -// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP3]]) +// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) // CHECK9-NEXT: ret void // CHECK9: terminate.lpad: // CHECK9-NEXT: [[TMP11:%.*]] = landingpad { ptr, i32 } @@ -3383,7 +3383,7 @@ int main() { // CHECK9: omp.inner.for.end: // CHECK9-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK9: omp.loop.exit: -// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP3]]) +// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) // CHECK9-NEXT: ret void // CHECK9: terminate.lpad: // CHECK9-NEXT: [[TMP11:%.*]] = landingpad { ptr, i32 } @@ -3530,7 +3530,7 @@ int main() { // CHECK9: omp.inner.for.end: // CHECK9-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK9: omp.loop.exit: -// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP3]]) +// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) // CHECK9-NEXT: ret void // CHECK9: terminate.lpad: // CHECK9-NEXT: [[TMP11:%.*]] = landingpad { ptr, i32 } @@ -3677,7 +3677,7 @@ int main() { // CHECK9: omp.inner.for.end: // CHECK9-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK9: omp.loop.exit: -// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP3]]) +// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) // CHECK9-NEXT: ret void // CHECK9: terminate.lpad: // CHECK9-NEXT: [[TMP11:%.*]] = landingpad { ptr, i32 } @@ -3839,7 +3839,7 @@ int main() { // CHECK9: omp.inner.for.end: // CHECK9-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK9: omp.loop.exit: -// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP3]]) +// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) // CHECK9-NEXT: ret void // CHECK9: terminate.lpad: // CHECK9-NEXT: [[TMP11:%.*]] = landingpad { ptr, i32 } @@ -4142,7 +4142,7 @@ int main() { // CHECK13: omp.inner.for.end: // CHECK13-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK13: omp.loop.exit: -// CHECK13-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP3]]) +// CHECK13-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) // CHECK13-NEXT: ret void // CHECK13: terminate.lpad: // CHECK13-NEXT: [[TMP11:%.*]] = landingpad { ptr, i32 } @@ -4303,7 +4303,7 @@ int main() { // CHECK13: omp.inner.for.end: // CHECK13-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK13: omp.loop.exit: -// CHECK13-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP3]]) +// CHECK13-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) // CHECK13-NEXT: ret void // CHECK13: terminate.lpad: // CHECK13-NEXT: [[TMP11:%.*]] = landingpad { ptr, i32 } @@ -4626,7 +4626,7 @@ int main() { // CHECK13: omp.inner.for.end: // CHECK13-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK13: omp.loop.exit: -// CHECK13-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP3]]) +// CHECK13-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) // CHECK13-NEXT: ret void // CHECK13: terminate.lpad: // CHECK13-NEXT: [[TMP11:%.*]] = landingpad { ptr, i32 } @@ -4773,7 +4773,7 @@ int main() { // CHECK13: omp.inner.for.end: // CHECK13-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK13: omp.loop.exit: -// CHECK13-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP3]]) +// CHECK13-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) // CHECK13-NEXT: ret void // CHECK13: terminate.lpad: // CHECK13-NEXT: [[TMP11:%.*]] = landingpad { ptr, i32 } @@ -4920,7 +4920,7 @@ int main() { // CHECK13: omp.inner.for.end: // CHECK13-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK13: omp.loop.exit: -// CHECK13-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP3]]) +// CHECK13-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) // CHECK13-NEXT: ret void // CHECK13: terminate.lpad: // CHECK13-NEXT: [[TMP11:%.*]] = landingpad { ptr, i32 } @@ -5082,7 +5082,7 @@ int main() { // CHECK13: omp.inner.for.end: // CHECK13-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK13: omp.loop.exit: -// CHECK13-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP3]]) +// CHECK13-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) // CHECK13-NEXT: ret void // CHECK13: terminate.lpad: // CHECK13-NEXT: [[TMP11:%.*]] = landingpad { ptr, i32 } diff --git a/clang/test/OpenMP/distribute_parallel_for_private_codegen.cpp b/clang/test/OpenMP/distribute_parallel_for_private_codegen.cpp index 249609c7d831c548a30304bc75d5d21ec909deb0..e2b0d64093ebc0313e4502f4af5cdb4cb959bd0d 100644 --- a/clang/test/OpenMP/distribute_parallel_for_private_codegen.cpp +++ b/clang/test/OpenMP/distribute_parallel_for_private_codegen.cpp @@ -313,7 +313,7 @@ int main() { // CHECK1: omp.inner.for.end: // CHECK1-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK1: omp.loop.exit: -// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP3]]) +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) // CHECK1-NEXT: ret void // // @@ -491,7 +491,7 @@ int main() { // CHECK3: omp.inner.for.end: // CHECK3-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK3: omp.loop.exit: -// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP3]]) +// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) // CHECK3-NEXT: ret void // // @@ -795,7 +795,7 @@ int main() { // CHECK9: omp.loop.exit: // CHECK9-NEXT: [[TMP15:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 // CHECK9-NEXT: [[TMP16:%.*]] = load i32, ptr [[TMP15]], align 4 -// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP16]]) +// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP16]]) // CHECK9-NEXT: call void @_ZN1SIfED1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[VAR]]) #[[ATTR4]] // CHECK9-NEXT: [[ARRAY_BEGIN8:%.*]] = getelementptr inbounds [2 x %struct.S], ptr [[S_ARR]], i32 0, i32 0 // CHECK9-NEXT: [[TMP17:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[ARRAY_BEGIN8]], i64 2 @@ -1147,7 +1147,7 @@ int main() { // CHECK9: omp.loop.exit: // CHECK9-NEXT: [[TMP15:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 // CHECK9-NEXT: [[TMP16:%.*]] = load i32, ptr [[TMP15]], align 4 -// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP16]]) +// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP16]]) // CHECK9-NEXT: call void @_ZN1SIiED1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[VAR]]) #[[ATTR4]] // CHECK9-NEXT: [[ARRAY_BEGIN8:%.*]] = getelementptr inbounds [2 x %struct.S.0], ptr [[S_ARR]], i32 0, i32 0 // CHECK9-NEXT: [[TMP17:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[ARRAY_BEGIN8]], i64 2 @@ -1500,7 +1500,7 @@ int main() { // CHECK11: omp.loop.exit: // CHECK11-NEXT: [[TMP15:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 4 // CHECK11-NEXT: [[TMP16:%.*]] = load i32, ptr [[TMP15]], align 4 -// CHECK11-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP16]]) +// CHECK11-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP16]]) // CHECK11-NEXT: call void @_ZN1SIfED1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[VAR]]) #[[ATTR4]] // CHECK11-NEXT: [[ARRAY_BEGIN6:%.*]] = getelementptr inbounds [2 x %struct.S], ptr [[S_ARR]], i32 0, i32 0 // CHECK11-NEXT: [[TMP17:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[ARRAY_BEGIN6]], i32 2 @@ -1846,7 +1846,7 @@ int main() { // CHECK11: omp.loop.exit: // CHECK11-NEXT: [[TMP15:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 4 // CHECK11-NEXT: [[TMP16:%.*]] = load i32, ptr [[TMP15]], align 4 -// CHECK11-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP16]]) +// CHECK11-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP16]]) // CHECK11-NEXT: call void @_ZN1SIiED1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[VAR]]) #[[ATTR4]] // CHECK11-NEXT: [[ARRAY_BEGIN6:%.*]] = getelementptr inbounds [2 x %struct.S.0], ptr [[S_ARR]], i32 0, i32 0 // CHECK11-NEXT: [[TMP17:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[ARRAY_BEGIN6]], i32 2 diff --git a/clang/test/OpenMP/distribute_parallel_for_proc_bind_codegen.cpp b/clang/test/OpenMP/distribute_parallel_for_proc_bind_codegen.cpp index 8784611d8399ed40eb088a14e5e2e19308729195..040f90b9ef78bd269355e1ac757e5b4498472b20 100644 --- a/clang/test/OpenMP/distribute_parallel_for_proc_bind_codegen.cpp +++ b/clang/test/OpenMP/distribute_parallel_for_proc_bind_codegen.cpp @@ -266,7 +266,7 @@ int main() { // CHECK1: omp.inner.for.end: // CHECK1-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK1: omp.loop.exit: -// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP3]]) +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) // CHECK1-NEXT: ret void // // @@ -404,7 +404,7 @@ int main() { // CHECK1: omp.inner.for.end: // CHECK1-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK1: omp.loop.exit: -// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP3]]) +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) // CHECK1-NEXT: ret void // // @@ -583,6 +583,6 @@ int main() { // CHECK1: omp.inner.for.end: // CHECK1-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK1: omp.loop.exit: -// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP3]]) +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) // CHECK1-NEXT: ret void // diff --git a/clang/test/OpenMP/distribute_parallel_for_reduction_task_codegen.cpp b/clang/test/OpenMP/distribute_parallel_for_reduction_task_codegen.cpp index 7caca83c25d647952e3a2a1d1ceca601a11210df..a019f09c14cb87fe31e5d5c4fffc937c247ac69e 100644 --- a/clang/test/OpenMP/distribute_parallel_for_reduction_task_codegen.cpp +++ b/clang/test/OpenMP/distribute_parallel_for_reduction_task_codegen.cpp @@ -328,7 +328,7 @@ int main(int argc, char **argv) { // CHECK1: omp.loop.exit: // CHECK1-NEXT: [[TMP78:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 // CHECK1-NEXT: [[TMP79:%.*]] = load i32, ptr [[TMP78]], align 4 -// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP79]]) +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB3]], i32 [[TMP79]]) // CHECK1-NEXT: [[TMP80:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 // CHECK1-NEXT: [[TMP81:%.*]] = load i32, ptr [[TMP80]], align 4 // CHECK1-NEXT: call void @__kmpc_task_reduction_modifier_fini(ptr @[[GLOB2]], i32 [[TMP81]], i32 1) @@ -343,8 +343,8 @@ int main(int argc, char **argv) { // CHECK1-NEXT: [[TMP87:%.*]] = load i32, ptr [[TMP86]], align 4 // CHECK1-NEXT: [[TMP88:%.*]] = call i32 @__kmpc_reduce_nowait(ptr @[[GLOB4:[0-9]+]], i32 [[TMP87]], i32 2, i64 24, ptr [[DOTOMP_REDUCTION_RED_LIST]], ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l14.omp_outlined.omp_outlined.omp.reduction.reduction_func, ptr @.gomp_critical_user_.reduction.var) // CHECK1-NEXT: switch i32 [[TMP88]], label [[DOTOMP_REDUCTION_DEFAULT:%.*]] [ -// CHECK1-NEXT: i32 1, label [[DOTOMP_REDUCTION_CASE1:%.*]] -// CHECK1-NEXT: i32 2, label [[DOTOMP_REDUCTION_CASE2:%.*]] +// CHECK1-NEXT: i32 1, label [[DOTOMP_REDUCTION_CASE1:%.*]] +// CHECK1-NEXT: i32 2, label [[DOTOMP_REDUCTION_CASE2:%.*]] // CHECK1-NEXT: ] // CHECK1: .omp.reduction.case1: // CHECK1-NEXT: [[TMP89:%.*]] = load i32, ptr [[TMP0]], align 4 @@ -536,21 +536,21 @@ int main(int argc, char **argv) { // CHECK1-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META6:![0-9]+]]) // CHECK1-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META8:![0-9]+]]) // CHECK1-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META10:![0-9]+]]) -// CHECK1-NEXT: store i32 [[TMP2]], ptr [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !12 -// CHECK1-NEXT: store ptr [[TMP5]], ptr [[DOTPART_ID__ADDR_I]], align 8, !noalias !12 -// CHECK1-NEXT: store ptr [[TMP8]], ptr [[DOTPRIVATES__ADDR_I]], align 8, !noalias !12 -// CHECK1-NEXT: store ptr @.omp_task_privates_map., ptr [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !12 -// CHECK1-NEXT: store ptr [[TMP3]], ptr [[DOTTASK_T__ADDR_I]], align 8, !noalias !12 -// CHECK1-NEXT: store ptr [[TMP7]], ptr [[__CONTEXT_ADDR_I]], align 8, !noalias !12 -// CHECK1-NEXT: [[TMP9:%.*]] = load ptr, ptr [[__CONTEXT_ADDR_I]], align 8, !noalias !12 -// CHECK1-NEXT: [[TMP10:%.*]] = load ptr, ptr [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !12 -// CHECK1-NEXT: [[TMP11:%.*]] = load ptr, ptr [[DOTPRIVATES__ADDR_I]], align 8, !noalias !12 +// CHECK1-NEXT: store i32 [[TMP2]], ptr [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias [[META12:![0-9]+]] +// CHECK1-NEXT: store ptr [[TMP5]], ptr [[DOTPART_ID__ADDR_I]], align 8, !noalias [[META12]] +// CHECK1-NEXT: store ptr [[TMP8]], ptr [[DOTPRIVATES__ADDR_I]], align 8, !noalias [[META12]] +// CHECK1-NEXT: store ptr @.omp_task_privates_map., ptr [[DOTCOPY_FN__ADDR_I]], align 8, !noalias [[META12]] +// CHECK1-NEXT: store ptr [[TMP3]], ptr [[DOTTASK_T__ADDR_I]], align 8, !noalias [[META12]] +// CHECK1-NEXT: store ptr [[TMP7]], ptr [[__CONTEXT_ADDR_I]], align 8, !noalias [[META12]] +// CHECK1-NEXT: [[TMP9:%.*]] = load ptr, ptr [[__CONTEXT_ADDR_I]], align 8, !noalias [[META12]] +// CHECK1-NEXT: [[TMP10:%.*]] = load ptr, ptr [[DOTCOPY_FN__ADDR_I]], align 8, !noalias [[META12]] +// CHECK1-NEXT: [[TMP11:%.*]] = load ptr, ptr [[DOTPRIVATES__ADDR_I]], align 8, !noalias [[META12]] // CHECK1-NEXT: call void [[TMP10]](ptr [[TMP11]], ptr [[DOTFIRSTPRIV_PTR_ADDR_I]]) #[[ATTR2]] -// CHECK1-NEXT: [[TMP12:%.*]] = load ptr, ptr [[DOTFIRSTPRIV_PTR_ADDR_I]], align 8, !noalias !12 +// CHECK1-NEXT: [[TMP12:%.*]] = load ptr, ptr [[DOTFIRSTPRIV_PTR_ADDR_I]], align 8, !noalias [[META12]] // CHECK1-NEXT: [[TMP13:%.*]] = getelementptr inbounds [[STRUCT_ANON:%.*]], ptr [[TMP9]], i32 0, i32 1 // CHECK1-NEXT: [[TMP14:%.*]] = load ptr, ptr [[TMP13]], align 8 // CHECK1-NEXT: [[TMP15:%.*]] = load ptr, ptr [[TMP12]], align 8 -// CHECK1-NEXT: [[TMP16:%.*]] = load i32, ptr [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !12 +// CHECK1-NEXT: [[TMP16:%.*]] = load i32, ptr [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias [[META12]] // CHECK1-NEXT: [[TMP17:%.*]] = call ptr @__kmpc_task_reduction_get_th_data(i32 [[TMP16]], ptr [[TMP15]], ptr [[TMP14]]) // CHECK1-NEXT: [[TMP18:%.*]] = getelementptr inbounds [[STRUCT_ANON]], ptr [[TMP9]], i32 0, i32 2 // CHECK1-NEXT: [[TMP19:%.*]] = load ptr, ptr [[TMP18]], align 8 @@ -570,7 +570,7 @@ int main(int argc, char **argv) { // CHECK1-NEXT: [[TMP30:%.*]] = sub i64 [[TMP28]], [[TMP29]] // CHECK1-NEXT: [[TMP31:%.*]] = add nuw i64 [[TMP30]], 1 // CHECK1-NEXT: [[TMP32:%.*]] = mul nuw i64 [[TMP31]], ptrtoint (ptr getelementptr (i8, ptr null, i32 1) to i64) -// CHECK1-NEXT: store i64 [[TMP31]], ptr @{{reduction_size[.].+[.]}}, align 8, !noalias !12 +// CHECK1-NEXT: store i64 [[TMP31]], ptr @{{reduction_size[.].+[.]}}, align 8, !noalias [[META12]] // CHECK1-NEXT: [[TMP33:%.*]] = load ptr, ptr [[TMP12]], align 8 // CHECK1-NEXT: [[TMP34:%.*]] = call ptr @__kmpc_task_reduction_get_th_data(i32 [[TMP16]], ptr [[TMP33]], ptr [[TMP20]]) // CHECK1-NEXT: [[TMP35:%.*]] = getelementptr inbounds [[STRUCT_ANON]], ptr [[TMP9]], i32 0, i32 2 @@ -580,8 +580,8 @@ int main(int argc, char **argv) { // CHECK1-NEXT: [[TMP39:%.*]] = ptrtoint ptr [[TMP20]] to i64 // CHECK1-NEXT: [[TMP40:%.*]] = sub i64 [[TMP38]], [[TMP39]] // CHECK1-NEXT: [[TMP41:%.*]] = getelementptr i8, ptr [[TMP34]], i64 [[TMP40]] -// CHECK1-NEXT: store ptr [[TMP4_I]], ptr [[TMP_I]], align 8, !noalias !12 -// CHECK1-NEXT: store ptr [[TMP41]], ptr [[TMP4_I]], align 8, !noalias !12 +// CHECK1-NEXT: store ptr [[TMP4_I]], ptr [[TMP_I]], align 8, !noalias [[META12]] +// CHECK1-NEXT: store ptr [[TMP41]], ptr [[TMP4_I]], align 8, !noalias [[META12]] // CHECK1-NEXT: ret i32 0 // // diff --git a/clang/test/OpenMP/distribute_parallel_for_simd_codegen.cpp b/clang/test/OpenMP/distribute_parallel_for_simd_codegen.cpp index e0618cb9924596e65d550595f58b949f80b16245..77336877e2be0427f853f0572766a4ee7dc8e551 100644 --- a/clang/test/OpenMP/distribute_parallel_for_simd_codegen.cpp +++ b/clang/test/OpenMP/distribute_parallel_for_simd_codegen.cpp @@ -1039,7 +1039,7 @@ int main() { // CHECK1: omp.loop.exit: // CHECK1-NEXT: [[TMP33:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 // CHECK1-NEXT: [[TMP34:%.*]] = load i32, ptr [[TMP33]], align 4 -// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP34]]) +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP34]]) // CHECK1-NEXT: [[TMP35:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK1-NEXT: [[TMP36:%.*]] = icmp ne i32 [[TMP35]], 0 // CHECK1-NEXT: br i1 [[TMP36]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -1302,7 +1302,7 @@ int main() { // CHECK1: omp.loop.exit: // CHECK1-NEXT: [[TMP33:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 // CHECK1-NEXT: [[TMP34:%.*]] = load i32, ptr [[TMP33]], align 4 -// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP34]]) +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP34]]) // CHECK1-NEXT: [[TMP35:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK1-NEXT: [[TMP36:%.*]] = icmp ne i32 [[TMP35]], 0 // CHECK1-NEXT: br i1 [[TMP36]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -1595,7 +1595,7 @@ int main() { // CHECK1: omp.loop.exit: // CHECK1-NEXT: [[TMP33:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 // CHECK1-NEXT: [[TMP34:%.*]] = load i32, ptr [[TMP33]], align 4 -// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP34]]) +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP34]]) // CHECK1-NEXT: [[TMP35:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK1-NEXT: [[TMP36:%.*]] = icmp ne i32 [[TMP35]], 0 // CHECK1-NEXT: br i1 [[TMP36]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -1858,7 +1858,7 @@ int main() { // CHECK1: omp.loop.exit: // CHECK1-NEXT: [[TMP33:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 // CHECK1-NEXT: [[TMP34:%.*]] = load i32, ptr [[TMP33]], align 4 -// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP34]]) +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP34]]) // CHECK1-NEXT: [[TMP35:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK1-NEXT: [[TMP36:%.*]] = icmp ne i32 [[TMP35]], 0 // CHECK1-NEXT: br i1 [[TMP36]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -2155,7 +2155,7 @@ int main() { // CHECK1: omp.dispatch.end: // CHECK1-NEXT: [[TMP40:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 // CHECK1-NEXT: [[TMP41:%.*]] = load i32, ptr [[TMP40]], align 4 -// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP41]]) +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP41]]) // CHECK1-NEXT: [[TMP42:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK1-NEXT: [[TMP43:%.*]] = icmp ne i32 [[TMP42]], 0 // CHECK1-NEXT: br i1 [[TMP43]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -2971,7 +2971,7 @@ int main() { // CHECK3: omp.loop.exit: // CHECK3-NEXT: [[TMP33:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 4 // CHECK3-NEXT: [[TMP34:%.*]] = load i32, ptr [[TMP33]], align 4 -// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP34]]) +// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP34]]) // CHECK3-NEXT: [[TMP35:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK3-NEXT: [[TMP36:%.*]] = icmp ne i32 [[TMP35]], 0 // CHECK3-NEXT: br i1 [[TMP36]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -3227,7 +3227,7 @@ int main() { // CHECK3: omp.loop.exit: // CHECK3-NEXT: [[TMP33:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 4 // CHECK3-NEXT: [[TMP34:%.*]] = load i32, ptr [[TMP33]], align 4 -// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP34]]) +// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP34]]) // CHECK3-NEXT: [[TMP35:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK3-NEXT: [[TMP36:%.*]] = icmp ne i32 [[TMP35]], 0 // CHECK3-NEXT: br i1 [[TMP36]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -3513,7 +3513,7 @@ int main() { // CHECK3: omp.loop.exit: // CHECK3-NEXT: [[TMP33:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 4 // CHECK3-NEXT: [[TMP34:%.*]] = load i32, ptr [[TMP33]], align 4 -// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP34]]) +// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP34]]) // CHECK3-NEXT: [[TMP35:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK3-NEXT: [[TMP36:%.*]] = icmp ne i32 [[TMP35]], 0 // CHECK3-NEXT: br i1 [[TMP36]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -3769,7 +3769,7 @@ int main() { // CHECK3: omp.loop.exit: // CHECK3-NEXT: [[TMP33:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 4 // CHECK3-NEXT: [[TMP34:%.*]] = load i32, ptr [[TMP33]], align 4 -// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP34]]) +// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP34]]) // CHECK3-NEXT: [[TMP35:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK3-NEXT: [[TMP36:%.*]] = icmp ne i32 [[TMP35]], 0 // CHECK3-NEXT: br i1 [[TMP36]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -4057,7 +4057,7 @@ int main() { // CHECK3: omp.dispatch.end: // CHECK3-NEXT: [[TMP40:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 4 // CHECK3-NEXT: [[TMP41:%.*]] = load i32, ptr [[TMP40]], align 4 -// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP41]]) +// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP41]]) // CHECK3-NEXT: [[TMP42:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK3-NEXT: [[TMP43:%.*]] = icmp ne i32 [[TMP42]], 0 // CHECK3-NEXT: br i1 [[TMP43]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -5510,7 +5510,7 @@ int main() { // CHECK9: omp.loop.exit: // CHECK9-NEXT: [[TMP29:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 // CHECK9-NEXT: [[TMP30:%.*]] = load i32, ptr [[TMP29]], align 4 -// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP30]]) +// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP30]]) // CHECK9-NEXT: [[TMP31:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK9-NEXT: [[TMP32:%.*]] = icmp ne i32 [[TMP31]], 0 // CHECK9-NEXT: br i1 [[TMP32]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -5763,7 +5763,7 @@ int main() { // CHECK9: omp.loop.exit: // CHECK9-NEXT: [[TMP29:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 // CHECK9-NEXT: [[TMP30:%.*]] = load i32, ptr [[TMP29]], align 4 -// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP30]]) +// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP30]]) // CHECK9-NEXT: [[TMP31:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK9-NEXT: [[TMP32:%.*]] = icmp ne i32 [[TMP31]], 0 // CHECK9-NEXT: br i1 [[TMP32]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -6046,7 +6046,7 @@ int main() { // CHECK9: omp.loop.exit: // CHECK9-NEXT: [[TMP29:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 // CHECK9-NEXT: [[TMP30:%.*]] = load i32, ptr [[TMP29]], align 4 -// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP30]]) +// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP30]]) // CHECK9-NEXT: [[TMP31:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK9-NEXT: [[TMP32:%.*]] = icmp ne i32 [[TMP31]], 0 // CHECK9-NEXT: br i1 [[TMP32]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -6299,7 +6299,7 @@ int main() { // CHECK9: omp.loop.exit: // CHECK9-NEXT: [[TMP29:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 // CHECK9-NEXT: [[TMP30:%.*]] = load i32, ptr [[TMP29]], align 4 -// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP30]]) +// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP30]]) // CHECK9-NEXT: [[TMP31:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK9-NEXT: [[TMP32:%.*]] = icmp ne i32 [[TMP31]], 0 // CHECK9-NEXT: br i1 [[TMP32]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -6586,7 +6586,7 @@ int main() { // CHECK9: omp.dispatch.end: // CHECK9-NEXT: [[TMP36:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 // CHECK9-NEXT: [[TMP37:%.*]] = load i32, ptr [[TMP36]], align 4 -// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP37]]) +// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP37]]) // CHECK9-NEXT: [[TMP38:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK9-NEXT: [[TMP39:%.*]] = icmp ne i32 [[TMP38]], 0 // CHECK9-NEXT: br i1 [[TMP39]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -7976,7 +7976,7 @@ int main() { // CHECK9: omp.loop.exit: // CHECK9-NEXT: [[TMP29:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 // CHECK9-NEXT: [[TMP30:%.*]] = load i32, ptr [[TMP29]], align 4 -// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP30]]) +// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP30]]) // CHECK9-NEXT: [[TMP31:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK9-NEXT: [[TMP32:%.*]] = icmp ne i32 [[TMP31]], 0 // CHECK9-NEXT: br i1 [[TMP32]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -8229,7 +8229,7 @@ int main() { // CHECK9: omp.loop.exit: // CHECK9-NEXT: [[TMP29:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 // CHECK9-NEXT: [[TMP30:%.*]] = load i32, ptr [[TMP29]], align 4 -// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP30]]) +// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP30]]) // CHECK9-NEXT: [[TMP31:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK9-NEXT: [[TMP32:%.*]] = icmp ne i32 [[TMP31]], 0 // CHECK9-NEXT: br i1 [[TMP32]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -8512,7 +8512,7 @@ int main() { // CHECK9: omp.loop.exit: // CHECK9-NEXT: [[TMP29:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 // CHECK9-NEXT: [[TMP30:%.*]] = load i32, ptr [[TMP29]], align 4 -// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP30]]) +// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP30]]) // CHECK9-NEXT: [[TMP31:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK9-NEXT: [[TMP32:%.*]] = icmp ne i32 [[TMP31]], 0 // CHECK9-NEXT: br i1 [[TMP32]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -8765,7 +8765,7 @@ int main() { // CHECK9: omp.loop.exit: // CHECK9-NEXT: [[TMP29:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 // CHECK9-NEXT: [[TMP30:%.*]] = load i32, ptr [[TMP29]], align 4 -// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP30]]) +// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP30]]) // CHECK9-NEXT: [[TMP31:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK9-NEXT: [[TMP32:%.*]] = icmp ne i32 [[TMP31]], 0 // CHECK9-NEXT: br i1 [[TMP32]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -9052,7 +9052,7 @@ int main() { // CHECK9: omp.dispatch.end: // CHECK9-NEXT: [[TMP36:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 // CHECK9-NEXT: [[TMP37:%.*]] = load i32, ptr [[TMP36]], align 4 -// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP37]]) +// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP37]]) // CHECK9-NEXT: [[TMP38:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK9-NEXT: [[TMP39:%.*]] = icmp ne i32 [[TMP38]], 0 // CHECK9-NEXT: br i1 [[TMP39]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -10438,7 +10438,7 @@ int main() { // CHECK11: omp.loop.exit: // CHECK11-NEXT: [[TMP29:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 4 // CHECK11-NEXT: [[TMP30:%.*]] = load i32, ptr [[TMP29]], align 4 -// CHECK11-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP30]]) +// CHECK11-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP30]]) // CHECK11-NEXT: [[TMP31:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK11-NEXT: [[TMP32:%.*]] = icmp ne i32 [[TMP31]], 0 // CHECK11-NEXT: br i1 [[TMP32]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -10684,7 +10684,7 @@ int main() { // CHECK11: omp.loop.exit: // CHECK11-NEXT: [[TMP29:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 4 // CHECK11-NEXT: [[TMP30:%.*]] = load i32, ptr [[TMP29]], align 4 -// CHECK11-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP30]]) +// CHECK11-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP30]]) // CHECK11-NEXT: [[TMP31:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK11-NEXT: [[TMP32:%.*]] = icmp ne i32 [[TMP31]], 0 // CHECK11-NEXT: br i1 [[TMP32]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -10960,7 +10960,7 @@ int main() { // CHECK11: omp.loop.exit: // CHECK11-NEXT: [[TMP29:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 4 // CHECK11-NEXT: [[TMP30:%.*]] = load i32, ptr [[TMP29]], align 4 -// CHECK11-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP30]]) +// CHECK11-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP30]]) // CHECK11-NEXT: [[TMP31:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK11-NEXT: [[TMP32:%.*]] = icmp ne i32 [[TMP31]], 0 // CHECK11-NEXT: br i1 [[TMP32]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -11206,7 +11206,7 @@ int main() { // CHECK11: omp.loop.exit: // CHECK11-NEXT: [[TMP29:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 4 // CHECK11-NEXT: [[TMP30:%.*]] = load i32, ptr [[TMP29]], align 4 -// CHECK11-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP30]]) +// CHECK11-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP30]]) // CHECK11-NEXT: [[TMP31:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK11-NEXT: [[TMP32:%.*]] = icmp ne i32 [[TMP31]], 0 // CHECK11-NEXT: br i1 [[TMP32]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -11484,7 +11484,7 @@ int main() { // CHECK11: omp.dispatch.end: // CHECK11-NEXT: [[TMP36:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 4 // CHECK11-NEXT: [[TMP37:%.*]] = load i32, ptr [[TMP36]], align 4 -// CHECK11-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP37]]) +// CHECK11-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP37]]) // CHECK11-NEXT: [[TMP38:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK11-NEXT: [[TMP39:%.*]] = icmp ne i32 [[TMP38]], 0 // CHECK11-NEXT: br i1 [[TMP39]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -12853,7 +12853,7 @@ int main() { // CHECK11: omp.loop.exit: // CHECK11-NEXT: [[TMP29:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 4 // CHECK11-NEXT: [[TMP30:%.*]] = load i32, ptr [[TMP29]], align 4 -// CHECK11-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP30]]) +// CHECK11-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP30]]) // CHECK11-NEXT: [[TMP31:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK11-NEXT: [[TMP32:%.*]] = icmp ne i32 [[TMP31]], 0 // CHECK11-NEXT: br i1 [[TMP32]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -13099,7 +13099,7 @@ int main() { // CHECK11: omp.loop.exit: // CHECK11-NEXT: [[TMP29:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 4 // CHECK11-NEXT: [[TMP30:%.*]] = load i32, ptr [[TMP29]], align 4 -// CHECK11-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP30]]) +// CHECK11-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP30]]) // CHECK11-NEXT: [[TMP31:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK11-NEXT: [[TMP32:%.*]] = icmp ne i32 [[TMP31]], 0 // CHECK11-NEXT: br i1 [[TMP32]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -13375,7 +13375,7 @@ int main() { // CHECK11: omp.loop.exit: // CHECK11-NEXT: [[TMP29:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 4 // CHECK11-NEXT: [[TMP30:%.*]] = load i32, ptr [[TMP29]], align 4 -// CHECK11-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP30]]) +// CHECK11-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP30]]) // CHECK11-NEXT: [[TMP31:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK11-NEXT: [[TMP32:%.*]] = icmp ne i32 [[TMP31]], 0 // CHECK11-NEXT: br i1 [[TMP32]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -13621,7 +13621,7 @@ int main() { // CHECK11: omp.loop.exit: // CHECK11-NEXT: [[TMP29:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 4 // CHECK11-NEXT: [[TMP30:%.*]] = load i32, ptr [[TMP29]], align 4 -// CHECK11-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP30]]) +// CHECK11-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP30]]) // CHECK11-NEXT: [[TMP31:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK11-NEXT: [[TMP32:%.*]] = icmp ne i32 [[TMP31]], 0 // CHECK11-NEXT: br i1 [[TMP32]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -13899,7 +13899,7 @@ int main() { // CHECK11: omp.dispatch.end: // CHECK11-NEXT: [[TMP36:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 4 // CHECK11-NEXT: [[TMP37:%.*]] = load i32, ptr [[TMP36]], align 4 -// CHECK11-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP37]]) +// CHECK11-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP37]]) // CHECK11-NEXT: [[TMP38:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK11-NEXT: [[TMP39:%.*]] = icmp ne i32 [[TMP38]], 0 // CHECK11-NEXT: br i1 [[TMP39]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] diff --git a/clang/test/OpenMP/distribute_parallel_for_simd_firstprivate_codegen.cpp b/clang/test/OpenMP/distribute_parallel_for_simd_firstprivate_codegen.cpp index 5c9b2aa1f47fb668f97679b83ce7e9d3e29126b4..f47b64b1e299d597f722b779b649e6f8dde3ce0b 100644 --- a/clang/test/OpenMP/distribute_parallel_for_simd_firstprivate_codegen.cpp +++ b/clang/test/OpenMP/distribute_parallel_for_simd_firstprivate_codegen.cpp @@ -506,7 +506,7 @@ int main() { // CHECK1: omp.inner.for.end: // CHECK1-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK1: omp.loop.exit: -// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP3]]) +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) // CHECK1-NEXT: [[TMP17:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK1-NEXT: [[TMP18:%.*]] = icmp ne i32 [[TMP17]], 0 // CHECK1-NEXT: br i1 [[TMP18]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -768,7 +768,7 @@ int main() { // CHECK3: omp.inner.for.end: // CHECK3-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK3: omp.loop.exit: -// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP5]]) +// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP5]]) // CHECK3-NEXT: [[TMP19:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK3-NEXT: [[TMP20:%.*]] = icmp ne i32 [[TMP19]], 0 // CHECK3-NEXT: br i1 [[TMP20]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -1237,7 +1237,7 @@ int main() { // CHECK8: omp.loop.exit: // CHECK8-NEXT: [[TMP20:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 // CHECK8-NEXT: [[TMP21:%.*]] = load i32, ptr [[TMP20]], align 4 -// CHECK8-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP21]]) +// CHECK8-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP21]]) // CHECK8-NEXT: [[TMP22:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK8-NEXT: [[TMP23:%.*]] = icmp ne i32 [[TMP22]], 0 // CHECK8-NEXT: br i1 [[TMP23]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -1696,7 +1696,7 @@ int main() { // CHECK8: omp.loop.exit: // CHECK8-NEXT: [[TMP20:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 // CHECK8-NEXT: [[TMP21:%.*]] = load i32, ptr [[TMP20]], align 4 -// CHECK8-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP21]]) +// CHECK8-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP21]]) // CHECK8-NEXT: [[TMP22:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK8-NEXT: [[TMP23:%.*]] = icmp ne i32 [[TMP22]], 0 // CHECK8-NEXT: br i1 [[TMP23]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -2178,7 +2178,7 @@ int main() { // CHECK10: omp.loop.exit: // CHECK10-NEXT: [[TMP20:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 4 // CHECK10-NEXT: [[TMP21:%.*]] = load i32, ptr [[TMP20]], align 4 -// CHECK10-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP21]]) +// CHECK10-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP21]]) // CHECK10-NEXT: [[TMP22:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK10-NEXT: [[TMP23:%.*]] = icmp ne i32 [[TMP22]], 0 // CHECK10-NEXT: br i1 [[TMP23]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -2631,7 +2631,7 @@ int main() { // CHECK10: omp.loop.exit: // CHECK10-NEXT: [[TMP20:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 4 // CHECK10-NEXT: [[TMP21:%.*]] = load i32, ptr [[TMP20]], align 4 -// CHECK10-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP21]]) +// CHECK10-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP21]]) // CHECK10-NEXT: [[TMP22:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK10-NEXT: [[TMP23:%.*]] = icmp ne i32 [[TMP22]], 0 // CHECK10-NEXT: br i1 [[TMP23]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] diff --git a/clang/test/OpenMP/distribute_parallel_for_simd_if_codegen.cpp b/clang/test/OpenMP/distribute_parallel_for_simd_if_codegen.cpp index 67384abc7751eef8624099a1dc1019c32240525a..b3e964fddcf0d7afa4ab343a766069974c5919cf 100644 --- a/clang/test/OpenMP/distribute_parallel_for_simd_if_codegen.cpp +++ b/clang/test/OpenMP/distribute_parallel_for_simd_if_codegen.cpp @@ -333,7 +333,7 @@ int main() { // CHECK1: omp.inner.for.end: // CHECK1-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK1: omp.loop.exit: -// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP3]]) +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) // CHECK1-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK1-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 // CHECK1-NEXT: br i1 [[TMP12]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -490,7 +490,7 @@ int main() { // CHECK1: omp.inner.for.end: // CHECK1-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK1: omp.loop.exit: -// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP3]]) +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) // CHECK1-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK1-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 // CHECK1-NEXT: br i1 [[TMP12]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -772,7 +772,7 @@ int main() { // CHECK1: omp.inner.for.end: // CHECK1-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK1: omp.loop.exit: -// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP3]]) +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) // CHECK1-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK1-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 // CHECK1-NEXT: br i1 [[TMP12]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -929,7 +929,7 @@ int main() { // CHECK1: omp.inner.for.end: // CHECK1-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK1: omp.loop.exit: -// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP3]]) +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) // CHECK1-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK1-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 // CHECK1-NEXT: br i1 [[TMP12]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -1100,7 +1100,7 @@ int main() { // CHECK1: omp.inner.for.end: // CHECK1-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK1: omp.loop.exit: -// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP3]]) +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) // CHECK1-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK1-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 // CHECK1-NEXT: br i1 [[TMP12]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -1380,7 +1380,7 @@ int main() { // CHECK1: omp.inner.for.end: // CHECK1-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK1: omp.loop.exit: -// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP3]]) +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) // CHECK1-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK1-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 // CHECK1-NEXT: br i1 [[TMP12]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -1537,7 +1537,7 @@ int main() { // CHECK1: omp.inner.for.end: // CHECK1-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK1: omp.loop.exit: -// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP3]]) +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) // CHECK1-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK1-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 // CHECK1-NEXT: br i1 [[TMP12]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -1708,7 +1708,7 @@ int main() { // CHECK1: omp.inner.for.end: // CHECK1-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK1: omp.loop.exit: -// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP3]]) +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) // CHECK1-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK1-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 // CHECK1-NEXT: br i1 [[TMP12]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -1935,7 +1935,7 @@ int main() { // CHECK3: omp.inner.for.end: // CHECK3-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK3: omp.loop.exit: -// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP3]]) +// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) // CHECK3-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK3-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 // CHECK3-NEXT: br i1 [[TMP12]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -2092,7 +2092,7 @@ int main() { // CHECK3: omp.inner.for.end: // CHECK3-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK3: omp.loop.exit: -// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP3]]) +// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) // CHECK3-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK3-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 // CHECK3-NEXT: br i1 [[TMP12]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -2374,7 +2374,7 @@ int main() { // CHECK3: omp.inner.for.end: // CHECK3-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK3: omp.loop.exit: -// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP3]]) +// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) // CHECK3-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK3-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 // CHECK3-NEXT: br i1 [[TMP12]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -2531,7 +2531,7 @@ int main() { // CHECK3: omp.inner.for.end: // CHECK3-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK3: omp.loop.exit: -// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP3]]) +// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) // CHECK3-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK3-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 // CHECK3-NEXT: br i1 [[TMP12]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -2810,7 +2810,7 @@ int main() { // CHECK3: omp.loop.exit: // CHECK3-NEXT: [[TMP21:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 // CHECK3-NEXT: [[TMP22:%.*]] = load i32, ptr [[TMP21]], align 4 -// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP22]]) +// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP22]]) // CHECK3-NEXT: [[TMP23:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK3-NEXT: [[TMP24:%.*]] = icmp ne i32 [[TMP23]], 0 // CHECK3-NEXT: br i1 [[TMP24]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -2937,7 +2937,7 @@ int main() { // CHECK3: omp.loop.exit: // CHECK3-NEXT: [[TMP21:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 // CHECK3-NEXT: [[TMP22:%.*]] = load i32, ptr [[TMP21]], align 4 -// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP22]]) +// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP22]]) // CHECK3-NEXT: [[TMP23:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK3-NEXT: [[TMP24:%.*]] = icmp ne i32 [[TMP23]], 0 // CHECK3-NEXT: br i1 [[TMP24]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -3217,7 +3217,7 @@ int main() { // CHECK3: omp.inner.for.end: // CHECK3-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK3: omp.loop.exit: -// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP3]]) +// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) // CHECK3-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK3-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 // CHECK3-NEXT: br i1 [[TMP12]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -3374,7 +3374,7 @@ int main() { // CHECK3: omp.inner.for.end: // CHECK3-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK3: omp.loop.exit: -// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP3]]) +// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) // CHECK3-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK3-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 // CHECK3-NEXT: br i1 [[TMP12]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -3545,7 +3545,7 @@ int main() { // CHECK3: omp.inner.for.end: // CHECK3-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK3: omp.loop.exit: -// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP3]]) +// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) // CHECK3-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK3-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 // CHECK3-NEXT: br i1 [[TMP12]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -4348,7 +4348,7 @@ int main() { // CHECK9: omp.inner.for.end: // CHECK9-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK9: omp.loop.exit: -// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP3]]) +// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) // CHECK9-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK9-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 // CHECK9-NEXT: br i1 [[TMP12]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -4505,7 +4505,7 @@ int main() { // CHECK9: omp.inner.for.end: // CHECK9-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK9: omp.loop.exit: -// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP3]]) +// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) // CHECK9-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK9-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 // CHECK9-NEXT: br i1 [[TMP12]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -4787,7 +4787,7 @@ int main() { // CHECK9: omp.inner.for.end: // CHECK9-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK9: omp.loop.exit: -// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP3]]) +// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) // CHECK9-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK9-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 // CHECK9-NEXT: br i1 [[TMP12]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -4944,7 +4944,7 @@ int main() { // CHECK9: omp.inner.for.end: // CHECK9-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK9: omp.loop.exit: -// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP3]]) +// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) // CHECK9-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK9-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 // CHECK9-NEXT: br i1 [[TMP12]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -5115,7 +5115,7 @@ int main() { // CHECK9: omp.inner.for.end: // CHECK9-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK9: omp.loop.exit: -// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP3]]) +// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) // CHECK9-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK9-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 // CHECK9-NEXT: br i1 [[TMP12]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -5395,7 +5395,7 @@ int main() { // CHECK9: omp.inner.for.end: // CHECK9-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK9: omp.loop.exit: -// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP3]]) +// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) // CHECK9-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK9-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 // CHECK9-NEXT: br i1 [[TMP12]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -5552,7 +5552,7 @@ int main() { // CHECK9: omp.inner.for.end: // CHECK9-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK9: omp.loop.exit: -// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP3]]) +// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) // CHECK9-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK9-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 // CHECK9-NEXT: br i1 [[TMP12]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -5723,7 +5723,7 @@ int main() { // CHECK9: omp.inner.for.end: // CHECK9-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK9: omp.loop.exit: -// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP3]]) +// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) // CHECK9-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK9-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 // CHECK9-NEXT: br i1 [[TMP12]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -5950,7 +5950,7 @@ int main() { // CHECK11: omp.inner.for.end: // CHECK11-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK11: omp.loop.exit: -// CHECK11-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP3]]) +// CHECK11-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) // CHECK11-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK11-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 // CHECK11-NEXT: br i1 [[TMP12]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -6107,7 +6107,7 @@ int main() { // CHECK11: omp.inner.for.end: // CHECK11-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK11: omp.loop.exit: -// CHECK11-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP3]]) +// CHECK11-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) // CHECK11-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK11-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 // CHECK11-NEXT: br i1 [[TMP12]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -6389,7 +6389,7 @@ int main() { // CHECK11: omp.inner.for.end: // CHECK11-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK11: omp.loop.exit: -// CHECK11-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP3]]) +// CHECK11-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) // CHECK11-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK11-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 // CHECK11-NEXT: br i1 [[TMP12]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -6546,7 +6546,7 @@ int main() { // CHECK11: omp.inner.for.end: // CHECK11-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK11: omp.loop.exit: -// CHECK11-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP3]]) +// CHECK11-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) // CHECK11-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK11-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 // CHECK11-NEXT: br i1 [[TMP12]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -6825,7 +6825,7 @@ int main() { // CHECK11: omp.loop.exit: // CHECK11-NEXT: [[TMP21:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 // CHECK11-NEXT: [[TMP22:%.*]] = load i32, ptr [[TMP21]], align 4 -// CHECK11-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP22]]) +// CHECK11-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP22]]) // CHECK11-NEXT: [[TMP23:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK11-NEXT: [[TMP24:%.*]] = icmp ne i32 [[TMP23]], 0 // CHECK11-NEXT: br i1 [[TMP24]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -6952,7 +6952,7 @@ int main() { // CHECK11: omp.loop.exit: // CHECK11-NEXT: [[TMP21:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 // CHECK11-NEXT: [[TMP22:%.*]] = load i32, ptr [[TMP21]], align 4 -// CHECK11-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP22]]) +// CHECK11-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP22]]) // CHECK11-NEXT: [[TMP23:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK11-NEXT: [[TMP24:%.*]] = icmp ne i32 [[TMP23]], 0 // CHECK11-NEXT: br i1 [[TMP24]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -7232,7 +7232,7 @@ int main() { // CHECK11: omp.inner.for.end: // CHECK11-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK11: omp.loop.exit: -// CHECK11-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP3]]) +// CHECK11-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) // CHECK11-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK11-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 // CHECK11-NEXT: br i1 [[TMP12]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -7389,7 +7389,7 @@ int main() { // CHECK11: omp.inner.for.end: // CHECK11-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK11: omp.loop.exit: -// CHECK11-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP3]]) +// CHECK11-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) // CHECK11-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK11-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 // CHECK11-NEXT: br i1 [[TMP12]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -7560,7 +7560,7 @@ int main() { // CHECK11: omp.inner.for.end: // CHECK11-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK11: omp.loop.exit: -// CHECK11-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP3]]) +// CHECK11-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) // CHECK11-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK11-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 // CHECK11-NEXT: br i1 [[TMP12]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] diff --git a/clang/test/OpenMP/distribute_parallel_for_simd_lastprivate_codegen.cpp b/clang/test/OpenMP/distribute_parallel_for_simd_lastprivate_codegen.cpp index adef55eee1cd5f9a58f7b1102cfdca6f223131ad..7656fb7bc2c519dc68b62a97ee344c76052e2b60 100644 --- a/clang/test/OpenMP/distribute_parallel_for_simd_lastprivate_codegen.cpp +++ b/clang/test/OpenMP/distribute_parallel_for_simd_lastprivate_codegen.cpp @@ -453,7 +453,7 @@ int main() { // CHECK1: omp.inner.for.end: // CHECK1-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK1: omp.loop.exit: -// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP8]]) +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP8]]) // CHECK1-NEXT: [[TMP22:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK1-NEXT: [[TMP23:%.*]] = icmp ne i32 [[TMP22]], 0 // CHECK1-NEXT: br i1 [[TMP23]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -732,7 +732,7 @@ int main() { // CHECK3: omp.inner.for.end: // CHECK3-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK3: omp.loop.exit: -// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP8]]) +// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP8]]) // CHECK3-NEXT: [[TMP22:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK3-NEXT: [[TMP23:%.*]] = icmp ne i32 [[TMP22]], 0 // CHECK3-NEXT: br i1 [[TMP23]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -1227,7 +1227,7 @@ int main() { // CHECK9: omp.loop.exit: // CHECK9-NEXT: [[TMP21:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 // CHECK9-NEXT: [[TMP22:%.*]] = load i32, ptr [[TMP21]], align 4 -// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP22]]) +// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP22]]) // CHECK9-NEXT: [[TMP23:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK9-NEXT: [[TMP24:%.*]] = icmp ne i32 [[TMP23]], 0 // CHECK9-NEXT: br i1 [[TMP24]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -1724,7 +1724,7 @@ int main() { // CHECK9: omp.loop.exit: // CHECK9-NEXT: [[TMP20:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 // CHECK9-NEXT: [[TMP21:%.*]] = load i32, ptr [[TMP20]], align 4 -// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP21]]) +// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP21]]) // CHECK9-NEXT: [[TMP22:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK9-NEXT: [[TMP23:%.*]] = icmp ne i32 [[TMP22]], 0 // CHECK9-NEXT: br i1 [[TMP23]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -2241,7 +2241,7 @@ int main() { // CHECK11: omp.loop.exit: // CHECK11-NEXT: [[TMP21:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 4 // CHECK11-NEXT: [[TMP22:%.*]] = load i32, ptr [[TMP21]], align 4 -// CHECK11-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP22]]) +// CHECK11-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP22]]) // CHECK11-NEXT: [[TMP23:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK11-NEXT: [[TMP24:%.*]] = icmp ne i32 [[TMP23]], 0 // CHECK11-NEXT: br i1 [[TMP24]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -2732,7 +2732,7 @@ int main() { // CHECK11: omp.loop.exit: // CHECK11-NEXT: [[TMP20:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 4 // CHECK11-NEXT: [[TMP21:%.*]] = load i32, ptr [[TMP20]], align 4 -// CHECK11-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP21]]) +// CHECK11-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP21]]) // CHECK11-NEXT: [[TMP22:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK11-NEXT: [[TMP23:%.*]] = icmp ne i32 [[TMP22]], 0 // CHECK11-NEXT: br i1 [[TMP23]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] diff --git a/clang/test/OpenMP/distribute_parallel_for_simd_num_threads_codegen.cpp b/clang/test/OpenMP/distribute_parallel_for_simd_num_threads_codegen.cpp index 0a0ed699acb1a2a2e160345fc1d803001c799b05..9f4fffbea63d16e3357eafe2fdab8fa0af5e8486 100644 --- a/clang/test/OpenMP/distribute_parallel_for_simd_num_threads_codegen.cpp +++ b/clang/test/OpenMP/distribute_parallel_for_simd_num_threads_codegen.cpp @@ -393,7 +393,7 @@ int main() { // CHECK1: omp.inner.for.end: // CHECK1-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK1: omp.loop.exit: -// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP3]]) +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) // CHECK1-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK1-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 // CHECK1-NEXT: br i1 [[TMP12]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -568,7 +568,7 @@ int main() { // CHECK1: omp.inner.for.end: // CHECK1-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK1: omp.loop.exit: -// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP3]]) +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) // CHECK1-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK1-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 // CHECK1-NEXT: br i1 [[TMP12]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -914,7 +914,7 @@ int main() { // CHECK1: omp.inner.for.end: // CHECK1-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK1: omp.loop.exit: -// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP3]]) +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) // CHECK1-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK1-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 // CHECK1-NEXT: br i1 [[TMP12]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -1075,7 +1075,7 @@ int main() { // CHECK1: omp.inner.for.end: // CHECK1-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK1: omp.loop.exit: -// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP3]]) +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) // CHECK1-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK1-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 // CHECK1-NEXT: br i1 [[TMP12]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -1236,7 +1236,7 @@ int main() { // CHECK1: omp.inner.for.end: // CHECK1-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK1: omp.loop.exit: -// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP3]]) +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) // CHECK1-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK1-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 // CHECK1-NEXT: br i1 [[TMP12]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -1412,7 +1412,7 @@ int main() { // CHECK1: omp.inner.for.end: // CHECK1-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK1: omp.loop.exit: -// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP3]]) +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) // CHECK1-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK1-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 // CHECK1-NEXT: br i1 [[TMP12]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -2068,7 +2068,7 @@ int main() { // CHECK5: omp.inner.for.end: // CHECK5-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK5: omp.loop.exit: -// CHECK5-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP3]]) +// CHECK5-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) // CHECK5-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK5-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 // CHECK5-NEXT: br i1 [[TMP12]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -2243,7 +2243,7 @@ int main() { // CHECK5: omp.inner.for.end: // CHECK5-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK5: omp.loop.exit: -// CHECK5-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP3]]) +// CHECK5-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) // CHECK5-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK5-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 // CHECK5-NEXT: br i1 [[TMP12]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -2580,7 +2580,7 @@ int main() { // CHECK5: omp.inner.for.end: // CHECK5-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK5: omp.loop.exit: -// CHECK5-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP3]]) +// CHECK5-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) // CHECK5-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK5-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 // CHECK5-NEXT: br i1 [[TMP12]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -2741,7 +2741,7 @@ int main() { // CHECK5: omp.inner.for.end: // CHECK5-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK5: omp.loop.exit: -// CHECK5-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP3]]) +// CHECK5-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) // CHECK5-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK5-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 // CHECK5-NEXT: br i1 [[TMP12]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -2902,7 +2902,7 @@ int main() { // CHECK5: omp.inner.for.end: // CHECK5-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK5: omp.loop.exit: -// CHECK5-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP3]]) +// CHECK5-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) // CHECK5-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK5-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 // CHECK5-NEXT: br i1 [[TMP12]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -3078,7 +3078,7 @@ int main() { // CHECK5: omp.inner.for.end: // CHECK5-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK5: omp.loop.exit: -// CHECK5-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP3]]) +// CHECK5-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) // CHECK5-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK5-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 // CHECK5-NEXT: br i1 [[TMP12]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -3404,7 +3404,7 @@ int main() { // CHECK9: omp.inner.for.end: // CHECK9-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK9: omp.loop.exit: -// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP3]]) +// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) // CHECK9-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK9-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 // CHECK9-NEXT: br i1 [[TMP12]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -3579,7 +3579,7 @@ int main() { // CHECK9: omp.inner.for.end: // CHECK9-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK9: omp.loop.exit: -// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP3]]) +// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) // CHECK9-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK9-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 // CHECK9-NEXT: br i1 [[TMP12]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -3925,7 +3925,7 @@ int main() { // CHECK9: omp.inner.for.end: // CHECK9-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK9: omp.loop.exit: -// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP3]]) +// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) // CHECK9-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK9-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 // CHECK9-NEXT: br i1 [[TMP12]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -4086,7 +4086,7 @@ int main() { // CHECK9: omp.inner.for.end: // CHECK9-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK9: omp.loop.exit: -// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP3]]) +// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) // CHECK9-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK9-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 // CHECK9-NEXT: br i1 [[TMP12]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -4247,7 +4247,7 @@ int main() { // CHECK9: omp.inner.for.end: // CHECK9-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK9: omp.loop.exit: -// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP3]]) +// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) // CHECK9-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK9-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 // CHECK9-NEXT: br i1 [[TMP12]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -4423,7 +4423,7 @@ int main() { // CHECK9: omp.inner.for.end: // CHECK9-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK9: omp.loop.exit: -// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP3]]) +// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) // CHECK9-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK9-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 // CHECK9-NEXT: br i1 [[TMP12]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -5079,7 +5079,7 @@ int main() { // CHECK13: omp.inner.for.end: // CHECK13-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK13: omp.loop.exit: -// CHECK13-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP3]]) +// CHECK13-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) // CHECK13-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK13-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 // CHECK13-NEXT: br i1 [[TMP12]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -5254,7 +5254,7 @@ int main() { // CHECK13: omp.inner.for.end: // CHECK13-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK13: omp.loop.exit: -// CHECK13-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP3]]) +// CHECK13-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) // CHECK13-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK13-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 // CHECK13-NEXT: br i1 [[TMP12]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -5591,7 +5591,7 @@ int main() { // CHECK13: omp.inner.for.end: // CHECK13-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK13: omp.loop.exit: -// CHECK13-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP3]]) +// CHECK13-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) // CHECK13-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK13-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 // CHECK13-NEXT: br i1 [[TMP12]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -5752,7 +5752,7 @@ int main() { // CHECK13: omp.inner.for.end: // CHECK13-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK13: omp.loop.exit: -// CHECK13-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP3]]) +// CHECK13-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) // CHECK13-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK13-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 // CHECK13-NEXT: br i1 [[TMP12]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -5913,7 +5913,7 @@ int main() { // CHECK13: omp.inner.for.end: // CHECK13-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK13: omp.loop.exit: -// CHECK13-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP3]]) +// CHECK13-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) // CHECK13-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK13-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 // CHECK13-NEXT: br i1 [[TMP12]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -6089,7 +6089,7 @@ int main() { // CHECK13: omp.inner.for.end: // CHECK13-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK13: omp.loop.exit: -// CHECK13-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP3]]) +// CHECK13-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) // CHECK13-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK13-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 // CHECK13-NEXT: br i1 [[TMP12]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] diff --git a/clang/test/OpenMP/distribute_parallel_for_simd_private_codegen.cpp b/clang/test/OpenMP/distribute_parallel_for_simd_private_codegen.cpp index 22208e2e2c1dc9526a62cc3bb45c19618a22d867..61f35d8b456cea954a88940053a19d7f58634731 100644 --- a/clang/test/OpenMP/distribute_parallel_for_simd_private_codegen.cpp +++ b/clang/test/OpenMP/distribute_parallel_for_simd_private_codegen.cpp @@ -320,7 +320,7 @@ int main() { // CHECK1: omp.inner.for.end: // CHECK1-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK1: omp.loop.exit: -// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP3]]) +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) // CHECK1-NEXT: [[TMP17:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK1-NEXT: [[TMP18:%.*]] = icmp ne i32 [[TMP17]], 0 // CHECK1-NEXT: br i1 [[TMP18]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -512,7 +512,7 @@ int main() { // CHECK3: omp.inner.for.end: // CHECK3-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK3: omp.loop.exit: -// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP3]]) +// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) // CHECK3-NEXT: [[TMP17:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK3-NEXT: [[TMP18:%.*]] = icmp ne i32 [[TMP17]], 0 // CHECK3-NEXT: br i1 [[TMP18]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -856,7 +856,7 @@ int main() { // CHECK9: omp.loop.exit: // CHECK9-NEXT: [[TMP15:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 // CHECK9-NEXT: [[TMP16:%.*]] = load i32, ptr [[TMP15]], align 4 -// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP16]]) +// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP16]]) // CHECK9-NEXT: [[TMP17:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK9-NEXT: [[TMP18:%.*]] = icmp ne i32 [[TMP17]], 0 // CHECK9-NEXT: br i1 [[TMP18]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -1222,7 +1222,7 @@ int main() { // CHECK9: omp.loop.exit: // CHECK9-NEXT: [[TMP15:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 // CHECK9-NEXT: [[TMP16:%.*]] = load i32, ptr [[TMP15]], align 4 -// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP16]]) +// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP16]]) // CHECK9-NEXT: [[TMP17:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK9-NEXT: [[TMP18:%.*]] = icmp ne i32 [[TMP17]], 0 // CHECK9-NEXT: br i1 [[TMP18]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -1589,7 +1589,7 @@ int main() { // CHECK11: omp.loop.exit: // CHECK11-NEXT: [[TMP15:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 4 // CHECK11-NEXT: [[TMP16:%.*]] = load i32, ptr [[TMP15]], align 4 -// CHECK11-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP16]]) +// CHECK11-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP16]]) // CHECK11-NEXT: [[TMP17:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK11-NEXT: [[TMP18:%.*]] = icmp ne i32 [[TMP17]], 0 // CHECK11-NEXT: br i1 [[TMP18]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -1949,7 +1949,7 @@ int main() { // CHECK11: omp.loop.exit: // CHECK11-NEXT: [[TMP15:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 4 // CHECK11-NEXT: [[TMP16:%.*]] = load i32, ptr [[TMP15]], align 4 -// CHECK11-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP16]]) +// CHECK11-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP16]]) // CHECK11-NEXT: [[TMP17:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK11-NEXT: [[TMP18:%.*]] = icmp ne i32 [[TMP17]], 0 // CHECK11-NEXT: br i1 [[TMP18]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] diff --git a/clang/test/OpenMP/distribute_parallel_for_simd_proc_bind_codegen.cpp b/clang/test/OpenMP/distribute_parallel_for_simd_proc_bind_codegen.cpp index d452ac3bed485b70bb6b66130da90e8ee07bbb6c..334965f59a826dba4ab7cc2cd59f4b1af33e1d1a 100644 --- a/clang/test/OpenMP/distribute_parallel_for_simd_proc_bind_codegen.cpp +++ b/clang/test/OpenMP/distribute_parallel_for_simd_proc_bind_codegen.cpp @@ -273,7 +273,7 @@ int main() { // CHECK1: omp.inner.for.end: // CHECK1-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK1: omp.loop.exit: -// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP3]]) +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) // CHECK1-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK1-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 // CHECK1-NEXT: br i1 [[TMP12]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -425,7 +425,7 @@ int main() { // CHECK1: omp.inner.for.end: // CHECK1-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK1: omp.loop.exit: -// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP3]]) +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) // CHECK1-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK1-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 // CHECK1-NEXT: br i1 [[TMP12]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -618,7 +618,7 @@ int main() { // CHECK1: omp.inner.for.end: // CHECK1-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK1: omp.loop.exit: -// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP3]]) +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) // CHECK1-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK1-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 // CHECK1-NEXT: br i1 [[TMP12]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] diff --git a/clang/test/OpenMP/metadirective_device_arch_codegen.cpp b/clang/test/OpenMP/metadirective_device_arch_codegen.cpp index 6150b7c07c167a2bd93430768ef635837a7a54d9..eecae310d0a77838d14b8a60eb06ae045f56ee75 100644 --- a/clang/test/OpenMP/metadirective_device_arch_codegen.cpp +++ b/clang/test/OpenMP/metadirective_device_arch_codegen.cpp @@ -60,6 +60,6 @@ int metadirective1() { // CHECK: omp.inner.for.body: // CHECK: store atomic {{.*}} monotonic // CHECK: omp.loop.exit: -// CHECK-NEXT: call void @__kmpc_distribute_static_fini +// CHECK-NEXT: call void @__kmpc_for_static_fini // CHECK-NEXT: ret void diff --git a/clang/test/OpenMP/nvptx_SPMD_codegen.cpp b/clang/test/OpenMP/nvptx_SPMD_codegen.cpp index 1ac5454994277b9da61c0d7090355536e9505f3c..d47025cd1acaa76cb0494ad76b6063ab88fe085b 100644 --- a/clang/test/OpenMP/nvptx_SPMD_codegen.cpp +++ b/clang/test/OpenMP/nvptx_SPMD_codegen.cpp @@ -573,7 +573,7 @@ int a; // CHECK-64: omp.loop.exit: // CHECK-64-NEXT: [[TMP19:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 // CHECK-64-NEXT: [[TMP20:%.*]] = load i32, ptr [[TMP19]], align 4 -// CHECK-64-NEXT: call void @__kmpc_distribute_static_fini(ptr @[[GLOB2]], i32 [[TMP20]]) +// CHECK-64-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB3]], i32 [[TMP20]]) // CHECK-64-NEXT: [[TMP21:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK-64-NEXT: [[TMP22:%.*]] = icmp ne i32 [[TMP21]], 0 // CHECK-64-NEXT: br i1 [[TMP22]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -680,7 +680,7 @@ int a; // CHECK-64: omp.loop.exit: // CHECK-64-NEXT: [[TMP19:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 // CHECK-64-NEXT: [[TMP20:%.*]] = load i32, ptr [[TMP19]], align 4 -// CHECK-64-NEXT: call void @__kmpc_distribute_static_fini(ptr @[[GLOB2]], i32 [[TMP20]]) +// CHECK-64-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB3]], i32 [[TMP20]]) // CHECK-64-NEXT: [[TMP21:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK-64-NEXT: [[TMP22:%.*]] = icmp ne i32 [[TMP21]], 0 // CHECK-64-NEXT: br i1 [[TMP22]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -873,7 +873,7 @@ int a; // CHECK-64: omp.inner.for.end: // CHECK-64-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK-64: omp.loop.exit: -// CHECK-64-NEXT: call void @__kmpc_distribute_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) +// CHECK-64-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB3]], i32 [[TMP3]]) // CHECK-64-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK-64-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 // CHECK-64-NEXT: br i1 [[TMP12]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -1057,7 +1057,7 @@ int a; // CHECK-64: omp.inner.for.end: // CHECK-64-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK-64: omp.loop.exit: -// CHECK-64-NEXT: call void @__kmpc_distribute_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) +// CHECK-64-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB3]], i32 [[TMP3]]) // CHECK-64-NEXT: [[TMP10:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK-64-NEXT: [[TMP11:%.*]] = icmp ne i32 [[TMP10]], 0 // CHECK-64-NEXT: br i1 [[TMP11]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -2028,7 +2028,7 @@ int a; // CHECK-64: omp.inner.for.end: // CHECK-64-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK-64: omp.loop.exit: -// CHECK-64-NEXT: call void @__kmpc_distribute_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) +// CHECK-64-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB3]], i32 [[TMP3]]) // CHECK-64-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK-64-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 // CHECK-64-NEXT: br i1 [[TMP12]], label [[DOTOMP_LASTPRIVATE_THEN:%.*]], label [[DOTOMP_LASTPRIVATE_DONE:%.*]] @@ -2215,7 +2215,7 @@ int a; // CHECK-64: omp.inner.for.end: // CHECK-64-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK-64: omp.loop.exit: -// CHECK-64-NEXT: call void @__kmpc_distribute_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) +// CHECK-64-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB3]], i32 [[TMP3]]) // CHECK-64-NEXT: ret void // // @@ -2385,7 +2385,7 @@ int a; // CHECK-64: omp.inner.for.end: // CHECK-64-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK-64: omp.loop.exit: -// CHECK-64-NEXT: call void @__kmpc_distribute_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) +// CHECK-64-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB3]], i32 [[TMP3]]) // CHECK-64-NEXT: ret void // // @@ -3271,7 +3271,7 @@ int a; // CHECK-64: omp.inner.for.end: // CHECK-64-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK-64: omp.loop.exit: -// CHECK-64-NEXT: call void @__kmpc_distribute_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) +// CHECK-64-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB3]], i32 [[TMP3]]) // CHECK-64-NEXT: [[TMP10:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK-64-NEXT: [[TMP11:%.*]] = icmp ne i32 [[TMP10]], 0 // CHECK-64-NEXT: br i1 [[TMP11]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -3466,7 +3466,7 @@ int a; // CHECK-64: omp.inner.for.end: // CHECK-64-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK-64: omp.loop.exit: -// CHECK-64-NEXT: call void @__kmpc_distribute_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) +// CHECK-64-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB3]], i32 [[TMP3]]) // CHECK-64-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK-64-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 // CHECK-64-NEXT: br i1 [[TMP12]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -3634,7 +3634,7 @@ int a; // CHECK-64: omp.inner.for.end: // CHECK-64-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK-64: omp.loop.exit: -// CHECK-64-NEXT: call void @__kmpc_distribute_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) +// CHECK-64-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB3]], i32 [[TMP3]]) // CHECK-64-NEXT: [[TMP10:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK-64-NEXT: [[TMP11:%.*]] = icmp ne i32 [[TMP10]], 0 // CHECK-64-NEXT: br i1 [[TMP11]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -4595,7 +4595,7 @@ int a; // CHECK-64: omp.inner.for.end: // CHECK-64-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK-64: omp.loop.exit: -// CHECK-64-NEXT: call void @__kmpc_distribute_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) +// CHECK-64-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB3]], i32 [[TMP3]]) // CHECK-64-NEXT: ret void // // @@ -4774,7 +4774,7 @@ int a; // CHECK-64: omp.inner.for.end: // CHECK-64-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK-64: omp.loop.exit: -// CHECK-64-NEXT: call void @__kmpc_distribute_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) +// CHECK-64-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB3]], i32 [[TMP3]]) // CHECK-64-NEXT: ret void // // @@ -4944,7 +4944,7 @@ int a; // CHECK-64: omp.inner.for.end: // CHECK-64-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK-64: omp.loop.exit: -// CHECK-64-NEXT: call void @__kmpc_distribute_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) +// CHECK-64-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB3]], i32 [[TMP3]]) // CHECK-64-NEXT: ret void // // @@ -5822,7 +5822,7 @@ int a; // CHECK-64: omp.inner.for.end: // CHECK-64-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK-64: omp.loop.exit: -// CHECK-64-NEXT: call void @__kmpc_distribute_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) +// CHECK-64-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB3]], i32 [[TMP3]]) // CHECK-64-NEXT: ret void // // @@ -6001,7 +6001,7 @@ int a; // CHECK-64: omp.inner.for.end: // CHECK-64-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK-64: omp.loop.exit: -// CHECK-64-NEXT: call void @__kmpc_distribute_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) +// CHECK-64-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB3]], i32 [[TMP3]]) // CHECK-64-NEXT: ret void // // @@ -6171,7 +6171,7 @@ int a; // CHECK-64: omp.inner.for.end: // CHECK-64-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK-64: omp.loop.exit: -// CHECK-64-NEXT: call void @__kmpc_distribute_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) +// CHECK-64-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB3]], i32 [[TMP3]]) // CHECK-64-NEXT: ret void // // @@ -9534,7 +9534,7 @@ int a; // CHECK-32: omp.loop.exit: // CHECK-32-NEXT: [[TMP19:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 4 // CHECK-32-NEXT: [[TMP20:%.*]] = load i32, ptr [[TMP19]], align 4 -// CHECK-32-NEXT: call void @__kmpc_distribute_static_fini(ptr @[[GLOB2]], i32 [[TMP20]]) +// CHECK-32-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB3]], i32 [[TMP20]]) // CHECK-32-NEXT: [[TMP21:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK-32-NEXT: [[TMP22:%.*]] = icmp ne i32 [[TMP21]], 0 // CHECK-32-NEXT: br i1 [[TMP22]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -9637,7 +9637,7 @@ int a; // CHECK-32: omp.loop.exit: // CHECK-32-NEXT: [[TMP19:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 4 // CHECK-32-NEXT: [[TMP20:%.*]] = load i32, ptr [[TMP19]], align 4 -// CHECK-32-NEXT: call void @__kmpc_distribute_static_fini(ptr @[[GLOB2]], i32 [[TMP20]]) +// CHECK-32-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB3]], i32 [[TMP20]]) // CHECK-32-NEXT: [[TMP21:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK-32-NEXT: [[TMP22:%.*]] = icmp ne i32 [[TMP21]], 0 // CHECK-32-NEXT: br i1 [[TMP22]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -9826,7 +9826,7 @@ int a; // CHECK-32: omp.inner.for.end: // CHECK-32-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK-32: omp.loop.exit: -// CHECK-32-NEXT: call void @__kmpc_distribute_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) +// CHECK-32-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB3]], i32 [[TMP3]]) // CHECK-32-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK-32-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 // CHECK-32-NEXT: br i1 [[TMP12]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -10005,7 +10005,7 @@ int a; // CHECK-32: omp.inner.for.end: // CHECK-32-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK-32: omp.loop.exit: -// CHECK-32-NEXT: call void @__kmpc_distribute_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) +// CHECK-32-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB3]], i32 [[TMP3]]) // CHECK-32-NEXT: [[TMP10:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK-32-NEXT: [[TMP11:%.*]] = icmp ne i32 [[TMP10]], 0 // CHECK-32-NEXT: br i1 [[TMP11]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -10955,7 +10955,7 @@ int a; // CHECK-32: omp.inner.for.end: // CHECK-32-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK-32: omp.loop.exit: -// CHECK-32-NEXT: call void @__kmpc_distribute_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) +// CHECK-32-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB3]], i32 [[TMP3]]) // CHECK-32-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK-32-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 // CHECK-32-NEXT: br i1 [[TMP12]], label [[DOTOMP_LASTPRIVATE_THEN:%.*]], label [[DOTOMP_LASTPRIVATE_DONE:%.*]] @@ -11138,7 +11138,7 @@ int a; // CHECK-32: omp.inner.for.end: // CHECK-32-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK-32: omp.loop.exit: -// CHECK-32-NEXT: call void @__kmpc_distribute_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) +// CHECK-32-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB3]], i32 [[TMP3]]) // CHECK-32-NEXT: ret void // // @@ -11303,7 +11303,7 @@ int a; // CHECK-32: omp.inner.for.end: // CHECK-32-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK-32: omp.loop.exit: -// CHECK-32-NEXT: call void @__kmpc_distribute_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) +// CHECK-32-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB3]], i32 [[TMP3]]) // CHECK-32-NEXT: ret void // // @@ -12168,7 +12168,7 @@ int a; // CHECK-32: omp.inner.for.end: // CHECK-32-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK-32: omp.loop.exit: -// CHECK-32-NEXT: call void @__kmpc_distribute_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) +// CHECK-32-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB3]], i32 [[TMP3]]) // CHECK-32-NEXT: [[TMP10:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK-32-NEXT: [[TMP11:%.*]] = icmp ne i32 [[TMP10]], 0 // CHECK-32-NEXT: br i1 [[TMP11]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -12359,7 +12359,7 @@ int a; // CHECK-32: omp.inner.for.end: // CHECK-32-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK-32: omp.loop.exit: -// CHECK-32-NEXT: call void @__kmpc_distribute_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) +// CHECK-32-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB3]], i32 [[TMP3]]) // CHECK-32-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK-32-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 // CHECK-32-NEXT: br i1 [[TMP12]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -12522,7 +12522,7 @@ int a; // CHECK-32: omp.inner.for.end: // CHECK-32-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK-32: omp.loop.exit: -// CHECK-32-NEXT: call void @__kmpc_distribute_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) +// CHECK-32-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB3]], i32 [[TMP3]]) // CHECK-32-NEXT: [[TMP10:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK-32-NEXT: [[TMP11:%.*]] = icmp ne i32 [[TMP10]], 0 // CHECK-32-NEXT: br i1 [[TMP11]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -13462,7 +13462,7 @@ int a; // CHECK-32: omp.inner.for.end: // CHECK-32-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK-32: omp.loop.exit: -// CHECK-32-NEXT: call void @__kmpc_distribute_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) +// CHECK-32-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB3]], i32 [[TMP3]]) // CHECK-32-NEXT: ret void // // @@ -13637,7 +13637,7 @@ int a; // CHECK-32: omp.inner.for.end: // CHECK-32-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK-32: omp.loop.exit: -// CHECK-32-NEXT: call void @__kmpc_distribute_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) +// CHECK-32-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB3]], i32 [[TMP3]]) // CHECK-32-NEXT: ret void // // @@ -13802,7 +13802,7 @@ int a; // CHECK-32: omp.inner.for.end: // CHECK-32-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK-32: omp.loop.exit: -// CHECK-32-NEXT: call void @__kmpc_distribute_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) +// CHECK-32-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB3]], i32 [[TMP3]]) // CHECK-32-NEXT: ret void // // @@ -14659,7 +14659,7 @@ int a; // CHECK-32: omp.inner.for.end: // CHECK-32-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK-32: omp.loop.exit: -// CHECK-32-NEXT: call void @__kmpc_distribute_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) +// CHECK-32-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB3]], i32 [[TMP3]]) // CHECK-32-NEXT: ret void // // @@ -14834,7 +14834,7 @@ int a; // CHECK-32: omp.inner.for.end: // CHECK-32-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK-32: omp.loop.exit: -// CHECK-32-NEXT: call void @__kmpc_distribute_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) +// CHECK-32-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB3]], i32 [[TMP3]]) // CHECK-32-NEXT: ret void // // @@ -14999,7 +14999,7 @@ int a; // CHECK-32: omp.inner.for.end: // CHECK-32-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK-32: omp.loop.exit: -// CHECK-32-NEXT: call void @__kmpc_distribute_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) +// CHECK-32-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB3]], i32 [[TMP3]]) // CHECK-32-NEXT: ret void // // @@ -18346,7 +18346,7 @@ int a; // CHECK-32-EX: omp.loop.exit: // CHECK-32-EX-NEXT: [[TMP19:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 4 // CHECK-32-EX-NEXT: [[TMP20:%.*]] = load i32, ptr [[TMP19]], align 4 -// CHECK-32-EX-NEXT: call void @__kmpc_distribute_static_fini(ptr @[[GLOB2]], i32 [[TMP20]]) +// CHECK-32-EX-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB3]], i32 [[TMP20]]) // CHECK-32-EX-NEXT: [[TMP21:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK-32-EX-NEXT: [[TMP22:%.*]] = icmp ne i32 [[TMP21]], 0 // CHECK-32-EX-NEXT: br i1 [[TMP22]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -18449,7 +18449,7 @@ int a; // CHECK-32-EX: omp.loop.exit: // CHECK-32-EX-NEXT: [[TMP19:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 4 // CHECK-32-EX-NEXT: [[TMP20:%.*]] = load i32, ptr [[TMP19]], align 4 -// CHECK-32-EX-NEXT: call void @__kmpc_distribute_static_fini(ptr @[[GLOB2]], i32 [[TMP20]]) +// CHECK-32-EX-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB3]], i32 [[TMP20]]) // CHECK-32-EX-NEXT: [[TMP21:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK-32-EX-NEXT: [[TMP22:%.*]] = icmp ne i32 [[TMP21]], 0 // CHECK-32-EX-NEXT: br i1 [[TMP22]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -18638,7 +18638,7 @@ int a; // CHECK-32-EX: omp.inner.for.end: // CHECK-32-EX-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK-32-EX: omp.loop.exit: -// CHECK-32-EX-NEXT: call void @__kmpc_distribute_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) +// CHECK-32-EX-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB3]], i32 [[TMP3]]) // CHECK-32-EX-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK-32-EX-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 // CHECK-32-EX-NEXT: br i1 [[TMP12]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -18817,7 +18817,7 @@ int a; // CHECK-32-EX: omp.inner.for.end: // CHECK-32-EX-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK-32-EX: omp.loop.exit: -// CHECK-32-EX-NEXT: call void @__kmpc_distribute_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) +// CHECK-32-EX-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB3]], i32 [[TMP3]]) // CHECK-32-EX-NEXT: [[TMP10:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK-32-EX-NEXT: [[TMP11:%.*]] = icmp ne i32 [[TMP10]], 0 // CHECK-32-EX-NEXT: br i1 [[TMP11]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -19767,7 +19767,7 @@ int a; // CHECK-32-EX: omp.inner.for.end: // CHECK-32-EX-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK-32-EX: omp.loop.exit: -// CHECK-32-EX-NEXT: call void @__kmpc_distribute_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) +// CHECK-32-EX-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB3]], i32 [[TMP3]]) // CHECK-32-EX-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK-32-EX-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 // CHECK-32-EX-NEXT: br i1 [[TMP12]], label [[DOTOMP_LASTPRIVATE_THEN:%.*]], label [[DOTOMP_LASTPRIVATE_DONE:%.*]] @@ -19950,7 +19950,7 @@ int a; // CHECK-32-EX: omp.inner.for.end: // CHECK-32-EX-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK-32-EX: omp.loop.exit: -// CHECK-32-EX-NEXT: call void @__kmpc_distribute_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) +// CHECK-32-EX-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB3]], i32 [[TMP3]]) // CHECK-32-EX-NEXT: ret void // // @@ -20115,7 +20115,7 @@ int a; // CHECK-32-EX: omp.inner.for.end: // CHECK-32-EX-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK-32-EX: omp.loop.exit: -// CHECK-32-EX-NEXT: call void @__kmpc_distribute_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) +// CHECK-32-EX-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB3]], i32 [[TMP3]]) // CHECK-32-EX-NEXT: ret void // // @@ -20980,7 +20980,7 @@ int a; // CHECK-32-EX: omp.inner.for.end: // CHECK-32-EX-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK-32-EX: omp.loop.exit: -// CHECK-32-EX-NEXT: call void @__kmpc_distribute_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) +// CHECK-32-EX-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB3]], i32 [[TMP3]]) // CHECK-32-EX-NEXT: [[TMP10:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK-32-EX-NEXT: [[TMP11:%.*]] = icmp ne i32 [[TMP10]], 0 // CHECK-32-EX-NEXT: br i1 [[TMP11]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -21171,7 +21171,7 @@ int a; // CHECK-32-EX: omp.inner.for.end: // CHECK-32-EX-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK-32-EX: omp.loop.exit: -// CHECK-32-EX-NEXT: call void @__kmpc_distribute_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) +// CHECK-32-EX-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB3]], i32 [[TMP3]]) // CHECK-32-EX-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK-32-EX-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 // CHECK-32-EX-NEXT: br i1 [[TMP12]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -21334,7 +21334,7 @@ int a; // CHECK-32-EX: omp.inner.for.end: // CHECK-32-EX-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK-32-EX: omp.loop.exit: -// CHECK-32-EX-NEXT: call void @__kmpc_distribute_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) +// CHECK-32-EX-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB3]], i32 [[TMP3]]) // CHECK-32-EX-NEXT: [[TMP10:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK-32-EX-NEXT: [[TMP11:%.*]] = icmp ne i32 [[TMP10]], 0 // CHECK-32-EX-NEXT: br i1 [[TMP11]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -22274,7 +22274,7 @@ int a; // CHECK-32-EX: omp.inner.for.end: // CHECK-32-EX-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK-32-EX: omp.loop.exit: -// CHECK-32-EX-NEXT: call void @__kmpc_distribute_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) +// CHECK-32-EX-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB3]], i32 [[TMP3]]) // CHECK-32-EX-NEXT: ret void // // @@ -22449,7 +22449,7 @@ int a; // CHECK-32-EX: omp.inner.for.end: // CHECK-32-EX-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK-32-EX: omp.loop.exit: -// CHECK-32-EX-NEXT: call void @__kmpc_distribute_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) +// CHECK-32-EX-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB3]], i32 [[TMP3]]) // CHECK-32-EX-NEXT: ret void // // @@ -22614,7 +22614,7 @@ int a; // CHECK-32-EX: omp.inner.for.end: // CHECK-32-EX-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK-32-EX: omp.loop.exit: -// CHECK-32-EX-NEXT: call void @__kmpc_distribute_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) +// CHECK-32-EX-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB3]], i32 [[TMP3]]) // CHECK-32-EX-NEXT: ret void // // @@ -23471,7 +23471,7 @@ int a; // CHECK-32-EX: omp.inner.for.end: // CHECK-32-EX-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK-32-EX: omp.loop.exit: -// CHECK-32-EX-NEXT: call void @__kmpc_distribute_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) +// CHECK-32-EX-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB3]], i32 [[TMP3]]) // CHECK-32-EX-NEXT: ret void // // @@ -23646,7 +23646,7 @@ int a; // CHECK-32-EX: omp.inner.for.end: // CHECK-32-EX-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK-32-EX: omp.loop.exit: -// CHECK-32-EX-NEXT: call void @__kmpc_distribute_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) +// CHECK-32-EX-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB3]], i32 [[TMP3]]) // CHECK-32-EX-NEXT: ret void // // @@ -23811,7 +23811,7 @@ int a; // CHECK-32-EX: omp.inner.for.end: // CHECK-32-EX-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK-32-EX: omp.loop.exit: -// CHECK-32-EX-NEXT: call void @__kmpc_distribute_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) +// CHECK-32-EX-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB3]], i32 [[TMP3]]) // CHECK-32-EX-NEXT: ret void // // diff --git a/clang/test/OpenMP/nvptx_distribute_parallel_generic_mode_codegen.cpp b/clang/test/OpenMP/nvptx_distribute_parallel_generic_mode_codegen.cpp index 7402698af3e4c00997d274b777d15b1a2d90a214..986aeadaf998c3bb8673b3f480615d518c18c06b 100644 --- a/clang/test/OpenMP/nvptx_distribute_parallel_generic_mode_codegen.cpp +++ b/clang/test/OpenMP/nvptx_distribute_parallel_generic_mode_codegen.cpp @@ -329,7 +329,7 @@ int main(int argc, char **argv) { // CHECK4: omp.loop.exit: // CHECK4-NEXT: [[TMP22:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 // CHECK4-NEXT: [[TMP23:%.*]] = load i32, ptr [[TMP22]], align 4 -// CHECK4-NEXT: call void @__kmpc_distribute_static_fini(ptr @[[GLOB2]], i32 [[TMP23]]) +// CHECK4-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB3]], i32 [[TMP23]]) // CHECK4-NEXT: [[TMP24:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK4-NEXT: [[TMP25:%.*]] = icmp ne i32 [[TMP24]], 0 // CHECK4-NEXT: br i1 [[TMP25]], label [[DOTOMP_LASTPRIVATE_THEN:%.*]], label [[DOTOMP_LASTPRIVATE_DONE:%.*]] @@ -639,7 +639,7 @@ int main(int argc, char **argv) { // CHECK5: omp.loop.exit: // CHECK5-NEXT: [[TMP22:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 4 // CHECK5-NEXT: [[TMP23:%.*]] = load i32, ptr [[TMP22]], align 4 -// CHECK5-NEXT: call void @__kmpc_distribute_static_fini(ptr @[[GLOB2]], i32 [[TMP23]]) +// CHECK5-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB3]], i32 [[TMP23]]) // CHECK5-NEXT: [[TMP24:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK5-NEXT: [[TMP25:%.*]] = icmp ne i32 [[TMP24]], 0 // CHECK5-NEXT: br i1 [[TMP25]], label [[DOTOMP_LASTPRIVATE_THEN:%.*]], label [[DOTOMP_LASTPRIVATE_DONE:%.*]] diff --git a/clang/test/OpenMP/nvptx_target_teams_distribute_parallel_for_codegen.cpp b/clang/test/OpenMP/nvptx_target_teams_distribute_parallel_for_codegen.cpp index 4d6982d10616eca5438aba26467ca0996f417edf..8397b93cbeedb56e33d8d586e7e9e26cae840753 100644 --- a/clang/test/OpenMP/nvptx_target_teams_distribute_parallel_for_codegen.cpp +++ b/clang/test/OpenMP/nvptx_target_teams_distribute_parallel_for_codegen.cpp @@ -371,7 +371,7 @@ int bar(int n){ // CHECK1: omp.dispatch.end: // CHECK1-NEXT: [[TMP26:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 // CHECK1-NEXT: [[TMP27:%.*]] = load i32, ptr [[TMP26]], align 4 -// CHECK1-NEXT: call void @__kmpc_distribute_static_fini(ptr @[[GLOB2]], i32 [[TMP27]]) +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB3]], i32 [[TMP27]]) // CHECK1-NEXT: [[TMP28:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK1-NEXT: [[TMP29:%.*]] = icmp ne i32 [[TMP28]], 0 // CHECK1-NEXT: br i1 [[TMP29]], label [[DOTOMP_LASTPRIVATE_THEN:%.*]], label [[DOTOMP_LASTPRIVATE_DONE:%.*]] @@ -633,7 +633,7 @@ int bar(int n){ // CHECK1: omp.loop.exit: // CHECK1-NEXT: [[TMP17:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 // CHECK1-NEXT: [[TMP18:%.*]] = load i32, ptr [[TMP17]], align 4 -// CHECK1-NEXT: call void @__kmpc_distribute_static_fini(ptr @[[GLOB2]], i32 [[TMP18]]) +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB3]], i32 [[TMP18]]) // CHECK1-NEXT: br label [[OMP_PRECOND_END]] // CHECK1: omp.precond.end: // CHECK1-NEXT: ret void @@ -822,7 +822,7 @@ int bar(int n){ // CHECK1: omp.inner.for.end: // CHECK1-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK1: omp.loop.exit: -// CHECK1-NEXT: call void @__kmpc_distribute_static_fini(ptr @[[GLOB2]], i32 [[TMP4]]) +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB3]], i32 [[TMP4]]) // CHECK1-NEXT: ret void // // @@ -1050,7 +1050,7 @@ int bar(int n){ // CHECK1: omp.inner.for.end: // CHECK1-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK1: omp.loop.exit: -// CHECK1-NEXT: call void @__kmpc_distribute_static_fini(ptr @[[GLOB2]], i32 [[TMP4]]) +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB3]], i32 [[TMP4]]) // CHECK1-NEXT: ret void // // @@ -1360,7 +1360,7 @@ int bar(int n){ // CHECK1: omp.loop.exit: // CHECK1-NEXT: [[TMP27:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 // CHECK1-NEXT: [[TMP28:%.*]] = load i32, ptr [[TMP27]], align 4 -// CHECK1-NEXT: call void @__kmpc_distribute_static_fini(ptr @[[GLOB2]], i32 [[TMP28]]) +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB3]], i32 [[TMP28]]) // CHECK1-NEXT: br label [[OMP_PRECOND_END]] // CHECK1: omp.precond.end: // CHECK1-NEXT: ret void @@ -1625,7 +1625,7 @@ int bar(int n){ // CHECK1: omp.loop.exit: // CHECK1-NEXT: [[TMP19:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 // CHECK1-NEXT: [[TMP20:%.*]] = load i32, ptr [[TMP19]], align 4 -// CHECK1-NEXT: call void @__kmpc_distribute_static_fini(ptr @[[GLOB2]], i32 [[TMP20]]) +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB3]], i32 [[TMP20]]) // CHECK1-NEXT: br label [[OMP_PRECOND_END]] // CHECK1: omp.precond.end: // CHECK1-NEXT: ret void @@ -1931,7 +1931,7 @@ int bar(int n){ // CHECK2: omp.dispatch.end: // CHECK2-NEXT: [[TMP26:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 // CHECK2-NEXT: [[TMP27:%.*]] = load i32, ptr [[TMP26]], align 4 -// CHECK2-NEXT: call void @__kmpc_distribute_static_fini(ptr @[[GLOB2]], i32 [[TMP27]]) +// CHECK2-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB3]], i32 [[TMP27]]) // CHECK2-NEXT: [[TMP28:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK2-NEXT: [[TMP29:%.*]] = icmp ne i32 [[TMP28]], 0 // CHECK2-NEXT: br i1 [[TMP29]], label [[DOTOMP_LASTPRIVATE_THEN:%.*]], label [[DOTOMP_LASTPRIVATE_DONE:%.*]] @@ -2193,7 +2193,7 @@ int bar(int n){ // CHECK2: omp.loop.exit: // CHECK2-NEXT: [[TMP17:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 // CHECK2-NEXT: [[TMP18:%.*]] = load i32, ptr [[TMP17]], align 4 -// CHECK2-NEXT: call void @__kmpc_distribute_static_fini(ptr @[[GLOB2]], i32 [[TMP18]]) +// CHECK2-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB3]], i32 [[TMP18]]) // CHECK2-NEXT: br label [[OMP_PRECOND_END]] // CHECK2: omp.precond.end: // CHECK2-NEXT: ret void @@ -2382,7 +2382,7 @@ int bar(int n){ // CHECK2: omp.inner.for.end: // CHECK2-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK2: omp.loop.exit: -// CHECK2-NEXT: call void @__kmpc_distribute_static_fini(ptr @[[GLOB2]], i32 [[TMP4]]) +// CHECK2-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB3]], i32 [[TMP4]]) // CHECK2-NEXT: ret void // // @@ -2610,7 +2610,7 @@ int bar(int n){ // CHECK2: omp.inner.for.end: // CHECK2-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK2: omp.loop.exit: -// CHECK2-NEXT: call void @__kmpc_distribute_static_fini(ptr @[[GLOB2]], i32 [[TMP4]]) +// CHECK2-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB3]], i32 [[TMP4]]) // CHECK2-NEXT: ret void // // @@ -2915,7 +2915,7 @@ int bar(int n){ // CHECK2: omp.loop.exit: // CHECK2-NEXT: [[TMP27:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 // CHECK2-NEXT: [[TMP28:%.*]] = load i32, ptr [[TMP27]], align 4 -// CHECK2-NEXT: call void @__kmpc_distribute_static_fini(ptr @[[GLOB2]], i32 [[TMP28]]) +// CHECK2-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB3]], i32 [[TMP28]]) // CHECK2-NEXT: br label [[OMP_PRECOND_END]] // CHECK2: omp.precond.end: // CHECK2-NEXT: ret void @@ -3180,7 +3180,7 @@ int bar(int n){ // CHECK2: omp.loop.exit: // CHECK2-NEXT: [[TMP19:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 // CHECK2-NEXT: [[TMP20:%.*]] = load i32, ptr [[TMP19]], align 4 -// CHECK2-NEXT: call void @__kmpc_distribute_static_fini(ptr @[[GLOB2]], i32 [[TMP20]]) +// CHECK2-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB3]], i32 [[TMP20]]) // CHECK2-NEXT: br label [[OMP_PRECOND_END]] // CHECK2: omp.precond.end: // CHECK2-NEXT: ret void @@ -3479,7 +3479,7 @@ int bar(int n){ // CHECK3: omp.dispatch.end: // CHECK3-NEXT: [[TMP26:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 4 // CHECK3-NEXT: [[TMP27:%.*]] = load i32, ptr [[TMP26]], align 4 -// CHECK3-NEXT: call void @__kmpc_distribute_static_fini(ptr @[[GLOB2]], i32 [[TMP27]]) +// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB3]], i32 [[TMP27]]) // CHECK3-NEXT: [[TMP28:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK3-NEXT: [[TMP29:%.*]] = icmp ne i32 [[TMP28]], 0 // CHECK3-NEXT: br i1 [[TMP29]], label [[DOTOMP_LASTPRIVATE_THEN:%.*]], label [[DOTOMP_LASTPRIVATE_DONE:%.*]] @@ -3735,7 +3735,7 @@ int bar(int n){ // CHECK3: omp.loop.exit: // CHECK3-NEXT: [[TMP17:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 4 // CHECK3-NEXT: [[TMP18:%.*]] = load i32, ptr [[TMP17]], align 4 -// CHECK3-NEXT: call void @__kmpc_distribute_static_fini(ptr @[[GLOB2]], i32 [[TMP18]]) +// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB3]], i32 [[TMP18]]) // CHECK3-NEXT: br label [[OMP_PRECOND_END]] // CHECK3: omp.precond.end: // CHECK3-NEXT: ret void @@ -3918,7 +3918,7 @@ int bar(int n){ // CHECK3: omp.inner.for.end: // CHECK3-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK3: omp.loop.exit: -// CHECK3-NEXT: call void @__kmpc_distribute_static_fini(ptr @[[GLOB2]], i32 [[TMP4]]) +// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB3]], i32 [[TMP4]]) // CHECK3-NEXT: ret void // // @@ -4139,7 +4139,7 @@ int bar(int n){ // CHECK3: omp.inner.for.end: // CHECK3-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK3: omp.loop.exit: -// CHECK3-NEXT: call void @__kmpc_distribute_static_fini(ptr @[[GLOB2]], i32 [[TMP4]]) +// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB3]], i32 [[TMP4]]) // CHECK3-NEXT: ret void // // @@ -4452,7 +4452,7 @@ int bar(int n){ // CHECK3: omp.loop.exit: // CHECK3-NEXT: [[TMP27:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 4 // CHECK3-NEXT: [[TMP28:%.*]] = load i32, ptr [[TMP27]], align 4 -// CHECK3-NEXT: call void @__kmpc_distribute_static_fini(ptr @[[GLOB2]], i32 [[TMP28]]) +// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB3]], i32 [[TMP28]]) // CHECK3-NEXT: br label [[OMP_PRECOND_END]] // CHECK3: omp.precond.end: // CHECK3-NEXT: ret void @@ -4710,7 +4710,7 @@ int bar(int n){ // CHECK3: omp.loop.exit: // CHECK3-NEXT: [[TMP19:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 4 // CHECK3-NEXT: [[TMP20:%.*]] = load i32, ptr [[TMP19]], align 4 -// CHECK3-NEXT: call void @__kmpc_distribute_static_fini(ptr @[[GLOB2]], i32 [[TMP20]]) +// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB3]], i32 [[TMP20]]) // CHECK3-NEXT: br label [[OMP_PRECOND_END]] // CHECK3: omp.precond.end: // CHECK3-NEXT: ret void diff --git a/clang/test/OpenMP/nvptx_target_teams_distribute_parallel_for_generic_mode_codegen.cpp b/clang/test/OpenMP/nvptx_target_teams_distribute_parallel_for_generic_mode_codegen.cpp index 045cd39b07b7369c7dcc8f2942c122e36b346217..e687a537ecf1eaab1ba872f3757fcda0265eb63f 100644 --- a/clang/test/OpenMP/nvptx_target_teams_distribute_parallel_for_generic_mode_codegen.cpp +++ b/clang/test/OpenMP/nvptx_target_teams_distribute_parallel_for_generic_mode_codegen.cpp @@ -323,7 +323,7 @@ int main(int argc, char **argv) { // CHECK1: omp.dispatch.end: // CHECK1-NEXT: [[TMP25:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 // CHECK1-NEXT: [[TMP26:%.*]] = load i32, ptr [[TMP25]], align 4 -// CHECK1-NEXT: call void @__kmpc_distribute_static_fini(ptr @[[GLOB2]], i32 [[TMP26]]) +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB3]], i32 [[TMP26]]) // CHECK1-NEXT: br label [[OMP_PRECOND_END]] // CHECK1: omp.precond.end: // CHECK1-NEXT: ret void @@ -617,7 +617,7 @@ int main(int argc, char **argv) { // CHECK2: omp.dispatch.end: // CHECK2-NEXT: [[TMP25:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 4 // CHECK2-NEXT: [[TMP26:%.*]] = load i32, ptr [[TMP25]], align 4 -// CHECK2-NEXT: call void @__kmpc_distribute_static_fini(ptr @[[GLOB2]], i32 [[TMP26]]) +// CHECK2-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB3]], i32 [[TMP26]]) // CHECK2-NEXT: br label [[OMP_PRECOND_END]] // CHECK2: omp.precond.end: // CHECK2-NEXT: ret void diff --git a/clang/test/OpenMP/nvptx_target_teams_distribute_parallel_for_simd_codegen.cpp b/clang/test/OpenMP/nvptx_target_teams_distribute_parallel_for_simd_codegen.cpp index 2520713da50e5605226cea39783856db55996c71..9aee4bd09282a46ef7cd563fedc7e3cfb2ea15fd 100644 --- a/clang/test/OpenMP/nvptx_target_teams_distribute_parallel_for_simd_codegen.cpp +++ b/clang/test/OpenMP/nvptx_target_teams_distribute_parallel_for_simd_codegen.cpp @@ -371,7 +371,7 @@ int bar(int n){ // CHECK1: omp.dispatch.end: // CHECK1-NEXT: [[TMP26:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 // CHECK1-NEXT: [[TMP27:%.*]] = load i32, ptr [[TMP26]], align 4 -// CHECK1-NEXT: call void @__kmpc_distribute_static_fini(ptr @[[GLOB2]], i32 [[TMP27]]) +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB3]], i32 [[TMP27]]) // CHECK1-NEXT: [[TMP28:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK1-NEXT: [[TMP29:%.*]] = icmp ne i32 [[TMP28]], 0 // CHECK1-NEXT: br i1 [[TMP29]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -657,7 +657,7 @@ int bar(int n){ // CHECK1: omp.loop.exit: // CHECK1-NEXT: [[TMP17:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 // CHECK1-NEXT: [[TMP18:%.*]] = load i32, ptr [[TMP17]], align 4 -// CHECK1-NEXT: call void @__kmpc_distribute_static_fini(ptr @[[GLOB2]], i32 [[TMP18]]) +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB3]], i32 [[TMP18]]) // CHECK1-NEXT: [[TMP19:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK1-NEXT: [[TMP20:%.*]] = icmp ne i32 [[TMP19]], 0 // CHECK1-NEXT: br i1 [[TMP20]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -865,7 +865,7 @@ int bar(int n){ // CHECK1: omp.inner.for.end: // CHECK1-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK1: omp.loop.exit: -// CHECK1-NEXT: call void @__kmpc_distribute_static_fini(ptr @[[GLOB2]], i32 [[TMP4]]) +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB3]], i32 [[TMP4]]) // CHECK1-NEXT: [[TMP13:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK1-NEXT: [[TMP14:%.*]] = icmp ne i32 [[TMP13]], 0 // CHECK1-NEXT: br i1 [[TMP14]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -1108,7 +1108,7 @@ int bar(int n){ // CHECK1: omp.inner.for.end: // CHECK1-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK1: omp.loop.exit: -// CHECK1-NEXT: call void @__kmpc_distribute_static_fini(ptr @[[GLOB2]], i32 [[TMP4]]) +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB3]], i32 [[TMP4]]) // CHECK1-NEXT: [[TMP19:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK1-NEXT: [[TMP20:%.*]] = icmp ne i32 [[TMP19]], 0 // CHECK1-NEXT: br i1 [[TMP20]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -1425,7 +1425,7 @@ int bar(int n){ // CHECK2: omp.dispatch.end: // CHECK2-NEXT: [[TMP26:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 4 // CHECK2-NEXT: [[TMP27:%.*]] = load i32, ptr [[TMP26]], align 4 -// CHECK2-NEXT: call void @__kmpc_distribute_static_fini(ptr @[[GLOB2]], i32 [[TMP27]]) +// CHECK2-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB3]], i32 [[TMP27]]) // CHECK2-NEXT: [[TMP28:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK2-NEXT: [[TMP29:%.*]] = icmp ne i32 [[TMP28]], 0 // CHECK2-NEXT: br i1 [[TMP29]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -1705,7 +1705,7 @@ int bar(int n){ // CHECK2: omp.loop.exit: // CHECK2-NEXT: [[TMP17:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 4 // CHECK2-NEXT: [[TMP18:%.*]] = load i32, ptr [[TMP17]], align 4 -// CHECK2-NEXT: call void @__kmpc_distribute_static_fini(ptr @[[GLOB2]], i32 [[TMP18]]) +// CHECK2-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB3]], i32 [[TMP18]]) // CHECK2-NEXT: [[TMP19:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK2-NEXT: [[TMP20:%.*]] = icmp ne i32 [[TMP19]], 0 // CHECK2-NEXT: br i1 [[TMP20]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -1907,7 +1907,7 @@ int bar(int n){ // CHECK2: omp.inner.for.end: // CHECK2-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK2: omp.loop.exit: -// CHECK2-NEXT: call void @__kmpc_distribute_static_fini(ptr @[[GLOB2]], i32 [[TMP4]]) +// CHECK2-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB3]], i32 [[TMP4]]) // CHECK2-NEXT: [[TMP13:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK2-NEXT: [[TMP14:%.*]] = icmp ne i32 [[TMP13]], 0 // CHECK2-NEXT: br i1 [[TMP14]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -2143,7 +2143,7 @@ int bar(int n){ // CHECK2: omp.inner.for.end: // CHECK2-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK2: omp.loop.exit: -// CHECK2-NEXT: call void @__kmpc_distribute_static_fini(ptr @[[GLOB2]], i32 [[TMP4]]) +// CHECK2-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB3]], i32 [[TMP4]]) // CHECK2-NEXT: [[TMP19:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK2-NEXT: [[TMP20:%.*]] = icmp ne i32 [[TMP19]], 0 // CHECK2-NEXT: br i1 [[TMP20]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] diff --git a/clang/test/OpenMP/nvptx_target_teams_generic_loop_codegen.cpp b/clang/test/OpenMP/nvptx_target_teams_generic_loop_codegen.cpp index fc83500a09f9846e4d9eace415325626dce2932d..5226b7498e4ce7321fa300b9796ca7fd3fa51bd7 100644 --- a/clang/test/OpenMP/nvptx_target_teams_generic_loop_codegen.cpp +++ b/clang/test/OpenMP/nvptx_target_teams_generic_loop_codegen.cpp @@ -219,7 +219,7 @@ int bar(int n){ // CHECK1: omp.loop.exit: // CHECK1-NEXT: [[TMP40:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 // CHECK1-NEXT: [[TMP41:%.*]] = load i32, ptr [[TMP40]], align 4 -// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB3:[0-9]+]], i32 [[TMP41]]) +// CHECK1-NEXT: call void @__kmpc_distribute_static_fini(ptr @[[GLOB2]], i32 [[TMP41]]) // CHECK1-NEXT: br label [[OMP_PRECOND_END]] // CHECK1: omp.precond.end: // CHECK1-NEXT: ret void @@ -276,7 +276,7 @@ int bar(int n){ // CHECK1-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK1-NEXT: [[TMP7:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 // CHECK1-NEXT: [[TMP8:%.*]] = load i32, ptr [[TMP7]], align 4 -// CHECK1-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB3]], i32 [[TMP8]], i32 33, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK1-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB3:[0-9]+]], i32 [[TMP8]], i32 33, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) // CHECK1-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4 // CHECK1-NEXT: store i32 [[TMP9]], ptr [[DOTOMP_IV]], align 4 // CHECK1-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] @@ -432,7 +432,7 @@ int bar(int n){ // CHECK1: omp.inner.for.end: // CHECK1-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK1: omp.loop.exit: -// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB3]], i32 [[TMP2]]) +// CHECK1-NEXT: call void @__kmpc_distribute_static_fini(ptr @[[GLOB2]], i32 [[TMP2]]) // CHECK1-NEXT: ret void // // @@ -637,7 +637,7 @@ int bar(int n){ // CHECK1: omp.inner.for.end: // CHECK1-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK1: omp.loop.exit: -// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB3]], i32 [[TMP2]]) +// CHECK1-NEXT: call void @__kmpc_distribute_static_fini(ptr @[[GLOB2]], i32 [[TMP2]]) // CHECK1-NEXT: ret void // // @@ -904,7 +904,7 @@ int bar(int n){ // CHECK1: omp.loop.exit: // CHECK1-NEXT: [[TMP41:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 // CHECK1-NEXT: [[TMP42:%.*]] = load i32, ptr [[TMP41]], align 4 -// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB3]], i32 [[TMP42]]) +// CHECK1-NEXT: call void @__kmpc_distribute_static_fini(ptr @[[GLOB2]], i32 [[TMP42]]) // CHECK1-NEXT: br label [[OMP_PRECOND_END]] // CHECK1: omp.precond.end: // CHECK1-NEXT: ret void @@ -1208,7 +1208,7 @@ int bar(int n){ // CHECK1: omp.loop.exit: // CHECK1-NEXT: [[TMP42:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 // CHECK1-NEXT: [[TMP43:%.*]] = load i32, ptr [[TMP42]], align 4 -// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB3]], i32 [[TMP43]]) +// CHECK1-NEXT: call void @__kmpc_distribute_static_fini(ptr @[[GLOB2]], i32 [[TMP43]]) // CHECK1-NEXT: br label [[OMP_PRECOND_END]] // CHECK1: omp.precond.end: // CHECK1-NEXT: ret void @@ -1465,7 +1465,7 @@ int bar(int n){ // CHECK2: omp.loop.exit: // CHECK2-NEXT: [[TMP40:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 // CHECK2-NEXT: [[TMP41:%.*]] = load i32, ptr [[TMP40]], align 4 -// CHECK2-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB3:[0-9]+]], i32 [[TMP41]]) +// CHECK2-NEXT: call void @__kmpc_distribute_static_fini(ptr @[[GLOB2]], i32 [[TMP41]]) // CHECK2-NEXT: br label [[OMP_PRECOND_END]] // CHECK2: omp.precond.end: // CHECK2-NEXT: ret void @@ -1522,7 +1522,7 @@ int bar(int n){ // CHECK2-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK2-NEXT: [[TMP7:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 // CHECK2-NEXT: [[TMP8:%.*]] = load i32, ptr [[TMP7]], align 4 -// CHECK2-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB3]], i32 [[TMP8]], i32 33, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK2-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB3:[0-9]+]], i32 [[TMP8]], i32 33, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) // CHECK2-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4 // CHECK2-NEXT: store i32 [[TMP9]], ptr [[DOTOMP_IV]], align 4 // CHECK2-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] @@ -1678,7 +1678,7 @@ int bar(int n){ // CHECK2: omp.inner.for.end: // CHECK2-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK2: omp.loop.exit: -// CHECK2-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB3]], i32 [[TMP2]]) +// CHECK2-NEXT: call void @__kmpc_distribute_static_fini(ptr @[[GLOB2]], i32 [[TMP2]]) // CHECK2-NEXT: ret void // // @@ -1883,7 +1883,7 @@ int bar(int n){ // CHECK2: omp.inner.for.end: // CHECK2-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK2: omp.loop.exit: -// CHECK2-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB3]], i32 [[TMP2]]) +// CHECK2-NEXT: call void @__kmpc_distribute_static_fini(ptr @[[GLOB2]], i32 [[TMP2]]) // CHECK2-NEXT: ret void // // @@ -2149,7 +2149,7 @@ int bar(int n){ // CHECK2: omp.loop.exit: // CHECK2-NEXT: [[TMP43:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 // CHECK2-NEXT: [[TMP44:%.*]] = load i32, ptr [[TMP43]], align 4 -// CHECK2-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB3]], i32 [[TMP44]]) +// CHECK2-NEXT: call void @__kmpc_distribute_static_fini(ptr @[[GLOB2]], i32 [[TMP44]]) // CHECK2-NEXT: br label [[OMP_PRECOND_END]] // CHECK2: omp.precond.end: // CHECK2-NEXT: ret void @@ -2449,7 +2449,7 @@ int bar(int n){ // CHECK2: omp.loop.exit: // CHECK2-NEXT: [[TMP42:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 // CHECK2-NEXT: [[TMP43:%.*]] = load i32, ptr [[TMP42]], align 4 -// CHECK2-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB3]], i32 [[TMP43]]) +// CHECK2-NEXT: call void @__kmpc_distribute_static_fini(ptr @[[GLOB2]], i32 [[TMP43]]) // CHECK2-NEXT: br label [[OMP_PRECOND_END]] // CHECK2: omp.precond.end: // CHECK2-NEXT: ret void @@ -2704,7 +2704,7 @@ int bar(int n){ // CHECK3: omp.loop.exit: // CHECK3-NEXT: [[TMP38:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 4 // CHECK3-NEXT: [[TMP39:%.*]] = load i32, ptr [[TMP38]], align 4 -// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB3:[0-9]+]], i32 [[TMP39]]) +// CHECK3-NEXT: call void @__kmpc_distribute_static_fini(ptr @[[GLOB2]], i32 [[TMP39]]) // CHECK3-NEXT: br label [[OMP_PRECOND_END]] // CHECK3: omp.precond.end: // CHECK3-NEXT: ret void @@ -2759,7 +2759,7 @@ int bar(int n){ // CHECK3-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK3-NEXT: [[TMP7:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 4 // CHECK3-NEXT: [[TMP8:%.*]] = load i32, ptr [[TMP7]], align 4 -// CHECK3-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB3]], i32 [[TMP8]], i32 33, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK3-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB3:[0-9]+]], i32 [[TMP8]], i32 33, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) // CHECK3-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4 // CHECK3-NEXT: store i32 [[TMP9]], ptr [[DOTOMP_IV]], align 4 // CHECK3-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] @@ -2911,7 +2911,7 @@ int bar(int n){ // CHECK3: omp.inner.for.end: // CHECK3-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK3: omp.loop.exit: -// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB3]], i32 [[TMP2]]) +// CHECK3-NEXT: call void @__kmpc_distribute_static_fini(ptr @[[GLOB2]], i32 [[TMP2]]) // CHECK3-NEXT: ret void // // @@ -3110,7 +3110,7 @@ int bar(int n){ // CHECK3: omp.inner.for.end: // CHECK3-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK3: omp.loop.exit: -// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB3]], i32 [[TMP2]]) +// CHECK3-NEXT: call void @__kmpc_distribute_static_fini(ptr @[[GLOB2]], i32 [[TMP2]]) // CHECK3-NEXT: ret void // // @@ -3374,7 +3374,7 @@ int bar(int n){ // CHECK3: omp.loop.exit: // CHECK3-NEXT: [[TMP43:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 4 // CHECK3-NEXT: [[TMP44:%.*]] = load i32, ptr [[TMP43]], align 4 -// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB3]], i32 [[TMP44]]) +// CHECK3-NEXT: call void @__kmpc_distribute_static_fini(ptr @[[GLOB2]], i32 [[TMP44]]) // CHECK3-NEXT: br label [[OMP_PRECOND_END]] // CHECK3: omp.precond.end: // CHECK3-NEXT: ret void @@ -3677,7 +3677,7 @@ int bar(int n){ // CHECK3: omp.loop.exit: // CHECK3-NEXT: [[TMP40:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 4 // CHECK3-NEXT: [[TMP41:%.*]] = load i32, ptr [[TMP40]], align 4 -// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB3]], i32 [[TMP41]]) +// CHECK3-NEXT: call void @__kmpc_distribute_static_fini(ptr @[[GLOB2]], i32 [[TMP41]]) // CHECK3-NEXT: br label [[OMP_PRECOND_END]] // CHECK3: omp.precond.end: // CHECK3-NEXT: ret void diff --git a/clang/test/OpenMP/nvptx_target_teams_generic_loop_generic_mode_codegen.cpp b/clang/test/OpenMP/nvptx_target_teams_generic_loop_generic_mode_codegen.cpp index ef26c9b1003ac55d948b3898d02715a69932fd4c..ca2670f0cd643fc110bde6595ea36f55989217d4 100644 --- a/clang/test/OpenMP/nvptx_target_teams_generic_loop_generic_mode_codegen.cpp +++ b/clang/test/OpenMP/nvptx_target_teams_generic_loop_generic_mode_codegen.cpp @@ -183,7 +183,7 @@ int main(int argc, char **argv) { // CHECK1: omp.loop.exit: // CHECK1-NEXT: [[TMP40:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 // CHECK1-NEXT: [[TMP41:%.*]] = load i32, ptr [[TMP40]], align 4 -// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB3:[0-9]+]], i32 [[TMP41]]) +// CHECK1-NEXT: call void @__kmpc_distribute_static_fini(ptr @[[GLOB2]], i32 [[TMP41]]) // CHECK1-NEXT: br label [[OMP_PRECOND_END]] // CHECK1: omp.precond.end: // CHECK1-NEXT: ret void @@ -240,7 +240,7 @@ int main(int argc, char **argv) { // CHECK1-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK1-NEXT: [[TMP7:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 // CHECK1-NEXT: [[TMP8:%.*]] = load i32, ptr [[TMP7]], align 4 -// CHECK1-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB3]], i32 [[TMP8]], i32 33, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK1-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB3:[0-9]+]], i32 [[TMP8]], i32 33, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) // CHECK1-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4 // CHECK1-NEXT: store i32 [[TMP9]], ptr [[DOTOMP_IV]], align 4 // CHECK1-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] @@ -433,7 +433,7 @@ int main(int argc, char **argv) { // CHECK2: omp.loop.exit: // CHECK2-NEXT: [[TMP38:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 4 // CHECK2-NEXT: [[TMP39:%.*]] = load i32, ptr [[TMP38]], align 4 -// CHECK2-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB3:[0-9]+]], i32 [[TMP39]]) +// CHECK2-NEXT: call void @__kmpc_distribute_static_fini(ptr @[[GLOB2]], i32 [[TMP39]]) // CHECK2-NEXT: br label [[OMP_PRECOND_END]] // CHECK2: omp.precond.end: // CHECK2-NEXT: ret void @@ -488,7 +488,7 @@ int main(int argc, char **argv) { // CHECK2-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK2-NEXT: [[TMP7:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 4 // CHECK2-NEXT: [[TMP8:%.*]] = load i32, ptr [[TMP7]], align 4 -// CHECK2-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB3]], i32 [[TMP8]], i32 33, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK2-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB3:[0-9]+]], i32 [[TMP8]], i32 33, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) // CHECK2-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4 // CHECK2-NEXT: store i32 [[TMP9]], ptr [[DOTOMP_IV]], align 4 // CHECK2-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] diff --git a/clang/test/OpenMP/reduction_implicit_map.cpp b/clang/test/OpenMP/reduction_implicit_map.cpp index d47c6ec7214df6a8d516756d999bcb91fae41c08..7305c56289e01b68464427ba1660125ca645a0de 100644 --- a/clang/test/OpenMP/reduction_implicit_map.cpp +++ b/clang/test/OpenMP/reduction_implicit_map.cpp @@ -1365,7 +1365,7 @@ int main() // CHECK2: omp.loop.exit: // CHECK2-NEXT: [[TMP29:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 4 // CHECK2-NEXT: [[TMP30:%.*]] = load i32, ptr [[TMP29]], align 4 -// CHECK2-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP30]]) +// CHECK2-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP30]]) // CHECK2-NEXT: [[TMP31:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOMP_REDUCTION_RED_LIST]], i32 0, i32 0 // CHECK2-NEXT: store ptr [[OUTPUT3]], ptr [[TMP31]], align 4 // CHECK2-NEXT: [[TMP32:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 4 @@ -1735,7 +1735,7 @@ int main() // CHECK2: omp.loop.exit: // CHECK2-NEXT: [[TMP31:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 4 // CHECK2-NEXT: [[TMP32:%.*]] = load i32, ptr [[TMP31]], align 4 -// CHECK2-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP32]]) +// CHECK2-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP32]]) // CHECK2-NEXT: [[TMP33:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOMP_REDUCTION_RED_LIST]], i32 0, i32 0 // CHECK2-NEXT: store ptr [[OUTPUT4]], ptr [[TMP33]], align 4 // CHECK2-NEXT: [[TMP34:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 4 diff --git a/clang/test/OpenMP/target_ompx_dyn_cgroup_mem_codegen.cpp b/clang/test/OpenMP/target_ompx_dyn_cgroup_mem_codegen.cpp index a8b241c17d248216d71df9447d3ec0e9a6210862..e8b074a9d5f8be980b00ba24d776e1e3bbd4bbd6 100644 --- a/clang/test/OpenMP/target_ompx_dyn_cgroup_mem_codegen.cpp +++ b/clang/test/OpenMP/target_ompx_dyn_cgroup_mem_codegen.cpp @@ -854,7 +854,7 @@ int bar(int n){ // CHECK1: omp.loop.exit: // CHECK1-NEXT: [[TMP17:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 // CHECK1-NEXT: [[TMP18:%.*]] = load i32, ptr [[TMP17]], align 4 -// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP18]]) +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB3]], i32 [[TMP18]]) // CHECK1-NEXT: [[TMP19:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK1-NEXT: [[TMP20:%.*]] = icmp ne i32 [[TMP19]], 0 // CHECK1-NEXT: br i1 [[TMP20]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -1732,7 +1732,7 @@ int bar(int n){ // CHECK3: omp.loop.exit: // CHECK3-NEXT: [[TMP17:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 4 // CHECK3-NEXT: [[TMP18:%.*]] = load i32, ptr [[TMP17]], align 4 -// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP18]]) +// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB3]], i32 [[TMP18]]) // CHECK3-NEXT: [[TMP19:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK3-NEXT: [[TMP20:%.*]] = icmp ne i32 [[TMP19]], 0 // CHECK3-NEXT: br i1 [[TMP20]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -2145,7 +2145,7 @@ int bar(int n){ // CHECK9: omp.loop.exit: // CHECK9-NEXT: [[TMP17:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 // CHECK9-NEXT: [[TMP18:%.*]] = load i32, ptr [[TMP17]], align 4 -// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP18]]) +// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP18]]) // CHECK9-NEXT: [[TMP19:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK9-NEXT: [[TMP20:%.*]] = icmp ne i32 [[TMP19]], 0 // CHECK9-NEXT: br i1 [[TMP20]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -2508,7 +2508,7 @@ int bar(int n){ // CHECK11: omp.loop.exit: // CHECK11-NEXT: [[TMP17:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 4 // CHECK11-NEXT: [[TMP18:%.*]] = load i32, ptr [[TMP17]], align 4 -// CHECK11-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP18]]) +// CHECK11-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP18]]) // CHECK11-NEXT: [[TMP19:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK11-NEXT: [[TMP20:%.*]] = icmp ne i32 [[TMP19]], 0 // CHECK11-NEXT: br i1 [[TMP20]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] diff --git a/clang/test/OpenMP/target_teams_distribute_parallel_for_codegen.cpp b/clang/test/OpenMP/target_teams_distribute_parallel_for_codegen.cpp index 9e12880be298d80fcadffb6a696e673fb86c2028..7e06d8c16169f74d14cad7613054d35555923e37 100644 --- a/clang/test/OpenMP/target_teams_distribute_parallel_for_codegen.cpp +++ b/clang/test/OpenMP/target_teams_distribute_parallel_for_codegen.cpp @@ -333,12 +333,12 @@ int target_teams_fun(int *g){ // CHECK1: omp.loop.exit: // CHECK1-NEXT: [[TMP23:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 // CHECK1-NEXT: [[TMP24:%.*]] = load i32, ptr [[TMP23]], align 4 -// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP24]]) +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP24]]) // CHECK1-NEXT: br label [[OMP_PRECOND_END]] // CHECK1: cancel.exit: // CHECK1-NEXT: [[TMP25:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 // CHECK1-NEXT: [[TMP26:%.*]] = load i32, ptr [[TMP25]], align 4 -// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP26]]) +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP26]]) // CHECK1-NEXT: br label [[CANCEL_CONT:%.*]] // CHECK1: omp.precond.end: // CHECK1-NEXT: br label [[CANCEL_CONT]] @@ -559,7 +559,7 @@ int target_teams_fun(int *g){ // CHECK1: omp.loop.exit: // CHECK1-NEXT: [[TMP21:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 // CHECK1-NEXT: [[TMP22:%.*]] = load i32, ptr [[TMP21]], align 4 -// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP22]]) +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP22]]) // CHECK1-NEXT: br label [[OMP_PRECOND_END]] // CHECK1: omp.precond.end: // CHECK1-NEXT: ret void @@ -975,12 +975,12 @@ int target_teams_fun(int *g){ // CHECK2: omp.loop.exit: // CHECK2-NEXT: [[TMP23:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 // CHECK2-NEXT: [[TMP24:%.*]] = load i32, ptr [[TMP23]], align 4 -// CHECK2-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP24]]) +// CHECK2-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP24]]) // CHECK2-NEXT: br label [[OMP_PRECOND_END]] // CHECK2: cancel.exit: // CHECK2-NEXT: [[TMP25:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 // CHECK2-NEXT: [[TMP26:%.*]] = load i32, ptr [[TMP25]], align 4 -// CHECK2-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP26]]) +// CHECK2-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP26]]) // CHECK2-NEXT: br label [[CANCEL_CONT:%.*]] // CHECK2: omp.precond.end: // CHECK2-NEXT: br label [[CANCEL_CONT]] @@ -1201,7 +1201,7 @@ int target_teams_fun(int *g){ // CHECK2: omp.loop.exit: // CHECK2-NEXT: [[TMP21:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 // CHECK2-NEXT: [[TMP22:%.*]] = load i32, ptr [[TMP21]], align 4 -// CHECK2-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP22]]) +// CHECK2-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP22]]) // CHECK2-NEXT: br label [[OMP_PRECOND_END]] // CHECK2: omp.precond.end: // CHECK2-NEXT: ret void @@ -1612,12 +1612,12 @@ int target_teams_fun(int *g){ // CHECK4: omp.loop.exit: // CHECK4-NEXT: [[TMP23:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 4 // CHECK4-NEXT: [[TMP24:%.*]] = load i32, ptr [[TMP23]], align 4 -// CHECK4-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP24]]) +// CHECK4-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP24]]) // CHECK4-NEXT: br label [[OMP_PRECOND_END]] // CHECK4: cancel.exit: // CHECK4-NEXT: [[TMP25:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 4 // CHECK4-NEXT: [[TMP26:%.*]] = load i32, ptr [[TMP25]], align 4 -// CHECK4-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP26]]) +// CHECK4-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP26]]) // CHECK4-NEXT: br label [[CANCEL_CONT:%.*]] // CHECK4: omp.precond.end: // CHECK4-NEXT: br label [[CANCEL_CONT]] @@ -1833,7 +1833,7 @@ int target_teams_fun(int *g){ // CHECK4: omp.loop.exit: // CHECK4-NEXT: [[TMP21:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 4 // CHECK4-NEXT: [[TMP22:%.*]] = load i32, ptr [[TMP21]], align 4 -// CHECK4-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP22]]) +// CHECK4-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP22]]) // CHECK4-NEXT: br label [[OMP_PRECOND_END]] // CHECK4: omp.precond.end: // CHECK4-NEXT: ret void @@ -2059,12 +2059,12 @@ int target_teams_fun(int *g){ // CHECK10: omp.loop.exit: // CHECK10-NEXT: [[TMP23:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 // CHECK10-NEXT: [[TMP24:%.*]] = load i32, ptr [[TMP23]], align 4 -// CHECK10-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP24]]) +// CHECK10-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP24]]) // CHECK10-NEXT: br label [[OMP_PRECOND_END]] // CHECK10: cancel.exit: // CHECK10-NEXT: [[TMP25:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 // CHECK10-NEXT: [[TMP26:%.*]] = load i32, ptr [[TMP25]], align 4 -// CHECK10-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP26]]) +// CHECK10-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP26]]) // CHECK10-NEXT: br label [[CANCEL_CONT:%.*]] // CHECK10: omp.precond.end: // CHECK10-NEXT: br label [[CANCEL_CONT]] @@ -2287,7 +2287,7 @@ int target_teams_fun(int *g){ // CHECK10: omp.loop.exit: // CHECK10-NEXT: [[TMP21:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 // CHECK10-NEXT: [[TMP22:%.*]] = load i32, ptr [[TMP21]], align 4 -// CHECK10-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP22]]) +// CHECK10-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP22]]) // CHECK10-NEXT: br label [[OMP_PRECOND_END]] // CHECK10: omp.precond.end: // CHECK10-NEXT: ret void @@ -2508,12 +2508,12 @@ int target_teams_fun(int *g){ // CHECK12: omp.loop.exit: // CHECK12-NEXT: [[TMP23:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 4 // CHECK12-NEXT: [[TMP24:%.*]] = load i32, ptr [[TMP23]], align 4 -// CHECK12-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP24]]) +// CHECK12-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP24]]) // CHECK12-NEXT: br label [[OMP_PRECOND_END]] // CHECK12: cancel.exit: // CHECK12-NEXT: [[TMP25:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 4 // CHECK12-NEXT: [[TMP26:%.*]] = load i32, ptr [[TMP25]], align 4 -// CHECK12-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP26]]) +// CHECK12-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP26]]) // CHECK12-NEXT: br label [[CANCEL_CONT:%.*]] // CHECK12: omp.precond.end: // CHECK12-NEXT: br label [[CANCEL_CONT]] @@ -2731,7 +2731,7 @@ int target_teams_fun(int *g){ // CHECK12: omp.loop.exit: // CHECK12-NEXT: [[TMP21:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 4 // CHECK12-NEXT: [[TMP22:%.*]] = load i32, ptr [[TMP21]], align 4 -// CHECK12-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP22]]) +// CHECK12-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP22]]) // CHECK12-NEXT: br label [[OMP_PRECOND_END]] // CHECK12: omp.precond.end: // CHECK12-NEXT: ret void diff --git a/clang/test/OpenMP/target_teams_distribute_parallel_for_collapse_codegen.cpp b/clang/test/OpenMP/target_teams_distribute_parallel_for_collapse_codegen.cpp index d13920ba956f1bbf094cd4ced7dd9ec506f3d80f..b812011ea4ca0413522eebf21a2d00de1a969a19 100644 --- a/clang/test/OpenMP/target_teams_distribute_parallel_for_collapse_codegen.cpp +++ b/clang/test/OpenMP/target_teams_distribute_parallel_for_collapse_codegen.cpp @@ -331,7 +331,7 @@ int main (int argc, char **argv) { // CHECK1: omp.inner.for.end: // CHECK1-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK1: omp.loop.exit: -// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP4]]) +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP4]]) // CHECK1-NEXT: ret void // // @@ -561,7 +561,7 @@ int main (int argc, char **argv) { // CHECK3: omp.inner.for.end: // CHECK3-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK3: omp.loop.exit: -// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP4]]) +// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP4]]) // CHECK3-NEXT: ret void // // @@ -1000,7 +1000,7 @@ int main (int argc, char **argv) { // CHECK9: omp.loop.exit: // CHECK9-NEXT: [[TMP31:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 // CHECK9-NEXT: [[TMP32:%.*]] = load i32, ptr [[TMP31]], align 4 -// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP32]]) +// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP32]]) // CHECK9-NEXT: br label [[OMP_PRECOND_END]] // CHECK9: omp.precond.end: // CHECK9-NEXT: ret void @@ -1224,7 +1224,7 @@ int main (int argc, char **argv) { // CHECK9: omp.inner.for.end: // CHECK9-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK9: omp.loop.exit: -// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP4]]) +// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP4]]) // CHECK9-NEXT: ret void // // @@ -1664,7 +1664,7 @@ int main (int argc, char **argv) { // CHECK11: omp.loop.exit: // CHECK11-NEXT: [[TMP31:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 4 // CHECK11-NEXT: [[TMP32:%.*]] = load i32, ptr [[TMP31]], align 4 -// CHECK11-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP32]]) +// CHECK11-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP32]]) // CHECK11-NEXT: br label [[OMP_PRECOND_END]] // CHECK11: omp.precond.end: // CHECK11-NEXT: ret void @@ -1882,6 +1882,6 @@ int main (int argc, char **argv) { // CHECK11: omp.inner.for.end: // CHECK11-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK11: omp.loop.exit: -// CHECK11-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP4]]) +// CHECK11-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP4]]) // CHECK11-NEXT: ret void // diff --git a/clang/test/OpenMP/target_teams_distribute_parallel_for_dist_schedule_codegen.cpp b/clang/test/OpenMP/target_teams_distribute_parallel_for_dist_schedule_codegen.cpp index 517ea936a1d680e1260351cc8ffd901d137f2f70..0aa75952a3c2b90f0a8087864944df87816a5773 100644 --- a/clang/test/OpenMP/target_teams_distribute_parallel_for_dist_schedule_codegen.cpp +++ b/clang/test/OpenMP/target_teams_distribute_parallel_for_dist_schedule_codegen.cpp @@ -442,7 +442,7 @@ int main (int argc, char **argv) { // CHECK1: omp.inner.for.end: // CHECK1-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK1: omp.loop.exit: -// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP4]]) +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP4]]) // CHECK1-NEXT: ret void // // @@ -593,7 +593,7 @@ int main (int argc, char **argv) { // CHECK1: omp.inner.for.end: // CHECK1-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK1: omp.loop.exit: -// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP4]]) +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP4]]) // CHECK1-NEXT: ret void // // @@ -764,7 +764,7 @@ int main (int argc, char **argv) { // CHECK1: omp.inner.for.end: // CHECK1-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK1: omp.loop.exit: -// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP4]]) +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP4]]) // CHECK1-NEXT: ret void // // @@ -1071,7 +1071,7 @@ int main (int argc, char **argv) { // CHECK3: omp.inner.for.end: // CHECK3-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK3: omp.loop.exit: -// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP4]]) +// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP4]]) // CHECK3-NEXT: ret void // // @@ -1217,7 +1217,7 @@ int main (int argc, char **argv) { // CHECK3: omp.inner.for.end: // CHECK3-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK3: omp.loop.exit: -// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP4]]) +// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP4]]) // CHECK3-NEXT: ret void // // @@ -1383,7 +1383,7 @@ int main (int argc, char **argv) { // CHECK3: omp.inner.for.end: // CHECK3-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK3: omp.loop.exit: -// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP4]]) +// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP4]]) // CHECK3-NEXT: ret void // // @@ -1881,7 +1881,7 @@ int main (int argc, char **argv) { // CHECK9: omp.loop.exit: // CHECK9-NEXT: [[TMP20:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 // CHECK9-NEXT: [[TMP21:%.*]] = load i32, ptr [[TMP20]], align 4 -// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP21]]) +// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP21]]) // CHECK9-NEXT: br label [[OMP_PRECOND_END]] // CHECK9: omp.precond.end: // CHECK9-NEXT: ret void @@ -2098,7 +2098,7 @@ int main (int argc, char **argv) { // CHECK9: omp.loop.exit: // CHECK9-NEXT: [[TMP20:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 // CHECK9-NEXT: [[TMP21:%.*]] = load i32, ptr [[TMP20]], align 4 -// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP21]]) +// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP21]]) // CHECK9-NEXT: br label [[OMP_PRECOND_END]] // CHECK9: omp.precond.end: // CHECK9-NEXT: ret void @@ -2354,7 +2354,7 @@ int main (int argc, char **argv) { // CHECK9: omp.loop.exit: // CHECK9-NEXT: [[TMP20:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 // CHECK9-NEXT: [[TMP21:%.*]] = load i32, ptr [[TMP20]], align 4 -// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP21]]) +// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP21]]) // CHECK9-NEXT: br label [[OMP_PRECOND_END]] // CHECK9: omp.precond.end: // CHECK9-NEXT: ret void @@ -2668,7 +2668,7 @@ int main (int argc, char **argv) { // CHECK9: omp.inner.for.end: // CHECK9-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK9: omp.loop.exit: -// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP4]]) +// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP4]]) // CHECK9-NEXT: ret void // // @@ -2818,7 +2818,7 @@ int main (int argc, char **argv) { // CHECK9: omp.inner.for.end: // CHECK9-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK9: omp.loop.exit: -// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP4]]) +// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP4]]) // CHECK9-NEXT: ret void // // @@ -3003,7 +3003,7 @@ int main (int argc, char **argv) { // CHECK9: omp.inner.for.end: // CHECK9-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK9: omp.loop.exit: -// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP4]]) +// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP4]]) // CHECK9-NEXT: ret void // // @@ -3498,7 +3498,7 @@ int main (int argc, char **argv) { // CHECK11: omp.loop.exit: // CHECK11-NEXT: [[TMP20:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 4 // CHECK11-NEXT: [[TMP21:%.*]] = load i32, ptr [[TMP20]], align 4 -// CHECK11-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP21]]) +// CHECK11-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP21]]) // CHECK11-NEXT: br label [[OMP_PRECOND_END]] // CHECK11: omp.precond.end: // CHECK11-NEXT: ret void @@ -3710,7 +3710,7 @@ int main (int argc, char **argv) { // CHECK11: omp.loop.exit: // CHECK11-NEXT: [[TMP20:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 4 // CHECK11-NEXT: [[TMP21:%.*]] = load i32, ptr [[TMP20]], align 4 -// CHECK11-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP21]]) +// CHECK11-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP21]]) // CHECK11-NEXT: br label [[OMP_PRECOND_END]] // CHECK11: omp.precond.end: // CHECK11-NEXT: ret void @@ -3961,7 +3961,7 @@ int main (int argc, char **argv) { // CHECK11: omp.loop.exit: // CHECK11-NEXT: [[TMP20:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 4 // CHECK11-NEXT: [[TMP21:%.*]] = load i32, ptr [[TMP20]], align 4 -// CHECK11-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP21]]) +// CHECK11-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP21]]) // CHECK11-NEXT: br label [[OMP_PRECOND_END]] // CHECK11: omp.precond.end: // CHECK11-NEXT: ret void @@ -4270,7 +4270,7 @@ int main (int argc, char **argv) { // CHECK11: omp.inner.for.end: // CHECK11-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK11: omp.loop.exit: -// CHECK11-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP4]]) +// CHECK11-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP4]]) // CHECK11-NEXT: ret void // // @@ -4415,7 +4415,7 @@ int main (int argc, char **argv) { // CHECK11: omp.inner.for.end: // CHECK11-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK11: omp.loop.exit: -// CHECK11-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP4]]) +// CHECK11-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP4]]) // CHECK11-NEXT: ret void // // @@ -4595,6 +4595,6 @@ int main (int argc, char **argv) { // CHECK11: omp.inner.for.end: // CHECK11-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK11: omp.loop.exit: -// CHECK11-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP4]]) +// CHECK11-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP4]]) // CHECK11-NEXT: ret void // diff --git a/clang/test/OpenMP/target_teams_distribute_parallel_for_firstprivate_codegen.cpp b/clang/test/OpenMP/target_teams_distribute_parallel_for_firstprivate_codegen.cpp index 9f11929ec372df3c793482154191465680f9d1c6..375279d9636080c2d2656afd91596d8379388853 100644 --- a/clang/test/OpenMP/target_teams_distribute_parallel_for_firstprivate_codegen.cpp +++ b/clang/test/OpenMP/target_teams_distribute_parallel_for_firstprivate_codegen.cpp @@ -703,7 +703,7 @@ int main() { // CHECK1: omp.loop.exit: // CHECK1-NEXT: [[TMP20:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 // CHECK1-NEXT: [[TMP21:%.*]] = load i32, ptr [[TMP20]], align 4 -// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP21]]) +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP21]]) // CHECK1-NEXT: call void @_ZN1SIfED1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[VAR5]]) #[[ATTR2]] // CHECK1-NEXT: [[ARRAY_BEGIN12:%.*]] = getelementptr inbounds [2 x %struct.S], ptr [[S_ARR3]], i32 0, i32 0 // CHECK1-NEXT: [[TMP22:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[ARRAY_BEGIN12]], i64 2 @@ -1170,7 +1170,7 @@ int main() { // CHECK1: omp.loop.exit: // CHECK1-NEXT: [[TMP20:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 // CHECK1-NEXT: [[TMP21:%.*]] = load i32, ptr [[TMP20]], align 4 -// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP21]]) +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP21]]) // CHECK1-NEXT: call void @_ZN1SIiED1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[VAR6]]) #[[ATTR2]] // CHECK1-NEXT: [[ARRAY_BEGIN13:%.*]] = getelementptr inbounds [2 x %struct.S.0], ptr [[S_ARR4]], i32 0, i32 0 // CHECK1-NEXT: [[TMP22:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[ARRAY_BEGIN13]], i64 2 @@ -1759,7 +1759,7 @@ int main() { // CHECK3: omp.loop.exit: // CHECK3-NEXT: [[TMP20:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 4 // CHECK3-NEXT: [[TMP21:%.*]] = load i32, ptr [[TMP20]], align 4 -// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP21]]) +// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP21]]) // CHECK3-NEXT: call void @_ZN1SIfED1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[VAR4]]) #[[ATTR2]] // CHECK3-NEXT: [[ARRAY_BEGIN10:%.*]] = getelementptr inbounds [2 x %struct.S], ptr [[S_ARR2]], i32 0, i32 0 // CHECK3-NEXT: [[TMP22:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[ARRAY_BEGIN10]], i32 2 @@ -2220,7 +2220,7 @@ int main() { // CHECK3: omp.loop.exit: // CHECK3-NEXT: [[TMP20:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 4 // CHECK3-NEXT: [[TMP21:%.*]] = load i32, ptr [[TMP20]], align 4 -// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP21]]) +// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP21]]) // CHECK3-NEXT: call void @_ZN1SIiED1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[VAR5]]) #[[ATTR2]] // CHECK3-NEXT: [[ARRAY_BEGIN11:%.*]] = getelementptr inbounds [2 x %struct.S.0], ptr [[S_ARR3]], i32 0, i32 0 // CHECK3-NEXT: [[TMP22:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[ARRAY_BEGIN11]], i32 2 @@ -2631,7 +2631,7 @@ int main() { // CHECK5: omp.inner.for.end: // CHECK5-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK5: omp.loop.exit: -// CHECK5-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP3]]) +// CHECK5-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) // CHECK5-NEXT: ret void // // @@ -2949,7 +2949,7 @@ int main() { // CHECK13: omp.loop.exit: // CHECK13-NEXT: [[TMP20:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 // CHECK13-NEXT: [[TMP21:%.*]] = load i32, ptr [[TMP20]], align 4 -// CHECK13-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP21]]) +// CHECK13-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP21]]) // CHECK13-NEXT: call void @_ZN1SIfED1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[VAR5]]) #[[ATTR5]] // CHECK13-NEXT: [[ARRAY_BEGIN12:%.*]] = getelementptr inbounds [2 x %struct.S], ptr [[S_ARR3]], i32 0, i32 0 // CHECK13-NEXT: [[TMP22:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[ARRAY_BEGIN12]], i64 2 @@ -3256,7 +3256,7 @@ int main() { // CHECK13: omp.loop.exit: // CHECK13-NEXT: [[TMP20:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 // CHECK13-NEXT: [[TMP21:%.*]] = load i32, ptr [[TMP20]], align 4 -// CHECK13-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP21]]) +// CHECK13-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP21]]) // CHECK13-NEXT: call void @_ZN1SIiED1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[VAR6]]) #[[ATTR5]] // CHECK13-NEXT: [[ARRAY_BEGIN13:%.*]] = getelementptr inbounds [2 x %struct.S.0], ptr [[S_ARR4]], i32 0, i32 0 // CHECK13-NEXT: [[TMP22:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[ARRAY_BEGIN13]], i64 2 @@ -3663,7 +3663,7 @@ int main() { // CHECK15: omp.loop.exit: // CHECK15-NEXT: [[TMP20:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 4 // CHECK15-NEXT: [[TMP21:%.*]] = load i32, ptr [[TMP20]], align 4 -// CHECK15-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP21]]) +// CHECK15-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP21]]) // CHECK15-NEXT: call void @_ZN1SIfED1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[VAR4]]) #[[ATTR5]] // CHECK15-NEXT: [[ARRAY_BEGIN10:%.*]] = getelementptr inbounds [2 x %struct.S], ptr [[S_ARR2]], i32 0, i32 0 // CHECK15-NEXT: [[TMP22:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[ARRAY_BEGIN10]], i32 2 @@ -3964,7 +3964,7 @@ int main() { // CHECK15: omp.loop.exit: // CHECK15-NEXT: [[TMP20:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 4 // CHECK15-NEXT: [[TMP21:%.*]] = load i32, ptr [[TMP20]], align 4 -// CHECK15-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP21]]) +// CHECK15-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP21]]) // CHECK15-NEXT: call void @_ZN1SIiED1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[VAR5]]) #[[ATTR5]] // CHECK15-NEXT: [[ARRAY_BEGIN11:%.*]] = getelementptr inbounds [2 x %struct.S.0], ptr [[S_ARR3]], i32 0, i32 0 // CHECK15-NEXT: [[TMP22:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[ARRAY_BEGIN11]], i32 2 @@ -4270,6 +4270,6 @@ int main() { // CHECK17: omp.inner.for.end: // CHECK17-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK17: omp.loop.exit: -// CHECK17-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP3]]) +// CHECK17-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) // CHECK17-NEXT: ret void // diff --git a/clang/test/OpenMP/target_teams_distribute_parallel_for_if_codegen.cpp b/clang/test/OpenMP/target_teams_distribute_parallel_for_if_codegen.cpp index fe2088aace15efc0141070aacfb0240af73d5eb8..9baf13385bef5bbf184d0e0990c136bed97b9e97 100644 --- a/clang/test/OpenMP/target_teams_distribute_parallel_for_if_codegen.cpp +++ b/clang/test/OpenMP/target_teams_distribute_parallel_for_if_codegen.cpp @@ -314,7 +314,7 @@ int main() { // CHECK1: omp.inner.for.end: // CHECK1-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK1: omp.loop.exit: -// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP3]]) +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) // CHECK1-NEXT: ret void // // @@ -457,7 +457,7 @@ int main() { // CHECK1: omp.inner.for.end: // CHECK1-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK1: omp.loop.exit: -// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP3]]) +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) // CHECK1-NEXT: ret void // // @@ -711,7 +711,7 @@ int main() { // CHECK1: omp.inner.for.end: // CHECK1-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK1: omp.loop.exit: -// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP3]]) +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) // CHECK1-NEXT: ret void // // @@ -854,7 +854,7 @@ int main() { // CHECK1: omp.inner.for.end: // CHECK1-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK1: omp.loop.exit: -// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP3]]) +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) // CHECK1-NEXT: ret void // // @@ -1016,7 +1016,7 @@ int main() { // CHECK1: omp.inner.for.end: // CHECK1-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK1: omp.loop.exit: -// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP3]]) +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) // CHECK1-NEXT: ret void // // @@ -1259,7 +1259,7 @@ int main() { // CHECK1: omp.inner.for.end: // CHECK1-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK1: omp.loop.exit: -// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP3]]) +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) // CHECK1-NEXT: ret void // // @@ -1402,7 +1402,7 @@ int main() { // CHECK1: omp.inner.for.end: // CHECK1-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK1: omp.loop.exit: -// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP3]]) +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) // CHECK1-NEXT: ret void // // @@ -1564,6 +1564,6 @@ int main() { // CHECK1: omp.inner.for.end: // CHECK1-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK1: omp.loop.exit: -// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP3]]) +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) // CHECK1-NEXT: ret void // diff --git a/clang/test/OpenMP/target_teams_distribute_parallel_for_lastprivate_codegen.cpp b/clang/test/OpenMP/target_teams_distribute_parallel_for_lastprivate_codegen.cpp index e2181e5088cc98f58a3082008c64e26ba7771932..e54c230eea7eefd96af9b8c30f2ae684a928ee22 100644 --- a/clang/test/OpenMP/target_teams_distribute_parallel_for_lastprivate_codegen.cpp +++ b/clang/test/OpenMP/target_teams_distribute_parallel_for_lastprivate_codegen.cpp @@ -428,7 +428,7 @@ int main() { // CHECK1: omp.inner.for.end: // CHECK1-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK1: omp.loop.exit: -// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP4]]) +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP4]]) // CHECK1-NEXT: [[TMP18:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK1-NEXT: [[TMP19:%.*]] = icmp ne i32 [[TMP18]], 0 // CHECK1-NEXT: br i1 [[TMP19]], label [[DOTOMP_LASTPRIVATE_THEN:%.*]], label [[DOTOMP_LASTPRIVATE_DONE:%.*]] @@ -692,7 +692,7 @@ int main() { // CHECK3: omp.inner.for.end: // CHECK3-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK3: omp.loop.exit: -// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP6]]) +// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP6]]) // CHECK3-NEXT: [[TMP20:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK3-NEXT: [[TMP21:%.*]] = icmp ne i32 [[TMP20]], 0 // CHECK3-NEXT: br i1 [[TMP21]], label [[DOTOMP_LASTPRIVATE_THEN:%.*]], label [[DOTOMP_LASTPRIVATE_DONE:%.*]] @@ -1144,7 +1144,7 @@ int main() { // CHECK5: omp.loop.exit: // CHECK5-NEXT: [[TMP19:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 // CHECK5-NEXT: [[TMP20:%.*]] = load i32, ptr [[TMP19]], align 4 -// CHECK5-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP20]]) +// CHECK5-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP20]]) // CHECK5-NEXT: [[TMP21:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK5-NEXT: [[TMP22:%.*]] = icmp ne i32 [[TMP21]], 0 // CHECK5-NEXT: br i1 [[TMP22]], label [[DOTOMP_LASTPRIVATE_THEN:%.*]], label [[DOTOMP_LASTPRIVATE_DONE:%.*]] @@ -1628,7 +1628,7 @@ int main() { // CHECK5: omp.loop.exit: // CHECK5-NEXT: [[TMP19:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 // CHECK5-NEXT: [[TMP20:%.*]] = load i32, ptr [[TMP19]], align 4 -// CHECK5-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP20]]) +// CHECK5-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP20]]) // CHECK5-NEXT: [[TMP21:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK5-NEXT: [[TMP22:%.*]] = icmp ne i32 [[TMP21]], 0 // CHECK5-NEXT: br i1 [[TMP22]], label [[DOTOMP_LASTPRIVATE_THEN:%.*]], label [[DOTOMP_LASTPRIVATE_DONE:%.*]] @@ -2138,7 +2138,7 @@ int main() { // CHECK7: omp.loop.exit: // CHECK7-NEXT: [[TMP19:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 4 // CHECK7-NEXT: [[TMP20:%.*]] = load i32, ptr [[TMP19]], align 4 -// CHECK7-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP20]]) +// CHECK7-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP20]]) // CHECK7-NEXT: [[TMP21:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK7-NEXT: [[TMP22:%.*]] = icmp ne i32 [[TMP21]], 0 // CHECK7-NEXT: br i1 [[TMP22]], label [[DOTOMP_LASTPRIVATE_THEN:%.*]], label [[DOTOMP_LASTPRIVATE_DONE:%.*]] @@ -2616,7 +2616,7 @@ int main() { // CHECK7: omp.loop.exit: // CHECK7-NEXT: [[TMP19:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 4 // CHECK7-NEXT: [[TMP20:%.*]] = load i32, ptr [[TMP19]], align 4 -// CHECK7-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP20]]) +// CHECK7-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP20]]) // CHECK7-NEXT: [[TMP21:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK7-NEXT: [[TMP22:%.*]] = icmp ne i32 [[TMP21]], 0 // CHECK7-NEXT: br i1 [[TMP22]], label [[DOTOMP_LASTPRIVATE_THEN:%.*]], label [[DOTOMP_LASTPRIVATE_DONE:%.*]] diff --git a/clang/test/OpenMP/target_teams_distribute_parallel_for_order_codegen.cpp b/clang/test/OpenMP/target_teams_distribute_parallel_for_order_codegen.cpp index 74dee0399f58e83539bbb63a35d2c54de97f1892..feab9cdc948bcba8fb8552ad79b83b34021a4d00 100644 --- a/clang/test/OpenMP/target_teams_distribute_parallel_for_order_codegen.cpp +++ b/clang/test/OpenMP/target_teams_distribute_parallel_for_order_codegen.cpp @@ -195,6 +195,6 @@ void gtid_test() { // CHECK1: omp.inner.for.end: // CHECK1-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK1: omp.loop.exit: -// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP3]]) +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) // CHECK1-NEXT: ret void // diff --git a/clang/test/OpenMP/target_teams_distribute_parallel_for_private_codegen.cpp b/clang/test/OpenMP/target_teams_distribute_parallel_for_private_codegen.cpp index 82f29fa1d3ef421875f1c461414f5f50c59c6b24..066d926e5abcbf2ec545ffbdb2cba6f61795f175 100644 --- a/clang/test/OpenMP/target_teams_distribute_parallel_for_private_codegen.cpp +++ b/clang/test/OpenMP/target_teams_distribute_parallel_for_private_codegen.cpp @@ -534,7 +534,7 @@ int main() { // CHECK1: omp.loop.exit: // CHECK1-NEXT: [[TMP16:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 // CHECK1-NEXT: [[TMP17:%.*]] = load i32, ptr [[TMP16]], align 4 -// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP17]]) +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP17]]) // CHECK1-NEXT: call void @_ZN1SIfED1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[VAR]]) #[[ATTR2]] // CHECK1-NEXT: [[ARRAY_BEGIN7:%.*]] = getelementptr inbounds [2 x %struct.S], ptr [[S_ARR]], i32 0, i32 0 // CHECK1-NEXT: [[TMP18:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[ARRAY_BEGIN7]], i64 2 @@ -842,7 +842,7 @@ int main() { // CHECK1: omp.loop.exit: // CHECK1-NEXT: [[TMP15:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 // CHECK1-NEXT: [[TMP16:%.*]] = load i32, ptr [[TMP15]], align 4 -// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP16]]) +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP16]]) // CHECK1-NEXT: call void @_ZN1SIiED1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[VAR]]) #[[ATTR2]] // CHECK1-NEXT: [[ARRAY_BEGIN8:%.*]] = getelementptr inbounds [2 x %struct.S.0], ptr [[S_ARR]], i32 0, i32 0 // CHECK1-NEXT: [[TMP17:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[ARRAY_BEGIN8]], i64 2 @@ -1261,7 +1261,7 @@ int main() { // CHECK3: omp.loop.exit: // CHECK3-NEXT: [[TMP16:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 4 // CHECK3-NEXT: [[TMP17:%.*]] = load i32, ptr [[TMP16]], align 4 -// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP17]]) +// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP17]]) // CHECK3-NEXT: call void @_ZN1SIfED1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[VAR]]) #[[ATTR2]] // CHECK3-NEXT: [[ARRAY_BEGIN5:%.*]] = getelementptr inbounds [2 x %struct.S], ptr [[S_ARR]], i32 0, i32 0 // CHECK3-NEXT: [[TMP18:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[ARRAY_BEGIN5]], i32 2 @@ -1563,7 +1563,7 @@ int main() { // CHECK3: omp.loop.exit: // CHECK3-NEXT: [[TMP15:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 4 // CHECK3-NEXT: [[TMP16:%.*]] = load i32, ptr [[TMP15]], align 4 -// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP16]]) +// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP16]]) // CHECK3-NEXT: call void @_ZN1SIiED1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[VAR]]) #[[ATTR2]] // CHECK3-NEXT: [[ARRAY_BEGIN6:%.*]] = getelementptr inbounds [2 x %struct.S.0], ptr [[S_ARR]], i32 0, i32 0 // CHECK3-NEXT: [[TMP17:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[ARRAY_BEGIN6]], i32 2 @@ -1917,7 +1917,7 @@ int main() { // CHECK5: omp.inner.for.end: // CHECK5-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK5: omp.loop.exit: -// CHECK5-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP3]]) +// CHECK5-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) // CHECK5-NEXT: ret void // // @@ -2139,7 +2139,7 @@ int main() { // CHECK13: omp.loop.exit: // CHECK13-NEXT: [[TMP16:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 // CHECK13-NEXT: [[TMP17:%.*]] = load i32, ptr [[TMP16]], align 4 -// CHECK13-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP17]]) +// CHECK13-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP17]]) // CHECK13-NEXT: call void @_ZN1SIfED1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[VAR]]) #[[ATTR5]] // CHECK13-NEXT: [[ARRAY_BEGIN7:%.*]] = getelementptr inbounds [2 x %struct.S], ptr [[S_ARR]], i32 0, i32 0 // CHECK13-NEXT: [[TMP18:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[ARRAY_BEGIN7]], i64 2 @@ -2376,7 +2376,7 @@ int main() { // CHECK13: omp.loop.exit: // CHECK13-NEXT: [[TMP15:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 // CHECK13-NEXT: [[TMP16:%.*]] = load i32, ptr [[TMP15]], align 4 -// CHECK13-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP16]]) +// CHECK13-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP16]]) // CHECK13-NEXT: call void @_ZN1SIiED1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[VAR]]) #[[ATTR5]] // CHECK13-NEXT: [[ARRAY_BEGIN8:%.*]] = getelementptr inbounds [2 x %struct.S.0], ptr [[S_ARR]], i32 0, i32 0 // CHECK13-NEXT: [[TMP17:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[ARRAY_BEGIN8]], i64 2 @@ -2647,7 +2647,7 @@ int main() { // CHECK15: omp.loop.exit: // CHECK15-NEXT: [[TMP16:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 4 // CHECK15-NEXT: [[TMP17:%.*]] = load i32, ptr [[TMP16]], align 4 -// CHECK15-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP17]]) +// CHECK15-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP17]]) // CHECK15-NEXT: call void @_ZN1SIfED1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[VAR]]) #[[ATTR5]] // CHECK15-NEXT: [[ARRAY_BEGIN5:%.*]] = getelementptr inbounds [2 x %struct.S], ptr [[S_ARR]], i32 0, i32 0 // CHECK15-NEXT: [[TMP18:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[ARRAY_BEGIN5]], i32 2 @@ -2878,7 +2878,7 @@ int main() { // CHECK15: omp.loop.exit: // CHECK15-NEXT: [[TMP15:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 4 // CHECK15-NEXT: [[TMP16:%.*]] = load i32, ptr [[TMP15]], align 4 -// CHECK15-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP16]]) +// CHECK15-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP16]]) // CHECK15-NEXT: call void @_ZN1SIiED1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[VAR]]) #[[ATTR5]] // CHECK15-NEXT: [[ARRAY_BEGIN6:%.*]] = getelementptr inbounds [2 x %struct.S.0], ptr [[S_ARR]], i32 0, i32 0 // CHECK15-NEXT: [[TMP17:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[ARRAY_BEGIN6]], i32 2 @@ -3108,6 +3108,6 @@ int main() { // CHECK17: omp.inner.for.end: // CHECK17-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK17: omp.loop.exit: -// CHECK17-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP3]]) +// CHECK17-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) // CHECK17-NEXT: ret void // diff --git a/clang/test/OpenMP/target_teams_distribute_parallel_for_proc_bind_codegen.cpp b/clang/test/OpenMP/target_teams_distribute_parallel_for_proc_bind_codegen.cpp index 6d22bc22e47960b9d5655cd82767ea7635f8303f..9f3e50fe20a62a08f035cf5a2ad6a4e8b069025d 100644 --- a/clang/test/OpenMP/target_teams_distribute_parallel_for_proc_bind_codegen.cpp +++ b/clang/test/OpenMP/target_teams_distribute_parallel_for_proc_bind_codegen.cpp @@ -261,7 +261,7 @@ int main() { // CHECK1: omp.inner.for.end: // CHECK1-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK1: omp.loop.exit: -// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP3]]) +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) // CHECK1-NEXT: ret void // // @@ -399,7 +399,7 @@ int main() { // CHECK1: omp.inner.for.end: // CHECK1-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK1: omp.loop.exit: -// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP3]]) +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) // CHECK1-NEXT: ret void // // @@ -578,6 +578,6 @@ int main() { // CHECK1: omp.inner.for.end: // CHECK1-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK1: omp.loop.exit: -// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP3]]) +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) // CHECK1-NEXT: ret void // diff --git a/clang/test/OpenMP/target_teams_distribute_parallel_for_reduction_codegen.cpp b/clang/test/OpenMP/target_teams_distribute_parallel_for_reduction_codegen.cpp index bfa00ee7a0f4ba0395c1396b44ad40441969acf1..1036ffd195de00e8544c669ee18c5580a14e2455 100644 --- a/clang/test/OpenMP/target_teams_distribute_parallel_for_reduction_codegen.cpp +++ b/clang/test/OpenMP/target_teams_distribute_parallel_for_reduction_codegen.cpp @@ -316,7 +316,7 @@ int main() { // CHECK1: omp.inner.for.end: // CHECK1-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK1: omp.loop.exit: -// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP4]]) +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP4]]) // CHECK1-NEXT: [[TMP14:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOMP_REDUCTION_RED_LIST]], i64 0, i64 0 // CHECK1-NEXT: store ptr [[SIVAR2]], ptr [[TMP14]], align 8 // CHECK1-NEXT: [[TMP15:%.*]] = call i32 @__kmpc_reduce_nowait(ptr @[[GLOB3]], i32 [[TMP4]], i32 1, i64 8, ptr [[DOTOMP_REDUCTION_RED_LIST]], ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l66.omp_outlined.omp_outlined.omp.reduction.reduction_func, ptr @.gomp_critical_user_.reduction.var) @@ -606,7 +606,7 @@ int main() { // CHECK1: omp.inner.for.end: // CHECK1-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK1: omp.loop.exit: -// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP4]]) +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP4]]) // CHECK1-NEXT: [[TMP14:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOMP_REDUCTION_RED_LIST]], i64 0, i64 0 // CHECK1-NEXT: store ptr [[T_VAR2]], ptr [[TMP14]], align 8 // CHECK1-NEXT: [[TMP15:%.*]] = call i32 @__kmpc_reduce_nowait(ptr @[[GLOB3]], i32 [[TMP4]], i32 1, i64 8, ptr [[DOTOMP_REDUCTION_RED_LIST]], ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiET_v_l32.omp_outlined.omp_outlined.omp.reduction.reduction_func, ptr @.gomp_critical_user_.reduction.var) @@ -891,7 +891,7 @@ int main() { // CHECK3: omp.inner.for.end: // CHECK3-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK3: omp.loop.exit: -// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP4]]) +// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP4]]) // CHECK3-NEXT: [[TMP14:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOMP_REDUCTION_RED_LIST]], i32 0, i32 0 // CHECK3-NEXT: store ptr [[SIVAR1]], ptr [[TMP14]], align 4 // CHECK3-NEXT: [[TMP15:%.*]] = call i32 @__kmpc_reduce_nowait(ptr @[[GLOB3]], i32 [[TMP4]], i32 1, i32 4, ptr [[DOTOMP_REDUCTION_RED_LIST]], ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l66.omp_outlined.omp_outlined.omp.reduction.reduction_func, ptr @.gomp_critical_user_.reduction.var) @@ -1177,7 +1177,7 @@ int main() { // CHECK3: omp.inner.for.end: // CHECK3-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK3: omp.loop.exit: -// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP4]]) +// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP4]]) // CHECK3-NEXT: [[TMP14:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOMP_REDUCTION_RED_LIST]], i32 0, i32 0 // CHECK3-NEXT: store ptr [[T_VAR1]], ptr [[TMP14]], align 4 // CHECK3-NEXT: [[TMP15:%.*]] = call i32 @__kmpc_reduce_nowait(ptr @[[GLOB3]], i32 [[TMP4]], i32 1, i32 4, ptr [[DOTOMP_REDUCTION_RED_LIST]], ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiET_v_l32.omp_outlined.omp_outlined.omp.reduction.reduction_func, ptr @.gomp_critical_user_.reduction.var) @@ -1425,7 +1425,7 @@ int main() { // CHECK5: omp.inner.for.end: // CHECK5-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK5: omp.loop.exit: -// CHECK5-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP4]]) +// CHECK5-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP4]]) // CHECK5-NEXT: [[TMP15:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOMP_REDUCTION_RED_LIST]], i64 0, i64 0 // CHECK5-NEXT: store ptr [[SIVAR2]], ptr [[TMP15]], align 8 // CHECK5-NEXT: [[TMP16:%.*]] = call i32 @__kmpc_reduce_nowait(ptr @[[GLOB3]], i32 [[TMP4]], i32 1, i64 8, ptr [[DOTOMP_REDUCTION_RED_LIST]], ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l44.omp_outlined.omp_outlined.omp.reduction.reduction_func, ptr @.gomp_critical_user_.reduction.var) diff --git a/clang/test/OpenMP/target_teams_distribute_parallel_for_reduction_task_codegen.cpp b/clang/test/OpenMP/target_teams_distribute_parallel_for_reduction_task_codegen.cpp index fea36e882b7ae2af3a8edbe222f589173041ed3f..6f1cc4d308a62fdc57058ae154061401828ba1f5 100644 --- a/clang/test/OpenMP/target_teams_distribute_parallel_for_reduction_task_codegen.cpp +++ b/clang/test/OpenMP/target_teams_distribute_parallel_for_reduction_task_codegen.cpp @@ -239,8 +239,8 @@ int main(int argc, char **argv) { // CHECK1-NEXT: [[TMP72:%.*]] = load i32, ptr [[TMP71]], align 4 // CHECK1-NEXT: [[TMP73:%.*]] = call i32 @__kmpc_reduce_nowait(ptr @[[GLOB4:[0-9]+]], i32 [[TMP72]], i32 2, i64 24, ptr [[DOTOMP_REDUCTION_RED_LIST]], ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l14.omp_outlined.omp.reduction.reduction_func, ptr @.gomp_critical_user_.reduction.var) // CHECK1-NEXT: switch i32 [[TMP73]], label [[DOTOMP_REDUCTION_DEFAULT:%.*]] [ -// CHECK1-NEXT: i32 1, label [[DOTOMP_REDUCTION_CASE1:%.*]] -// CHECK1-NEXT: i32 2, label [[DOTOMP_REDUCTION_CASE2:%.*]] +// CHECK1-NEXT: i32 1, label [[DOTOMP_REDUCTION_CASE1:%.*]] +// CHECK1-NEXT: i32 2, label [[DOTOMP_REDUCTION_CASE2:%.*]] // CHECK1-NEXT: ] // CHECK1: .omp.reduction.case1: // CHECK1-NEXT: [[TMP74:%.*]] = load i32, ptr [[TMP0]], align 4 @@ -588,7 +588,7 @@ int main(int argc, char **argv) { // CHECK1: omp.loop.exit: // CHECK1-NEXT: [[TMP78:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 // CHECK1-NEXT: [[TMP79:%.*]] = load i32, ptr [[TMP78]], align 4 -// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP79]]) +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB3]], i32 [[TMP79]]) // CHECK1-NEXT: [[TMP80:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 // CHECK1-NEXT: [[TMP81:%.*]] = load i32, ptr [[TMP80]], align 4 // CHECK1-NEXT: call void @__kmpc_task_reduction_modifier_fini(ptr @[[GLOB1]], i32 [[TMP81]], i32 1) @@ -603,8 +603,8 @@ int main(int argc, char **argv) { // CHECK1-NEXT: [[TMP87:%.*]] = load i32, ptr [[TMP86]], align 4 // CHECK1-NEXT: [[TMP88:%.*]] = call i32 @__kmpc_reduce_nowait(ptr @[[GLOB4]], i32 [[TMP87]], i32 2, i64 24, ptr [[DOTOMP_REDUCTION_RED_LIST]], ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l14.omp_outlined.omp_outlined.omp.reduction.reduction_func, ptr @.gomp_critical_user_.reduction.var) // CHECK1-NEXT: switch i32 [[TMP88]], label [[DOTOMP_REDUCTION_DEFAULT:%.*]] [ -// CHECK1-NEXT: i32 1, label [[DOTOMP_REDUCTION_CASE1:%.*]] -// CHECK1-NEXT: i32 2, label [[DOTOMP_REDUCTION_CASE2:%.*]] +// CHECK1-NEXT: i32 1, label [[DOTOMP_REDUCTION_CASE1:%.*]] +// CHECK1-NEXT: i32 2, label [[DOTOMP_REDUCTION_CASE2:%.*]] // CHECK1-NEXT: ] // CHECK1: .omp.reduction.case1: // CHECK1-NEXT: [[TMP89:%.*]] = load i32, ptr [[TMP0]], align 4 @@ -796,21 +796,21 @@ int main(int argc, char **argv) { // CHECK1-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META6:![0-9]+]]) // CHECK1-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META8:![0-9]+]]) // CHECK1-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META10:![0-9]+]]) -// CHECK1-NEXT: store i32 [[TMP2]], ptr [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !12 -// CHECK1-NEXT: store ptr [[TMP5]], ptr [[DOTPART_ID__ADDR_I]], align 8, !noalias !12 -// CHECK1-NEXT: store ptr [[TMP8]], ptr [[DOTPRIVATES__ADDR_I]], align 8, !noalias !12 -// CHECK1-NEXT: store ptr @.omp_task_privates_map., ptr [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !12 -// CHECK1-NEXT: store ptr [[TMP3]], ptr [[DOTTASK_T__ADDR_I]], align 8, !noalias !12 -// CHECK1-NEXT: store ptr [[TMP7]], ptr [[__CONTEXT_ADDR_I]], align 8, !noalias !12 -// CHECK1-NEXT: [[TMP9:%.*]] = load ptr, ptr [[__CONTEXT_ADDR_I]], align 8, !noalias !12 -// CHECK1-NEXT: [[TMP10:%.*]] = load ptr, ptr [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !12 -// CHECK1-NEXT: [[TMP11:%.*]] = load ptr, ptr [[DOTPRIVATES__ADDR_I]], align 8, !noalias !12 +// CHECK1-NEXT: store i32 [[TMP2]], ptr [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias [[META12:![0-9]+]] +// CHECK1-NEXT: store ptr [[TMP5]], ptr [[DOTPART_ID__ADDR_I]], align 8, !noalias [[META12]] +// CHECK1-NEXT: store ptr [[TMP8]], ptr [[DOTPRIVATES__ADDR_I]], align 8, !noalias [[META12]] +// CHECK1-NEXT: store ptr @.omp_task_privates_map., ptr [[DOTCOPY_FN__ADDR_I]], align 8, !noalias [[META12]] +// CHECK1-NEXT: store ptr [[TMP3]], ptr [[DOTTASK_T__ADDR_I]], align 8, !noalias [[META12]] +// CHECK1-NEXT: store ptr [[TMP7]], ptr [[__CONTEXT_ADDR_I]], align 8, !noalias [[META12]] +// CHECK1-NEXT: [[TMP9:%.*]] = load ptr, ptr [[__CONTEXT_ADDR_I]], align 8, !noalias [[META12]] +// CHECK1-NEXT: [[TMP10:%.*]] = load ptr, ptr [[DOTCOPY_FN__ADDR_I]], align 8, !noalias [[META12]] +// CHECK1-NEXT: [[TMP11:%.*]] = load ptr, ptr [[DOTPRIVATES__ADDR_I]], align 8, !noalias [[META12]] // CHECK1-NEXT: call void [[TMP10]](ptr [[TMP11]], ptr [[DOTFIRSTPRIV_PTR_ADDR_I]]) #[[ATTR6]] -// CHECK1-NEXT: [[TMP12:%.*]] = load ptr, ptr [[DOTFIRSTPRIV_PTR_ADDR_I]], align 8, !noalias !12 +// CHECK1-NEXT: [[TMP12:%.*]] = load ptr, ptr [[DOTFIRSTPRIV_PTR_ADDR_I]], align 8, !noalias [[META12]] // CHECK1-NEXT: [[TMP13:%.*]] = getelementptr inbounds [[STRUCT_ANON:%.*]], ptr [[TMP9]], i32 0, i32 1 // CHECK1-NEXT: [[TMP14:%.*]] = load ptr, ptr [[TMP13]], align 8 // CHECK1-NEXT: [[TMP15:%.*]] = load ptr, ptr [[TMP12]], align 8 -// CHECK1-NEXT: [[TMP16:%.*]] = load i32, ptr [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !12 +// CHECK1-NEXT: [[TMP16:%.*]] = load i32, ptr [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias [[META12]] // CHECK1-NEXT: [[TMP17:%.*]] = call ptr @__kmpc_task_reduction_get_th_data(i32 [[TMP16]], ptr [[TMP15]], ptr [[TMP14]]) // CHECK1-NEXT: [[TMP18:%.*]] = getelementptr inbounds [[STRUCT_ANON]], ptr [[TMP9]], i32 0, i32 2 // CHECK1-NEXT: [[TMP19:%.*]] = load ptr, ptr [[TMP18]], align 8 @@ -830,7 +830,7 @@ int main(int argc, char **argv) { // CHECK1-NEXT: [[TMP30:%.*]] = sub i64 [[TMP28]], [[TMP29]] // CHECK1-NEXT: [[TMP31:%.*]] = add nuw i64 [[TMP30]], 1 // CHECK1-NEXT: [[TMP32:%.*]] = mul nuw i64 [[TMP31]], ptrtoint (ptr getelementptr (i8, ptr null, i32 1) to i64) -// CHECK1-NEXT: store i64 [[TMP31]], ptr @{{reduction_size[.].+[.]}}, align 8, !noalias !12 +// CHECK1-NEXT: store i64 [[TMP31]], ptr @{{reduction_size[.].+[.]}}, align 8, !noalias [[META12]] // CHECK1-NEXT: [[TMP33:%.*]] = load ptr, ptr [[TMP12]], align 8 // CHECK1-NEXT: [[TMP34:%.*]] = call ptr @__kmpc_task_reduction_get_th_data(i32 [[TMP16]], ptr [[TMP33]], ptr [[TMP20]]) // CHECK1-NEXT: [[TMP35:%.*]] = getelementptr inbounds [[STRUCT_ANON]], ptr [[TMP9]], i32 0, i32 2 @@ -840,8 +840,8 @@ int main(int argc, char **argv) { // CHECK1-NEXT: [[TMP39:%.*]] = ptrtoint ptr [[TMP20]] to i64 // CHECK1-NEXT: [[TMP40:%.*]] = sub i64 [[TMP38]], [[TMP39]] // CHECK1-NEXT: [[TMP41:%.*]] = getelementptr i8, ptr [[TMP34]], i64 [[TMP40]] -// CHECK1-NEXT: store ptr [[TMP4_I]], ptr [[TMP_I]], align 8, !noalias !12 -// CHECK1-NEXT: store ptr [[TMP41]], ptr [[TMP4_I]], align 8, !noalias !12 +// CHECK1-NEXT: store ptr [[TMP4_I]], ptr [[TMP_I]], align 8, !noalias [[META12]] +// CHECK1-NEXT: store ptr [[TMP41]], ptr [[TMP4_I]], align 8, !noalias [[META12]] // CHECK1-NEXT: ret i32 0 // // diff --git a/clang/test/OpenMP/target_teams_distribute_parallel_for_schedule_codegen.cpp b/clang/test/OpenMP/target_teams_distribute_parallel_for_schedule_codegen.cpp index f71a5ca734377d6dcc7169055b4afd14b0697057..3d031e09aa07d698c637a51632c621cf1c1fc26e 100644 --- a/clang/test/OpenMP/target_teams_distribute_parallel_for_schedule_codegen.cpp +++ b/clang/test/OpenMP/target_teams_distribute_parallel_for_schedule_codegen.cpp @@ -596,7 +596,7 @@ int main (int argc, char **argv) { // CHECK1: omp.inner.for.end: // CHECK1-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK1: omp.loop.exit: -// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP4]]) +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP4]]) // CHECK1-NEXT: ret void // // @@ -747,7 +747,7 @@ int main (int argc, char **argv) { // CHECK1: omp.inner.for.end: // CHECK1-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK1: omp.loop.exit: -// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP4]]) +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP4]]) // CHECK1-NEXT: ret void // // @@ -919,7 +919,7 @@ int main (int argc, char **argv) { // CHECK1-NEXT: store i32 [[ADD8]], ptr [[DOTOMP_UB]], align 4 // CHECK1-NEXT: br label [[OMP_DISPATCH_COND]] // CHECK1: omp.dispatch.end: -// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP4]]) +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP4]]) // CHECK1-NEXT: ret void // // @@ -1618,7 +1618,7 @@ int main (int argc, char **argv) { // CHECK3: omp.inner.for.end: // CHECK3-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK3: omp.loop.exit: -// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP4]]) +// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP4]]) // CHECK3-NEXT: ret void // // @@ -1764,7 +1764,7 @@ int main (int argc, char **argv) { // CHECK3: omp.inner.for.end: // CHECK3-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK3: omp.loop.exit: -// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP4]]) +// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP4]]) // CHECK3-NEXT: ret void // // @@ -1929,7 +1929,7 @@ int main (int argc, char **argv) { // CHECK3-NEXT: store i32 [[ADD5]], ptr [[DOTOMP_UB]], align 4 // CHECK3-NEXT: br label [[OMP_DISPATCH_COND]] // CHECK3: omp.dispatch.end: -// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP4]]) +// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP4]]) // CHECK3-NEXT: ret void // // @@ -2623,7 +2623,7 @@ int main (int argc, char **argv) { // CHECK5: omp.inner.for.end: // CHECK5-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK5: omp.loop.exit: -// CHECK5-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP4]]) +// CHECK5-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP4]]) // CHECK5-NEXT: ret void // // @@ -2774,7 +2774,7 @@ int main (int argc, char **argv) { // CHECK5: omp.inner.for.end: // CHECK5-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK5: omp.loop.exit: -// CHECK5-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP4]]) +// CHECK5-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP4]]) // CHECK5-NEXT: ret void // // @@ -2946,7 +2946,7 @@ int main (int argc, char **argv) { // CHECK5-NEXT: store i32 [[ADD8]], ptr [[DOTOMP_UB]], align 4 // CHECK5-NEXT: br label [[OMP_DISPATCH_COND]] // CHECK5: omp.dispatch.end: -// CHECK5-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP4]]) +// CHECK5-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP4]]) // CHECK5-NEXT: ret void // // @@ -3645,7 +3645,7 @@ int main (int argc, char **argv) { // CHECK7: omp.inner.for.end: // CHECK7-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK7: omp.loop.exit: -// CHECK7-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP4]]) +// CHECK7-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP4]]) // CHECK7-NEXT: ret void // // @@ -3791,7 +3791,7 @@ int main (int argc, char **argv) { // CHECK7: omp.inner.for.end: // CHECK7-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK7: omp.loop.exit: -// CHECK7-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP4]]) +// CHECK7-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP4]]) // CHECK7-NEXT: ret void // // @@ -3956,7 +3956,7 @@ int main (int argc, char **argv) { // CHECK7-NEXT: store i32 [[ADD5]], ptr [[DOTOMP_UB]], align 4 // CHECK7-NEXT: br label [[OMP_DISPATCH_COND]] // CHECK7: omp.dispatch.end: -// CHECK7-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP4]]) +// CHECK7-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP4]]) // CHECK7-NEXT: ret void // // @@ -4915,7 +4915,7 @@ int main (int argc, char **argv) { // CHECK13: omp.loop.exit: // CHECK13-NEXT: [[TMP20:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 // CHECK13-NEXT: [[TMP21:%.*]] = load i32, ptr [[TMP20]], align 4 -// CHECK13-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP21]]) +// CHECK13-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP21]]) // CHECK13-NEXT: br label [[OMP_PRECOND_END]] // CHECK13: omp.precond.end: // CHECK13-NEXT: ret void @@ -5132,7 +5132,7 @@ int main (int argc, char **argv) { // CHECK13: omp.loop.exit: // CHECK13-NEXT: [[TMP20:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 // CHECK13-NEXT: [[TMP21:%.*]] = load i32, ptr [[TMP20]], align 4 -// CHECK13-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP21]]) +// CHECK13-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP21]]) // CHECK13-NEXT: br label [[OMP_PRECOND_END]] // CHECK13: omp.precond.end: // CHECK13-NEXT: ret void @@ -5388,7 +5388,7 @@ int main (int argc, char **argv) { // CHECK13: omp.loop.exit: // CHECK13-NEXT: [[TMP20:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 // CHECK13-NEXT: [[TMP21:%.*]] = load i32, ptr [[TMP20]], align 4 -// CHECK13-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP21]]) +// CHECK13-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP21]]) // CHECK13-NEXT: br label [[OMP_PRECOND_END]] // CHECK13: omp.precond.end: // CHECK13-NEXT: ret void @@ -6248,7 +6248,7 @@ int main (int argc, char **argv) { // CHECK13: omp.inner.for.end: // CHECK13-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK13: omp.loop.exit: -// CHECK13-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP4]]) +// CHECK13-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP4]]) // CHECK13-NEXT: ret void // // @@ -6398,7 +6398,7 @@ int main (int argc, char **argv) { // CHECK13: omp.inner.for.end: // CHECK13-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK13: omp.loop.exit: -// CHECK13-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP4]]) +// CHECK13-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP4]]) // CHECK13-NEXT: ret void // // @@ -6584,7 +6584,7 @@ int main (int argc, char **argv) { // CHECK13-NEXT: store i32 [[ADD8]], ptr [[DOTOMP_UB]], align 4 // CHECK13-NEXT: br label [[OMP_DISPATCH_COND]] // CHECK13: omp.dispatch.end: -// CHECK13-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP5]]) +// CHECK13-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP5]]) // CHECK13-NEXT: ret void // // @@ -7565,7 +7565,7 @@ int main (int argc, char **argv) { // CHECK15: omp.loop.exit: // CHECK15-NEXT: [[TMP20:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 4 // CHECK15-NEXT: [[TMP21:%.*]] = load i32, ptr [[TMP20]], align 4 -// CHECK15-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP21]]) +// CHECK15-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP21]]) // CHECK15-NEXT: br label [[OMP_PRECOND_END]] // CHECK15: omp.precond.end: // CHECK15-NEXT: ret void @@ -7777,7 +7777,7 @@ int main (int argc, char **argv) { // CHECK15: omp.loop.exit: // CHECK15-NEXT: [[TMP20:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 4 // CHECK15-NEXT: [[TMP21:%.*]] = load i32, ptr [[TMP20]], align 4 -// CHECK15-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP21]]) +// CHECK15-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP21]]) // CHECK15-NEXT: br label [[OMP_PRECOND_END]] // CHECK15: omp.precond.end: // CHECK15-NEXT: ret void @@ -8028,7 +8028,7 @@ int main (int argc, char **argv) { // CHECK15: omp.loop.exit: // CHECK15-NEXT: [[TMP20:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 4 // CHECK15-NEXT: [[TMP21:%.*]] = load i32, ptr [[TMP20]], align 4 -// CHECK15-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP21]]) +// CHECK15-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP21]]) // CHECK15-NEXT: br label [[OMP_PRECOND_END]] // CHECK15: omp.precond.end: // CHECK15-NEXT: ret void @@ -8873,7 +8873,7 @@ int main (int argc, char **argv) { // CHECK15: omp.inner.for.end: // CHECK15-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK15: omp.loop.exit: -// CHECK15-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP4]]) +// CHECK15-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP4]]) // CHECK15-NEXT: ret void // // @@ -9018,7 +9018,7 @@ int main (int argc, char **argv) { // CHECK15: omp.inner.for.end: // CHECK15-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK15: omp.loop.exit: -// CHECK15-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP4]]) +// CHECK15-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP4]]) // CHECK15-NEXT: ret void // // @@ -9197,7 +9197,7 @@ int main (int argc, char **argv) { // CHECK15-NEXT: store i32 [[ADD5]], ptr [[DOTOMP_UB]], align 4 // CHECK15-NEXT: br label [[OMP_DISPATCH_COND]] // CHECK15: omp.dispatch.end: -// CHECK15-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP5]]) +// CHECK15-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP5]]) // CHECK15-NEXT: ret void // // @@ -10169,7 +10169,7 @@ int main (int argc, char **argv) { // CHECK17: omp.loop.exit: // CHECK17-NEXT: [[TMP20:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 // CHECK17-NEXT: [[TMP21:%.*]] = load i32, ptr [[TMP20]], align 4 -// CHECK17-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP21]]) +// CHECK17-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP21]]) // CHECK17-NEXT: br label [[OMP_PRECOND_END]] // CHECK17: omp.precond.end: // CHECK17-NEXT: ret void @@ -10386,7 +10386,7 @@ int main (int argc, char **argv) { // CHECK17: omp.loop.exit: // CHECK17-NEXT: [[TMP20:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 // CHECK17-NEXT: [[TMP21:%.*]] = load i32, ptr [[TMP20]], align 4 -// CHECK17-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP21]]) +// CHECK17-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP21]]) // CHECK17-NEXT: br label [[OMP_PRECOND_END]] // CHECK17: omp.precond.end: // CHECK17-NEXT: ret void @@ -10642,7 +10642,7 @@ int main (int argc, char **argv) { // CHECK17: omp.loop.exit: // CHECK17-NEXT: [[TMP20:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 // CHECK17-NEXT: [[TMP21:%.*]] = load i32, ptr [[TMP20]], align 4 -// CHECK17-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP21]]) +// CHECK17-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP21]]) // CHECK17-NEXT: br label [[OMP_PRECOND_END]] // CHECK17: omp.precond.end: // CHECK17-NEXT: ret void @@ -11502,7 +11502,7 @@ int main (int argc, char **argv) { // CHECK17: omp.inner.for.end: // CHECK17-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK17: omp.loop.exit: -// CHECK17-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP4]]) +// CHECK17-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP4]]) // CHECK17-NEXT: ret void // // @@ -11652,7 +11652,7 @@ int main (int argc, char **argv) { // CHECK17: omp.inner.for.end: // CHECK17-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK17: omp.loop.exit: -// CHECK17-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP4]]) +// CHECK17-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP4]]) // CHECK17-NEXT: ret void // // @@ -11838,7 +11838,7 @@ int main (int argc, char **argv) { // CHECK17-NEXT: store i32 [[ADD8]], ptr [[DOTOMP_UB]], align 4 // CHECK17-NEXT: br label [[OMP_DISPATCH_COND]] // CHECK17: omp.dispatch.end: -// CHECK17-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP5]]) +// CHECK17-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP5]]) // CHECK17-NEXT: ret void // // @@ -12819,7 +12819,7 @@ int main (int argc, char **argv) { // CHECK19: omp.loop.exit: // CHECK19-NEXT: [[TMP20:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 4 // CHECK19-NEXT: [[TMP21:%.*]] = load i32, ptr [[TMP20]], align 4 -// CHECK19-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP21]]) +// CHECK19-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP21]]) // CHECK19-NEXT: br label [[OMP_PRECOND_END]] // CHECK19: omp.precond.end: // CHECK19-NEXT: ret void @@ -13031,7 +13031,7 @@ int main (int argc, char **argv) { // CHECK19: omp.loop.exit: // CHECK19-NEXT: [[TMP20:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 4 // CHECK19-NEXT: [[TMP21:%.*]] = load i32, ptr [[TMP20]], align 4 -// CHECK19-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP21]]) +// CHECK19-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP21]]) // CHECK19-NEXT: br label [[OMP_PRECOND_END]] // CHECK19: omp.precond.end: // CHECK19-NEXT: ret void @@ -13282,7 +13282,7 @@ int main (int argc, char **argv) { // CHECK19: omp.loop.exit: // CHECK19-NEXT: [[TMP20:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 4 // CHECK19-NEXT: [[TMP21:%.*]] = load i32, ptr [[TMP20]], align 4 -// CHECK19-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP21]]) +// CHECK19-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP21]]) // CHECK19-NEXT: br label [[OMP_PRECOND_END]] // CHECK19: omp.precond.end: // CHECK19-NEXT: ret void @@ -14127,7 +14127,7 @@ int main (int argc, char **argv) { // CHECK19: omp.inner.for.end: // CHECK19-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK19: omp.loop.exit: -// CHECK19-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP4]]) +// CHECK19-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP4]]) // CHECK19-NEXT: ret void // // @@ -14272,7 +14272,7 @@ int main (int argc, char **argv) { // CHECK19: omp.inner.for.end: // CHECK19-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK19: omp.loop.exit: -// CHECK19-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP4]]) +// CHECK19-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP4]]) // CHECK19-NEXT: ret void // // @@ -14451,7 +14451,7 @@ int main (int argc, char **argv) { // CHECK19-NEXT: store i32 [[ADD5]], ptr [[DOTOMP_UB]], align 4 // CHECK19-NEXT: br label [[OMP_DISPATCH_COND]] // CHECK19: omp.dispatch.end: -// CHECK19-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP5]]) +// CHECK19-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP5]]) // CHECK19-NEXT: ret void // // diff --git a/clang/test/OpenMP/target_teams_distribute_parallel_for_simd_codegen.cpp b/clang/test/OpenMP/target_teams_distribute_parallel_for_simd_codegen.cpp index 5294f0d65eb6de0485036b58d47327fff2684487..109063c623a11da7de177058c66963289e71f9cb 100644 --- a/clang/test/OpenMP/target_teams_distribute_parallel_for_simd_codegen.cpp +++ b/clang/test/OpenMP/target_teams_distribute_parallel_for_simd_codegen.cpp @@ -535,7 +535,7 @@ void test_target_teams_atomic() { // CHECK1: omp.loop.exit: // CHECK1-NEXT: [[TMP23:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 // CHECK1-NEXT: [[TMP24:%.*]] = load i32, ptr [[TMP23]], align 4 -// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP24]]) +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB3]], i32 [[TMP24]]) // CHECK1-NEXT: [[TMP25:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK1-NEXT: [[TMP26:%.*]] = icmp ne i32 [[TMP25]], 0 // CHECK1-NEXT: br i1 [[TMP26]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -784,7 +784,7 @@ void test_target_teams_atomic() { // CHECK1: omp.loop.exit: // CHECK1-NEXT: [[TMP21:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 // CHECK1-NEXT: [[TMP22:%.*]] = load i32, ptr [[TMP21]], align 4 -// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP22]]) +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB3]], i32 [[TMP22]]) // CHECK1-NEXT: [[TMP23:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK1-NEXT: [[TMP24:%.*]] = icmp ne i32 [[TMP23]], 0 // CHECK1-NEXT: br i1 [[TMP24]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -1006,7 +1006,7 @@ void test_target_teams_atomic() { // CHECK1: omp.inner.for.end: // CHECK1-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK1: omp.loop.exit: -// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP4]]) +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB3]], i32 [[TMP4]]) // CHECK1-NEXT: [[TMP13:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK1-NEXT: [[TMP14:%.*]] = icmp ne i32 [[TMP13]], 0 // CHECK1-NEXT: br i1 [[TMP14]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -1465,7 +1465,7 @@ void test_target_teams_atomic() { // CHECK3: omp.loop.exit: // CHECK3-NEXT: [[TMP23:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 4 // CHECK3-NEXT: [[TMP24:%.*]] = load i32, ptr [[TMP23]], align 4 -// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP24]]) +// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB3]], i32 [[TMP24]]) // CHECK3-NEXT: [[TMP25:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK3-NEXT: [[TMP26:%.*]] = icmp ne i32 [[TMP25]], 0 // CHECK3-NEXT: br i1 [[TMP26]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -1709,7 +1709,7 @@ void test_target_teams_atomic() { // CHECK3: omp.loop.exit: // CHECK3-NEXT: [[TMP21:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 4 // CHECK3-NEXT: [[TMP22:%.*]] = load i32, ptr [[TMP21]], align 4 -// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP22]]) +// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB3]], i32 [[TMP22]]) // CHECK3-NEXT: [[TMP23:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK3-NEXT: [[TMP24:%.*]] = icmp ne i32 [[TMP23]], 0 // CHECK3-NEXT: br i1 [[TMP24]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -1927,7 +1927,7 @@ void test_target_teams_atomic() { // CHECK3: omp.inner.for.end: // CHECK3-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK3: omp.loop.exit: -// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP4]]) +// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB3]], i32 [[TMP4]]) // CHECK3-NEXT: [[TMP13:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK3-NEXT: [[TMP14:%.*]] = icmp ne i32 [[TMP13]], 0 // CHECK3-NEXT: br i1 [[TMP14]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -2574,7 +2574,7 @@ void test_target_teams_atomic() { // CHECK9: omp.loop.exit: // CHECK9-NEXT: [[TMP23:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 // CHECK9-NEXT: [[TMP24:%.*]] = load i32, ptr [[TMP23]], align 4 -// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP24]]) +// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB3]], i32 [[TMP24]]) // CHECK9-NEXT: [[TMP25:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK9-NEXT: [[TMP26:%.*]] = icmp ne i32 [[TMP25]], 0 // CHECK9-NEXT: br i1 [[TMP26]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -2825,7 +2825,7 @@ void test_target_teams_atomic() { // CHECK9: omp.loop.exit: // CHECK9-NEXT: [[TMP21:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 // CHECK9-NEXT: [[TMP22:%.*]] = load i32, ptr [[TMP21]], align 4 -// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP22]]) +// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB3]], i32 [[TMP22]]) // CHECK9-NEXT: [[TMP23:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK9-NEXT: [[TMP24:%.*]] = icmp ne i32 [[TMP23]], 0 // CHECK9-NEXT: br i1 [[TMP24]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -2995,7 +2995,7 @@ void test_target_teams_atomic() { // CHECK9: omp.inner.for.end: // CHECK9-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK9: omp.loop.exit: -// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP4]]) +// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB3]], i32 [[TMP4]]) // CHECK9-NEXT: [[TMP13:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK9-NEXT: [[TMP14:%.*]] = icmp ne i32 [[TMP13]], 0 // CHECK9-NEXT: br i1 [[TMP14]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -3253,7 +3253,7 @@ void test_target_teams_atomic() { // CHECK11: omp.loop.exit: // CHECK11-NEXT: [[TMP23:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 4 // CHECK11-NEXT: [[TMP24:%.*]] = load i32, ptr [[TMP23]], align 4 -// CHECK11-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP24]]) +// CHECK11-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB3]], i32 [[TMP24]]) // CHECK11-NEXT: [[TMP25:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK11-NEXT: [[TMP26:%.*]] = icmp ne i32 [[TMP25]], 0 // CHECK11-NEXT: br i1 [[TMP26]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -3499,7 +3499,7 @@ void test_target_teams_atomic() { // CHECK11: omp.loop.exit: // CHECK11-NEXT: [[TMP21:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 4 // CHECK11-NEXT: [[TMP22:%.*]] = load i32, ptr [[TMP21]], align 4 -// CHECK11-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP22]]) +// CHECK11-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB3]], i32 [[TMP22]]) // CHECK11-NEXT: [[TMP23:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK11-NEXT: [[TMP24:%.*]] = icmp ne i32 [[TMP23]], 0 // CHECK11-NEXT: br i1 [[TMP24]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -3665,7 +3665,7 @@ void test_target_teams_atomic() { // CHECK11: omp.inner.for.end: // CHECK11-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK11: omp.loop.exit: -// CHECK11-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP4]]) +// CHECK11-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB3]], i32 [[TMP4]]) // CHECK11-NEXT: [[TMP13:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK11-NEXT: [[TMP14:%.*]] = icmp ne i32 [[TMP13]], 0 // CHECK11-NEXT: br i1 [[TMP14]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] diff --git a/clang/test/OpenMP/target_teams_distribute_parallel_for_simd_collapse_codegen.cpp b/clang/test/OpenMP/target_teams_distribute_parallel_for_simd_collapse_codegen.cpp index 2b4d31d14524083ca935887270f10e3bd5e24663..306ec1db2ab2158a7ffdf3f5a60f44913842ba75 100644 --- a/clang/test/OpenMP/target_teams_distribute_parallel_for_simd_collapse_codegen.cpp +++ b/clang/test/OpenMP/target_teams_distribute_parallel_for_simd_collapse_codegen.cpp @@ -339,7 +339,7 @@ int main (int argc, char **argv) { // CHECK1: omp.inner.for.end: // CHECK1-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK1: omp.loop.exit: -// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP4]]) +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP4]]) // CHECK1-NEXT: [[TMP16:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK1-NEXT: [[TMP17:%.*]] = icmp ne i32 [[TMP16]], 0 // CHECK1-NEXT: br i1 [[TMP17]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -585,7 +585,7 @@ int main (int argc, char **argv) { // CHECK3: omp.inner.for.end: // CHECK3-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK3: omp.loop.exit: -// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP4]]) +// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP4]]) // CHECK3-NEXT: [[TMP16:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK3-NEXT: [[TMP17:%.*]] = icmp ne i32 [[TMP16]], 0 // CHECK3-NEXT: br i1 [[TMP17]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -1190,7 +1190,7 @@ int main (int argc, char **argv) { // CHECK9: omp.loop.exit: // CHECK9-NEXT: [[TMP31:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 // CHECK9-NEXT: [[TMP32:%.*]] = load i32, ptr [[TMP31]], align 4 -// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP32]]) +// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP32]]) // CHECK9-NEXT: [[TMP33:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK9-NEXT: [[TMP34:%.*]] = icmp ne i32 [[TMP33]], 0 // CHECK9-NEXT: br i1 [[TMP34]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -1440,7 +1440,7 @@ int main (int argc, char **argv) { // CHECK9: omp.inner.for.end: // CHECK9-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK9: omp.loop.exit: -// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP4]]) +// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP4]]) // CHECK9-NEXT: [[TMP16:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK9-NEXT: [[TMP17:%.*]] = icmp ne i32 [[TMP16]], 0 // CHECK9-NEXT: br i1 [[TMP17]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -1906,7 +1906,7 @@ int main (int argc, char **argv) { // CHECK11: omp.loop.exit: // CHECK11-NEXT: [[TMP31:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 4 // CHECK11-NEXT: [[TMP32:%.*]] = load i32, ptr [[TMP31]], align 4 -// CHECK11-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP32]]) +// CHECK11-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP32]]) // CHECK11-NEXT: [[TMP33:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK11-NEXT: [[TMP34:%.*]] = icmp ne i32 [[TMP33]], 0 // CHECK11-NEXT: br i1 [[TMP34]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -2150,7 +2150,7 @@ int main (int argc, char **argv) { // CHECK11: omp.inner.for.end: // CHECK11-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK11: omp.loop.exit: -// CHECK11-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP4]]) +// CHECK11-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP4]]) // CHECK11-NEXT: [[TMP16:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK11-NEXT: [[TMP17:%.*]] = icmp ne i32 [[TMP16]], 0 // CHECK11-NEXT: br i1 [[TMP17]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] diff --git a/clang/test/OpenMP/target_teams_distribute_parallel_for_simd_dist_schedule_codegen.cpp b/clang/test/OpenMP/target_teams_distribute_parallel_for_simd_dist_schedule_codegen.cpp index 90fa290370b45b154a8ccf412658dd82f3cae602..c265c1c616b14a4423b092f99fd5336ddbef8a14 100644 --- a/clang/test/OpenMP/target_teams_distribute_parallel_for_simd_dist_schedule_codegen.cpp +++ b/clang/test/OpenMP/target_teams_distribute_parallel_for_simd_dist_schedule_codegen.cpp @@ -449,7 +449,7 @@ int main (int argc, char **argv) { // CHECK1: omp.inner.for.end: // CHECK1-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK1: omp.loop.exit: -// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP4]]) +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP4]]) // CHECK1-NEXT: [[TMP13:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK1-NEXT: [[TMP14:%.*]] = icmp ne i32 [[TMP13]], 0 // CHECK1-NEXT: br i1 [[TMP14]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -614,7 +614,7 @@ int main (int argc, char **argv) { // CHECK1: omp.inner.for.end: // CHECK1-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK1: omp.loop.exit: -// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP4]]) +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP4]]) // CHECK1-NEXT: [[TMP13:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK1-NEXT: [[TMP14:%.*]] = icmp ne i32 [[TMP13]], 0 // CHECK1-NEXT: br i1 [[TMP14]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -799,7 +799,7 @@ int main (int argc, char **argv) { // CHECK1: omp.inner.for.end: // CHECK1-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK1: omp.loop.exit: -// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP4]]) +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP4]]) // CHECK1-NEXT: [[TMP13:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK1-NEXT: [[TMP14:%.*]] = icmp ne i32 [[TMP13]], 0 // CHECK1-NEXT: br i1 [[TMP14]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -1120,7 +1120,7 @@ int main (int argc, char **argv) { // CHECK3: omp.inner.for.end: // CHECK3-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK3: omp.loop.exit: -// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP4]]) +// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP4]]) // CHECK3-NEXT: [[TMP13:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK3-NEXT: [[TMP14:%.*]] = icmp ne i32 [[TMP13]], 0 // CHECK3-NEXT: br i1 [[TMP14]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -1280,7 +1280,7 @@ int main (int argc, char **argv) { // CHECK3: omp.inner.for.end: // CHECK3-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK3: omp.loop.exit: -// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP4]]) +// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP4]]) // CHECK3-NEXT: [[TMP13:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK3-NEXT: [[TMP14:%.*]] = icmp ne i32 [[TMP13]], 0 // CHECK3-NEXT: br i1 [[TMP14]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -1460,7 +1460,7 @@ int main (int argc, char **argv) { // CHECK3: omp.inner.for.end: // CHECK3-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK3: omp.loop.exit: -// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP4]]) +// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP4]]) // CHECK3-NEXT: [[TMP13:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK3-NEXT: [[TMP14:%.*]] = icmp ne i32 [[TMP13]], 0 // CHECK3-NEXT: br i1 [[TMP14]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -2224,7 +2224,7 @@ int main (int argc, char **argv) { // CHECK9: omp.loop.exit: // CHECK9-NEXT: [[TMP20:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 // CHECK9-NEXT: [[TMP21:%.*]] = load i32, ptr [[TMP20]], align 4 -// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP21]]) +// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP21]]) // CHECK9-NEXT: [[TMP22:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK9-NEXT: [[TMP23:%.*]] = icmp ne i32 [[TMP22]], 0 // CHECK9-NEXT: br i1 [[TMP23]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -2465,7 +2465,7 @@ int main (int argc, char **argv) { // CHECK9: omp.loop.exit: // CHECK9-NEXT: [[TMP20:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 // CHECK9-NEXT: [[TMP21:%.*]] = load i32, ptr [[TMP20]], align 4 -// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP21]]) +// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP21]]) // CHECK9-NEXT: [[TMP22:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK9-NEXT: [[TMP23:%.*]] = icmp ne i32 [[TMP22]], 0 // CHECK9-NEXT: br i1 [[TMP23]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -2745,7 +2745,7 @@ int main (int argc, char **argv) { // CHECK9: omp.loop.exit: // CHECK9-NEXT: [[TMP20:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 // CHECK9-NEXT: [[TMP21:%.*]] = load i32, ptr [[TMP20]], align 4 -// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP21]]) +// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP21]]) // CHECK9-NEXT: [[TMP22:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK9-NEXT: [[TMP23:%.*]] = icmp ne i32 [[TMP22]], 0 // CHECK9-NEXT: br i1 [[TMP23]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -3078,7 +3078,7 @@ int main (int argc, char **argv) { // CHECK9: omp.inner.for.end: // CHECK9-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK9: omp.loop.exit: -// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP4]]) +// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP4]]) // CHECK9-NEXT: [[TMP13:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK9-NEXT: [[TMP14:%.*]] = icmp ne i32 [[TMP13]], 0 // CHECK9-NEXT: br i1 [[TMP14]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -3242,7 +3242,7 @@ int main (int argc, char **argv) { // CHECK9: omp.inner.for.end: // CHECK9-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK9: omp.loop.exit: -// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP4]]) +// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP4]]) // CHECK9-NEXT: [[TMP13:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK9-NEXT: [[TMP14:%.*]] = icmp ne i32 [[TMP13]], 0 // CHECK9-NEXT: br i1 [[TMP14]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -3441,7 +3441,7 @@ int main (int argc, char **argv) { // CHECK9: omp.inner.for.end: // CHECK9-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK9: omp.loop.exit: -// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP4]]) +// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP4]]) // CHECK9-NEXT: [[TMP13:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK9-NEXT: [[TMP14:%.*]] = icmp ne i32 [[TMP13]], 0 // CHECK9-NEXT: br i1 [[TMP14]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -3955,7 +3955,7 @@ int main (int argc, char **argv) { // CHECK11: omp.loop.exit: // CHECK11-NEXT: [[TMP20:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 4 // CHECK11-NEXT: [[TMP21:%.*]] = load i32, ptr [[TMP20]], align 4 -// CHECK11-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP21]]) +// CHECK11-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP21]]) // CHECK11-NEXT: [[TMP22:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK11-NEXT: [[TMP23:%.*]] = icmp ne i32 [[TMP22]], 0 // CHECK11-NEXT: br i1 [[TMP23]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -4191,7 +4191,7 @@ int main (int argc, char **argv) { // CHECK11: omp.loop.exit: // CHECK11-NEXT: [[TMP20:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 4 // CHECK11-NEXT: [[TMP21:%.*]] = load i32, ptr [[TMP20]], align 4 -// CHECK11-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP21]]) +// CHECK11-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP21]]) // CHECK11-NEXT: [[TMP22:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK11-NEXT: [[TMP23:%.*]] = icmp ne i32 [[TMP22]], 0 // CHECK11-NEXT: br i1 [[TMP23]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -4466,7 +4466,7 @@ int main (int argc, char **argv) { // CHECK11: omp.loop.exit: // CHECK11-NEXT: [[TMP20:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 4 // CHECK11-NEXT: [[TMP21:%.*]] = load i32, ptr [[TMP20]], align 4 -// CHECK11-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP21]]) +// CHECK11-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP21]]) // CHECK11-NEXT: [[TMP22:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK11-NEXT: [[TMP23:%.*]] = icmp ne i32 [[TMP22]], 0 // CHECK11-NEXT: br i1 [[TMP23]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -4794,7 +4794,7 @@ int main (int argc, char **argv) { // CHECK11: omp.inner.for.end: // CHECK11-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK11: omp.loop.exit: -// CHECK11-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP4]]) +// CHECK11-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP4]]) // CHECK11-NEXT: [[TMP13:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK11-NEXT: [[TMP14:%.*]] = icmp ne i32 [[TMP13]], 0 // CHECK11-NEXT: br i1 [[TMP14]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -4953,7 +4953,7 @@ int main (int argc, char **argv) { // CHECK11: omp.inner.for.end: // CHECK11-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK11: omp.loop.exit: -// CHECK11-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP4]]) +// CHECK11-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP4]]) // CHECK11-NEXT: [[TMP13:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK11-NEXT: [[TMP14:%.*]] = icmp ne i32 [[TMP13]], 0 // CHECK11-NEXT: br i1 [[TMP14]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -5147,7 +5147,7 @@ int main (int argc, char **argv) { // CHECK11: omp.inner.for.end: // CHECK11-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK11: omp.loop.exit: -// CHECK11-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP4]]) +// CHECK11-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP4]]) // CHECK11-NEXT: [[TMP13:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK11-NEXT: [[TMP14:%.*]] = icmp ne i32 [[TMP13]], 0 // CHECK11-NEXT: br i1 [[TMP14]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] diff --git a/clang/test/OpenMP/target_teams_distribute_parallel_for_simd_firstprivate_codegen.cpp b/clang/test/OpenMP/target_teams_distribute_parallel_for_simd_firstprivate_codegen.cpp index bf79fe669d83a23cd633a312956f8d9e066153e0..37c1f428ef9a3010b934c0cc1bd2cc6975cb1592 100644 --- a/clang/test/OpenMP/target_teams_distribute_parallel_for_simd_firstprivate_codegen.cpp +++ b/clang/test/OpenMP/target_teams_distribute_parallel_for_simd_firstprivate_codegen.cpp @@ -708,7 +708,7 @@ int main() { // CHECK1: omp.loop.exit: // CHECK1-NEXT: [[TMP20:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 // CHECK1-NEXT: [[TMP21:%.*]] = load i32, ptr [[TMP20]], align 4 -// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP21]]) +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP21]]) // CHECK1-NEXT: [[TMP22:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK1-NEXT: [[TMP23:%.*]] = icmp ne i32 [[TMP22]], 0 // CHECK1-NEXT: br i1 [[TMP23]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -1189,7 +1189,7 @@ int main() { // CHECK1: omp.loop.exit: // CHECK1-NEXT: [[TMP20:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 // CHECK1-NEXT: [[TMP21:%.*]] = load i32, ptr [[TMP20]], align 4 -// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP21]]) +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP21]]) // CHECK1-NEXT: [[TMP22:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK1-NEXT: [[TMP23:%.*]] = icmp ne i32 [[TMP22]], 0 // CHECK1-NEXT: br i1 [[TMP23]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -1792,7 +1792,7 @@ int main() { // CHECK3: omp.loop.exit: // CHECK3-NEXT: [[TMP20:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 4 // CHECK3-NEXT: [[TMP21:%.*]] = load i32, ptr [[TMP20]], align 4 -// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP21]]) +// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP21]]) // CHECK3-NEXT: [[TMP22:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK3-NEXT: [[TMP23:%.*]] = icmp ne i32 [[TMP22]], 0 // CHECK3-NEXT: br i1 [[TMP23]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -2267,7 +2267,7 @@ int main() { // CHECK3: omp.loop.exit: // CHECK3-NEXT: [[TMP20:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 4 // CHECK3-NEXT: [[TMP21:%.*]] = load i32, ptr [[TMP20]], align 4 -// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP21]]) +// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP21]]) // CHECK3-NEXT: [[TMP22:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK3-NEXT: [[TMP23:%.*]] = icmp ne i32 [[TMP22]], 0 // CHECK3-NEXT: br i1 [[TMP23]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -2692,7 +2692,7 @@ int main() { // CHECK5: omp.inner.for.end: // CHECK5-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK5: omp.loop.exit: -// CHECK5-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP3]]) +// CHECK5-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) // CHECK5-NEXT: [[TMP16:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK5-NEXT: [[TMP17:%.*]] = icmp ne i32 [[TMP16]], 0 // CHECK5-NEXT: br i1 [[TMP17]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -3798,7 +3798,7 @@ int main() { // CHECK13: omp.loop.exit: // CHECK13-NEXT: [[TMP20:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 // CHECK13-NEXT: [[TMP21:%.*]] = load i32, ptr [[TMP20]], align 4 -// CHECK13-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP21]]) +// CHECK13-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP21]]) // CHECK13-NEXT: [[TMP22:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK13-NEXT: [[TMP23:%.*]] = icmp ne i32 [[TMP22]], 0 // CHECK13-NEXT: br i1 [[TMP23]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -4119,7 +4119,7 @@ int main() { // CHECK13: omp.loop.exit: // CHECK13-NEXT: [[TMP20:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 // CHECK13-NEXT: [[TMP21:%.*]] = load i32, ptr [[TMP20]], align 4 -// CHECK13-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP21]]) +// CHECK13-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP21]]) // CHECK13-NEXT: [[TMP22:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK13-NEXT: [[TMP23:%.*]] = icmp ne i32 [[TMP22]], 0 // CHECK13-NEXT: br i1 [[TMP23]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -4540,7 +4540,7 @@ int main() { // CHECK15: omp.loop.exit: // CHECK15-NEXT: [[TMP20:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 4 // CHECK15-NEXT: [[TMP21:%.*]] = load i32, ptr [[TMP20]], align 4 -// CHECK15-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP21]]) +// CHECK15-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP21]]) // CHECK15-NEXT: [[TMP22:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK15-NEXT: [[TMP23:%.*]] = icmp ne i32 [[TMP22]], 0 // CHECK15-NEXT: br i1 [[TMP23]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -4855,7 +4855,7 @@ int main() { // CHECK15: omp.loop.exit: // CHECK15-NEXT: [[TMP20:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 4 // CHECK15-NEXT: [[TMP21:%.*]] = load i32, ptr [[TMP20]], align 4 -// CHECK15-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP21]]) +// CHECK15-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP21]]) // CHECK15-NEXT: [[TMP22:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK15-NEXT: [[TMP23:%.*]] = icmp ne i32 [[TMP22]], 0 // CHECK15-NEXT: br i1 [[TMP23]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -5175,7 +5175,7 @@ int main() { // CHECK17: omp.inner.for.end: // CHECK17-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK17: omp.loop.exit: -// CHECK17-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP3]]) +// CHECK17-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) // CHECK17-NEXT: [[TMP16:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK17-NEXT: [[TMP17:%.*]] = icmp ne i32 [[TMP16]], 0 // CHECK17-NEXT: br i1 [[TMP17]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] diff --git a/clang/test/OpenMP/target_teams_distribute_parallel_for_simd_if_codegen.cpp b/clang/test/OpenMP/target_teams_distribute_parallel_for_simd_if_codegen.cpp index 329cd788c8bab8b4252c6382624d56ba1230c221..df5dd7ba680523cc1fe9583627f5980021b39696 100644 --- a/clang/test/OpenMP/target_teams_distribute_parallel_for_simd_if_codegen.cpp +++ b/clang/test/OpenMP/target_teams_distribute_parallel_for_simd_if_codegen.cpp @@ -353,7 +353,7 @@ int main() { // CHECK1: omp.inner.for.end: // CHECK1-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK1: omp.loop.exit: -// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP3]]) +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) // CHECK1-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK1-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 // CHECK1-NEXT: br i1 [[TMP12]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -510,7 +510,7 @@ int main() { // CHECK1: omp.inner.for.end: // CHECK1-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK1: omp.loop.exit: -// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP3]]) +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) // CHECK1-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK1-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 // CHECK1-NEXT: br i1 [[TMP12]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -778,7 +778,7 @@ int main() { // CHECK1: omp.inner.for.end: // CHECK1-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK1: omp.loop.exit: -// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP3]]) +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) // CHECK1-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK1-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 // CHECK1-NEXT: br i1 [[TMP12]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -935,7 +935,7 @@ int main() { // CHECK1: omp.inner.for.end: // CHECK1-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK1: omp.loop.exit: -// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP3]]) +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) // CHECK1-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK1-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 // CHECK1-NEXT: br i1 [[TMP12]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -1111,7 +1111,7 @@ int main() { // CHECK1: omp.inner.for.end: // CHECK1-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK1: omp.loop.exit: -// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP3]]) +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) // CHECK1-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK1-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 // CHECK1-NEXT: br i1 [[TMP12]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -1368,7 +1368,7 @@ int main() { // CHECK1: omp.inner.for.end: // CHECK1-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK1: omp.loop.exit: -// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP3]]) +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) // CHECK1-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK1-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 // CHECK1-NEXT: br i1 [[TMP12]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -1525,7 +1525,7 @@ int main() { // CHECK1: omp.inner.for.end: // CHECK1-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK1: omp.loop.exit: -// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP3]]) +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) // CHECK1-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK1-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 // CHECK1-NEXT: br i1 [[TMP12]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -1701,7 +1701,7 @@ int main() { // CHECK1: omp.inner.for.end: // CHECK1-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK1: omp.loop.exit: -// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP3]]) +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) // CHECK1-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK1-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 // CHECK1-NEXT: br i1 [[TMP12]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -1958,7 +1958,7 @@ int main() { // CHECK3: omp.inner.for.end: // CHECK3-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK3: omp.loop.exit: -// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP3]]) +// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) // CHECK3-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK3-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 // CHECK3-NEXT: br i1 [[TMP12]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -2115,7 +2115,7 @@ int main() { // CHECK3: omp.inner.for.end: // CHECK3-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK3: omp.loop.exit: -// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP3]]) +// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) // CHECK3-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK3-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 // CHECK3-NEXT: br i1 [[TMP12]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -2383,7 +2383,7 @@ int main() { // CHECK3: omp.inner.for.end: // CHECK3-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK3: omp.loop.exit: -// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP3]]) +// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) // CHECK3-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK3-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 // CHECK3-NEXT: br i1 [[TMP12]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -2540,7 +2540,7 @@ int main() { // CHECK3: omp.inner.for.end: // CHECK3-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK3: omp.loop.exit: -// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP3]]) +// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) // CHECK3-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK3-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 // CHECK3-NEXT: br i1 [[TMP12]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -2819,7 +2819,7 @@ int main() { // CHECK3: omp.loop.exit: // CHECK3-NEXT: [[TMP21:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 // CHECK3-NEXT: [[TMP22:%.*]] = load i32, ptr [[TMP21]], align 4 -// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP22]]) +// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP22]]) // CHECK3-NEXT: [[TMP23:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK3-NEXT: [[TMP24:%.*]] = icmp ne i32 [[TMP23]], 0 // CHECK3-NEXT: br i1 [[TMP24]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -2946,7 +2946,7 @@ int main() { // CHECK3: omp.loop.exit: // CHECK3-NEXT: [[TMP21:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 // CHECK3-NEXT: [[TMP22:%.*]] = load i32, ptr [[TMP21]], align 4 -// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP22]]) +// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP22]]) // CHECK3-NEXT: [[TMP23:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK3-NEXT: [[TMP24:%.*]] = icmp ne i32 [[TMP23]], 0 // CHECK3-NEXT: br i1 [[TMP24]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -3203,7 +3203,7 @@ int main() { // CHECK3: omp.inner.for.end: // CHECK3-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK3: omp.loop.exit: -// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP3]]) +// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) // CHECK3-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK3-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 // CHECK3-NEXT: br i1 [[TMP12]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -3360,7 +3360,7 @@ int main() { // CHECK3: omp.inner.for.end: // CHECK3-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK3: omp.loop.exit: -// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP3]]) +// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) // CHECK3-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK3-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 // CHECK3-NEXT: br i1 [[TMP12]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -3536,7 +3536,7 @@ int main() { // CHECK3: omp.inner.for.end: // CHECK3-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK3: omp.loop.exit: -// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP3]]) +// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) // CHECK3-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK3-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 // CHECK3-NEXT: br i1 [[TMP12]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -4386,7 +4386,7 @@ int main() { // CHECK9: omp.inner.for.end: // CHECK9-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK9: omp.loop.exit: -// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP3]]) +// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) // CHECK9-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK9-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 // CHECK9-NEXT: br i1 [[TMP12]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -4543,7 +4543,7 @@ int main() { // CHECK9: omp.inner.for.end: // CHECK9-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK9: omp.loop.exit: -// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP3]]) +// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) // CHECK9-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK9-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 // CHECK9-NEXT: br i1 [[TMP12]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -4811,7 +4811,7 @@ int main() { // CHECK9: omp.inner.for.end: // CHECK9-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK9: omp.loop.exit: -// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP3]]) +// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) // CHECK9-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK9-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 // CHECK9-NEXT: br i1 [[TMP12]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -4968,7 +4968,7 @@ int main() { // CHECK9: omp.inner.for.end: // CHECK9-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK9: omp.loop.exit: -// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP3]]) +// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) // CHECK9-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK9-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 // CHECK9-NEXT: br i1 [[TMP12]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -5144,7 +5144,7 @@ int main() { // CHECK9: omp.inner.for.end: // CHECK9-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK9: omp.loop.exit: -// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP3]]) +// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) // CHECK9-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK9-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 // CHECK9-NEXT: br i1 [[TMP12]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -5401,7 +5401,7 @@ int main() { // CHECK9: omp.inner.for.end: // CHECK9-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK9: omp.loop.exit: -// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP3]]) +// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) // CHECK9-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK9-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 // CHECK9-NEXT: br i1 [[TMP12]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -5558,7 +5558,7 @@ int main() { // CHECK9: omp.inner.for.end: // CHECK9-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK9: omp.loop.exit: -// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP3]]) +// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) // CHECK9-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK9-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 // CHECK9-NEXT: br i1 [[TMP12]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -5734,7 +5734,7 @@ int main() { // CHECK9: omp.inner.for.end: // CHECK9-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK9: omp.loop.exit: -// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP3]]) +// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) // CHECK9-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK9-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 // CHECK9-NEXT: br i1 [[TMP12]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -5991,7 +5991,7 @@ int main() { // CHECK11: omp.inner.for.end: // CHECK11-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK11: omp.loop.exit: -// CHECK11-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP3]]) +// CHECK11-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) // CHECK11-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK11-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 // CHECK11-NEXT: br i1 [[TMP12]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -6148,7 +6148,7 @@ int main() { // CHECK11: omp.inner.for.end: // CHECK11-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK11: omp.loop.exit: -// CHECK11-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP3]]) +// CHECK11-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) // CHECK11-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK11-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 // CHECK11-NEXT: br i1 [[TMP12]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -6416,7 +6416,7 @@ int main() { // CHECK11: omp.inner.for.end: // CHECK11-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK11: omp.loop.exit: -// CHECK11-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP3]]) +// CHECK11-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) // CHECK11-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK11-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 // CHECK11-NEXT: br i1 [[TMP12]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -6573,7 +6573,7 @@ int main() { // CHECK11: omp.inner.for.end: // CHECK11-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK11: omp.loop.exit: -// CHECK11-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP3]]) +// CHECK11-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) // CHECK11-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK11-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 // CHECK11-NEXT: br i1 [[TMP12]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -6852,7 +6852,7 @@ int main() { // CHECK11: omp.loop.exit: // CHECK11-NEXT: [[TMP21:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 // CHECK11-NEXT: [[TMP22:%.*]] = load i32, ptr [[TMP21]], align 4 -// CHECK11-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP22]]) +// CHECK11-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP22]]) // CHECK11-NEXT: [[TMP23:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK11-NEXT: [[TMP24:%.*]] = icmp ne i32 [[TMP23]], 0 // CHECK11-NEXT: br i1 [[TMP24]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -6979,7 +6979,7 @@ int main() { // CHECK11: omp.loop.exit: // CHECK11-NEXT: [[TMP21:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 // CHECK11-NEXT: [[TMP22:%.*]] = load i32, ptr [[TMP21]], align 4 -// CHECK11-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP22]]) +// CHECK11-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP22]]) // CHECK11-NEXT: [[TMP23:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK11-NEXT: [[TMP24:%.*]] = icmp ne i32 [[TMP23]], 0 // CHECK11-NEXT: br i1 [[TMP24]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -7236,7 +7236,7 @@ int main() { // CHECK11: omp.inner.for.end: // CHECK11-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK11: omp.loop.exit: -// CHECK11-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP3]]) +// CHECK11-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) // CHECK11-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK11-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 // CHECK11-NEXT: br i1 [[TMP12]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -7393,7 +7393,7 @@ int main() { // CHECK11: omp.inner.for.end: // CHECK11-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK11: omp.loop.exit: -// CHECK11-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP3]]) +// CHECK11-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) // CHECK11-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK11-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 // CHECK11-NEXT: br i1 [[TMP12]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -7569,7 +7569,7 @@ int main() { // CHECK11: omp.inner.for.end: // CHECK11-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK11: omp.loop.exit: -// CHECK11-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP3]]) +// CHECK11-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) // CHECK11-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK11-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 // CHECK11-NEXT: br i1 [[TMP12]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] diff --git a/clang/test/OpenMP/target_teams_distribute_parallel_for_simd_lastprivate_codegen.cpp b/clang/test/OpenMP/target_teams_distribute_parallel_for_simd_lastprivate_codegen.cpp index 903ecb865a2507becf67d743f7c2ae7b164180b7..3fdc0c482541084b9a5245d7692f8e4167b6f6e7 100644 --- a/clang/test/OpenMP/target_teams_distribute_parallel_for_simd_lastprivate_codegen.cpp +++ b/clang/test/OpenMP/target_teams_distribute_parallel_for_simd_lastprivate_codegen.cpp @@ -435,7 +435,7 @@ int main() { // CHECK1: omp.inner.for.end: // CHECK1-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK1: omp.loop.exit: -// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP4]]) +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP4]]) // CHECK1-NEXT: [[TMP18:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK1-NEXT: [[TMP19:%.*]] = icmp ne i32 [[TMP18]], 0 // CHECK1-NEXT: br i1 [[TMP19]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -713,7 +713,7 @@ int main() { // CHECK3: omp.inner.for.end: // CHECK3-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK3: omp.loop.exit: -// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP6]]) +// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP6]]) // CHECK3-NEXT: [[TMP20:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK3-NEXT: [[TMP21:%.*]] = icmp ne i32 [[TMP20]], 0 // CHECK3-NEXT: br i1 [[TMP21]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -1179,7 +1179,7 @@ int main() { // CHECK5: omp.loop.exit: // CHECK5-NEXT: [[TMP19:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 // CHECK5-NEXT: [[TMP20:%.*]] = load i32, ptr [[TMP19]], align 4 -// CHECK5-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP20]]) +// CHECK5-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP20]]) // CHECK5-NEXT: [[TMP21:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK5-NEXT: [[TMP22:%.*]] = icmp ne i32 [[TMP21]], 0 // CHECK5-NEXT: br i1 [[TMP22]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -1677,7 +1677,7 @@ int main() { // CHECK5: omp.loop.exit: // CHECK5-NEXT: [[TMP19:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 // CHECK5-NEXT: [[TMP20:%.*]] = load i32, ptr [[TMP19]], align 4 -// CHECK5-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP20]]) +// CHECK5-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP20]]) // CHECK5-NEXT: [[TMP21:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK5-NEXT: [[TMP22:%.*]] = icmp ne i32 [[TMP21]], 0 // CHECK5-NEXT: br i1 [[TMP22]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -2201,7 +2201,7 @@ int main() { // CHECK7: omp.loop.exit: // CHECK7-NEXT: [[TMP19:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 4 // CHECK7-NEXT: [[TMP20:%.*]] = load i32, ptr [[TMP19]], align 4 -// CHECK7-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP20]]) +// CHECK7-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP20]]) // CHECK7-NEXT: [[TMP21:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK7-NEXT: [[TMP22:%.*]] = icmp ne i32 [[TMP21]], 0 // CHECK7-NEXT: br i1 [[TMP22]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -2693,7 +2693,7 @@ int main() { // CHECK7: omp.loop.exit: // CHECK7-NEXT: [[TMP19:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 4 // CHECK7-NEXT: [[TMP20:%.*]] = load i32, ptr [[TMP19]], align 4 -// CHECK7-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP20]]) +// CHECK7-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP20]]) // CHECK7-NEXT: [[TMP21:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK7-NEXT: [[TMP22:%.*]] = icmp ne i32 [[TMP21]], 0 // CHECK7-NEXT: br i1 [[TMP22]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] diff --git a/clang/test/OpenMP/target_teams_distribute_parallel_for_simd_private_codegen.cpp b/clang/test/OpenMP/target_teams_distribute_parallel_for_simd_private_codegen.cpp index 7a211b4cd06b22931ecfc2a59896d7aac77177db..bba97a750adc6294190ae92cf4c83bb05b55a953 100644 --- a/clang/test/OpenMP/target_teams_distribute_parallel_for_simd_private_codegen.cpp +++ b/clang/test/OpenMP/target_teams_distribute_parallel_for_simd_private_codegen.cpp @@ -541,7 +541,7 @@ int main() { // CHECK1: omp.loop.exit: // CHECK1-NEXT: [[TMP16:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 // CHECK1-NEXT: [[TMP17:%.*]] = load i32, ptr [[TMP16]], align 4 -// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP17]]) +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP17]]) // CHECK1-NEXT: [[TMP18:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK1-NEXT: [[TMP19:%.*]] = icmp ne i32 [[TMP18]], 0 // CHECK1-NEXT: br i1 [[TMP19]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -863,7 +863,7 @@ int main() { // CHECK1: omp.loop.exit: // CHECK1-NEXT: [[TMP15:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 // CHECK1-NEXT: [[TMP16:%.*]] = load i32, ptr [[TMP15]], align 4 -// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP16]]) +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP16]]) // CHECK1-NEXT: [[TMP17:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK1-NEXT: [[TMP18:%.*]] = icmp ne i32 [[TMP17]], 0 // CHECK1-NEXT: br i1 [[TMP18]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -1296,7 +1296,7 @@ int main() { // CHECK3: omp.loop.exit: // CHECK3-NEXT: [[TMP16:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 4 // CHECK3-NEXT: [[TMP17:%.*]] = load i32, ptr [[TMP16]], align 4 -// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP17]]) +// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP17]]) // CHECK3-NEXT: [[TMP18:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK3-NEXT: [[TMP19:%.*]] = icmp ne i32 [[TMP18]], 0 // CHECK3-NEXT: br i1 [[TMP19]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -1612,7 +1612,7 @@ int main() { // CHECK3: omp.loop.exit: // CHECK3-NEXT: [[TMP15:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 4 // CHECK3-NEXT: [[TMP16:%.*]] = load i32, ptr [[TMP15]], align 4 -// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP16]]) +// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP16]]) // CHECK3-NEXT: [[TMP17:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK3-NEXT: [[TMP18:%.*]] = icmp ne i32 [[TMP17]], 0 // CHECK3-NEXT: br i1 [[TMP18]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -1980,7 +1980,7 @@ int main() { // CHECK5: omp.inner.for.end: // CHECK5-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK5: omp.loop.exit: -// CHECK5-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP3]]) +// CHECK5-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) // CHECK5-NEXT: [[TMP16:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK5-NEXT: [[TMP17:%.*]] = icmp ne i32 [[TMP16]], 0 // CHECK5-NEXT: br i1 [[TMP17]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -3100,7 +3100,7 @@ int main() { // CHECK13: omp.loop.exit: // CHECK13-NEXT: [[TMP16:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 // CHECK13-NEXT: [[TMP17:%.*]] = load i32, ptr [[TMP16]], align 4 -// CHECK13-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP17]]) +// CHECK13-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP17]]) // CHECK13-NEXT: [[TMP18:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK13-NEXT: [[TMP19:%.*]] = icmp ne i32 [[TMP18]], 0 // CHECK13-NEXT: br i1 [[TMP19]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -3351,7 +3351,7 @@ int main() { // CHECK13: omp.loop.exit: // CHECK13-NEXT: [[TMP15:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 // CHECK13-NEXT: [[TMP16:%.*]] = load i32, ptr [[TMP15]], align 4 -// CHECK13-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP16]]) +// CHECK13-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP16]]) // CHECK13-NEXT: [[TMP17:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK13-NEXT: [[TMP18:%.*]] = icmp ne i32 [[TMP17]], 0 // CHECK13-NEXT: br i1 [[TMP18]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -3636,7 +3636,7 @@ int main() { // CHECK15: omp.loop.exit: // CHECK15-NEXT: [[TMP16:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 4 // CHECK15-NEXT: [[TMP17:%.*]] = load i32, ptr [[TMP16]], align 4 -// CHECK15-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP17]]) +// CHECK15-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP17]]) // CHECK15-NEXT: [[TMP18:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK15-NEXT: [[TMP19:%.*]] = icmp ne i32 [[TMP18]], 0 // CHECK15-NEXT: br i1 [[TMP19]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -3881,7 +3881,7 @@ int main() { // CHECK15: omp.loop.exit: // CHECK15-NEXT: [[TMP15:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 4 // CHECK15-NEXT: [[TMP16:%.*]] = load i32, ptr [[TMP15]], align 4 -// CHECK15-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP16]]) +// CHECK15-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP16]]) // CHECK15-NEXT: [[TMP17:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK15-NEXT: [[TMP18:%.*]] = icmp ne i32 [[TMP17]], 0 // CHECK15-NEXT: br i1 [[TMP18]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -4125,7 +4125,7 @@ int main() { // CHECK17: omp.inner.for.end: // CHECK17-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK17: omp.loop.exit: -// CHECK17-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP3]]) +// CHECK17-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) // CHECK17-NEXT: [[TMP16:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK17-NEXT: [[TMP17:%.*]] = icmp ne i32 [[TMP16]], 0 // CHECK17-NEXT: br i1 [[TMP17]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] diff --git a/clang/test/OpenMP/target_teams_distribute_parallel_for_simd_proc_bind_codegen.cpp b/clang/test/OpenMP/target_teams_distribute_parallel_for_simd_proc_bind_codegen.cpp index 31941b48f92dff1f5452f2849ccb608d55f245c9..c347743bd4fdd7efb5c01593c2835fd0d0d4f4ab 100644 --- a/clang/test/OpenMP/target_teams_distribute_parallel_for_simd_proc_bind_codegen.cpp +++ b/clang/test/OpenMP/target_teams_distribute_parallel_for_simd_proc_bind_codegen.cpp @@ -268,7 +268,7 @@ int main() { // CHECK1: omp.inner.for.end: // CHECK1-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK1: omp.loop.exit: -// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP3]]) +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) // CHECK1-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK1-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 // CHECK1-NEXT: br i1 [[TMP12]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -420,7 +420,7 @@ int main() { // CHECK1: omp.inner.for.end: // CHECK1-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK1: omp.loop.exit: -// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP3]]) +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) // CHECK1-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK1-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 // CHECK1-NEXT: br i1 [[TMP12]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -613,7 +613,7 @@ int main() { // CHECK1: omp.inner.for.end: // CHECK1-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK1: omp.loop.exit: -// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP3]]) +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) // CHECK1-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK1-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 // CHECK1-NEXT: br i1 [[TMP12]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] diff --git a/clang/test/OpenMP/target_teams_distribute_parallel_for_simd_reduction_codegen.cpp b/clang/test/OpenMP/target_teams_distribute_parallel_for_simd_reduction_codegen.cpp index f255c3f084dbf9d38d7ae8a7b542d528434d36ae..52430d51cde1b5866a75a746d2fbe2a6d32cb863 100644 --- a/clang/test/OpenMP/target_teams_distribute_parallel_for_simd_reduction_codegen.cpp +++ b/clang/test/OpenMP/target_teams_distribute_parallel_for_simd_reduction_codegen.cpp @@ -323,7 +323,7 @@ int main() { // CHECK1: omp.inner.for.end: // CHECK1-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK1: omp.loop.exit: -// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP4]]) +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP4]]) // CHECK1-NEXT: [[TMP14:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK1-NEXT: [[TMP15:%.*]] = icmp ne i32 [[TMP14]], 0 // CHECK1-NEXT: br i1 [[TMP15]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -627,7 +627,7 @@ int main() { // CHECK1: omp.inner.for.end: // CHECK1-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK1: omp.loop.exit: -// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP4]]) +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP4]]) // CHECK1-NEXT: [[TMP14:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK1-NEXT: [[TMP15:%.*]] = icmp ne i32 [[TMP14]], 0 // CHECK1-NEXT: br i1 [[TMP15]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -926,7 +926,7 @@ int main() { // CHECK3: omp.inner.for.end: // CHECK3-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK3: omp.loop.exit: -// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP4]]) +// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP4]]) // CHECK3-NEXT: [[TMP14:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK3-NEXT: [[TMP15:%.*]] = icmp ne i32 [[TMP14]], 0 // CHECK3-NEXT: br i1 [[TMP15]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -1226,7 +1226,7 @@ int main() { // CHECK3: omp.inner.for.end: // CHECK3-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK3: omp.loop.exit: -// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP4]]) +// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP4]]) // CHECK3-NEXT: [[TMP14:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK3-NEXT: [[TMP15:%.*]] = icmp ne i32 [[TMP14]], 0 // CHECK3-NEXT: br i1 [[TMP15]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -1488,7 +1488,7 @@ int main() { // CHECK5: omp.inner.for.end: // CHECK5-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK5: omp.loop.exit: -// CHECK5-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP4]]) +// CHECK5-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP4]]) // CHECK5-NEXT: [[TMP15:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK5-NEXT: [[TMP16:%.*]] = icmp ne i32 [[TMP15]], 0 // CHECK5-NEXT: br i1 [[TMP16]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] diff --git a/clang/test/OpenMP/target_teams_distribute_parallel_for_simd_schedule_codegen.cpp b/clang/test/OpenMP/target_teams_distribute_parallel_for_simd_schedule_codegen.cpp index b41571eb415d989ef9155f7870601ad62ab5d2dd..f7c0666d58b66183ad6ecb1a52244609b8ebf49b 100644 --- a/clang/test/OpenMP/target_teams_distribute_parallel_for_simd_schedule_codegen.cpp +++ b/clang/test/OpenMP/target_teams_distribute_parallel_for_simd_schedule_codegen.cpp @@ -603,7 +603,7 @@ int main (int argc, char **argv) { // CHECK1: omp.inner.for.end: // CHECK1-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK1: omp.loop.exit: -// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP4]]) +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP4]]) // CHECK1-NEXT: [[TMP13:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK1-NEXT: [[TMP14:%.*]] = icmp ne i32 [[TMP13]], 0 // CHECK1-NEXT: br i1 [[TMP14]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -768,7 +768,7 @@ int main (int argc, char **argv) { // CHECK1: omp.inner.for.end: // CHECK1-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK1: omp.loop.exit: -// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP4]]) +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP4]]) // CHECK1-NEXT: [[TMP13:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK1-NEXT: [[TMP14:%.*]] = icmp ne i32 [[TMP13]], 0 // CHECK1-NEXT: br i1 [[TMP14]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -954,7 +954,7 @@ int main (int argc, char **argv) { // CHECK1-NEXT: store i32 [[ADD8]], ptr [[DOTOMP_UB]], align 4 // CHECK1-NEXT: br label [[OMP_DISPATCH_COND]] // CHECK1: omp.dispatch.end: -// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP4]]) +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP4]]) // CHECK1-NEXT: [[TMP21:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK1-NEXT: [[TMP22:%.*]] = icmp ne i32 [[TMP21]], 0 // CHECK1-NEXT: br i1 [[TMP22]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -1695,7 +1695,7 @@ int main (int argc, char **argv) { // CHECK3: omp.inner.for.end: // CHECK3-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK3: omp.loop.exit: -// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP4]]) +// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP4]]) // CHECK3-NEXT: [[TMP13:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK3-NEXT: [[TMP14:%.*]] = icmp ne i32 [[TMP13]], 0 // CHECK3-NEXT: br i1 [[TMP14]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -1855,7 +1855,7 @@ int main (int argc, char **argv) { // CHECK3: omp.inner.for.end: // CHECK3-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK3: omp.loop.exit: -// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP4]]) +// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP4]]) // CHECK3-NEXT: [[TMP13:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK3-NEXT: [[TMP14:%.*]] = icmp ne i32 [[TMP13]], 0 // CHECK3-NEXT: br i1 [[TMP14]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -2034,7 +2034,7 @@ int main (int argc, char **argv) { // CHECK3-NEXT: store i32 [[ADD5]], ptr [[DOTOMP_UB]], align 4 // CHECK3-NEXT: br label [[OMP_DISPATCH_COND]] // CHECK3: omp.dispatch.end: -// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP4]]) +// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP4]]) // CHECK3-NEXT: [[TMP21:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK3-NEXT: [[TMP22:%.*]] = icmp ne i32 [[TMP21]], 0 // CHECK3-NEXT: br i1 [[TMP22]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -2770,7 +2770,7 @@ int main (int argc, char **argv) { // CHECK5: omp.inner.for.end: // CHECK5-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK5: omp.loop.exit: -// CHECK5-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP4]]) +// CHECK5-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP4]]) // CHECK5-NEXT: [[TMP13:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK5-NEXT: [[TMP14:%.*]] = icmp ne i32 [[TMP13]], 0 // CHECK5-NEXT: br i1 [[TMP14]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -2935,7 +2935,7 @@ int main (int argc, char **argv) { // CHECK5: omp.inner.for.end: // CHECK5-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK5: omp.loop.exit: -// CHECK5-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP4]]) +// CHECK5-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP4]]) // CHECK5-NEXT: [[TMP13:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK5-NEXT: [[TMP14:%.*]] = icmp ne i32 [[TMP13]], 0 // CHECK5-NEXT: br i1 [[TMP14]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -3121,7 +3121,7 @@ int main (int argc, char **argv) { // CHECK5-NEXT: store i32 [[ADD8]], ptr [[DOTOMP_UB]], align 4 // CHECK5-NEXT: br label [[OMP_DISPATCH_COND]] // CHECK5: omp.dispatch.end: -// CHECK5-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP4]]) +// CHECK5-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP4]]) // CHECK5-NEXT: [[TMP21:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK5-NEXT: [[TMP22:%.*]] = icmp ne i32 [[TMP21]], 0 // CHECK5-NEXT: br i1 [[TMP22]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -3862,7 +3862,7 @@ int main (int argc, char **argv) { // CHECK7: omp.inner.for.end: // CHECK7-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK7: omp.loop.exit: -// CHECK7-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP4]]) +// CHECK7-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP4]]) // CHECK7-NEXT: [[TMP13:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK7-NEXT: [[TMP14:%.*]] = icmp ne i32 [[TMP13]], 0 // CHECK7-NEXT: br i1 [[TMP14]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -4022,7 +4022,7 @@ int main (int argc, char **argv) { // CHECK7: omp.inner.for.end: // CHECK7-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK7: omp.loop.exit: -// CHECK7-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP4]]) +// CHECK7-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP4]]) // CHECK7-NEXT: [[TMP13:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK7-NEXT: [[TMP14:%.*]] = icmp ne i32 [[TMP13]], 0 // CHECK7-NEXT: br i1 [[TMP14]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -4201,7 +4201,7 @@ int main (int argc, char **argv) { // CHECK7-NEXT: store i32 [[ADD5]], ptr [[DOTOMP_UB]], align 4 // CHECK7-NEXT: br label [[OMP_DISPATCH_COND]] // CHECK7: omp.dispatch.end: -// CHECK7-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP4]]) +// CHECK7-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP4]]) // CHECK7-NEXT: [[TMP21:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK7-NEXT: [[TMP22:%.*]] = icmp ne i32 [[TMP21]], 0 // CHECK7-NEXT: br i1 [[TMP22]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -5592,7 +5592,7 @@ int main (int argc, char **argv) { // CHECK13: omp.loop.exit: // CHECK13-NEXT: [[TMP20:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 // CHECK13-NEXT: [[TMP21:%.*]] = load i32, ptr [[TMP20]], align 4 -// CHECK13-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP21]]) +// CHECK13-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP21]]) // CHECK13-NEXT: [[TMP22:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK13-NEXT: [[TMP23:%.*]] = icmp ne i32 [[TMP22]], 0 // CHECK13-NEXT: br i1 [[TMP23]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -5833,7 +5833,7 @@ int main (int argc, char **argv) { // CHECK13: omp.loop.exit: // CHECK13-NEXT: [[TMP20:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 // CHECK13-NEXT: [[TMP21:%.*]] = load i32, ptr [[TMP20]], align 4 -// CHECK13-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP21]]) +// CHECK13-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP21]]) // CHECK13-NEXT: [[TMP22:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK13-NEXT: [[TMP23:%.*]] = icmp ne i32 [[TMP22]], 0 // CHECK13-NEXT: br i1 [[TMP23]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -6113,7 +6113,7 @@ int main (int argc, char **argv) { // CHECK13: omp.loop.exit: // CHECK13-NEXT: [[TMP20:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 // CHECK13-NEXT: [[TMP21:%.*]] = load i32, ptr [[TMP20]], align 4 -// CHECK13-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP21]]) +// CHECK13-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP21]]) // CHECK13-NEXT: [[TMP22:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK13-NEXT: [[TMP23:%.*]] = icmp ne i32 [[TMP22]], 0 // CHECK13-NEXT: br i1 [[TMP23]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -7040,7 +7040,7 @@ int main (int argc, char **argv) { // CHECK13: omp.inner.for.end: // CHECK13-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK13: omp.loop.exit: -// CHECK13-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP4]]) +// CHECK13-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP4]]) // CHECK13-NEXT: [[TMP13:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK13-NEXT: [[TMP14:%.*]] = icmp ne i32 [[TMP13]], 0 // CHECK13-NEXT: br i1 [[TMP14]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -7204,7 +7204,7 @@ int main (int argc, char **argv) { // CHECK13: omp.inner.for.end: // CHECK13-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK13: omp.loop.exit: -// CHECK13-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP4]]) +// CHECK13-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP4]]) // CHECK13-NEXT: [[TMP13:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK13-NEXT: [[TMP14:%.*]] = icmp ne i32 [[TMP13]], 0 // CHECK13-NEXT: br i1 [[TMP14]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -7404,7 +7404,7 @@ int main (int argc, char **argv) { // CHECK13-NEXT: store i32 [[ADD8]], ptr [[DOTOMP_UB]], align 4 // CHECK13-NEXT: br label [[OMP_DISPATCH_COND]] // CHECK13: omp.dispatch.end: -// CHECK13-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP5]]) +// CHECK13-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP5]]) // CHECK13-NEXT: [[TMP22:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK13-NEXT: [[TMP23:%.*]] = icmp ne i32 [[TMP22]], 0 // CHECK13-NEXT: br i1 [[TMP23]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -8432,7 +8432,7 @@ int main (int argc, char **argv) { // CHECK15: omp.loop.exit: // CHECK15-NEXT: [[TMP20:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 4 // CHECK15-NEXT: [[TMP21:%.*]] = load i32, ptr [[TMP20]], align 4 -// CHECK15-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP21]]) +// CHECK15-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP21]]) // CHECK15-NEXT: [[TMP22:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK15-NEXT: [[TMP23:%.*]] = icmp ne i32 [[TMP22]], 0 // CHECK15-NEXT: br i1 [[TMP23]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -8668,7 +8668,7 @@ int main (int argc, char **argv) { // CHECK15: omp.loop.exit: // CHECK15-NEXT: [[TMP20:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 4 // CHECK15-NEXT: [[TMP21:%.*]] = load i32, ptr [[TMP20]], align 4 -// CHECK15-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP21]]) +// CHECK15-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP21]]) // CHECK15-NEXT: [[TMP22:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK15-NEXT: [[TMP23:%.*]] = icmp ne i32 [[TMP22]], 0 // CHECK15-NEXT: br i1 [[TMP23]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -8943,7 +8943,7 @@ int main (int argc, char **argv) { // CHECK15: omp.loop.exit: // CHECK15-NEXT: [[TMP20:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 4 // CHECK15-NEXT: [[TMP21:%.*]] = load i32, ptr [[TMP20]], align 4 -// CHECK15-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP21]]) +// CHECK15-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP21]]) // CHECK15-NEXT: [[TMP22:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK15-NEXT: [[TMP23:%.*]] = icmp ne i32 [[TMP22]], 0 // CHECK15-NEXT: br i1 [[TMP23]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -9855,7 +9855,7 @@ int main (int argc, char **argv) { // CHECK15: omp.inner.for.end: // CHECK15-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK15: omp.loop.exit: -// CHECK15-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP4]]) +// CHECK15-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP4]]) // CHECK15-NEXT: [[TMP13:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK15-NEXT: [[TMP14:%.*]] = icmp ne i32 [[TMP13]], 0 // CHECK15-NEXT: br i1 [[TMP14]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -10014,7 +10014,7 @@ int main (int argc, char **argv) { // CHECK15: omp.inner.for.end: // CHECK15-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK15: omp.loop.exit: -// CHECK15-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP4]]) +// CHECK15-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP4]]) // CHECK15-NEXT: [[TMP13:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK15-NEXT: [[TMP14:%.*]] = icmp ne i32 [[TMP13]], 0 // CHECK15-NEXT: br i1 [[TMP14]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -10207,7 +10207,7 @@ int main (int argc, char **argv) { // CHECK15-NEXT: store i32 [[ADD5]], ptr [[DOTOMP_UB]], align 4 // CHECK15-NEXT: br label [[OMP_DISPATCH_COND]] // CHECK15: omp.dispatch.end: -// CHECK15-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP5]]) +// CHECK15-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP5]]) // CHECK15-NEXT: [[TMP22:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK15-NEXT: [[TMP23:%.*]] = icmp ne i32 [[TMP22]], 0 // CHECK15-NEXT: br i1 [[TMP23]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -11226,7 +11226,7 @@ int main (int argc, char **argv) { // CHECK17: omp.loop.exit: // CHECK17-NEXT: [[TMP20:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 // CHECK17-NEXT: [[TMP21:%.*]] = load i32, ptr [[TMP20]], align 4 -// CHECK17-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP21]]) +// CHECK17-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP21]]) // CHECK17-NEXT: [[TMP22:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK17-NEXT: [[TMP23:%.*]] = icmp ne i32 [[TMP22]], 0 // CHECK17-NEXT: br i1 [[TMP23]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -11467,7 +11467,7 @@ int main (int argc, char **argv) { // CHECK17: omp.loop.exit: // CHECK17-NEXT: [[TMP20:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 // CHECK17-NEXT: [[TMP21:%.*]] = load i32, ptr [[TMP20]], align 4 -// CHECK17-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP21]]) +// CHECK17-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP21]]) // CHECK17-NEXT: [[TMP22:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK17-NEXT: [[TMP23:%.*]] = icmp ne i32 [[TMP22]], 0 // CHECK17-NEXT: br i1 [[TMP23]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -11747,7 +11747,7 @@ int main (int argc, char **argv) { // CHECK17: omp.loop.exit: // CHECK17-NEXT: [[TMP20:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 // CHECK17-NEXT: [[TMP21:%.*]] = load i32, ptr [[TMP20]], align 4 -// CHECK17-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP21]]) +// CHECK17-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP21]]) // CHECK17-NEXT: [[TMP22:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK17-NEXT: [[TMP23:%.*]] = icmp ne i32 [[TMP22]], 0 // CHECK17-NEXT: br i1 [[TMP23]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -12674,7 +12674,7 @@ int main (int argc, char **argv) { // CHECK17: omp.inner.for.end: // CHECK17-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK17: omp.loop.exit: -// CHECK17-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP4]]) +// CHECK17-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP4]]) // CHECK17-NEXT: [[TMP13:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK17-NEXT: [[TMP14:%.*]] = icmp ne i32 [[TMP13]], 0 // CHECK17-NEXT: br i1 [[TMP14]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -12838,7 +12838,7 @@ int main (int argc, char **argv) { // CHECK17: omp.inner.for.end: // CHECK17-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK17: omp.loop.exit: -// CHECK17-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP4]]) +// CHECK17-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP4]]) // CHECK17-NEXT: [[TMP13:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK17-NEXT: [[TMP14:%.*]] = icmp ne i32 [[TMP13]], 0 // CHECK17-NEXT: br i1 [[TMP14]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -13038,7 +13038,7 @@ int main (int argc, char **argv) { // CHECK17-NEXT: store i32 [[ADD8]], ptr [[DOTOMP_UB]], align 4 // CHECK17-NEXT: br label [[OMP_DISPATCH_COND]] // CHECK17: omp.dispatch.end: -// CHECK17-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP5]]) +// CHECK17-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP5]]) // CHECK17-NEXT: [[TMP22:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK17-NEXT: [[TMP23:%.*]] = icmp ne i32 [[TMP22]], 0 // CHECK17-NEXT: br i1 [[TMP23]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -14066,7 +14066,7 @@ int main (int argc, char **argv) { // CHECK19: omp.loop.exit: // CHECK19-NEXT: [[TMP20:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 4 // CHECK19-NEXT: [[TMP21:%.*]] = load i32, ptr [[TMP20]], align 4 -// CHECK19-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP21]]) +// CHECK19-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP21]]) // CHECK19-NEXT: [[TMP22:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK19-NEXT: [[TMP23:%.*]] = icmp ne i32 [[TMP22]], 0 // CHECK19-NEXT: br i1 [[TMP23]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -14302,7 +14302,7 @@ int main (int argc, char **argv) { // CHECK19: omp.loop.exit: // CHECK19-NEXT: [[TMP20:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 4 // CHECK19-NEXT: [[TMP21:%.*]] = load i32, ptr [[TMP20]], align 4 -// CHECK19-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP21]]) +// CHECK19-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP21]]) // CHECK19-NEXT: [[TMP22:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK19-NEXT: [[TMP23:%.*]] = icmp ne i32 [[TMP22]], 0 // CHECK19-NEXT: br i1 [[TMP23]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -14577,7 +14577,7 @@ int main (int argc, char **argv) { // CHECK19: omp.loop.exit: // CHECK19-NEXT: [[TMP20:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 4 // CHECK19-NEXT: [[TMP21:%.*]] = load i32, ptr [[TMP20]], align 4 -// CHECK19-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP21]]) +// CHECK19-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP21]]) // CHECK19-NEXT: [[TMP22:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK19-NEXT: [[TMP23:%.*]] = icmp ne i32 [[TMP22]], 0 // CHECK19-NEXT: br i1 [[TMP23]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -15489,7 +15489,7 @@ int main (int argc, char **argv) { // CHECK19: omp.inner.for.end: // CHECK19-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK19: omp.loop.exit: -// CHECK19-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP4]]) +// CHECK19-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP4]]) // CHECK19-NEXT: [[TMP13:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK19-NEXT: [[TMP14:%.*]] = icmp ne i32 [[TMP13]], 0 // CHECK19-NEXT: br i1 [[TMP14]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -15648,7 +15648,7 @@ int main (int argc, char **argv) { // CHECK19: omp.inner.for.end: // CHECK19-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK19: omp.loop.exit: -// CHECK19-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP4]]) +// CHECK19-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP4]]) // CHECK19-NEXT: [[TMP13:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK19-NEXT: [[TMP14:%.*]] = icmp ne i32 [[TMP13]], 0 // CHECK19-NEXT: br i1 [[TMP14]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -15841,7 +15841,7 @@ int main (int argc, char **argv) { // CHECK19-NEXT: store i32 [[ADD5]], ptr [[DOTOMP_UB]], align 4 // CHECK19-NEXT: br label [[OMP_DISPATCH_COND]] // CHECK19: omp.dispatch.end: -// CHECK19-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP5]]) +// CHECK19-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP5]]) // CHECK19-NEXT: [[TMP22:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK19-NEXT: [[TMP23:%.*]] = icmp ne i32 [[TMP22]], 0 // CHECK19-NEXT: br i1 [[TMP23]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] diff --git a/clang/test/OpenMP/target_teams_generic_loop_codegen-1.cpp b/clang/test/OpenMP/target_teams_generic_loop_codegen-1.cpp index 26c9e4713f3e63d5eb1d55c6567d414dee23e7f4..190ea17e96070455c1955b4414679be029870d00 100644 --- a/clang/test/OpenMP/target_teams_generic_loop_codegen-1.cpp +++ b/clang/test/OpenMP/target_teams_generic_loop_codegen-1.cpp @@ -223,7 +223,7 @@ int target_teams_fun(int *g){ // CHECK1: omp.loop.exit: // CHECK1-NEXT: [[TMP22:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 // CHECK1-NEXT: [[TMP23:%.*]] = load i32, ptr [[TMP22]], align 4 -// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2:[0-9]+]], i32 [[TMP23]]) +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP23]]) // CHECK1-NEXT: br label [[OMP_PRECOND_END]] // CHECK1: omp.precond.end: // CHECK1-NEXT: ret void @@ -280,7 +280,7 @@ int target_teams_fun(int *g){ // CHECK1-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK1-NEXT: [[TMP7:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 // CHECK1-NEXT: [[TMP8:%.*]] = load i32, ptr [[TMP7]], align 4 -// CHECK1-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB2]], i32 [[TMP8]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK1-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB2:[0-9]+]], i32 [[TMP8]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) // CHECK1-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 // CHECK1-NEXT: [[TMP10:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_1]], align 4 // CHECK1-NEXT: [[CMP5:%.*]] = icmp sgt i32 [[TMP9]], [[TMP10]] @@ -437,7 +437,7 @@ int target_teams_fun(int *g){ // CHECK1: omp.loop.exit: // CHECK1-NEXT: [[TMP23:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 // CHECK1-NEXT: [[TMP24:%.*]] = load i32, ptr [[TMP23]], align 4 -// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP24]]) +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP24]]) // CHECK1-NEXT: br label [[OMP_PRECOND_END]] // CHECK1: omp.precond.end: // CHECK1-NEXT: ret void @@ -848,7 +848,7 @@ int target_teams_fun(int *g){ // CHECK2: omp.loop.exit: // CHECK2-NEXT: [[TMP22:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 // CHECK2-NEXT: [[TMP23:%.*]] = load i32, ptr [[TMP22]], align 4 -// CHECK2-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2:[0-9]+]], i32 [[TMP23]]) +// CHECK2-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP23]]) // CHECK2-NEXT: br label [[OMP_PRECOND_END]] // CHECK2: omp.precond.end: // CHECK2-NEXT: ret void @@ -905,7 +905,7 @@ int target_teams_fun(int *g){ // CHECK2-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK2-NEXT: [[TMP7:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 // CHECK2-NEXT: [[TMP8:%.*]] = load i32, ptr [[TMP7]], align 4 -// CHECK2-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB2]], i32 [[TMP8]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK2-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB2:[0-9]+]], i32 [[TMP8]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) // CHECK2-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 // CHECK2-NEXT: [[TMP10:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_1]], align 4 // CHECK2-NEXT: [[CMP5:%.*]] = icmp sgt i32 [[TMP9]], [[TMP10]] @@ -1062,7 +1062,7 @@ int target_teams_fun(int *g){ // CHECK2: omp.loop.exit: // CHECK2-NEXT: [[TMP23:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 // CHECK2-NEXT: [[TMP24:%.*]] = load i32, ptr [[TMP23]], align 4 -// CHECK2-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP24]]) +// CHECK2-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP24]]) // CHECK2-NEXT: br label [[OMP_PRECOND_END]] // CHECK2: omp.precond.end: // CHECK2-NEXT: ret void @@ -1471,7 +1471,7 @@ int target_teams_fun(int *g){ // CHECK4: omp.loop.exit: // CHECK4-NEXT: [[TMP20:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 4 // CHECK4-NEXT: [[TMP21:%.*]] = load i32, ptr [[TMP20]], align 4 -// CHECK4-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2:[0-9]+]], i32 [[TMP21]]) +// CHECK4-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP21]]) // CHECK4-NEXT: br label [[OMP_PRECOND_END]] // CHECK4: omp.precond.end: // CHECK4-NEXT: ret void @@ -1526,7 +1526,7 @@ int target_teams_fun(int *g){ // CHECK4-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK4-NEXT: [[TMP7:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 4 // CHECK4-NEXT: [[TMP8:%.*]] = load i32, ptr [[TMP7]], align 4 -// CHECK4-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB2]], i32 [[TMP8]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK4-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB2:[0-9]+]], i32 [[TMP8]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) // CHECK4-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 // CHECK4-NEXT: [[TMP10:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_1]], align 4 // CHECK4-NEXT: [[CMP4:%.*]] = icmp sgt i32 [[TMP9]], [[TMP10]] @@ -1680,7 +1680,7 @@ int target_teams_fun(int *g){ // CHECK4: omp.loop.exit: // CHECK4-NEXT: [[TMP21:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 4 // CHECK4-NEXT: [[TMP22:%.*]] = load i32, ptr [[TMP21]], align 4 -// CHECK4-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP22]]) +// CHECK4-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP22]]) // CHECK4-NEXT: br label [[OMP_PRECOND_END]] // CHECK4: omp.precond.end: // CHECK4-NEXT: ret void @@ -1900,7 +1900,7 @@ int target_teams_fun(int *g){ // CHECK10: omp.loop.exit: // CHECK10-NEXT: [[TMP22:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 // CHECK10-NEXT: [[TMP23:%.*]] = load i32, ptr [[TMP22]], align 4 -// CHECK10-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2:[0-9]+]], i32 [[TMP23]]) +// CHECK10-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP23]]) // CHECK10-NEXT: br label [[OMP_PRECOND_END]] // CHECK10: omp.precond.end: // CHECK10-NEXT: ret void @@ -1957,7 +1957,7 @@ int target_teams_fun(int *g){ // CHECK10-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK10-NEXT: [[TMP7:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 // CHECK10-NEXT: [[TMP8:%.*]] = load i32, ptr [[TMP7]], align 4 -// CHECK10-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB2]], i32 [[TMP8]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK10-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB2:[0-9]+]], i32 [[TMP8]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) // CHECK10-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 // CHECK10-NEXT: [[TMP10:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_1]], align 4 // CHECK10-NEXT: [[CMP5:%.*]] = icmp sgt i32 [[TMP9]], [[TMP10]] @@ -2116,7 +2116,7 @@ int target_teams_fun(int *g){ // CHECK10: omp.loop.exit: // CHECK10-NEXT: [[TMP23:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 // CHECK10-NEXT: [[TMP24:%.*]] = load i32, ptr [[TMP23]], align 4 -// CHECK10-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP24]]) +// CHECK10-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP24]]) // CHECK10-NEXT: br label [[OMP_PRECOND_END]] // CHECK10: omp.precond.end: // CHECK10-NEXT: ret void @@ -2337,7 +2337,7 @@ int target_teams_fun(int *g){ // CHECK12: omp.loop.exit: // CHECK12-NEXT: [[TMP20:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 4 // CHECK12-NEXT: [[TMP21:%.*]] = load i32, ptr [[TMP20]], align 4 -// CHECK12-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2:[0-9]+]], i32 [[TMP21]]) +// CHECK12-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP21]]) // CHECK12-NEXT: br label [[OMP_PRECOND_END]] // CHECK12: omp.precond.end: // CHECK12-NEXT: ret void @@ -2392,7 +2392,7 @@ int target_teams_fun(int *g){ // CHECK12-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK12-NEXT: [[TMP7:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 4 // CHECK12-NEXT: [[TMP8:%.*]] = load i32, ptr [[TMP7]], align 4 -// CHECK12-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB2]], i32 [[TMP8]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK12-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB2:[0-9]+]], i32 [[TMP8]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) // CHECK12-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 // CHECK12-NEXT: [[TMP10:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_1]], align 4 // CHECK12-NEXT: [[CMP4:%.*]] = icmp sgt i32 [[TMP9]], [[TMP10]] @@ -2548,7 +2548,7 @@ int target_teams_fun(int *g){ // CHECK12: omp.loop.exit: // CHECK12-NEXT: [[TMP21:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 4 // CHECK12-NEXT: [[TMP22:%.*]] = load i32, ptr [[TMP21]], align 4 -// CHECK12-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP22]]) +// CHECK12-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP22]]) // CHECK12-NEXT: br label [[OMP_PRECOND_END]] // CHECK12: omp.precond.end: // CHECK12-NEXT: ret void diff --git a/clang/test/OpenMP/target_teams_generic_loop_codegen.cpp b/clang/test/OpenMP/target_teams_generic_loop_codegen.cpp index 3b1af7618794db6d4451be873bd68f5db3c5336d..22cf534bf0ba27933ce268956a5602f278505cfb 100644 --- a/clang/test/OpenMP/target_teams_generic_loop_codegen.cpp +++ b/clang/test/OpenMP/target_teams_generic_loop_codegen.cpp @@ -1312,7 +1312,7 @@ int foo() { // IR-GPU: omp.loop.exit: // IR-GPU-NEXT: [[TMP32:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR_ASCAST]], align 8 // IR-GPU-NEXT: [[TMP33:%.*]] = load i32, ptr [[TMP32]], align 4 -// IR-GPU-NEXT: call void @__kmpc_for_static_fini(ptr addrspacecast (ptr addrspace(1) @[[GLOB3:[0-9]+]] to ptr), i32 [[TMP33]]) +// IR-GPU-NEXT: call void @__kmpc_distribute_static_fini(ptr addrspacecast (ptr addrspace(1) @[[GLOB2]] to ptr), i32 [[TMP33]]) // IR-GPU-NEXT: [[TMP34:%.*]] = load i32, ptr [[DOTOMP_IS_LAST_ASCAST]], align 4 // IR-GPU-NEXT: [[TMP35:%.*]] = icmp ne i32 [[TMP34]], 0 // IR-GPU-NEXT: br i1 [[TMP35]], label [[DOTOMP_LASTPRIVATE_THEN:%.*]], label [[DOTOMP_LASTPRIVATE_DONE:%.*]] @@ -1418,7 +1418,7 @@ int foo() { // IR-GPU: omp.arrayinit.done: // IR-GPU-NEXT: [[TMP4:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR_ASCAST]], align 8 // IR-GPU-NEXT: [[TMP5:%.*]] = load i32, ptr [[TMP4]], align 4 -// IR-GPU-NEXT: call void @__kmpc_for_static_init_4(ptr addrspacecast (ptr addrspace(1) @[[GLOB3]] to ptr), i32 [[TMP5]], i32 33, ptr [[DOTOMP_IS_LAST_ASCAST]], ptr [[DOTOMP_LB_ASCAST]], ptr [[DOTOMP_UB_ASCAST]], ptr [[DOTOMP_STRIDE_ASCAST]], i32 1, i32 1) +// IR-GPU-NEXT: call void @__kmpc_for_static_init_4(ptr addrspacecast (ptr addrspace(1) @[[GLOB3:[0-9]+]] to ptr), i32 [[TMP5]], i32 33, ptr [[DOTOMP_IS_LAST_ASCAST]], ptr [[DOTOMP_LB_ASCAST]], ptr [[DOTOMP_UB_ASCAST]], ptr [[DOTOMP_STRIDE_ASCAST]], i32 1, i32 1) // IR-GPU-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_LB_ASCAST]], align 4 // IR-GPU-NEXT: store i32 [[TMP6]], ptr [[DOTOMP_IV_ASCAST]], align 4 // IR-GPU-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] @@ -2001,7 +2001,7 @@ int foo() { // IR: omp.loop.exit: // IR-NEXT: [[TMP17:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 // IR-NEXT: [[TMP18:%.*]] = load i32, ptr [[TMP17]], align 4 -// IR-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2:[0-9]+]], i32 [[TMP18]]) +// IR-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP18]]) // IR-NEXT: [[TMP19:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // IR-NEXT: [[TMP20:%.*]] = icmp ne i32 [[TMP19]], 0 // IR-NEXT: br i1 [[TMP20]], label [[DOTOMP_LASTPRIVATE_THEN:%.*]], label [[DOTOMP_LASTPRIVATE_DONE:%.*]] @@ -2109,7 +2109,7 @@ int foo() { // IR: omp.arrayinit.done: // IR-NEXT: [[TMP4:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 // IR-NEXT: [[TMP5:%.*]] = load i32, ptr [[TMP4]], align 4 -// IR-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB2]], i32 [[TMP5]], 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_4(ptr @[[GLOB2:[0-9]+]], i32 [[TMP5]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) // IR-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 // IR-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP6]], 99 // IR-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] @@ -2398,7 +2398,7 @@ int foo() { // IR-PCH: omp.loop.exit: // IR-PCH-NEXT: [[TMP17:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 // IR-PCH-NEXT: [[TMP18:%.*]] = load i32, ptr [[TMP17]], align 4 -// IR-PCH-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2:[0-9]+]], i32 [[TMP18]]) +// IR-PCH-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP18]]) // IR-PCH-NEXT: [[TMP19:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // IR-PCH-NEXT: [[TMP20:%.*]] = icmp ne i32 [[TMP19]], 0 // IR-PCH-NEXT: br i1 [[TMP20]], label [[DOTOMP_LASTPRIVATE_THEN:%.*]], label [[DOTOMP_LASTPRIVATE_DONE:%.*]] @@ -2506,7 +2506,7 @@ int foo() { // IR-PCH: omp.arrayinit.done: // IR-PCH-NEXT: [[TMP4:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 // IR-PCH-NEXT: [[TMP5:%.*]] = load i32, ptr [[TMP4]], align 4 -// IR-PCH-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB2]], i32 [[TMP5]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// IR-PCH-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB2:[0-9]+]], i32 [[TMP5]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) // IR-PCH-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 // IR-PCH-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP6]], 99 // IR-PCH-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] diff --git a/clang/test/OpenMP/target_teams_generic_loop_collapse_codegen.cpp b/clang/test/OpenMP/target_teams_generic_loop_collapse_codegen.cpp index 6a30ef7f6eb8fa8061cbf87281e60ba343932912..82ad43373327af7f7e7cedc394c55d7e1430e2bf 100644 --- a/clang/test/OpenMP/target_teams_generic_loop_collapse_codegen.cpp +++ b/clang/test/OpenMP/target_teams_generic_loop_collapse_codegen.cpp @@ -239,7 +239,7 @@ int main (int argc, char **argv) { // CHECK1: omp.inner.for.end: // CHECK1-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK1: omp.loop.exit: -// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2:[0-9]+]], i32 [[TMP2]]) +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP2]]) // CHECK1-NEXT: ret void // // @@ -278,7 +278,7 @@ int main (int argc, char **argv) { // CHECK1-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK1-NEXT: [[TMP3:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 // CHECK1-NEXT: [[TMP4:%.*]] = load i32, ptr [[TMP3]], align 4 -// CHECK1-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB2]], i32 [[TMP4]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK1-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB2:[0-9]+]], i32 [[TMP4]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) // CHECK1-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 // CHECK1-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP5]], 56087 // CHECK1-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] @@ -473,7 +473,7 @@ int main (int argc, char **argv) { // CHECK3: omp.inner.for.end: // CHECK3-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK3: omp.loop.exit: -// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2:[0-9]+]], i32 [[TMP2]]) +// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP2]]) // CHECK3-NEXT: ret void // // @@ -510,7 +510,7 @@ int main (int argc, char **argv) { // CHECK3-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK3-NEXT: [[TMP3:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 4 // CHECK3-NEXT: [[TMP4:%.*]] = load i32, ptr [[TMP3]], align 4 -// CHECK3-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB2]], i32 [[TMP4]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK3-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB2:[0-9]+]], i32 [[TMP4]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) // CHECK3-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 // CHECK3-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP5]], 56087 // CHECK3-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] @@ -846,7 +846,7 @@ int main (int argc, char **argv) { // CHECK9: omp.loop.exit: // CHECK9-NEXT: [[TMP27:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 // CHECK9-NEXT: [[TMP28:%.*]] = load i32, ptr [[TMP27]], align 4 -// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2:[0-9]+]], i32 [[TMP28]]) +// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP28]]) // CHECK9-NEXT: br label [[OMP_PRECOND_END]] // CHECK9: omp.precond.end: // CHECK9-NEXT: ret void @@ -926,7 +926,7 @@ int main (int argc, char **argv) { // CHECK9-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK9-NEXT: [[TMP12:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 // CHECK9-NEXT: [[TMP13:%.*]] = load i32, ptr [[TMP12]], align 4 -// CHECK9-NEXT: call void @__kmpc_for_static_init_8(ptr @[[GLOB2]], i32 [[TMP13]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i64 1, i64 1) +// CHECK9-NEXT: call void @__kmpc_for_static_init_8(ptr @[[GLOB2:[0-9]+]], i32 [[TMP13]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i64 1, i64 1) // CHECK9-NEXT: [[TMP14:%.*]] = load i64, ptr [[DOTOMP_UB]], align 8 // CHECK9-NEXT: [[TMP15:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR_5]], align 8 // CHECK9-NEXT: [[CMP13:%.*]] = icmp sgt i64 [[TMP14]], [[TMP15]] @@ -1133,7 +1133,7 @@ int main (int argc, char **argv) { // CHECK9: omp.inner.for.end: // CHECK9-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK9: omp.loop.exit: -// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP2]]) +// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP2]]) // CHECK9-NEXT: ret void // // @@ -1510,7 +1510,7 @@ int main (int argc, char **argv) { // CHECK11: omp.loop.exit: // CHECK11-NEXT: [[TMP29:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 4 // CHECK11-NEXT: [[TMP30:%.*]] = load i32, ptr [[TMP29]], align 4 -// CHECK11-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2:[0-9]+]], i32 [[TMP30]]) +// CHECK11-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP30]]) // CHECK11-NEXT: br label [[OMP_PRECOND_END]] // CHECK11: omp.precond.end: // CHECK11-NEXT: ret void @@ -1592,7 +1592,7 @@ int main (int argc, char **argv) { // CHECK11-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK11-NEXT: [[TMP12:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 4 // CHECK11-NEXT: [[TMP13:%.*]] = load i32, ptr [[TMP12]], align 4 -// CHECK11-NEXT: call void @__kmpc_for_static_init_8(ptr @[[GLOB2]], i32 [[TMP13]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i64 1, i64 1) +// CHECK11-NEXT: call void @__kmpc_for_static_init_8(ptr @[[GLOB2:[0-9]+]], i32 [[TMP13]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i64 1, i64 1) // CHECK11-NEXT: [[TMP14:%.*]] = load i64, ptr [[DOTOMP_UB]], align 8 // CHECK11-NEXT: [[TMP15:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR_5]], align 8 // CHECK11-NEXT: [[CMP15:%.*]] = icmp sgt i64 [[TMP14]], [[TMP15]] @@ -1795,7 +1795,7 @@ int main (int argc, char **argv) { // CHECK11: omp.inner.for.end: // CHECK11-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK11: omp.loop.exit: -// CHECK11-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP2]]) +// CHECK11-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP2]]) // CHECK11-NEXT: ret void // // diff --git a/clang/test/OpenMP/target_teams_generic_loop_if_codegen.cpp b/clang/test/OpenMP/target_teams_generic_loop_if_codegen.cpp index c19323c35b4e182da024e0ef05882260cccaf4f3..b2ff4c20db7a12ad70cdb887ae4c76396f0fbf50 100644 --- a/clang/test/OpenMP/target_teams_generic_loop_if_codegen.cpp +++ b/clang/test/OpenMP/target_teams_generic_loop_if_codegen.cpp @@ -210,7 +210,7 @@ int main() { // CHECK1: omp.inner.for.end: // CHECK1-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK1: omp.loop.exit: -// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2:[0-9]+]], i32 [[TMP1]]) +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP1]]) // CHECK1-NEXT: ret void // // @@ -244,7 +244,7 @@ int main() { // CHECK1-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK1-NEXT: [[TMP2:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 // CHECK1-NEXT: [[TMP3:%.*]] = load i32, ptr [[TMP2]], align 4 -// CHECK1-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB2]], i32 [[TMP3]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK1-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB2:[0-9]+]], i32 [[TMP3]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) // CHECK1-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 // CHECK1-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP4]], 99 // CHECK1-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] @@ -347,7 +347,7 @@ int main() { // CHECK1: omp.inner.for.end: // CHECK1-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK1: omp.loop.exit: -// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP1]]) +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP1]]) // CHECK1-NEXT: ret void // // @@ -601,7 +601,7 @@ int main() { // CHECK1: omp.inner.for.end: // CHECK1-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK1: omp.loop.exit: -// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP1]]) +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP1]]) // CHECK1-NEXT: ret void // // @@ -744,7 +744,7 @@ int main() { // CHECK1: omp.inner.for.end: // CHECK1-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK1: omp.loop.exit: -// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP1]]) +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP1]]) // CHECK1-NEXT: ret void // // @@ -906,7 +906,7 @@ int main() { // CHECK1: omp.inner.for.end: // CHECK1-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK1: omp.loop.exit: -// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP1]]) +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP1]]) // CHECK1-NEXT: ret void // // @@ -1132,7 +1132,7 @@ int main() { // CHECK1: omp.inner.for.end: // CHECK1-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK1: omp.loop.exit: -// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP1]]) +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP1]]) // CHECK1-NEXT: ret void // // @@ -1275,7 +1275,7 @@ int main() { // CHECK1: omp.inner.for.end: // CHECK1-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK1: omp.loop.exit: -// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP1]]) +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP1]]) // CHECK1-NEXT: ret void // // @@ -1413,7 +1413,7 @@ int main() { // CHECK1: omp.inner.for.end: // CHECK1-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK1: omp.loop.exit: -// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP1]]) +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP1]]) // CHECK1-NEXT: ret void // // diff --git a/clang/test/OpenMP/target_teams_generic_loop_order_codegen.cpp b/clang/test/OpenMP/target_teams_generic_loop_order_codegen.cpp index 195989692dc3902e553fac23f69286e1c06a986b..85f6a85a11bd815bfd797bfbdce332dde8c08a1c 100644 --- a/clang/test/OpenMP/target_teams_generic_loop_order_codegen.cpp +++ b/clang/test/OpenMP/target_teams_generic_loop_order_codegen.cpp @@ -125,7 +125,7 @@ void gtid_test() { // CHECK1: omp.inner.for.end: // CHECK1-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK1: omp.loop.exit: -// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2:[0-9]+]], i32 [[TMP1]]) +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP1]]) // CHECK1-NEXT: ret void // // @@ -159,7 +159,7 @@ void gtid_test() { // CHECK1-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK1-NEXT: [[TMP2:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 // CHECK1-NEXT: [[TMP3:%.*]] = load i32, ptr [[TMP2]], align 4 -// CHECK1-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB2]], i32 [[TMP3]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK1-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB2:[0-9]+]], i32 [[TMP3]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) // CHECK1-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 // CHECK1-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP4]], 99 // CHECK1-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] diff --git a/clang/test/OpenMP/target_teams_generic_loop_private_codegen.cpp b/clang/test/OpenMP/target_teams_generic_loop_private_codegen.cpp index 987c12adc6f66b462f574a4a47371d35a7e4154e..7503b69b92aa91005cdd4153b1ab58f2e1321cc5 100644 --- a/clang/test/OpenMP/target_teams_generic_loop_private_codegen.cpp +++ b/clang/test/OpenMP/target_teams_generic_loop_private_codegen.cpp @@ -420,7 +420,7 @@ int main() { // CHECK1: omp.loop.exit: // CHECK1-NEXT: [[TMP13:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 // CHECK1-NEXT: [[TMP14:%.*]] = load i32, ptr [[TMP13]], align 4 -// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2:[0-9]+]], i32 [[TMP14]]) +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP14]]) // CHECK1-NEXT: call void @_ZN1SIfED1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[VAR]]) #[[ATTR2]] // CHECK1-NEXT: [[ARRAY_BEGIN2:%.*]] = getelementptr inbounds [2 x %struct.S], ptr [[S_ARR]], i32 0, i32 0 // CHECK1-NEXT: [[TMP15:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[ARRAY_BEGIN2]], i64 2 @@ -481,7 +481,7 @@ int main() { // CHECK1-NEXT: call void @_ZN1SIfEC1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[VAR]]) // CHECK1-NEXT: [[TMP2:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 // CHECK1-NEXT: [[TMP3:%.*]] = load i32, ptr [[TMP2]], align 4 -// CHECK1-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB2]], i32 [[TMP3]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK1-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB2:[0-9]+]], i32 [[TMP3]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) // CHECK1-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 // CHECK1-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP4]], 1 // CHECK1-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] @@ -728,7 +728,7 @@ int main() { // CHECK1: omp.loop.exit: // CHECK1-NEXT: [[TMP13:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 // CHECK1-NEXT: [[TMP14:%.*]] = load i32, ptr [[TMP13]], align 4 -// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP14]]) +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP14]]) // CHECK1-NEXT: call void @_ZN1SIiED1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[VAR]]) #[[ATTR2]] // CHECK1-NEXT: [[ARRAY_BEGIN4:%.*]] = getelementptr inbounds [2 x %struct.S.0], ptr [[S_ARR]], i32 0, i32 0 // CHECK1-NEXT: [[TMP15:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[ARRAY_BEGIN4]], i64 2 @@ -1151,7 +1151,7 @@ int main() { // CHECK3: omp.loop.exit: // CHECK3-NEXT: [[TMP11:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 4 // CHECK3-NEXT: [[TMP12:%.*]] = load i32, ptr [[TMP11]], align 4 -// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2:[0-9]+]], i32 [[TMP12]]) +// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP12]]) // CHECK3-NEXT: call void @_ZN1SIfED1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[VAR]]) #[[ATTR2]] // CHECK3-NEXT: [[ARRAY_BEGIN2:%.*]] = getelementptr inbounds [2 x %struct.S], ptr [[S_ARR]], i32 0, i32 0 // CHECK3-NEXT: [[TMP13:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[ARRAY_BEGIN2]], i32 2 @@ -1210,7 +1210,7 @@ int main() { // CHECK3-NEXT: call void @_ZN1SIfEC1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[VAR]]) // CHECK3-NEXT: [[TMP2:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 4 // CHECK3-NEXT: [[TMP3:%.*]] = load i32, ptr [[TMP2]], align 4 -// CHECK3-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB2]], i32 [[TMP3]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK3-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB2:[0-9]+]], i32 [[TMP3]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) // CHECK3-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 // CHECK3-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP4]], 1 // CHECK3-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] @@ -1453,7 +1453,7 @@ int main() { // CHECK3: omp.loop.exit: // CHECK3-NEXT: [[TMP11:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 4 // CHECK3-NEXT: [[TMP12:%.*]] = load i32, ptr [[TMP11]], align 4 -// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP12]]) +// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP12]]) // CHECK3-NEXT: call void @_ZN1SIiED1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[VAR]]) #[[ATTR2]] // CHECK3-NEXT: [[ARRAY_BEGIN4:%.*]] = getelementptr inbounds [2 x %struct.S.0], ptr [[S_ARR]], i32 0, i32 0 // CHECK3-NEXT: [[TMP13:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[ARRAY_BEGIN4]], i32 2 @@ -1827,7 +1827,7 @@ int main() { // CHECK5: omp.inner.for.end: // CHECK5-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK5: omp.loop.exit: -// CHECK5-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2:[0-9]+]], i32 [[TMP1]]) +// CHECK5-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP1]]) // CHECK5-NEXT: ret void // // @@ -1869,7 +1869,7 @@ int main() { // CHECK5-NEXT: store ptr [[G1]], ptr [[_TMP3]], align 8 // CHECK5-NEXT: [[TMP2:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 // CHECK5-NEXT: [[TMP3:%.*]] = load i32, ptr [[TMP2]], align 4 -// CHECK5-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB2]], i32 [[TMP3]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK5-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB2:[0-9]+]], i32 [[TMP3]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) // CHECK5-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 // CHECK5-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP4]], 1 // CHECK5-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] @@ -2015,7 +2015,7 @@ int main() { // CHECK13: omp.loop.exit: // CHECK13-NEXT: [[TMP13:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 // CHECK13-NEXT: [[TMP14:%.*]] = load i32, ptr [[TMP13]], align 4 -// CHECK13-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2:[0-9]+]], i32 [[TMP14]]) +// CHECK13-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP14]]) // CHECK13-NEXT: call void @_ZN1SIfED1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[VAR]]) #[[ATTR5:[0-9]+]] // CHECK13-NEXT: [[ARRAY_BEGIN2:%.*]] = getelementptr inbounds [2 x %struct.S], ptr [[S_ARR]], i32 0, i32 0 // CHECK13-NEXT: [[TMP15:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[ARRAY_BEGIN2]], i64 2 @@ -2086,7 +2086,7 @@ int main() { // CHECK13-NEXT: call void @_ZN1SIfEC1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[VAR]]) #[[ATTR4]] // CHECK13-NEXT: [[TMP2:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 // CHECK13-NEXT: [[TMP3:%.*]] = load i32, ptr [[TMP2]], align 4 -// CHECK13-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB2]], i32 [[TMP3]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK13-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB2:[0-9]+]], i32 [[TMP3]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) // CHECK13-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 // CHECK13-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP4]], 1 // CHECK13-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] @@ -2252,7 +2252,7 @@ int main() { // CHECK13: omp.loop.exit: // CHECK13-NEXT: [[TMP13:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 // CHECK13-NEXT: [[TMP14:%.*]] = load i32, ptr [[TMP13]], align 4 -// CHECK13-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP14]]) +// CHECK13-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP14]]) // CHECK13-NEXT: call void @_ZN1SIiED1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[VAR]]) #[[ATTR5]] // CHECK13-NEXT: [[ARRAY_BEGIN4:%.*]] = getelementptr inbounds [2 x %struct.S.0], ptr [[S_ARR]], i32 0, i32 0 // CHECK13-NEXT: [[TMP15:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[ARRAY_BEGIN4]], i64 2 @@ -2527,7 +2527,7 @@ int main() { // CHECK15: omp.loop.exit: // CHECK15-NEXT: [[TMP11:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 4 // CHECK15-NEXT: [[TMP12:%.*]] = load i32, ptr [[TMP11]], align 4 -// CHECK15-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2:[0-9]+]], i32 [[TMP12]]) +// CHECK15-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP12]]) // CHECK15-NEXT: call void @_ZN1SIfED1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[VAR]]) #[[ATTR5:[0-9]+]] // CHECK15-NEXT: [[ARRAY_BEGIN2:%.*]] = getelementptr inbounds [2 x %struct.S], ptr [[S_ARR]], i32 0, i32 0 // CHECK15-NEXT: [[TMP13:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[ARRAY_BEGIN2]], i32 2 @@ -2596,7 +2596,7 @@ int main() { // CHECK15-NEXT: call void @_ZN1SIfEC1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[VAR]]) #[[ATTR4]] // CHECK15-NEXT: [[TMP2:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 4 // CHECK15-NEXT: [[TMP3:%.*]] = load i32, ptr [[TMP2]], align 4 -// CHECK15-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB2]], i32 [[TMP3]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK15-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB2:[0-9]+]], i32 [[TMP3]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) // CHECK15-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 // CHECK15-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP4]], 1 // CHECK15-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] @@ -2758,7 +2758,7 @@ int main() { // CHECK15: omp.loop.exit: // CHECK15-NEXT: [[TMP11:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 4 // CHECK15-NEXT: [[TMP12:%.*]] = load i32, ptr [[TMP11]], align 4 -// CHECK15-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP12]]) +// CHECK15-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP12]]) // CHECK15-NEXT: call void @_ZN1SIiED1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[VAR]]) #[[ATTR5]] // CHECK15-NEXT: [[ARRAY_BEGIN4:%.*]] = getelementptr inbounds [2 x %struct.S.0], ptr [[S_ARR]], i32 0, i32 0 // CHECK15-NEXT: [[TMP13:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[ARRAY_BEGIN4]], i32 2 @@ -3018,7 +3018,7 @@ int main() { // CHECK17: omp.inner.for.end: // CHECK17-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK17: omp.loop.exit: -// CHECK17-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2:[0-9]+]], i32 [[TMP1]]) +// CHECK17-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP1]]) // CHECK17-NEXT: ret void // // @@ -3060,7 +3060,7 @@ int main() { // CHECK17-NEXT: store ptr [[G1]], ptr [[_TMP3]], align 8 // CHECK17-NEXT: [[TMP2:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 // CHECK17-NEXT: [[TMP3:%.*]] = load i32, ptr [[TMP2]], align 4 -// CHECK17-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB2]], i32 [[TMP3]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK17-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB2:[0-9]+]], i32 [[TMP3]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) // CHECK17-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 // CHECK17-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP4]], 1 // CHECK17-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] diff --git a/clang/test/OpenMP/target_teams_generic_loop_reduction_codegen.cpp b/clang/test/OpenMP/target_teams_generic_loop_reduction_codegen.cpp index bfa00ee7a0f4ba0395c1396b44ad40441969acf1..1036ffd195de00e8544c669ee18c5580a14e2455 100644 --- a/clang/test/OpenMP/target_teams_generic_loop_reduction_codegen.cpp +++ b/clang/test/OpenMP/target_teams_generic_loop_reduction_codegen.cpp @@ -316,7 +316,7 @@ int main() { // CHECK1: omp.inner.for.end: // CHECK1-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK1: omp.loop.exit: -// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP4]]) +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP4]]) // CHECK1-NEXT: [[TMP14:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOMP_REDUCTION_RED_LIST]], i64 0, i64 0 // CHECK1-NEXT: store ptr [[SIVAR2]], ptr [[TMP14]], align 8 // CHECK1-NEXT: [[TMP15:%.*]] = call i32 @__kmpc_reduce_nowait(ptr @[[GLOB3]], i32 [[TMP4]], i32 1, i64 8, ptr [[DOTOMP_REDUCTION_RED_LIST]], ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l66.omp_outlined.omp_outlined.omp.reduction.reduction_func, ptr @.gomp_critical_user_.reduction.var) @@ -606,7 +606,7 @@ int main() { // CHECK1: omp.inner.for.end: // CHECK1-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK1: omp.loop.exit: -// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP4]]) +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP4]]) // CHECK1-NEXT: [[TMP14:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOMP_REDUCTION_RED_LIST]], i64 0, i64 0 // CHECK1-NEXT: store ptr [[T_VAR2]], ptr [[TMP14]], align 8 // CHECK1-NEXT: [[TMP15:%.*]] = call i32 @__kmpc_reduce_nowait(ptr @[[GLOB3]], i32 [[TMP4]], i32 1, i64 8, ptr [[DOTOMP_REDUCTION_RED_LIST]], ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiET_v_l32.omp_outlined.omp_outlined.omp.reduction.reduction_func, ptr @.gomp_critical_user_.reduction.var) @@ -891,7 +891,7 @@ int main() { // CHECK3: omp.inner.for.end: // CHECK3-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK3: omp.loop.exit: -// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP4]]) +// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP4]]) // CHECK3-NEXT: [[TMP14:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOMP_REDUCTION_RED_LIST]], i32 0, i32 0 // CHECK3-NEXT: store ptr [[SIVAR1]], ptr [[TMP14]], align 4 // CHECK3-NEXT: [[TMP15:%.*]] = call i32 @__kmpc_reduce_nowait(ptr @[[GLOB3]], i32 [[TMP4]], i32 1, i32 4, ptr [[DOTOMP_REDUCTION_RED_LIST]], ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l66.omp_outlined.omp_outlined.omp.reduction.reduction_func, ptr @.gomp_critical_user_.reduction.var) @@ -1177,7 +1177,7 @@ int main() { // CHECK3: omp.inner.for.end: // CHECK3-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK3: omp.loop.exit: -// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP4]]) +// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP4]]) // CHECK3-NEXT: [[TMP14:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOMP_REDUCTION_RED_LIST]], i32 0, i32 0 // CHECK3-NEXT: store ptr [[T_VAR1]], ptr [[TMP14]], align 4 // CHECK3-NEXT: [[TMP15:%.*]] = call i32 @__kmpc_reduce_nowait(ptr @[[GLOB3]], i32 [[TMP4]], i32 1, i32 4, ptr [[DOTOMP_REDUCTION_RED_LIST]], ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiET_v_l32.omp_outlined.omp_outlined.omp.reduction.reduction_func, ptr @.gomp_critical_user_.reduction.var) @@ -1425,7 +1425,7 @@ int main() { // CHECK5: omp.inner.for.end: // CHECK5-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK5: omp.loop.exit: -// CHECK5-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP4]]) +// CHECK5-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP4]]) // CHECK5-NEXT: [[TMP15:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOMP_REDUCTION_RED_LIST]], i64 0, i64 0 // CHECK5-NEXT: store ptr [[SIVAR2]], ptr [[TMP15]], align 8 // CHECK5-NEXT: [[TMP16:%.*]] = call i32 @__kmpc_reduce_nowait(ptr @[[GLOB3]], i32 [[TMP4]], i32 1, i64 8, ptr [[DOTOMP_REDUCTION_RED_LIST]], ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l44.omp_outlined.omp_outlined.omp.reduction.reduction_func, ptr @.gomp_critical_user_.reduction.var) diff --git a/clang/test/OpenMP/target_teams_generic_loop_uses_allocators_codegen.cpp b/clang/test/OpenMP/target_teams_generic_loop_uses_allocators_codegen.cpp index f945dc9b21d4eb39e560586d75787832d80e5d00..0dc2c95641e286d20a5a9ea38d8ee2cf83e82d94 100644 --- a/clang/test/OpenMP/target_teams_generic_loop_uses_allocators_codegen.cpp +++ b/clang/test/OpenMP/target_teams_generic_loop_uses_allocators_codegen.cpp @@ -400,7 +400,7 @@ void foo() { // CHECK: omp.inner.for.end: // CHECK-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK: omp.loop.exit: -// CHECK-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB3:[0-9]+]], i32 [[TMP1]]) +// CHECK-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP1]]) // CHECK-NEXT: ret void // // @@ -434,7 +434,7 @@ void foo() { // CHECK-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK-NEXT: [[TMP2:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 // CHECK-NEXT: [[TMP3:%.*]] = load i32, ptr [[TMP2]], align 4 -// CHECK-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB3]], i32 [[TMP3]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB3:[0-9]+]], i32 [[TMP3]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) // CHECK-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 // CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP4]], 9 // CHECK-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] diff --git a/clang/test/OpenMP/teams_distribute_parallel_for_codegen.cpp b/clang/test/OpenMP/teams_distribute_parallel_for_codegen.cpp index 6dcfa4f6f2abc66b842b8a9e674c07698ccd4a6e..a13b565cb38d854ad66237cef295bda78948889c 100644 --- a/clang/test/OpenMP/teams_distribute_parallel_for_codegen.cpp +++ b/clang/test/OpenMP/teams_distribute_parallel_for_codegen.cpp @@ -562,12 +562,12 @@ int main (int argc, char **argv) { // CHECK1: omp.loop.exit: // CHECK1-NEXT: [[TMP24:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 // CHECK1-NEXT: [[TMP25:%.*]] = load i32, ptr [[TMP24]], align 4 -// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP25]]) +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP25]]) // CHECK1-NEXT: br label [[OMP_PRECOND_END]] // CHECK1: cancel.exit: // CHECK1-NEXT: [[TMP26:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 // CHECK1-NEXT: [[TMP27:%.*]] = load i32, ptr [[TMP26]], align 4 -// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP27]]) +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP27]]) // CHECK1-NEXT: br label [[CANCEL_CONT:%.*]] // CHECK1: omp.precond.end: // CHECK1-NEXT: br label [[CANCEL_CONT]] @@ -771,7 +771,7 @@ int main (int argc, char **argv) { // CHECK1: omp.loop.exit: // CHECK1-NEXT: [[TMP20:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 // CHECK1-NEXT: [[TMP21:%.*]] = load i32, ptr [[TMP20]], align 4 -// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP21]]) +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP21]]) // CHECK1-NEXT: br label [[OMP_PRECOND_END]] // CHECK1: omp.precond.end: // CHECK1-NEXT: ret void @@ -1159,12 +1159,12 @@ int main (int argc, char **argv) { // CHECK3: omp.loop.exit: // CHECK3-NEXT: [[TMP24:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 4 // CHECK3-NEXT: [[TMP25:%.*]] = load i32, ptr [[TMP24]], align 4 -// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP25]]) +// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP25]]) // CHECK3-NEXT: br label [[OMP_PRECOND_END]] // CHECK3: cancel.exit: // CHECK3-NEXT: [[TMP26:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 4 // CHECK3-NEXT: [[TMP27:%.*]] = load i32, ptr [[TMP26]], align 4 -// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP27]]) +// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP27]]) // CHECK3-NEXT: br label [[CANCEL_CONT:%.*]] // CHECK3: omp.precond.end: // CHECK3-NEXT: br label [[CANCEL_CONT]] @@ -1363,7 +1363,7 @@ int main (int argc, char **argv) { // CHECK3: omp.loop.exit: // CHECK3-NEXT: [[TMP20:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 4 // CHECK3-NEXT: [[TMP21:%.*]] = load i32, ptr [[TMP20]], align 4 -// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP21]]) +// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP21]]) // CHECK3-NEXT: br label [[OMP_PRECOND_END]] // CHECK3: omp.precond.end: // CHECK3-NEXT: ret void @@ -1674,7 +1674,7 @@ int main (int argc, char **argv) { // CHECK9: omp.loop.exit: // CHECK9-NEXT: [[TMP21:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 // CHECK9-NEXT: [[TMP22:%.*]] = load i32, ptr [[TMP21]], align 4 -// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP22]]) +// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP22]]) // CHECK9-NEXT: br label [[OMP_PRECOND_END]] // CHECK9: omp.precond.end: // CHECK9-NEXT: ret void @@ -1980,7 +1980,7 @@ int main (int argc, char **argv) { // CHECK11: omp.loop.exit: // CHECK11-NEXT: [[TMP21:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 4 // CHECK11-NEXT: [[TMP22:%.*]] = load i32, ptr [[TMP21]], align 4 -// CHECK11-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP22]]) +// CHECK11-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP22]]) // CHECK11-NEXT: br label [[OMP_PRECOND_END]] // CHECK11: omp.precond.end: // CHECK11-NEXT: ret void @@ -2200,7 +2200,7 @@ int main (int argc, char **argv) { // CHECK17: omp.inner.for.end: // CHECK17-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK17: omp.loop.exit: -// CHECK17-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP4]]) +// CHECK17-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP4]]) // CHECK17-NEXT: ret void // // @@ -2413,7 +2413,7 @@ int main (int argc, char **argv) { // CHECK19: omp.inner.for.end: // CHECK19-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK19: omp.loop.exit: -// CHECK19-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP4]]) +// CHECK19-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP4]]) // CHECK19-NEXT: ret void // // @@ -2730,7 +2730,7 @@ int main (int argc, char **argv) { // CHECK25: omp.loop.exit: // CHECK25-NEXT: [[TMP21:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 // CHECK25-NEXT: [[TMP22:%.*]] = load i32, ptr [[TMP21]], align 4 -// CHECK25-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP22]]) +// CHECK25-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP22]]) // CHECK25-NEXT: br label [[OMP_PRECOND_END]] // CHECK25: omp.precond.end: // CHECK25-NEXT: ret void @@ -2973,7 +2973,7 @@ int main (int argc, char **argv) { // CHECK25: omp.inner.for.end: // CHECK25-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK25: omp.loop.exit: -// CHECK25-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP4]]) +// CHECK25-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP4]]) // CHECK25-NEXT: ret void // // @@ -3285,7 +3285,7 @@ int main (int argc, char **argv) { // CHECK27: omp.loop.exit: // CHECK27-NEXT: [[TMP21:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 4 // CHECK27-NEXT: [[TMP22:%.*]] = load i32, ptr [[TMP21]], align 4 -// CHECK27-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP22]]) +// CHECK27-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP22]]) // CHECK27-NEXT: br label [[OMP_PRECOND_END]] // CHECK27: omp.precond.end: // CHECK27-NEXT: ret void @@ -3523,6 +3523,6 @@ int main (int argc, char **argv) { // CHECK27: omp.inner.for.end: // CHECK27-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK27: omp.loop.exit: -// CHECK27-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP4]]) +// CHECK27-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP4]]) // CHECK27-NEXT: ret void // diff --git a/clang/test/OpenMP/teams_distribute_parallel_for_collapse_codegen.cpp b/clang/test/OpenMP/teams_distribute_parallel_for_collapse_codegen.cpp index 60c54f7bc0b432881a432b1e4508137f8982a81e..64ee660b706ccf1c5f3ee54c24a581ae11164798 100644 --- a/clang/test/OpenMP/teams_distribute_parallel_for_collapse_codegen.cpp +++ b/clang/test/OpenMP/teams_distribute_parallel_for_collapse_codegen.cpp @@ -334,7 +334,7 @@ int main (int argc, char **argv) { // CHECK1: omp.inner.for.end: // CHECK1-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK1: omp.loop.exit: -// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP4]]) +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP4]]) // CHECK1-NEXT: ret void // // @@ -564,7 +564,7 @@ int main (int argc, char **argv) { // CHECK3: omp.inner.for.end: // CHECK3-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK3: omp.loop.exit: -// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP4]]) +// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP4]]) // CHECK3-NEXT: ret void // // @@ -991,7 +991,7 @@ int main (int argc, char **argv) { // CHECK9: omp.loop.exit: // CHECK9-NEXT: [[TMP33:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 // CHECK9-NEXT: [[TMP34:%.*]] = load i32, ptr [[TMP33]], align 4 -// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP34]]) +// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP34]]) // CHECK9-NEXT: br label [[OMP_PRECOND_END]] // CHECK9: omp.precond.end: // CHECK9-NEXT: ret void @@ -1215,7 +1215,7 @@ int main (int argc, char **argv) { // CHECK9: omp.inner.for.end: // CHECK9-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK9: omp.loop.exit: -// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP4]]) +// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP4]]) // CHECK9-NEXT: ret void // // @@ -1643,7 +1643,7 @@ int main (int argc, char **argv) { // CHECK11: omp.loop.exit: // CHECK11-NEXT: [[TMP33:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 4 // CHECK11-NEXT: [[TMP34:%.*]] = load i32, ptr [[TMP33]], align 4 -// CHECK11-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP34]]) +// CHECK11-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP34]]) // CHECK11-NEXT: br label [[OMP_PRECOND_END]] // CHECK11: omp.precond.end: // CHECK11-NEXT: ret void @@ -1861,6 +1861,6 @@ int main (int argc, char **argv) { // CHECK11: omp.inner.for.end: // CHECK11-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK11: omp.loop.exit: -// CHECK11-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP4]]) +// CHECK11-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP4]]) // CHECK11-NEXT: ret void // diff --git a/clang/test/OpenMP/teams_distribute_parallel_for_copyin_codegen.cpp b/clang/test/OpenMP/teams_distribute_parallel_for_copyin_codegen.cpp index 3455597f90900d3596535b7f970fd6069912b65e..37d19f86a9509ba7db7d99ae332f63dae029232e 100644 --- a/clang/test/OpenMP/teams_distribute_parallel_for_copyin_codegen.cpp +++ b/clang/test/OpenMP/teams_distribute_parallel_for_copyin_codegen.cpp @@ -314,7 +314,7 @@ int main() { // CHECK1: omp.inner.for.end: // CHECK1-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK1: omp.loop.exit: -// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP5]]) +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP5]]) // CHECK1-NEXT: ret void // // @@ -537,7 +537,7 @@ int main() { // CHECK1: omp.inner.for.end: // CHECK1-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK1: omp.loop.exit: -// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP5]]) +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP5]]) // CHECK1-NEXT: ret void // // @@ -764,7 +764,7 @@ int main() { // CHECK3: omp.inner.for.end: // CHECK3-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK3: omp.loop.exit: -// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP5]]) +// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP5]]) // CHECK3-NEXT: ret void // // @@ -982,7 +982,7 @@ int main() { // CHECK3: omp.inner.for.end: // CHECK3-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK3: omp.loop.exit: -// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP5]]) +// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP5]]) // CHECK3-NEXT: ret void // // @@ -1168,7 +1168,7 @@ int main() { // CHECK9: omp.inner.for.end: // CHECK9-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK9: omp.loop.exit: -// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP5]]) +// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP5]]) // CHECK9-NEXT: ret void // // diff --git a/clang/test/OpenMP/teams_distribute_parallel_for_dist_schedule_codegen.cpp b/clang/test/OpenMP/teams_distribute_parallel_for_dist_schedule_codegen.cpp index f324d2c7ac90c834f87788dccf7efe29401cde08..eb3d2fc84568ab92ebcd9eb7781c9ad6e2a596d5 100644 --- a/clang/test/OpenMP/teams_distribute_parallel_for_dist_schedule_codegen.cpp +++ b/clang/test/OpenMP/teams_distribute_parallel_for_dist_schedule_codegen.cpp @@ -451,7 +451,7 @@ int main (int argc, char **argv) { // CHECK1: omp.inner.for.end: // CHECK1-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK1: omp.loop.exit: -// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP4]]) +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP4]]) // CHECK1-NEXT: ret void // // @@ -602,7 +602,7 @@ int main (int argc, char **argv) { // CHECK1: omp.inner.for.end: // CHECK1-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK1: omp.loop.exit: -// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP4]]) +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP4]]) // CHECK1-NEXT: ret void // // @@ -773,7 +773,7 @@ int main (int argc, char **argv) { // CHECK1: omp.inner.for.end: // CHECK1-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK1: omp.loop.exit: -// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP4]]) +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP4]]) // CHECK1-NEXT: ret void // // @@ -1080,7 +1080,7 @@ int main (int argc, char **argv) { // CHECK3: omp.inner.for.end: // CHECK3-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK3: omp.loop.exit: -// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP4]]) +// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP4]]) // CHECK3-NEXT: ret void // // @@ -1226,7 +1226,7 @@ int main (int argc, char **argv) { // CHECK3: omp.inner.for.end: // CHECK3-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK3: omp.loop.exit: -// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP4]]) +// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP4]]) // CHECK3-NEXT: ret void // // @@ -1392,7 +1392,7 @@ int main (int argc, char **argv) { // CHECK3: omp.inner.for.end: // CHECK3-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK3: omp.loop.exit: -// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP4]]) +// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP4]]) // CHECK3-NEXT: ret void // // @@ -1881,7 +1881,7 @@ int main (int argc, char **argv) { // CHECK9: omp.loop.exit: // CHECK9-NEXT: [[TMP21:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 // CHECK9-NEXT: [[TMP22:%.*]] = load i32, ptr [[TMP21]], align 4 -// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP22]]) +// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP22]]) // CHECK9-NEXT: br label [[OMP_PRECOND_END]] // CHECK9: omp.precond.end: // CHECK9-NEXT: ret void @@ -2092,7 +2092,7 @@ int main (int argc, char **argv) { // CHECK9: omp.loop.exit: // CHECK9-NEXT: [[TMP21:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 // CHECK9-NEXT: [[TMP22:%.*]] = load i32, ptr [[TMP21]], align 4 -// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP22]]) +// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP22]]) // CHECK9-NEXT: br label [[OMP_PRECOND_END]] // CHECK9: omp.precond.end: // CHECK9-NEXT: ret void @@ -2345,7 +2345,7 @@ int main (int argc, char **argv) { // CHECK9: omp.loop.exit: // CHECK9-NEXT: [[TMP21:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 // CHECK9-NEXT: [[TMP22:%.*]] = load i32, ptr [[TMP21]], align 4 -// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP22]]) +// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP22]]) // CHECK9-NEXT: br label [[OMP_PRECOND_END]] // CHECK9: omp.precond.end: // CHECK9-NEXT: ret void @@ -2656,7 +2656,7 @@ int main (int argc, char **argv) { // CHECK9: omp.inner.for.end: // CHECK9-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK9: omp.loop.exit: -// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP4]]) +// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP4]]) // CHECK9-NEXT: ret void // // @@ -2806,7 +2806,7 @@ int main (int argc, char **argv) { // CHECK9: omp.inner.for.end: // CHECK9-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK9: omp.loop.exit: -// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP4]]) +// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP4]]) // CHECK9-NEXT: ret void // // @@ -2994,7 +2994,7 @@ int main (int argc, char **argv) { // CHECK9: omp.inner.for.end: // CHECK9-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK9: omp.loop.exit: -// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP4]]) +// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP4]]) // CHECK9-NEXT: ret void // // @@ -3480,7 +3480,7 @@ int main (int argc, char **argv) { // CHECK11: omp.loop.exit: // CHECK11-NEXT: [[TMP21:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 4 // CHECK11-NEXT: [[TMP22:%.*]] = load i32, ptr [[TMP21]], align 4 -// CHECK11-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP22]]) +// CHECK11-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP22]]) // CHECK11-NEXT: br label [[OMP_PRECOND_END]] // CHECK11: omp.precond.end: // CHECK11-NEXT: ret void @@ -3686,7 +3686,7 @@ int main (int argc, char **argv) { // CHECK11: omp.loop.exit: // CHECK11-NEXT: [[TMP21:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 4 // CHECK11-NEXT: [[TMP22:%.*]] = load i32, ptr [[TMP21]], align 4 -// CHECK11-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP22]]) +// CHECK11-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP22]]) // CHECK11-NEXT: br label [[OMP_PRECOND_END]] // CHECK11: omp.precond.end: // CHECK11-NEXT: ret void @@ -3934,7 +3934,7 @@ int main (int argc, char **argv) { // CHECK11: omp.loop.exit: // CHECK11-NEXT: [[TMP21:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 4 // CHECK11-NEXT: [[TMP22:%.*]] = load i32, ptr [[TMP21]], align 4 -// CHECK11-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP22]]) +// CHECK11-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP22]]) // CHECK11-NEXT: br label [[OMP_PRECOND_END]] // CHECK11: omp.precond.end: // CHECK11-NEXT: ret void @@ -4240,7 +4240,7 @@ int main (int argc, char **argv) { // CHECK11: omp.inner.for.end: // CHECK11-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK11: omp.loop.exit: -// CHECK11-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP4]]) +// CHECK11-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP4]]) // CHECK11-NEXT: ret void // // @@ -4385,7 +4385,7 @@ int main (int argc, char **argv) { // CHECK11: omp.inner.for.end: // CHECK11-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK11: omp.loop.exit: -// CHECK11-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP4]]) +// CHECK11-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP4]]) // CHECK11-NEXT: ret void // // @@ -4568,6 +4568,6 @@ int main (int argc, char **argv) { // CHECK11: omp.inner.for.end: // CHECK11-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK11: omp.loop.exit: -// CHECK11-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP4]]) +// CHECK11-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP4]]) // CHECK11-NEXT: ret void // diff --git a/clang/test/OpenMP/teams_distribute_parallel_for_firstprivate_codegen.cpp b/clang/test/OpenMP/teams_distribute_parallel_for_firstprivate_codegen.cpp index 24c3bc4adfefd2bef9a947a3f40f4a7ccc5d6b2b..904e6a1c1ce7bb045a58ae3c7ad42c164e77cbae 100644 --- a/clang/test/OpenMP/teams_distribute_parallel_for_firstprivate_codegen.cpp +++ b/clang/test/OpenMP/teams_distribute_parallel_for_firstprivate_codegen.cpp @@ -679,7 +679,7 @@ int main() { // CHECK1: omp.loop.exit: // CHECK1-NEXT: [[TMP20:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 // CHECK1-NEXT: [[TMP21:%.*]] = load i32, ptr [[TMP20]], align 4 -// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP21]]) +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP21]]) // CHECK1-NEXT: call void @_ZN1SIfED1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[VAR5]]) #[[ATTR2]] // CHECK1-NEXT: [[ARRAY_BEGIN12:%.*]] = getelementptr inbounds [2 x %struct.S], ptr [[S_ARR3]], i32 0, i32 0 // CHECK1-NEXT: [[TMP22:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[ARRAY_BEGIN12]], i64 2 @@ -1148,7 +1148,7 @@ int main() { // CHECK1: omp.loop.exit: // CHECK1-NEXT: [[TMP20:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 // CHECK1-NEXT: [[TMP21:%.*]] = load i32, ptr [[TMP20]], align 4 -// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP21]]) +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP21]]) // CHECK1-NEXT: call void @_ZN1SIiED1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[VAR6]]) #[[ATTR2]] // CHECK1-NEXT: [[ARRAY_BEGIN13:%.*]] = getelementptr inbounds [2 x %struct.S.0], ptr [[S_ARR4]], i32 0, i32 0 // CHECK1-NEXT: [[TMP22:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[ARRAY_BEGIN13]], i64 2 @@ -1737,7 +1737,7 @@ int main() { // CHECK3: omp.loop.exit: // CHECK3-NEXT: [[TMP20:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 4 // CHECK3-NEXT: [[TMP21:%.*]] = load i32, ptr [[TMP20]], align 4 -// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP21]]) +// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP21]]) // CHECK3-NEXT: call void @_ZN1SIfED1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[VAR4]]) #[[ATTR2]] // CHECK3-NEXT: [[ARRAY_BEGIN10:%.*]] = getelementptr inbounds [2 x %struct.S], ptr [[S_ARR2]], i32 0, i32 0 // CHECK3-NEXT: [[TMP22:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[ARRAY_BEGIN10]], i32 2 @@ -2200,7 +2200,7 @@ int main() { // CHECK3: omp.loop.exit: // CHECK3-NEXT: [[TMP20:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 4 // CHECK3-NEXT: [[TMP21:%.*]] = load i32, ptr [[TMP20]], align 4 -// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP21]]) +// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP21]]) // CHECK3-NEXT: call void @_ZN1SIiED1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[VAR5]]) #[[ATTR2]] // CHECK3-NEXT: [[ARRAY_BEGIN11:%.*]] = getelementptr inbounds [2 x %struct.S.0], ptr [[S_ARR3]], i32 0, i32 0 // CHECK3-NEXT: [[TMP22:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[ARRAY_BEGIN11]], i32 2 @@ -2611,7 +2611,7 @@ int main() { // CHECK9: omp.inner.for.end: // CHECK9-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK9: omp.loop.exit: -// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP3]]) +// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) // CHECK9-NEXT: ret void // // diff --git a/clang/test/OpenMP/teams_distribute_parallel_for_if_codegen.cpp b/clang/test/OpenMP/teams_distribute_parallel_for_if_codegen.cpp index 31367697db2352653dcba4e1ed98140896375acc..49ff6a5d08beed513035186f560fb30c700d3f73 100644 --- a/clang/test/OpenMP/teams_distribute_parallel_for_if_codegen.cpp +++ b/clang/test/OpenMP/teams_distribute_parallel_for_if_codegen.cpp @@ -322,7 +322,7 @@ int main() { // CHECK1: omp.inner.for.end: // CHECK1-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK1: omp.loop.exit: -// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP3]]) +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) // CHECK1-NEXT: ret void // // @@ -465,7 +465,7 @@ int main() { // CHECK1: omp.inner.for.end: // CHECK1-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK1: omp.loop.exit: -// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP3]]) +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) // CHECK1-NEXT: ret void // // @@ -742,7 +742,7 @@ int main() { // CHECK1: omp.inner.for.end: // CHECK1-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK1: omp.loop.exit: -// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP3]]) +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) // CHECK1-NEXT: ret void // // @@ -885,7 +885,7 @@ int main() { // CHECK1: omp.inner.for.end: // CHECK1-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK1: omp.loop.exit: -// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP3]]) +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) // CHECK1-NEXT: ret void // // @@ -1052,7 +1052,7 @@ int main() { // CHECK1: omp.inner.for.end: // CHECK1-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK1: omp.loop.exit: -// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP3]]) +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) // CHECK1-NEXT: ret void // // @@ -1327,7 +1327,7 @@ int main() { // CHECK1: omp.inner.for.end: // CHECK1-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK1: omp.loop.exit: -// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP3]]) +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) // CHECK1-NEXT: ret void // // @@ -1470,7 +1470,7 @@ int main() { // CHECK1: omp.inner.for.end: // CHECK1-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK1: omp.loop.exit: -// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP3]]) +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) // CHECK1-NEXT: ret void // // @@ -1637,6 +1637,6 @@ int main() { // CHECK1: omp.inner.for.end: // CHECK1-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK1: omp.loop.exit: -// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP3]]) +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) // CHECK1-NEXT: ret void // diff --git a/clang/test/OpenMP/teams_distribute_parallel_for_lastprivate_codegen.cpp b/clang/test/OpenMP/teams_distribute_parallel_for_lastprivate_codegen.cpp index 45197d5e296de5b218752e4426c23c4ef9ec760e..7b8df7367b828ff62e6ae478d8474c6a2b6c4279 100644 --- a/clang/test/OpenMP/teams_distribute_parallel_for_lastprivate_codegen.cpp +++ b/clang/test/OpenMP/teams_distribute_parallel_for_lastprivate_codegen.cpp @@ -411,7 +411,7 @@ int main() { // CHECK1: omp.inner.for.end: // CHECK1-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK1: omp.loop.exit: -// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP8]]) +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP8]]) // CHECK1-NEXT: [[TMP22:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK1-NEXT: [[TMP23:%.*]] = icmp ne i32 [[TMP22]], 0 // CHECK1-NEXT: br i1 [[TMP23]], label [[DOTOMP_LASTPRIVATE_THEN:%.*]], label [[DOTOMP_LASTPRIVATE_DONE:%.*]] @@ -673,7 +673,7 @@ int main() { // CHECK3: omp.inner.for.end: // CHECK3-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK3: omp.loop.exit: -// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP8]]) +// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP8]]) // CHECK3-NEXT: [[TMP22:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK3-NEXT: [[TMP23:%.*]] = icmp ne i32 [[TMP22]], 0 // CHECK3-NEXT: br i1 [[TMP23]], label [[DOTOMP_LASTPRIVATE_THEN:%.*]], label [[DOTOMP_LASTPRIVATE_DONE:%.*]] @@ -1115,7 +1115,7 @@ int main() { // CHECK9: omp.loop.exit: // CHECK9-NEXT: [[TMP21:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 // CHECK9-NEXT: [[TMP22:%.*]] = load i32, ptr [[TMP21]], align 4 -// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP22]]) +// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP22]]) // CHECK9-NEXT: [[TMP23:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK9-NEXT: [[TMP24:%.*]] = icmp ne i32 [[TMP23]], 0 // CHECK9-NEXT: br i1 [[TMP24]], label [[DOTOMP_LASTPRIVATE_THEN:%.*]], label [[DOTOMP_LASTPRIVATE_DONE:%.*]] @@ -1595,7 +1595,7 @@ int main() { // CHECK9: omp.loop.exit: // CHECK9-NEXT: [[TMP20:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 // CHECK9-NEXT: [[TMP21:%.*]] = load i32, ptr [[TMP20]], align 4 -// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP21]]) +// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP21]]) // CHECK9-NEXT: [[TMP22:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK9-NEXT: [[TMP23:%.*]] = icmp ne i32 [[TMP22]], 0 // CHECK9-NEXT: br i1 [[TMP23]], label [[DOTOMP_LASTPRIVATE_THEN:%.*]], label [[DOTOMP_LASTPRIVATE_DONE:%.*]] @@ -2095,7 +2095,7 @@ int main() { // CHECK11: omp.loop.exit: // CHECK11-NEXT: [[TMP21:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 4 // CHECK11-NEXT: [[TMP22:%.*]] = load i32, ptr [[TMP21]], align 4 -// CHECK11-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP22]]) +// CHECK11-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP22]]) // CHECK11-NEXT: [[TMP23:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK11-NEXT: [[TMP24:%.*]] = icmp ne i32 [[TMP23]], 0 // CHECK11-NEXT: br i1 [[TMP24]], label [[DOTOMP_LASTPRIVATE_THEN:%.*]], label [[DOTOMP_LASTPRIVATE_DONE:%.*]] @@ -2569,7 +2569,7 @@ int main() { // CHECK11: omp.loop.exit: // CHECK11-NEXT: [[TMP20:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 4 // CHECK11-NEXT: [[TMP21:%.*]] = load i32, ptr [[TMP20]], align 4 -// CHECK11-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP21]]) +// CHECK11-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP21]]) // CHECK11-NEXT: [[TMP22:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK11-NEXT: [[TMP23:%.*]] = icmp ne i32 [[TMP22]], 0 // CHECK11-NEXT: br i1 [[TMP23]], label [[DOTOMP_LASTPRIVATE_THEN:%.*]], label [[DOTOMP_LASTPRIVATE_DONE:%.*]] diff --git a/clang/test/OpenMP/teams_distribute_parallel_for_num_threads_codegen.cpp b/clang/test/OpenMP/teams_distribute_parallel_for_num_threads_codegen.cpp index c805d739cf9c23adeb5de447d090970267be2e61..a7b1f6eb309ee9e4891fc5c89c1329e814a37d59 100644 --- a/clang/test/OpenMP/teams_distribute_parallel_for_num_threads_codegen.cpp +++ b/clang/test/OpenMP/teams_distribute_parallel_for_num_threads_codegen.cpp @@ -371,7 +371,7 @@ int main() { // CHECK1: omp.inner.for.end: // CHECK1-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK1: omp.loop.exit: -// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP3]]) +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) // CHECK1-NEXT: ret void // CHECK1: terminate.lpad: // CHECK1-NEXT: [[TMP11:%.*]] = landingpad { ptr, i32 } @@ -538,7 +538,7 @@ int main() { // CHECK1: omp.inner.for.end: // CHECK1-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK1: omp.loop.exit: -// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP3]]) +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) // CHECK1-NEXT: ret void // CHECK1: terminate.lpad: // CHECK1-NEXT: [[TMP11:%.*]] = landingpad { ptr, i32 } @@ -887,7 +887,7 @@ int main() { // CHECK1: omp.inner.for.end: // CHECK1-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK1: omp.loop.exit: -// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP3]]) +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) // CHECK1-NEXT: ret void // CHECK1: terminate.lpad: // CHECK1-NEXT: [[TMP11:%.*]] = landingpad { ptr, i32 } @@ -1034,7 +1034,7 @@ int main() { // CHECK1: omp.inner.for.end: // CHECK1-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK1: omp.loop.exit: -// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP3]]) +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) // CHECK1-NEXT: ret void // CHECK1: terminate.lpad: // CHECK1-NEXT: [[TMP11:%.*]] = landingpad { ptr, i32 } @@ -1181,7 +1181,7 @@ int main() { // CHECK1: omp.inner.for.end: // CHECK1-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK1: omp.loop.exit: -// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP3]]) +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) // CHECK1-NEXT: ret void // CHECK1: terminate.lpad: // CHECK1-NEXT: [[TMP11:%.*]] = landingpad { ptr, i32 } @@ -1350,7 +1350,7 @@ int main() { // CHECK1: omp.inner.for.end: // CHECK1-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK1: omp.loop.exit: -// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP3]]) +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) // CHECK1-NEXT: ret void // CHECK1: terminate.lpad: // CHECK1-NEXT: [[TMP11:%.*]] = landingpad { ptr, i32 } @@ -1658,7 +1658,7 @@ int main() { // CHECK5: omp.inner.for.end: // CHECK5-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK5: omp.loop.exit: -// CHECK5-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP3]]) +// CHECK5-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) // CHECK5-NEXT: ret void // CHECK5: terminate.lpad: // CHECK5-NEXT: [[TMP11:%.*]] = landingpad { ptr, i32 } @@ -1825,7 +1825,7 @@ int main() { // CHECK5: omp.inner.for.end: // CHECK5-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK5: omp.loop.exit: -// CHECK5-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP3]]) +// CHECK5-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) // CHECK5-NEXT: ret void // CHECK5: terminate.lpad: // CHECK5-NEXT: [[TMP11:%.*]] = landingpad { ptr, i32 } @@ -2165,7 +2165,7 @@ int main() { // CHECK5: omp.inner.for.end: // CHECK5-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK5: omp.loop.exit: -// CHECK5-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP3]]) +// CHECK5-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) // CHECK5-NEXT: ret void // CHECK5: terminate.lpad: // CHECK5-NEXT: [[TMP11:%.*]] = landingpad { ptr, i32 } @@ -2312,7 +2312,7 @@ int main() { // CHECK5: omp.inner.for.end: // CHECK5-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK5: omp.loop.exit: -// CHECK5-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP3]]) +// CHECK5-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) // CHECK5-NEXT: ret void // CHECK5: terminate.lpad: // CHECK5-NEXT: [[TMP11:%.*]] = landingpad { ptr, i32 } @@ -2459,7 +2459,7 @@ int main() { // CHECK5: omp.inner.for.end: // CHECK5-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK5: omp.loop.exit: -// CHECK5-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP3]]) +// CHECK5-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) // CHECK5-NEXT: ret void // CHECK5: terminate.lpad: // CHECK5-NEXT: [[TMP11:%.*]] = landingpad { ptr, i32 } @@ -2628,7 +2628,7 @@ int main() { // CHECK5: omp.inner.for.end: // CHECK5-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK5: omp.loop.exit: -// CHECK5-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP3]]) +// CHECK5-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) // CHECK5-NEXT: ret void // CHECK5: terminate.lpad: // CHECK5-NEXT: [[TMP11:%.*]] = landingpad { ptr, i32 } diff --git a/clang/test/OpenMP/teams_distribute_parallel_for_private_codegen.cpp b/clang/test/OpenMP/teams_distribute_parallel_for_private_codegen.cpp index fe537dc743d4e738b826699b67e402d45371d372..dc430fc55787c11f370ef715316199196ff2256f 100644 --- a/clang/test/OpenMP/teams_distribute_parallel_for_private_codegen.cpp +++ b/clang/test/OpenMP/teams_distribute_parallel_for_private_codegen.cpp @@ -496,7 +496,7 @@ int main() { // CHECK1: omp.loop.exit: // CHECK1-NEXT: [[TMP16:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 // CHECK1-NEXT: [[TMP17:%.*]] = load i32, ptr [[TMP16]], align 4 -// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP17]]) +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP17]]) // CHECK1-NEXT: call void @_ZN1SIfED1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[VAR]]) #[[ATTR2]] // CHECK1-NEXT: [[ARRAY_BEGIN7:%.*]] = getelementptr inbounds [2 x %struct.S], ptr [[S_ARR]], i32 0, i32 0 // CHECK1-NEXT: [[TMP18:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[ARRAY_BEGIN7]], i64 2 @@ -804,7 +804,7 @@ int main() { // CHECK1: omp.loop.exit: // CHECK1-NEXT: [[TMP15:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 // CHECK1-NEXT: [[TMP16:%.*]] = load i32, ptr [[TMP15]], align 4 -// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP16]]) +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP16]]) // CHECK1-NEXT: call void @_ZN1SIiED1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[VAR]]) #[[ATTR2]] // CHECK1-NEXT: [[ARRAY_BEGIN8:%.*]] = getelementptr inbounds [2 x %struct.S.0], ptr [[S_ARR]], i32 0, i32 0 // CHECK1-NEXT: [[TMP17:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[ARRAY_BEGIN8]], i64 2 @@ -1223,7 +1223,7 @@ int main() { // CHECK3: omp.loop.exit: // CHECK3-NEXT: [[TMP16:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 4 // CHECK3-NEXT: [[TMP17:%.*]] = load i32, ptr [[TMP16]], align 4 -// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP17]]) +// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP17]]) // CHECK3-NEXT: call void @_ZN1SIfED1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[VAR]]) #[[ATTR2]] // CHECK3-NEXT: [[ARRAY_BEGIN5:%.*]] = getelementptr inbounds [2 x %struct.S], ptr [[S_ARR]], i32 0, i32 0 // CHECK3-NEXT: [[TMP18:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[ARRAY_BEGIN5]], i32 2 @@ -1525,7 +1525,7 @@ int main() { // CHECK3: omp.loop.exit: // CHECK3-NEXT: [[TMP15:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 4 // CHECK3-NEXT: [[TMP16:%.*]] = load i32, ptr [[TMP15]], align 4 -// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP16]]) +// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP16]]) // CHECK3-NEXT: call void @_ZN1SIiED1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[VAR]]) #[[ATTR2]] // CHECK3-NEXT: [[ARRAY_BEGIN6:%.*]] = getelementptr inbounds [2 x %struct.S.0], ptr [[S_ARR]], i32 0, i32 0 // CHECK3-NEXT: [[TMP17:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[ARRAY_BEGIN6]], i32 2 @@ -1883,7 +1883,7 @@ int main() { // CHECK9: omp.inner.for.end: // CHECK9-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK9: omp.loop.exit: -// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP3]]) +// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) // CHECK9-NEXT: ret void // // diff --git a/clang/test/OpenMP/teams_distribute_parallel_for_proc_bind_codegen.cpp b/clang/test/OpenMP/teams_distribute_parallel_for_proc_bind_codegen.cpp index cbd426aabb9c7c62f38d5923785ed19d720af41e..386e772b78970f8843ea19d17def0ad5eca3241c 100644 --- a/clang/test/OpenMP/teams_distribute_parallel_for_proc_bind_codegen.cpp +++ b/clang/test/OpenMP/teams_distribute_parallel_for_proc_bind_codegen.cpp @@ -263,7 +263,7 @@ int main() { // CHECK1: omp.inner.for.end: // CHECK1-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK1: omp.loop.exit: -// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP3]]) +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) // CHECK1-NEXT: ret void // // @@ -401,7 +401,7 @@ int main() { // CHECK1: omp.inner.for.end: // CHECK1-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK1: omp.loop.exit: -// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP3]]) +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) // CHECK1-NEXT: ret void // // @@ -580,6 +580,6 @@ int main() { // CHECK1: omp.inner.for.end: // CHECK1-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK1: omp.loop.exit: -// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP3]]) +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) // CHECK1-NEXT: ret void // diff --git a/clang/test/OpenMP/teams_distribute_parallel_for_reduction_codegen.cpp b/clang/test/OpenMP/teams_distribute_parallel_for_reduction_codegen.cpp index a003b9f203a4775f48693c4feb6de03868952cc0..7ac42579e91b95e7fba950f92ed8d9a06d4be59d 100644 --- a/clang/test/OpenMP/teams_distribute_parallel_for_reduction_codegen.cpp +++ b/clang/test/OpenMP/teams_distribute_parallel_for_reduction_codegen.cpp @@ -322,7 +322,7 @@ int main() { // CHECK1: omp.inner.for.end: // CHECK1-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK1: omp.loop.exit: -// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP4]]) +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP4]]) // CHECK1-NEXT: [[TMP14:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOMP_REDUCTION_RED_LIST]], i64 0, i64 0 // CHECK1-NEXT: store ptr [[SIVAR2]], ptr [[TMP14]], align 8 // CHECK1-NEXT: [[TMP15:%.*]] = call i32 @__kmpc_reduce_nowait(ptr @[[GLOB3]], i32 [[TMP4]], i32 1, i64 8, ptr [[DOTOMP_REDUCTION_RED_LIST]], ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l68.omp_outlined.omp_outlined.omp.reduction.reduction_func, ptr @.gomp_critical_user_.reduction.var) @@ -615,7 +615,7 @@ int main() { // CHECK1: omp.inner.for.end: // CHECK1-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK1: omp.loop.exit: -// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP4]]) +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP4]]) // CHECK1-NEXT: [[TMP14:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOMP_REDUCTION_RED_LIST]], i64 0, i64 0 // CHECK1-NEXT: store ptr [[T_VAR2]], ptr [[TMP14]], align 8 // CHECK1-NEXT: [[TMP15:%.*]] = call i32 @__kmpc_reduce_nowait(ptr @[[GLOB3]], i32 [[TMP4]], i32 1, i64 8, ptr [[DOTOMP_REDUCTION_RED_LIST]], ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiET_v_l32.omp_outlined.omp_outlined.omp.reduction.reduction_func, ptr @.gomp_critical_user_.reduction.var) @@ -903,7 +903,7 @@ int main() { // CHECK3: omp.inner.for.end: // CHECK3-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK3: omp.loop.exit: -// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP4]]) +// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP4]]) // CHECK3-NEXT: [[TMP14:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOMP_REDUCTION_RED_LIST]], i32 0, i32 0 // CHECK3-NEXT: store ptr [[SIVAR1]], ptr [[TMP14]], align 4 // CHECK3-NEXT: [[TMP15:%.*]] = call i32 @__kmpc_reduce_nowait(ptr @[[GLOB3]], i32 [[TMP4]], i32 1, i32 4, ptr [[DOTOMP_REDUCTION_RED_LIST]], ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l68.omp_outlined.omp_outlined.omp.reduction.reduction_func, ptr @.gomp_critical_user_.reduction.var) @@ -1192,7 +1192,7 @@ int main() { // CHECK3: omp.inner.for.end: // CHECK3-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK3: omp.loop.exit: -// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP4]]) +// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP4]]) // CHECK3-NEXT: [[TMP14:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOMP_REDUCTION_RED_LIST]], i32 0, i32 0 // CHECK3-NEXT: store ptr [[T_VAR1]], ptr [[TMP14]], align 4 // CHECK3-NEXT: [[TMP15:%.*]] = call i32 @__kmpc_reduce_nowait(ptr @[[GLOB3]], i32 [[TMP4]], i32 1, i32 4, ptr [[DOTOMP_REDUCTION_RED_LIST]], ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiET_v_l32.omp_outlined.omp_outlined.omp.reduction.reduction_func, ptr @.gomp_critical_user_.reduction.var) @@ -1439,7 +1439,7 @@ int main() { // CHECK9: omp.inner.for.end: // CHECK9-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK9: omp.loop.exit: -// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP4]]) +// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP4]]) // CHECK9-NEXT: [[TMP15:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOMP_REDUCTION_RED_LIST]], i64 0, i64 0 // CHECK9-NEXT: store ptr [[SIVAR2]], ptr [[TMP15]], align 8 // CHECK9-NEXT: [[TMP16:%.*]] = call i32 @__kmpc_reduce_nowait(ptr @[[GLOB3]], i32 [[TMP4]], i32 1, i64 8, ptr [[DOTOMP_REDUCTION_RED_LIST]], ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l45.omp_outlined.omp_outlined.omp.reduction.reduction_func, ptr @.gomp_critical_user_.reduction.var) diff --git a/clang/test/OpenMP/teams_distribute_parallel_for_reduction_task_codegen.cpp b/clang/test/OpenMP/teams_distribute_parallel_for_reduction_task_codegen.cpp index b583fcad2d3731c95d402d1d3a6218b1c31987c3..f58c848f4caec644dba0b8995f8bbfbe449d4da7 100644 --- a/clang/test/OpenMP/teams_distribute_parallel_for_reduction_task_codegen.cpp +++ b/clang/test/OpenMP/teams_distribute_parallel_for_reduction_task_codegen.cpp @@ -248,8 +248,8 @@ int main(int argc, char **argv) { // CHECK1-NEXT: [[TMP72:%.*]] = load i32, ptr [[TMP71]], align 4 // CHECK1-NEXT: [[TMP73:%.*]] = call i32 @__kmpc_reduce_nowait(ptr @[[GLOB4:[0-9]+]], i32 [[TMP72]], i32 2, i64 24, ptr [[DOTOMP_REDUCTION_RED_LIST]], ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l16.omp_outlined.omp.reduction.reduction_func, ptr @.gomp_critical_user_.reduction.var) // CHECK1-NEXT: switch i32 [[TMP73]], label [[DOTOMP_REDUCTION_DEFAULT:%.*]] [ -// CHECK1-NEXT: i32 1, label [[DOTOMP_REDUCTION_CASE1:%.*]] -// CHECK1-NEXT: i32 2, label [[DOTOMP_REDUCTION_CASE2:%.*]] +// CHECK1-NEXT: i32 1, label [[DOTOMP_REDUCTION_CASE1:%.*]] +// CHECK1-NEXT: i32 2, label [[DOTOMP_REDUCTION_CASE2:%.*]] // CHECK1-NEXT: ] // CHECK1: .omp.reduction.case1: // CHECK1-NEXT: [[TMP74:%.*]] = load i32, ptr [[TMP0]], align 4 @@ -597,7 +597,7 @@ int main(int argc, char **argv) { // CHECK1: omp.loop.exit: // CHECK1-NEXT: [[TMP78:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 // CHECK1-NEXT: [[TMP79:%.*]] = load i32, ptr [[TMP78]], align 4 -// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP79]]) +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB3]], i32 [[TMP79]]) // CHECK1-NEXT: [[TMP80:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 // CHECK1-NEXT: [[TMP81:%.*]] = load i32, ptr [[TMP80]], align 4 // CHECK1-NEXT: call void @__kmpc_task_reduction_modifier_fini(ptr @[[GLOB1]], i32 [[TMP81]], i32 1) @@ -612,8 +612,8 @@ int main(int argc, char **argv) { // CHECK1-NEXT: [[TMP87:%.*]] = load i32, ptr [[TMP86]], align 4 // CHECK1-NEXT: [[TMP88:%.*]] = call i32 @__kmpc_reduce_nowait(ptr @[[GLOB4]], i32 [[TMP87]], i32 2, i64 24, ptr [[DOTOMP_REDUCTION_RED_LIST]], ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l16.omp_outlined.omp_outlined.omp.reduction.reduction_func, ptr @.gomp_critical_user_.reduction.var) // CHECK1-NEXT: switch i32 [[TMP88]], label [[DOTOMP_REDUCTION_DEFAULT:%.*]] [ -// CHECK1-NEXT: i32 1, label [[DOTOMP_REDUCTION_CASE1:%.*]] -// CHECK1-NEXT: i32 2, label [[DOTOMP_REDUCTION_CASE2:%.*]] +// CHECK1-NEXT: i32 1, label [[DOTOMP_REDUCTION_CASE1:%.*]] +// CHECK1-NEXT: i32 2, label [[DOTOMP_REDUCTION_CASE2:%.*]] // CHECK1-NEXT: ] // CHECK1: .omp.reduction.case1: // CHECK1-NEXT: [[TMP89:%.*]] = load i32, ptr [[TMP0]], align 4 @@ -805,21 +805,21 @@ int main(int argc, char **argv) { // CHECK1-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META6:![0-9]+]]) // CHECK1-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META8:![0-9]+]]) // CHECK1-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META10:![0-9]+]]) -// CHECK1-NEXT: store i32 [[TMP2]], ptr [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !12 -// CHECK1-NEXT: store ptr [[TMP5]], ptr [[DOTPART_ID__ADDR_I]], align 8, !noalias !12 -// CHECK1-NEXT: store ptr [[TMP8]], ptr [[DOTPRIVATES__ADDR_I]], align 8, !noalias !12 -// CHECK1-NEXT: store ptr @.omp_task_privates_map., ptr [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !12 -// CHECK1-NEXT: store ptr [[TMP3]], ptr [[DOTTASK_T__ADDR_I]], align 8, !noalias !12 -// CHECK1-NEXT: store ptr [[TMP7]], ptr [[__CONTEXT_ADDR_I]], align 8, !noalias !12 -// CHECK1-NEXT: [[TMP9:%.*]] = load ptr, ptr [[__CONTEXT_ADDR_I]], align 8, !noalias !12 -// CHECK1-NEXT: [[TMP10:%.*]] = load ptr, ptr [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !12 -// CHECK1-NEXT: [[TMP11:%.*]] = load ptr, ptr [[DOTPRIVATES__ADDR_I]], align 8, !noalias !12 +// CHECK1-NEXT: store i32 [[TMP2]], ptr [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias [[META12:![0-9]+]] +// CHECK1-NEXT: store ptr [[TMP5]], ptr [[DOTPART_ID__ADDR_I]], align 8, !noalias [[META12]] +// CHECK1-NEXT: store ptr [[TMP8]], ptr [[DOTPRIVATES__ADDR_I]], align 8, !noalias [[META12]] +// CHECK1-NEXT: store ptr @.omp_task_privates_map., ptr [[DOTCOPY_FN__ADDR_I]], align 8, !noalias [[META12]] +// CHECK1-NEXT: store ptr [[TMP3]], ptr [[DOTTASK_T__ADDR_I]], align 8, !noalias [[META12]] +// CHECK1-NEXT: store ptr [[TMP7]], ptr [[__CONTEXT_ADDR_I]], align 8, !noalias [[META12]] +// CHECK1-NEXT: [[TMP9:%.*]] = load ptr, ptr [[__CONTEXT_ADDR_I]], align 8, !noalias [[META12]] +// CHECK1-NEXT: [[TMP10:%.*]] = load ptr, ptr [[DOTCOPY_FN__ADDR_I]], align 8, !noalias [[META12]] +// CHECK1-NEXT: [[TMP11:%.*]] = load ptr, ptr [[DOTPRIVATES__ADDR_I]], align 8, !noalias [[META12]] // CHECK1-NEXT: call void [[TMP10]](ptr [[TMP11]], ptr [[DOTFIRSTPRIV_PTR_ADDR_I]]) #[[ATTR6]] -// CHECK1-NEXT: [[TMP12:%.*]] = load ptr, ptr [[DOTFIRSTPRIV_PTR_ADDR_I]], align 8, !noalias !12 +// CHECK1-NEXT: [[TMP12:%.*]] = load ptr, ptr [[DOTFIRSTPRIV_PTR_ADDR_I]], align 8, !noalias [[META12]] // CHECK1-NEXT: [[TMP13:%.*]] = getelementptr inbounds [[STRUCT_ANON:%.*]], ptr [[TMP9]], i32 0, i32 1 // CHECK1-NEXT: [[TMP14:%.*]] = load ptr, ptr [[TMP13]], align 8 // CHECK1-NEXT: [[TMP15:%.*]] = load ptr, ptr [[TMP12]], align 8 -// CHECK1-NEXT: [[TMP16:%.*]] = load i32, ptr [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !12 +// CHECK1-NEXT: [[TMP16:%.*]] = load i32, ptr [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias [[META12]] // CHECK1-NEXT: [[TMP17:%.*]] = call ptr @__kmpc_task_reduction_get_th_data(i32 [[TMP16]], ptr [[TMP15]], ptr [[TMP14]]) // CHECK1-NEXT: [[TMP18:%.*]] = getelementptr inbounds [[STRUCT_ANON]], ptr [[TMP9]], i32 0, i32 2 // CHECK1-NEXT: [[TMP19:%.*]] = load ptr, ptr [[TMP18]], align 8 @@ -839,7 +839,7 @@ int main(int argc, char **argv) { // CHECK1-NEXT: [[TMP30:%.*]] = sub i64 [[TMP28]], [[TMP29]] // CHECK1-NEXT: [[TMP31:%.*]] = add nuw i64 [[TMP30]], 1 // CHECK1-NEXT: [[TMP32:%.*]] = mul nuw i64 [[TMP31]], ptrtoint (ptr getelementptr (i8, ptr null, i32 1) to i64) -// CHECK1-NEXT: store i64 [[TMP31]], ptr @{{reduction_size[.].+[.]}}, align 8, !noalias !12 +// CHECK1-NEXT: store i64 [[TMP31]], ptr @{{reduction_size[.].+[.]}}, align 8, !noalias [[META12]] // CHECK1-NEXT: [[TMP33:%.*]] = load ptr, ptr [[TMP12]], align 8 // CHECK1-NEXT: [[TMP34:%.*]] = call ptr @__kmpc_task_reduction_get_th_data(i32 [[TMP16]], ptr [[TMP33]], ptr [[TMP20]]) // CHECK1-NEXT: [[TMP35:%.*]] = getelementptr inbounds [[STRUCT_ANON]], ptr [[TMP9]], i32 0, i32 2 @@ -849,8 +849,8 @@ int main(int argc, char **argv) { // CHECK1-NEXT: [[TMP39:%.*]] = ptrtoint ptr [[TMP20]] to i64 // CHECK1-NEXT: [[TMP40:%.*]] = sub i64 [[TMP38]], [[TMP39]] // CHECK1-NEXT: [[TMP41:%.*]] = getelementptr i8, ptr [[TMP34]], i64 [[TMP40]] -// CHECK1-NEXT: store ptr [[TMP4_I]], ptr [[TMP_I]], align 8, !noalias !12 -// CHECK1-NEXT: store ptr [[TMP41]], ptr [[TMP4_I]], align 8, !noalias !12 +// CHECK1-NEXT: store ptr [[TMP4_I]], ptr [[TMP_I]], align 8, !noalias [[META12]] +// CHECK1-NEXT: store ptr [[TMP41]], ptr [[TMP4_I]], align 8, !noalias [[META12]] // CHECK1-NEXT: ret i32 0 // // diff --git a/clang/test/OpenMP/teams_distribute_parallel_for_schedule_codegen.cpp b/clang/test/OpenMP/teams_distribute_parallel_for_schedule_codegen.cpp index ab0e08259efe0d847d34cf2ee298d5a6050a7e94..7518179f477655773bbf95eafa4cbdbede186af8 100644 --- a/clang/test/OpenMP/teams_distribute_parallel_for_schedule_codegen.cpp +++ b/clang/test/OpenMP/teams_distribute_parallel_for_schedule_codegen.cpp @@ -610,7 +610,7 @@ int main (int argc, char **argv) { // CHECK1: omp.inner.for.end: // CHECK1-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK1: omp.loop.exit: -// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP4]]) +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP4]]) // CHECK1-NEXT: ret void // // @@ -761,7 +761,7 @@ int main (int argc, char **argv) { // CHECK1: omp.inner.for.end: // CHECK1-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK1: omp.loop.exit: -// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP4]]) +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP4]]) // CHECK1-NEXT: ret void // // @@ -933,7 +933,7 @@ int main (int argc, char **argv) { // CHECK1-NEXT: store i32 [[ADD8]], ptr [[DOTOMP_UB]], align 4 // CHECK1-NEXT: br label [[OMP_DISPATCH_COND]] // CHECK1: omp.dispatch.end: -// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP4]]) +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP4]]) // CHECK1-NEXT: ret void // // @@ -1632,7 +1632,7 @@ int main (int argc, char **argv) { // CHECK3: omp.inner.for.end: // CHECK3-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK3: omp.loop.exit: -// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP4]]) +// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP4]]) // CHECK3-NEXT: ret void // // @@ -1778,7 +1778,7 @@ int main (int argc, char **argv) { // CHECK3: omp.inner.for.end: // CHECK3-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK3: omp.loop.exit: -// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP4]]) +// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP4]]) // CHECK3-NEXT: ret void // // @@ -1943,7 +1943,7 @@ int main (int argc, char **argv) { // CHECK3-NEXT: store i32 [[ADD5]], ptr [[DOTOMP_UB]], align 4 // CHECK3-NEXT: br label [[OMP_DISPATCH_COND]] // CHECK3: omp.dispatch.end: -// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP4]]) +// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP4]]) // CHECK3-NEXT: ret void // // @@ -2637,7 +2637,7 @@ int main (int argc, char **argv) { // CHECK5: omp.inner.for.end: // CHECK5-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK5: omp.loop.exit: -// CHECK5-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP4]]) +// CHECK5-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP4]]) // CHECK5-NEXT: ret void // // @@ -2788,7 +2788,7 @@ int main (int argc, char **argv) { // CHECK5: omp.inner.for.end: // CHECK5-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK5: omp.loop.exit: -// CHECK5-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP4]]) +// CHECK5-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP4]]) // CHECK5-NEXT: ret void // // @@ -2960,7 +2960,7 @@ int main (int argc, char **argv) { // CHECK5-NEXT: store i32 [[ADD8]], ptr [[DOTOMP_UB]], align 4 // CHECK5-NEXT: br label [[OMP_DISPATCH_COND]] // CHECK5: omp.dispatch.end: -// CHECK5-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP4]]) +// CHECK5-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP4]]) // CHECK5-NEXT: ret void // // @@ -3659,7 +3659,7 @@ int main (int argc, char **argv) { // CHECK7: omp.inner.for.end: // CHECK7-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK7: omp.loop.exit: -// CHECK7-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP4]]) +// CHECK7-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP4]]) // CHECK7-NEXT: ret void // // @@ -3805,7 +3805,7 @@ int main (int argc, char **argv) { // CHECK7: omp.inner.for.end: // CHECK7-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK7: omp.loop.exit: -// CHECK7-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP4]]) +// CHECK7-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP4]]) // CHECK7-NEXT: ret void // // @@ -3970,7 +3970,7 @@ int main (int argc, char **argv) { // CHECK7-NEXT: store i32 [[ADD5]], ptr [[DOTOMP_UB]], align 4 // CHECK7-NEXT: br label [[OMP_DISPATCH_COND]] // CHECK7: omp.dispatch.end: -// CHECK7-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP4]]) +// CHECK7-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP4]]) // CHECK7-NEXT: ret void // // @@ -4917,7 +4917,7 @@ int main (int argc, char **argv) { // CHECK13: omp.loop.exit: // CHECK13-NEXT: [[TMP21:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 // CHECK13-NEXT: [[TMP22:%.*]] = load i32, ptr [[TMP21]], align 4 -// CHECK13-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP22]]) +// CHECK13-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP22]]) // CHECK13-NEXT: br label [[OMP_PRECOND_END]] // CHECK13: omp.precond.end: // CHECK13-NEXT: ret void @@ -5128,7 +5128,7 @@ int main (int argc, char **argv) { // CHECK13: omp.loop.exit: // CHECK13-NEXT: [[TMP21:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 // CHECK13-NEXT: [[TMP22:%.*]] = load i32, ptr [[TMP21]], align 4 -// CHECK13-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP22]]) +// CHECK13-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP22]]) // CHECK13-NEXT: br label [[OMP_PRECOND_END]] // CHECK13: omp.precond.end: // CHECK13-NEXT: ret void @@ -5381,7 +5381,7 @@ int main (int argc, char **argv) { // CHECK13: omp.loop.exit: // CHECK13-NEXT: [[TMP21:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 // CHECK13-NEXT: [[TMP22:%.*]] = load i32, ptr [[TMP21]], align 4 -// CHECK13-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP22]]) +// CHECK13-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP22]]) // CHECK13-NEXT: br label [[OMP_PRECOND_END]] // CHECK13: omp.precond.end: // CHECK13-NEXT: ret void @@ -6226,7 +6226,7 @@ int main (int argc, char **argv) { // CHECK13: omp.inner.for.end: // CHECK13-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK13: omp.loop.exit: -// CHECK13-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP4]]) +// CHECK13-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP4]]) // CHECK13-NEXT: ret void // // @@ -6376,7 +6376,7 @@ int main (int argc, char **argv) { // CHECK13: omp.inner.for.end: // CHECK13-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK13: omp.loop.exit: -// CHECK13-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP4]]) +// CHECK13-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP4]]) // CHECK13-NEXT: ret void // // @@ -6565,7 +6565,7 @@ int main (int argc, char **argv) { // CHECK13-NEXT: store i32 [[ADD8]], ptr [[DOTOMP_UB]], align 4 // CHECK13-NEXT: br label [[OMP_DISPATCH_COND]] // CHECK13: omp.dispatch.end: -// CHECK13-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP5]]) +// CHECK13-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP5]]) // CHECK13-NEXT: ret void // // @@ -7537,7 +7537,7 @@ int main (int argc, char **argv) { // CHECK15: omp.loop.exit: // CHECK15-NEXT: [[TMP21:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 4 // CHECK15-NEXT: [[TMP22:%.*]] = load i32, ptr [[TMP21]], align 4 -// CHECK15-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP22]]) +// CHECK15-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP22]]) // CHECK15-NEXT: br label [[OMP_PRECOND_END]] // CHECK15: omp.precond.end: // CHECK15-NEXT: ret void @@ -7743,7 +7743,7 @@ int main (int argc, char **argv) { // CHECK15: omp.loop.exit: // CHECK15-NEXT: [[TMP21:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 4 // CHECK15-NEXT: [[TMP22:%.*]] = load i32, ptr [[TMP21]], align 4 -// CHECK15-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP22]]) +// CHECK15-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP22]]) // CHECK15-NEXT: br label [[OMP_PRECOND_END]] // CHECK15: omp.precond.end: // CHECK15-NEXT: ret void @@ -7991,7 +7991,7 @@ int main (int argc, char **argv) { // CHECK15: omp.loop.exit: // CHECK15-NEXT: [[TMP21:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 4 // CHECK15-NEXT: [[TMP22:%.*]] = load i32, ptr [[TMP21]], align 4 -// CHECK15-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP22]]) +// CHECK15-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP22]]) // CHECK15-NEXT: br label [[OMP_PRECOND_END]] // CHECK15: omp.precond.end: // CHECK15-NEXT: ret void @@ -8821,7 +8821,7 @@ int main (int argc, char **argv) { // CHECK15: omp.inner.for.end: // CHECK15-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK15: omp.loop.exit: -// CHECK15-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP4]]) +// CHECK15-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP4]]) // CHECK15-NEXT: ret void // // @@ -8966,7 +8966,7 @@ int main (int argc, char **argv) { // CHECK15: omp.inner.for.end: // CHECK15-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK15: omp.loop.exit: -// CHECK15-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP4]]) +// CHECK15-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP4]]) // CHECK15-NEXT: ret void // // @@ -9148,7 +9148,7 @@ int main (int argc, char **argv) { // CHECK15-NEXT: store i32 [[ADD5]], ptr [[DOTOMP_UB]], align 4 // CHECK15-NEXT: br label [[OMP_DISPATCH_COND]] // CHECK15: omp.dispatch.end: -// CHECK15-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP5]]) +// CHECK15-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP5]]) // CHECK15-NEXT: ret void // // @@ -10111,7 +10111,7 @@ int main (int argc, char **argv) { // CHECK17: omp.loop.exit: // CHECK17-NEXT: [[TMP21:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 // CHECK17-NEXT: [[TMP22:%.*]] = load i32, ptr [[TMP21]], align 4 -// CHECK17-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP22]]) +// CHECK17-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP22]]) // CHECK17-NEXT: br label [[OMP_PRECOND_END]] // CHECK17: omp.precond.end: // CHECK17-NEXT: ret void @@ -10322,7 +10322,7 @@ int main (int argc, char **argv) { // CHECK17: omp.loop.exit: // CHECK17-NEXT: [[TMP21:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 // CHECK17-NEXT: [[TMP22:%.*]] = load i32, ptr [[TMP21]], align 4 -// CHECK17-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP22]]) +// CHECK17-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP22]]) // CHECK17-NEXT: br label [[OMP_PRECOND_END]] // CHECK17: omp.precond.end: // CHECK17-NEXT: ret void @@ -10575,7 +10575,7 @@ int main (int argc, char **argv) { // CHECK17: omp.loop.exit: // CHECK17-NEXT: [[TMP21:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 // CHECK17-NEXT: [[TMP22:%.*]] = load i32, ptr [[TMP21]], align 4 -// CHECK17-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP22]]) +// CHECK17-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP22]]) // CHECK17-NEXT: br label [[OMP_PRECOND_END]] // CHECK17: omp.precond.end: // CHECK17-NEXT: ret void @@ -11420,7 +11420,7 @@ int main (int argc, char **argv) { // CHECK17: omp.inner.for.end: // CHECK17-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK17: omp.loop.exit: -// CHECK17-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP4]]) +// CHECK17-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP4]]) // CHECK17-NEXT: ret void // // @@ -11570,7 +11570,7 @@ int main (int argc, char **argv) { // CHECK17: omp.inner.for.end: // CHECK17-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK17: omp.loop.exit: -// CHECK17-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP4]]) +// CHECK17-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP4]]) // CHECK17-NEXT: ret void // // @@ -11759,7 +11759,7 @@ int main (int argc, char **argv) { // CHECK17-NEXT: store i32 [[ADD8]], ptr [[DOTOMP_UB]], align 4 // CHECK17-NEXT: br label [[OMP_DISPATCH_COND]] // CHECK17: omp.dispatch.end: -// CHECK17-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP5]]) +// CHECK17-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP5]]) // CHECK17-NEXT: ret void // // @@ -12731,7 +12731,7 @@ int main (int argc, char **argv) { // CHECK19: omp.loop.exit: // CHECK19-NEXT: [[TMP21:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 4 // CHECK19-NEXT: [[TMP22:%.*]] = load i32, ptr [[TMP21]], align 4 -// CHECK19-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP22]]) +// CHECK19-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP22]]) // CHECK19-NEXT: br label [[OMP_PRECOND_END]] // CHECK19: omp.precond.end: // CHECK19-NEXT: ret void @@ -12937,7 +12937,7 @@ int main (int argc, char **argv) { // CHECK19: omp.loop.exit: // CHECK19-NEXT: [[TMP21:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 4 // CHECK19-NEXT: [[TMP22:%.*]] = load i32, ptr [[TMP21]], align 4 -// CHECK19-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP22]]) +// CHECK19-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP22]]) // CHECK19-NEXT: br label [[OMP_PRECOND_END]] // CHECK19: omp.precond.end: // CHECK19-NEXT: ret void @@ -13185,7 +13185,7 @@ int main (int argc, char **argv) { // CHECK19: omp.loop.exit: // CHECK19-NEXT: [[TMP21:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 4 // CHECK19-NEXT: [[TMP22:%.*]] = load i32, ptr [[TMP21]], align 4 -// CHECK19-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP22]]) +// CHECK19-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP22]]) // CHECK19-NEXT: br label [[OMP_PRECOND_END]] // CHECK19: omp.precond.end: // CHECK19-NEXT: ret void @@ -14015,7 +14015,7 @@ int main (int argc, char **argv) { // CHECK19: omp.inner.for.end: // CHECK19-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK19: omp.loop.exit: -// CHECK19-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP4]]) +// CHECK19-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP4]]) // CHECK19-NEXT: ret void // // @@ -14160,7 +14160,7 @@ int main (int argc, char **argv) { // CHECK19: omp.inner.for.end: // CHECK19-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK19: omp.loop.exit: -// CHECK19-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP4]]) +// CHECK19-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP4]]) // CHECK19-NEXT: ret void // // @@ -14342,7 +14342,7 @@ int main (int argc, char **argv) { // CHECK19-NEXT: store i32 [[ADD5]], ptr [[DOTOMP_UB]], align 4 // CHECK19-NEXT: br label [[OMP_DISPATCH_COND]] // CHECK19: omp.dispatch.end: -// CHECK19-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP5]]) +// CHECK19-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP5]]) // CHECK19-NEXT: ret void // // diff --git a/clang/test/OpenMP/teams_distribute_parallel_for_simd_codegen.cpp b/clang/test/OpenMP/teams_distribute_parallel_for_simd_codegen.cpp index 96439c053ea89740a20c9b5ebe1c5420a8436012..854afe3b9bbc827e217ee9eed8992092e21c8e4c 100644 --- a/clang/test/OpenMP/teams_distribute_parallel_for_simd_codegen.cpp +++ b/clang/test/OpenMP/teams_distribute_parallel_for_simd_codegen.cpp @@ -583,7 +583,7 @@ int main (int argc, char **argv) { // CHECK1: omp.loop.exit: // CHECK1-NEXT: [[TMP20:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 // CHECK1-NEXT: [[TMP21:%.*]] = load i32, ptr [[TMP20]], align 4 -// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP21]]) +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP21]]) // CHECK1-NEXT: [[TMP22:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK1-NEXT: [[TMP23:%.*]] = icmp ne i32 [[TMP22]], 0 // CHECK1-NEXT: br i1 [[TMP23]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -828,7 +828,7 @@ int main (int argc, char **argv) { // CHECK1: omp.loop.exit: // CHECK1-NEXT: [[TMP24:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 // CHECK1-NEXT: [[TMP25:%.*]] = load i32, ptr [[TMP24]], align 4 -// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP25]]) +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP25]]) // CHECK1-NEXT: [[TMP26:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK1-NEXT: [[TMP27:%.*]] = icmp ne i32 [[TMP26]], 0 // CHECK1-NEXT: br i1 [[TMP27]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -1249,7 +1249,7 @@ int main (int argc, char **argv) { // CHECK3: omp.loop.exit: // CHECK3-NEXT: [[TMP20:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 4 // CHECK3-NEXT: [[TMP21:%.*]] = load i32, ptr [[TMP20]], align 4 -// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP21]]) +// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP21]]) // CHECK3-NEXT: [[TMP22:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK3-NEXT: [[TMP23:%.*]] = icmp ne i32 [[TMP22]], 0 // CHECK3-NEXT: br i1 [[TMP23]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -1489,7 +1489,7 @@ int main (int argc, char **argv) { // CHECK3: omp.loop.exit: // CHECK3-NEXT: [[TMP24:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 4 // CHECK3-NEXT: [[TMP25:%.*]] = load i32, ptr [[TMP24]], align 4 -// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP25]]) +// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP25]]) // CHECK3-NEXT: [[TMP26:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK3-NEXT: [[TMP27:%.*]] = icmp ne i32 [[TMP26]], 0 // CHECK3-NEXT: br i1 [[TMP27]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -2126,7 +2126,7 @@ int main (int argc, char **argv) { // CHECK9: omp.loop.exit: // CHECK9-NEXT: [[TMP25:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 // CHECK9-NEXT: [[TMP26:%.*]] = load i32, ptr [[TMP25]], align 4 -// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP26]]) +// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB3]], i32 [[TMP26]]) // CHECK9-NEXT: [[TMP27:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK9-NEXT: [[TMP28:%.*]] = icmp ne i32 [[TMP27]], 0 // CHECK9-NEXT: br i1 [[TMP28]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -2490,7 +2490,7 @@ int main (int argc, char **argv) { // CHECK11: omp.loop.exit: // CHECK11-NEXT: [[TMP25:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 4 // CHECK11-NEXT: [[TMP26:%.*]] = load i32, ptr [[TMP25]], align 4 -// CHECK11-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP26]]) +// CHECK11-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB3]], i32 [[TMP26]]) // CHECK11-NEXT: [[TMP27:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK11-NEXT: [[TMP28:%.*]] = icmp ne i32 [[TMP27]], 0 // CHECK11-NEXT: br i1 [[TMP28]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -2929,7 +2929,7 @@ int main (int argc, char **argv) { // CHECK17: omp.inner.for.end: // CHECK17-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK17: omp.loop.exit: -// CHECK17-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP6]]) +// CHECK17-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB3]], i32 [[TMP6]]) // CHECK17-NEXT: [[TMP15:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK17-NEXT: [[TMP16:%.*]] = icmp ne i32 [[TMP15]], 0 // CHECK17-NEXT: br i1 [[TMP16]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -3192,7 +3192,7 @@ int main (int argc, char **argv) { // CHECK19: omp.inner.for.end: // CHECK19-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK19: omp.loop.exit: -// CHECK19-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP6]]) +// CHECK19-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB3]], i32 [[TMP6]]) // CHECK19-NEXT: [[TMP15:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK19-NEXT: [[TMP16:%.*]] = icmp ne i32 [[TMP15]], 0 // CHECK19-NEXT: br i1 [[TMP16]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -3687,7 +3687,7 @@ int main (int argc, char **argv) { // CHECK25: omp.loop.exit: // CHECK25-NEXT: [[TMP25:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 // CHECK25-NEXT: [[TMP26:%.*]] = load i32, ptr [[TMP25]], align 4 -// CHECK25-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP26]]) +// CHECK25-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB3]], i32 [[TMP26]]) // CHECK25-NEXT: [[TMP27:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK25-NEXT: [[TMP28:%.*]] = icmp ne i32 [[TMP27]], 0 // CHECK25-NEXT: br i1 [[TMP28]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -3955,7 +3955,7 @@ int main (int argc, char **argv) { // CHECK25: omp.inner.for.end: // CHECK25-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK25: omp.loop.exit: -// CHECK25-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP4]]) +// CHECK25-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB3]], i32 [[TMP4]]) // CHECK25-NEXT: [[TMP13:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK25-NEXT: [[TMP14:%.*]] = icmp ne i32 [[TMP13]], 0 // CHECK25-NEXT: br i1 [[TMP14]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -4314,7 +4314,7 @@ int main (int argc, char **argv) { // CHECK27: omp.loop.exit: // CHECK27-NEXT: [[TMP25:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 4 // CHECK27-NEXT: [[TMP26:%.*]] = load i32, ptr [[TMP25]], align 4 -// CHECK27-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP26]]) +// CHECK27-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB3]], i32 [[TMP26]]) // CHECK27-NEXT: [[TMP27:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK27-NEXT: [[TMP28:%.*]] = icmp ne i32 [[TMP27]], 0 // CHECK27-NEXT: br i1 [[TMP28]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -4577,7 +4577,7 @@ int main (int argc, char **argv) { // CHECK27: omp.inner.for.end: // CHECK27-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK27: omp.loop.exit: -// CHECK27-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP4]]) +// CHECK27-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB3]], i32 [[TMP4]]) // CHECK27-NEXT: [[TMP13:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK27-NEXT: [[TMP14:%.*]] = icmp ne i32 [[TMP13]], 0 // CHECK27-NEXT: br i1 [[TMP14]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] diff --git a/clang/test/OpenMP/teams_distribute_parallel_for_simd_collapse_codegen.cpp b/clang/test/OpenMP/teams_distribute_parallel_for_simd_collapse_codegen.cpp index e68bd591519b73cee9af3e711c3e2851cd454993..e7b9978dd43cd81d2298a03927affddc2a861357 100644 --- a/clang/test/OpenMP/teams_distribute_parallel_for_simd_collapse_codegen.cpp +++ b/clang/test/OpenMP/teams_distribute_parallel_for_simd_collapse_codegen.cpp @@ -347,7 +347,7 @@ int main (int argc, char **argv) { // CHECK1: omp.inner.for.end: // CHECK1-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK1: omp.loop.exit: -// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP4]]) +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP4]]) // CHECK1-NEXT: [[TMP16:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK1-NEXT: [[TMP17:%.*]] = icmp ne i32 [[TMP16]], 0 // CHECK1-NEXT: br i1 [[TMP17]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -593,7 +593,7 @@ int main (int argc, char **argv) { // CHECK3: omp.inner.for.end: // CHECK3-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK3: omp.loop.exit: -// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP4]]) +// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP4]]) // CHECK3-NEXT: [[TMP16:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK3-NEXT: [[TMP17:%.*]] = icmp ne i32 [[TMP16]], 0 // CHECK3-NEXT: br i1 [[TMP17]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -1186,7 +1186,7 @@ int main (int argc, char **argv) { // CHECK9: omp.loop.exit: // CHECK9-NEXT: [[TMP33:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 // CHECK9-NEXT: [[TMP34:%.*]] = load i32, ptr [[TMP33]], align 4 -// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP34]]) +// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP34]]) // CHECK9-NEXT: [[TMP35:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK9-NEXT: [[TMP36:%.*]] = icmp ne i32 [[TMP35]], 0 // CHECK9-NEXT: br i1 [[TMP36]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -1436,7 +1436,7 @@ int main (int argc, char **argv) { // CHECK9: omp.inner.for.end: // CHECK9-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK9: omp.loop.exit: -// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP4]]) +// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP4]]) // CHECK9-NEXT: [[TMP16:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK9-NEXT: [[TMP17:%.*]] = icmp ne i32 [[TMP16]], 0 // CHECK9-NEXT: br i1 [[TMP17]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -1890,7 +1890,7 @@ int main (int argc, char **argv) { // CHECK11: omp.loop.exit: // CHECK11-NEXT: [[TMP33:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 4 // CHECK11-NEXT: [[TMP34:%.*]] = load i32, ptr [[TMP33]], align 4 -// CHECK11-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP34]]) +// CHECK11-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP34]]) // CHECK11-NEXT: [[TMP35:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK11-NEXT: [[TMP36:%.*]] = icmp ne i32 [[TMP35]], 0 // CHECK11-NEXT: br i1 [[TMP36]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -2134,7 +2134,7 @@ int main (int argc, char **argv) { // CHECK11: omp.inner.for.end: // CHECK11-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK11: omp.loop.exit: -// CHECK11-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP4]]) +// CHECK11-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP4]]) // CHECK11-NEXT: [[TMP16:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK11-NEXT: [[TMP17:%.*]] = icmp ne i32 [[TMP16]], 0 // CHECK11-NEXT: br i1 [[TMP17]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] diff --git a/clang/test/OpenMP/teams_distribute_parallel_for_simd_dist_schedule_codegen.cpp b/clang/test/OpenMP/teams_distribute_parallel_for_simd_dist_schedule_codegen.cpp index c2226bc9e75d7c99ac9f9d9d3af2c9fcd5c78254..d3777e81047ca0bdfae179d438146458532745a2 100644 --- a/clang/test/OpenMP/teams_distribute_parallel_for_simd_dist_schedule_codegen.cpp +++ b/clang/test/OpenMP/teams_distribute_parallel_for_simd_dist_schedule_codegen.cpp @@ -461,7 +461,7 @@ int main (int argc, char **argv) { // CHECK1: omp.inner.for.end: // CHECK1-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK1: omp.loop.exit: -// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP4]]) +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP4]]) // CHECK1-NEXT: [[TMP13:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK1-NEXT: [[TMP14:%.*]] = icmp ne i32 [[TMP13]], 0 // CHECK1-NEXT: br i1 [[TMP14]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -626,7 +626,7 @@ int main (int argc, char **argv) { // CHECK1: omp.inner.for.end: // CHECK1-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK1: omp.loop.exit: -// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP4]]) +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP4]]) // CHECK1-NEXT: [[TMP13:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK1-NEXT: [[TMP14:%.*]] = icmp ne i32 [[TMP13]], 0 // CHECK1-NEXT: br i1 [[TMP14]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -811,7 +811,7 @@ int main (int argc, char **argv) { // CHECK1: omp.inner.for.end: // CHECK1-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK1: omp.loop.exit: -// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP4]]) +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP4]]) // CHECK1-NEXT: [[TMP13:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK1-NEXT: [[TMP14:%.*]] = icmp ne i32 [[TMP13]], 0 // CHECK1-NEXT: br i1 [[TMP14]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -1132,7 +1132,7 @@ int main (int argc, char **argv) { // CHECK3: omp.inner.for.end: // CHECK3-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK3: omp.loop.exit: -// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP4]]) +// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP4]]) // CHECK3-NEXT: [[TMP13:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK3-NEXT: [[TMP14:%.*]] = icmp ne i32 [[TMP13]], 0 // CHECK3-NEXT: br i1 [[TMP14]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -1292,7 +1292,7 @@ int main (int argc, char **argv) { // CHECK3: omp.inner.for.end: // CHECK3-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK3: omp.loop.exit: -// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP4]]) +// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP4]]) // CHECK3-NEXT: [[TMP13:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK3-NEXT: [[TMP14:%.*]] = icmp ne i32 [[TMP13]], 0 // CHECK3-NEXT: br i1 [[TMP14]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -1472,7 +1472,7 @@ int main (int argc, char **argv) { // CHECK3: omp.inner.for.end: // CHECK3-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK3: omp.loop.exit: -// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP4]]) +// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP4]]) // CHECK3-NEXT: [[TMP13:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK3-NEXT: [[TMP14:%.*]] = icmp ne i32 [[TMP13]], 0 // CHECK3-NEXT: br i1 [[TMP14]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -2227,7 +2227,7 @@ int main (int argc, char **argv) { // CHECK9: omp.loop.exit: // CHECK9-NEXT: [[TMP21:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 // CHECK9-NEXT: [[TMP22:%.*]] = load i32, ptr [[TMP21]], align 4 -// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP22]]) +// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP22]]) // CHECK9-NEXT: [[TMP23:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK9-NEXT: [[TMP24:%.*]] = icmp ne i32 [[TMP23]], 0 // CHECK9-NEXT: br i1 [[TMP24]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -2462,7 +2462,7 @@ int main (int argc, char **argv) { // CHECK9: omp.loop.exit: // CHECK9-NEXT: [[TMP21:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 // CHECK9-NEXT: [[TMP22:%.*]] = load i32, ptr [[TMP21]], align 4 -// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP22]]) +// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP22]]) // CHECK9-NEXT: [[TMP23:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK9-NEXT: [[TMP24:%.*]] = icmp ne i32 [[TMP23]], 0 // CHECK9-NEXT: br i1 [[TMP24]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -2739,7 +2739,7 @@ int main (int argc, char **argv) { // CHECK9: omp.loop.exit: // CHECK9-NEXT: [[TMP21:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 // CHECK9-NEXT: [[TMP22:%.*]] = load i32, ptr [[TMP21]], align 4 -// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP22]]) +// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP22]]) // CHECK9-NEXT: [[TMP23:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK9-NEXT: [[TMP24:%.*]] = icmp ne i32 [[TMP23]], 0 // CHECK9-NEXT: br i1 [[TMP24]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -3069,7 +3069,7 @@ int main (int argc, char **argv) { // CHECK9: omp.inner.for.end: // CHECK9-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK9: omp.loop.exit: -// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP4]]) +// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP4]]) // CHECK9-NEXT: [[TMP13:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK9-NEXT: [[TMP14:%.*]] = icmp ne i32 [[TMP13]], 0 // CHECK9-NEXT: br i1 [[TMP14]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -3233,7 +3233,7 @@ int main (int argc, char **argv) { // CHECK9: omp.inner.for.end: // CHECK9-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK9: omp.loop.exit: -// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP4]]) +// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP4]]) // CHECK9-NEXT: [[TMP13:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK9-NEXT: [[TMP14:%.*]] = icmp ne i32 [[TMP13]], 0 // CHECK9-NEXT: br i1 [[TMP14]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -3435,7 +3435,7 @@ int main (int argc, char **argv) { // CHECK9: omp.inner.for.end: // CHECK9-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK9: omp.loop.exit: -// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP4]]) +// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP4]]) // CHECK9-NEXT: [[TMP13:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK9-NEXT: [[TMP14:%.*]] = icmp ne i32 [[TMP13]], 0 // CHECK9-NEXT: br i1 [[TMP14]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -3940,7 +3940,7 @@ int main (int argc, char **argv) { // CHECK11: omp.loop.exit: // CHECK11-NEXT: [[TMP21:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 4 // CHECK11-NEXT: [[TMP22:%.*]] = load i32, ptr [[TMP21]], align 4 -// CHECK11-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP22]]) +// CHECK11-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP22]]) // CHECK11-NEXT: [[TMP23:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK11-NEXT: [[TMP24:%.*]] = icmp ne i32 [[TMP23]], 0 // CHECK11-NEXT: br i1 [[TMP24]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -4170,7 +4170,7 @@ int main (int argc, char **argv) { // CHECK11: omp.loop.exit: // CHECK11-NEXT: [[TMP21:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 4 // CHECK11-NEXT: [[TMP22:%.*]] = load i32, ptr [[TMP21]], align 4 -// CHECK11-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP22]]) +// CHECK11-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP22]]) // CHECK11-NEXT: [[TMP23:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK11-NEXT: [[TMP24:%.*]] = icmp ne i32 [[TMP23]], 0 // CHECK11-NEXT: br i1 [[TMP24]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -4442,7 +4442,7 @@ int main (int argc, char **argv) { // CHECK11: omp.loop.exit: // CHECK11-NEXT: [[TMP21:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 4 // CHECK11-NEXT: [[TMP22:%.*]] = load i32, ptr [[TMP21]], align 4 -// CHECK11-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP22]]) +// CHECK11-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP22]]) // CHECK11-NEXT: [[TMP23:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK11-NEXT: [[TMP24:%.*]] = icmp ne i32 [[TMP23]], 0 // CHECK11-NEXT: br i1 [[TMP24]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -4767,7 +4767,7 @@ int main (int argc, char **argv) { // CHECK11: omp.inner.for.end: // CHECK11-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK11: omp.loop.exit: -// CHECK11-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP4]]) +// CHECK11-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP4]]) // CHECK11-NEXT: [[TMP13:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK11-NEXT: [[TMP14:%.*]] = icmp ne i32 [[TMP13]], 0 // CHECK11-NEXT: br i1 [[TMP14]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -4926,7 +4926,7 @@ int main (int argc, char **argv) { // CHECK11: omp.inner.for.end: // CHECK11-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK11: omp.loop.exit: -// CHECK11-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP4]]) +// CHECK11-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP4]]) // CHECK11-NEXT: [[TMP13:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK11-NEXT: [[TMP14:%.*]] = icmp ne i32 [[TMP13]], 0 // CHECK11-NEXT: br i1 [[TMP14]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -5123,7 +5123,7 @@ int main (int argc, char **argv) { // CHECK11: omp.inner.for.end: // CHECK11-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK11: omp.loop.exit: -// CHECK11-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP4]]) +// CHECK11-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP4]]) // CHECK11-NEXT: [[TMP13:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK11-NEXT: [[TMP14:%.*]] = icmp ne i32 [[TMP13]], 0 // CHECK11-NEXT: br i1 [[TMP14]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] diff --git a/clang/test/OpenMP/teams_distribute_parallel_for_simd_firstprivate_codegen.cpp b/clang/test/OpenMP/teams_distribute_parallel_for_simd_firstprivate_codegen.cpp index 4c9299e6cb9d282ded23b9a7e801d39dd93ec3bd..4f87d40e58f683f1a572d61289d7052fff795d3a 100644 --- a/clang/test/OpenMP/teams_distribute_parallel_for_simd_firstprivate_codegen.cpp +++ b/clang/test/OpenMP/teams_distribute_parallel_for_simd_firstprivate_codegen.cpp @@ -689,7 +689,7 @@ int main() { // CHECK1: omp.loop.exit: // CHECK1-NEXT: [[TMP20:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 // CHECK1-NEXT: [[TMP21:%.*]] = load i32, ptr [[TMP20]], align 4 -// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP21]]) +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP21]]) // CHECK1-NEXT: [[TMP22:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK1-NEXT: [[TMP23:%.*]] = icmp ne i32 [[TMP22]], 0 // CHECK1-NEXT: br i1 [[TMP23]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -1172,7 +1172,7 @@ int main() { // CHECK1: omp.loop.exit: // CHECK1-NEXT: [[TMP20:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 // CHECK1-NEXT: [[TMP21:%.*]] = load i32, ptr [[TMP20]], align 4 -// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP21]]) +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP21]]) // CHECK1-NEXT: [[TMP22:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK1-NEXT: [[TMP23:%.*]] = icmp ne i32 [[TMP22]], 0 // CHECK1-NEXT: br i1 [[TMP23]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -1775,7 +1775,7 @@ int main() { // CHECK3: omp.loop.exit: // CHECK3-NEXT: [[TMP20:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 4 // CHECK3-NEXT: [[TMP21:%.*]] = load i32, ptr [[TMP20]], align 4 -// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP21]]) +// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP21]]) // CHECK3-NEXT: [[TMP22:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK3-NEXT: [[TMP23:%.*]] = icmp ne i32 [[TMP22]], 0 // CHECK3-NEXT: br i1 [[TMP23]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -2252,7 +2252,7 @@ int main() { // CHECK3: omp.loop.exit: // CHECK3-NEXT: [[TMP20:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 4 // CHECK3-NEXT: [[TMP21:%.*]] = load i32, ptr [[TMP20]], align 4 -// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP21]]) +// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP21]]) // CHECK3-NEXT: [[TMP22:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK3-NEXT: [[TMP23:%.*]] = icmp ne i32 [[TMP22]], 0 // CHECK3-NEXT: br i1 [[TMP23]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -3323,7 +3323,7 @@ int main() { // CHECK9: omp.inner.for.end: // CHECK9-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK9: omp.loop.exit: -// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP3]]) +// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) // CHECK9-NEXT: [[TMP16:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK9-NEXT: [[TMP17:%.*]] = icmp ne i32 [[TMP16]], 0 // CHECK9-NEXT: br i1 [[TMP17]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] diff --git a/clang/test/OpenMP/teams_distribute_parallel_for_simd_if_codegen.cpp b/clang/test/OpenMP/teams_distribute_parallel_for_simd_if_codegen.cpp index 275058b195e375bd2c37428c1e2f8758dcbdd8c2..7c86b180ec674bd347fc090086ee42536fe8cf7f 100644 --- a/clang/test/OpenMP/teams_distribute_parallel_for_simd_if_codegen.cpp +++ b/clang/test/OpenMP/teams_distribute_parallel_for_simd_if_codegen.cpp @@ -326,7 +326,7 @@ int main() { // CHECK1: omp.inner.for.end: // CHECK1-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK1: omp.loop.exit: -// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP3]]) +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) // CHECK1-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK1-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 // CHECK1-NEXT: br i1 [[TMP12]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -483,7 +483,7 @@ int main() { // CHECK1: omp.inner.for.end: // CHECK1-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK1: omp.loop.exit: -// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP3]]) +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) // CHECK1-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK1-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 // CHECK1-NEXT: br i1 [[TMP12]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -774,7 +774,7 @@ int main() { // CHECK1: omp.inner.for.end: // CHECK1-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK1: omp.loop.exit: -// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP3]]) +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) // CHECK1-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK1-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 // CHECK1-NEXT: br i1 [[TMP12]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -931,7 +931,7 @@ int main() { // CHECK1: omp.inner.for.end: // CHECK1-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK1: omp.loop.exit: -// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP3]]) +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) // CHECK1-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK1-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 // CHECK1-NEXT: br i1 [[TMP12]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -1112,7 +1112,7 @@ int main() { // CHECK1: omp.inner.for.end: // CHECK1-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK1: omp.loop.exit: -// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP3]]) +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) // CHECK1-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK1-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 // CHECK1-NEXT: br i1 [[TMP12]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -1401,7 +1401,7 @@ int main() { // CHECK1: omp.inner.for.end: // CHECK1-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK1: omp.loop.exit: -// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP3]]) +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) // CHECK1-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK1-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 // CHECK1-NEXT: br i1 [[TMP12]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -1558,7 +1558,7 @@ int main() { // CHECK1: omp.inner.for.end: // CHECK1-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK1: omp.loop.exit: -// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP3]]) +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) // CHECK1-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK1-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 // CHECK1-NEXT: br i1 [[TMP12]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -1739,7 +1739,7 @@ int main() { // CHECK1: omp.inner.for.end: // CHECK1-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK1: omp.loop.exit: -// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP3]]) +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) // CHECK1-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK1-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 // CHECK1-NEXT: br i1 [[TMP12]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -1966,7 +1966,7 @@ int main() { // CHECK3: omp.inner.for.end: // CHECK3-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK3: omp.loop.exit: -// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP3]]) +// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) // CHECK3-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK3-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 // CHECK3-NEXT: br i1 [[TMP12]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -2123,7 +2123,7 @@ int main() { // CHECK3: omp.inner.for.end: // CHECK3-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK3: omp.loop.exit: -// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP3]]) +// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) // CHECK3-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK3-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 // CHECK3-NEXT: br i1 [[TMP12]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -2414,7 +2414,7 @@ int main() { // CHECK3: omp.inner.for.end: // CHECK3-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK3: omp.loop.exit: -// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP3]]) +// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) // CHECK3-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK3-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 // CHECK3-NEXT: br i1 [[TMP12]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -2571,7 +2571,7 @@ int main() { // CHECK3: omp.inner.for.end: // CHECK3-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK3: omp.loop.exit: -// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP3]]) +// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) // CHECK3-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK3-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 // CHECK3-NEXT: br i1 [[TMP12]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -2855,7 +2855,7 @@ int main() { // CHECK3: omp.loop.exit: // CHECK3-NEXT: [[TMP21:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 // CHECK3-NEXT: [[TMP22:%.*]] = load i32, ptr [[TMP21]], align 4 -// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP22]]) +// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP22]]) // CHECK3-NEXT: [[TMP23:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK3-NEXT: [[TMP24:%.*]] = icmp ne i32 [[TMP23]], 0 // CHECK3-NEXT: br i1 [[TMP24]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -2982,7 +2982,7 @@ int main() { // CHECK3: omp.loop.exit: // CHECK3-NEXT: [[TMP21:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 // CHECK3-NEXT: [[TMP22:%.*]] = load i32, ptr [[TMP21]], align 4 -// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP22]]) +// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP22]]) // CHECK3-NEXT: [[TMP23:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK3-NEXT: [[TMP24:%.*]] = icmp ne i32 [[TMP23]], 0 // CHECK3-NEXT: br i1 [[TMP24]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -3271,7 +3271,7 @@ int main() { // CHECK3: omp.inner.for.end: // CHECK3-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK3: omp.loop.exit: -// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP3]]) +// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) // CHECK3-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK3-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 // CHECK3-NEXT: br i1 [[TMP12]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -3428,7 +3428,7 @@ int main() { // CHECK3: omp.inner.for.end: // CHECK3-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK3: omp.loop.exit: -// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP3]]) +// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) // CHECK3-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK3-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 // CHECK3-NEXT: br i1 [[TMP12]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -3609,7 +3609,7 @@ int main() { // CHECK3: omp.inner.for.end: // CHECK3-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK3: omp.loop.exit: -// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP3]]) +// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) // CHECK3-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK3-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 // CHECK3-NEXT: br i1 [[TMP12]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -4427,7 +4427,7 @@ int main() { // CHECK9: omp.inner.for.end: // CHECK9-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK9: omp.loop.exit: -// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP3]]) +// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) // CHECK9-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK9-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 // CHECK9-NEXT: br i1 [[TMP12]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -4584,7 +4584,7 @@ int main() { // CHECK9: omp.inner.for.end: // CHECK9-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK9: omp.loop.exit: -// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP3]]) +// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) // CHECK9-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK9-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 // CHECK9-NEXT: br i1 [[TMP12]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -4875,7 +4875,7 @@ int main() { // CHECK9: omp.inner.for.end: // CHECK9-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK9: omp.loop.exit: -// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP3]]) +// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) // CHECK9-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK9-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 // CHECK9-NEXT: br i1 [[TMP12]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -5032,7 +5032,7 @@ int main() { // CHECK9: omp.inner.for.end: // CHECK9-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK9: omp.loop.exit: -// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP3]]) +// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) // CHECK9-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK9-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 // CHECK9-NEXT: br i1 [[TMP12]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -5213,7 +5213,7 @@ int main() { // CHECK9: omp.inner.for.end: // CHECK9-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK9: omp.loop.exit: -// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP3]]) +// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) // CHECK9-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK9-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 // CHECK9-NEXT: br i1 [[TMP12]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -5502,7 +5502,7 @@ int main() { // CHECK9: omp.inner.for.end: // CHECK9-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK9: omp.loop.exit: -// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP3]]) +// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) // CHECK9-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK9-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 // CHECK9-NEXT: br i1 [[TMP12]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -5659,7 +5659,7 @@ int main() { // CHECK9: omp.inner.for.end: // CHECK9-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK9: omp.loop.exit: -// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP3]]) +// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) // CHECK9-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK9-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 // CHECK9-NEXT: br i1 [[TMP12]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -5840,7 +5840,7 @@ int main() { // CHECK9: omp.inner.for.end: // CHECK9-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK9: omp.loop.exit: -// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP3]]) +// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) // CHECK9-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK9-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 // CHECK9-NEXT: br i1 [[TMP12]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -6067,7 +6067,7 @@ int main() { // CHECK11: omp.inner.for.end: // CHECK11-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK11: omp.loop.exit: -// CHECK11-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP3]]) +// CHECK11-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) // CHECK11-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK11-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 // CHECK11-NEXT: br i1 [[TMP12]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -6224,7 +6224,7 @@ int main() { // CHECK11: omp.inner.for.end: // CHECK11-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK11: omp.loop.exit: -// CHECK11-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP3]]) +// CHECK11-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) // CHECK11-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK11-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 // CHECK11-NEXT: br i1 [[TMP12]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -6515,7 +6515,7 @@ int main() { // CHECK11: omp.inner.for.end: // CHECK11-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK11: omp.loop.exit: -// CHECK11-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP3]]) +// CHECK11-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) // CHECK11-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK11-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 // CHECK11-NEXT: br i1 [[TMP12]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -6672,7 +6672,7 @@ int main() { // CHECK11: omp.inner.for.end: // CHECK11-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK11: omp.loop.exit: -// CHECK11-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP3]]) +// CHECK11-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) // CHECK11-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK11-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 // CHECK11-NEXT: br i1 [[TMP12]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -6956,7 +6956,7 @@ int main() { // CHECK11: omp.loop.exit: // CHECK11-NEXT: [[TMP21:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 // CHECK11-NEXT: [[TMP22:%.*]] = load i32, ptr [[TMP21]], align 4 -// CHECK11-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP22]]) +// CHECK11-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP22]]) // CHECK11-NEXT: [[TMP23:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK11-NEXT: [[TMP24:%.*]] = icmp ne i32 [[TMP23]], 0 // CHECK11-NEXT: br i1 [[TMP24]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -7083,7 +7083,7 @@ int main() { // CHECK11: omp.loop.exit: // CHECK11-NEXT: [[TMP21:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 // CHECK11-NEXT: [[TMP22:%.*]] = load i32, ptr [[TMP21]], align 4 -// CHECK11-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP22]]) +// CHECK11-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP22]]) // CHECK11-NEXT: [[TMP23:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK11-NEXT: [[TMP24:%.*]] = icmp ne i32 [[TMP23]], 0 // CHECK11-NEXT: br i1 [[TMP24]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -7372,7 +7372,7 @@ int main() { // CHECK11: omp.inner.for.end: // CHECK11-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK11: omp.loop.exit: -// CHECK11-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP3]]) +// CHECK11-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) // CHECK11-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK11-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 // CHECK11-NEXT: br i1 [[TMP12]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -7529,7 +7529,7 @@ int main() { // CHECK11: omp.inner.for.end: // CHECK11-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK11: omp.loop.exit: -// CHECK11-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP3]]) +// CHECK11-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) // CHECK11-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK11-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 // CHECK11-NEXT: br i1 [[TMP12]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -7710,7 +7710,7 @@ int main() { // CHECK11: omp.inner.for.end: // CHECK11-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK11: omp.loop.exit: -// CHECK11-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP3]]) +// CHECK11-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) // CHECK11-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK11-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 // CHECK11-NEXT: br i1 [[TMP12]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] diff --git a/clang/test/OpenMP/teams_distribute_parallel_for_simd_lastprivate_codegen.cpp b/clang/test/OpenMP/teams_distribute_parallel_for_simd_lastprivate_codegen.cpp index fe2001842c26858eb799f3c684b8295d9a59123e..268298c14801cdd6ab3b2e78f4fb9339a3533a0a 100644 --- a/clang/test/OpenMP/teams_distribute_parallel_for_simd_lastprivate_codegen.cpp +++ b/clang/test/OpenMP/teams_distribute_parallel_for_simd_lastprivate_codegen.cpp @@ -427,7 +427,7 @@ int main() { // CHECK1: omp.inner.for.end: // CHECK1-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK1: omp.loop.exit: -// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP8]]) +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP8]]) // CHECK1-NEXT: [[TMP22:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK1-NEXT: [[TMP23:%.*]] = icmp ne i32 [[TMP22]], 0 // CHECK1-NEXT: br i1 [[TMP23]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -703,7 +703,7 @@ int main() { // CHECK3: omp.inner.for.end: // CHECK3-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK3: omp.loop.exit: -// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP8]]) +// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP8]]) // CHECK3-NEXT: [[TMP22:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK3-NEXT: [[TMP23:%.*]] = icmp ne i32 [[TMP22]], 0 // CHECK3-NEXT: br i1 [[TMP23]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -1195,7 +1195,7 @@ int main() { // CHECK9: omp.loop.exit: // CHECK9-NEXT: [[TMP21:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 // CHECK9-NEXT: [[TMP22:%.*]] = load i32, ptr [[TMP21]], align 4 -// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP22]]) +// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP22]]) // CHECK9-NEXT: [[TMP23:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK9-NEXT: [[TMP24:%.*]] = icmp ne i32 [[TMP23]], 0 // CHECK9-NEXT: br i1 [[TMP24]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -1689,7 +1689,7 @@ int main() { // CHECK9: omp.loop.exit: // CHECK9-NEXT: [[TMP20:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 // CHECK9-NEXT: [[TMP21:%.*]] = load i32, ptr [[TMP20]], align 4 -// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP21]]) +// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP21]]) // CHECK9-NEXT: [[TMP22:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK9-NEXT: [[TMP23:%.*]] = icmp ne i32 [[TMP22]], 0 // CHECK9-NEXT: br i1 [[TMP23]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -2203,7 +2203,7 @@ int main() { // CHECK11: omp.loop.exit: // CHECK11-NEXT: [[TMP21:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 4 // CHECK11-NEXT: [[TMP22:%.*]] = load i32, ptr [[TMP21]], align 4 -// CHECK11-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP22]]) +// CHECK11-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP22]]) // CHECK11-NEXT: [[TMP23:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK11-NEXT: [[TMP24:%.*]] = icmp ne i32 [[TMP23]], 0 // CHECK11-NEXT: br i1 [[TMP24]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -2691,7 +2691,7 @@ int main() { // CHECK11: omp.loop.exit: // CHECK11-NEXT: [[TMP20:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 4 // CHECK11-NEXT: [[TMP21:%.*]] = load i32, ptr [[TMP20]], align 4 -// CHECK11-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP21]]) +// CHECK11-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP21]]) // CHECK11-NEXT: [[TMP22:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK11-NEXT: [[TMP23:%.*]] = icmp ne i32 [[TMP22]], 0 // CHECK11-NEXT: br i1 [[TMP23]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] diff --git a/clang/test/OpenMP/teams_distribute_parallel_for_simd_num_threads_codegen.cpp b/clang/test/OpenMP/teams_distribute_parallel_for_simd_num_threads_codegen.cpp index 49f57a000d3ff58e596c432b40fc8158d49c12b3..fa8bcf65b8fb63d87dd582a92d43c8c714a1f271 100644 --- a/clang/test/OpenMP/teams_distribute_parallel_for_simd_num_threads_codegen.cpp +++ b/clang/test/OpenMP/teams_distribute_parallel_for_simd_num_threads_codegen.cpp @@ -380,7 +380,7 @@ int main() { // CHECK1: omp.inner.for.end: // CHECK1-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK1: omp.loop.exit: -// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP3]]) +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) // CHECK1-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK1-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 // CHECK1-NEXT: br i1 [[TMP12]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -561,7 +561,7 @@ int main() { // CHECK1: omp.inner.for.end: // CHECK1-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK1: omp.loop.exit: -// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP3]]) +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) // CHECK1-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK1-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 // CHECK1-NEXT: br i1 [[TMP12]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -924,7 +924,7 @@ int main() { // CHECK1: omp.inner.for.end: // CHECK1-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK1: omp.loop.exit: -// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP3]]) +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) // CHECK1-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK1-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 // CHECK1-NEXT: br i1 [[TMP12]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -1085,7 +1085,7 @@ int main() { // CHECK1: omp.inner.for.end: // CHECK1-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK1: omp.loop.exit: -// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP3]]) +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) // CHECK1-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK1-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 // CHECK1-NEXT: br i1 [[TMP12]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -1246,7 +1246,7 @@ int main() { // CHECK1: omp.inner.for.end: // CHECK1-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK1: omp.loop.exit: -// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP3]]) +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) // CHECK1-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK1-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 // CHECK1-NEXT: br i1 [[TMP12]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -1429,7 +1429,7 @@ int main() { // CHECK1: omp.inner.for.end: // CHECK1-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK1: omp.loop.exit: -// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP3]]) +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) // CHECK1-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK1-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 // CHECK1-NEXT: br i1 [[TMP12]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -2100,7 +2100,7 @@ int main() { // CHECK5: omp.inner.for.end: // CHECK5-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK5: omp.loop.exit: -// CHECK5-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP3]]) +// CHECK5-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) // CHECK5-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK5-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 // CHECK5-NEXT: br i1 [[TMP12]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -2281,7 +2281,7 @@ int main() { // CHECK5: omp.inner.for.end: // CHECK5-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK5: omp.loop.exit: -// CHECK5-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP3]]) +// CHECK5-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) // CHECK5-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK5-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 // CHECK5-NEXT: br i1 [[TMP12]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -2635,7 +2635,7 @@ int main() { // CHECK5: omp.inner.for.end: // CHECK5-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK5: omp.loop.exit: -// CHECK5-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP3]]) +// CHECK5-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) // CHECK5-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK5-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 // CHECK5-NEXT: br i1 [[TMP12]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -2796,7 +2796,7 @@ int main() { // CHECK5: omp.inner.for.end: // CHECK5-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK5: omp.loop.exit: -// CHECK5-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP3]]) +// CHECK5-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) // CHECK5-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK5-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 // CHECK5-NEXT: br i1 [[TMP12]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -2957,7 +2957,7 @@ int main() { // CHECK5: omp.inner.for.end: // CHECK5-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK5: omp.loop.exit: -// CHECK5-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP3]]) +// CHECK5-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) // CHECK5-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK5-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 // CHECK5-NEXT: br i1 [[TMP12]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -3140,7 +3140,7 @@ int main() { // CHECK5: omp.inner.for.end: // CHECK5-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK5: omp.loop.exit: -// CHECK5-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP3]]) +// CHECK5-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) // CHECK5-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK5-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 // CHECK5-NEXT: br i1 [[TMP12]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] diff --git a/clang/test/OpenMP/teams_distribute_parallel_for_simd_private_codegen.cpp b/clang/test/OpenMP/teams_distribute_parallel_for_simd_private_codegen.cpp index 7721daf4aa32bf87547e125b8d646855b514b7a2..03bee1dbb63c099b9374580b580eb3cf07705807 100644 --- a/clang/test/OpenMP/teams_distribute_parallel_for_simd_private_codegen.cpp +++ b/clang/test/OpenMP/teams_distribute_parallel_for_simd_private_codegen.cpp @@ -505,7 +505,7 @@ int main() { // CHECK1: omp.loop.exit: // CHECK1-NEXT: [[TMP16:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 // CHECK1-NEXT: [[TMP17:%.*]] = load i32, ptr [[TMP16]], align 4 -// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP17]]) +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP17]]) // CHECK1-NEXT: [[TMP18:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK1-NEXT: [[TMP19:%.*]] = icmp ne i32 [[TMP18]], 0 // CHECK1-NEXT: br i1 [[TMP19]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -827,7 +827,7 @@ int main() { // CHECK1: omp.loop.exit: // CHECK1-NEXT: [[TMP15:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 // CHECK1-NEXT: [[TMP16:%.*]] = load i32, ptr [[TMP15]], align 4 -// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP16]]) +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP16]]) // CHECK1-NEXT: [[TMP17:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK1-NEXT: [[TMP18:%.*]] = icmp ne i32 [[TMP17]], 0 // CHECK1-NEXT: br i1 [[TMP18]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -1260,7 +1260,7 @@ int main() { // CHECK3: omp.loop.exit: // CHECK3-NEXT: [[TMP16:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 4 // CHECK3-NEXT: [[TMP17:%.*]] = load i32, ptr [[TMP16]], align 4 -// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP17]]) +// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP17]]) // CHECK3-NEXT: [[TMP18:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK3-NEXT: [[TMP19:%.*]] = icmp ne i32 [[TMP18]], 0 // CHECK3-NEXT: br i1 [[TMP19]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -1576,7 +1576,7 @@ int main() { // CHECK3: omp.loop.exit: // CHECK3-NEXT: [[TMP15:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 4 // CHECK3-NEXT: [[TMP16:%.*]] = load i32, ptr [[TMP15]], align 4 -// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP16]]) +// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP16]]) // CHECK3-NEXT: [[TMP17:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK3-NEXT: [[TMP18:%.*]] = icmp ne i32 [[TMP17]], 0 // CHECK3-NEXT: br i1 [[TMP18]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -2700,7 +2700,7 @@ int main() { // CHECK9: omp.inner.for.end: // CHECK9-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK9: omp.loop.exit: -// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP3]]) +// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) // CHECK9-NEXT: [[TMP16:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK9-NEXT: [[TMP17:%.*]] = icmp ne i32 [[TMP16]], 0 // CHECK9-NEXT: br i1 [[TMP17]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] diff --git a/clang/test/OpenMP/teams_distribute_parallel_for_simd_proc_bind_codegen.cpp b/clang/test/OpenMP/teams_distribute_parallel_for_simd_proc_bind_codegen.cpp index 2a3abf176929bb11ae92db11d5a4ce6b4508db09..7d35ea305f92b57c9d323223780c46baaf2a6c28 100644 --- a/clang/test/OpenMP/teams_distribute_parallel_for_simd_proc_bind_codegen.cpp +++ b/clang/test/OpenMP/teams_distribute_parallel_for_simd_proc_bind_codegen.cpp @@ -272,7 +272,7 @@ int main() { // CHECK1: omp.inner.for.end: // CHECK1-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK1: omp.loop.exit: -// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP3]]) +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) // CHECK1-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK1-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 // CHECK1-NEXT: br i1 [[TMP12]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -424,7 +424,7 @@ int main() { // CHECK1: omp.inner.for.end: // CHECK1-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK1: omp.loop.exit: -// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP3]]) +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) // CHECK1-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK1-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 // CHECK1-NEXT: br i1 [[TMP12]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -617,7 +617,7 @@ int main() { // CHECK1: omp.inner.for.end: // CHECK1-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK1: omp.loop.exit: -// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP3]]) +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) // CHECK1-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK1-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 // CHECK1-NEXT: br i1 [[TMP12]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] diff --git a/clang/test/OpenMP/teams_distribute_parallel_for_simd_reduction_codegen.cpp b/clang/test/OpenMP/teams_distribute_parallel_for_simd_reduction_codegen.cpp index 8745dd9710f64696932dc67a75e24abfaa7a56c0..2dd1db48f0306bee4bc912e3d2e1115152eed1b2 100644 --- a/clang/test/OpenMP/teams_distribute_parallel_for_simd_reduction_codegen.cpp +++ b/clang/test/OpenMP/teams_distribute_parallel_for_simd_reduction_codegen.cpp @@ -333,7 +333,7 @@ int main() { // CHECK1: omp.inner.for.end: // CHECK1-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK1: omp.loop.exit: -// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP4]]) +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP4]]) // CHECK1-NEXT: [[TMP14:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK1-NEXT: [[TMP15:%.*]] = icmp ne i32 [[TMP14]], 0 // CHECK1-NEXT: br i1 [[TMP15]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -640,7 +640,7 @@ int main() { // CHECK1: omp.inner.for.end: // CHECK1-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK1: omp.loop.exit: -// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP4]]) +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP4]]) // CHECK1-NEXT: [[TMP14:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK1-NEXT: [[TMP15:%.*]] = icmp ne i32 [[TMP14]], 0 // CHECK1-NEXT: br i1 [[TMP15]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -942,7 +942,7 @@ int main() { // CHECK3: omp.inner.for.end: // CHECK3-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK3: omp.loop.exit: -// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP4]]) +// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP4]]) // CHECK3-NEXT: [[TMP14:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK3-NEXT: [[TMP15:%.*]] = icmp ne i32 [[TMP14]], 0 // CHECK3-NEXT: br i1 [[TMP15]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -1245,7 +1245,7 @@ int main() { // CHECK3: omp.inner.for.end: // CHECK3-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK3: omp.loop.exit: -// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP4]]) +// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP4]]) // CHECK3-NEXT: [[TMP14:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK3-NEXT: [[TMP15:%.*]] = icmp ne i32 [[TMP14]], 0 // CHECK3-NEXT: br i1 [[TMP15]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -1704,7 +1704,7 @@ int main() { // CHECK9: omp.inner.for.end: // CHECK9-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK9: omp.loop.exit: -// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP4]]) +// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP4]]) // CHECK9-NEXT: [[TMP15:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK9-NEXT: [[TMP16:%.*]] = icmp ne i32 [[TMP15]], 0 // CHECK9-NEXT: br i1 [[TMP16]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] diff --git a/clang/test/OpenMP/teams_distribute_parallel_for_simd_schedule_codegen.cpp b/clang/test/OpenMP/teams_distribute_parallel_for_simd_schedule_codegen.cpp index 0c0945a23d482bade7756fb6af729a3d93e0fcc7..ff70e71e0126739ce20d354fef168413432c623e 100644 --- a/clang/test/OpenMP/teams_distribute_parallel_for_simd_schedule_codegen.cpp +++ b/clang/test/OpenMP/teams_distribute_parallel_for_simd_schedule_codegen.cpp @@ -627,7 +627,7 @@ int main (int argc, char **argv) { // CHECK1: omp.inner.for.end: // CHECK1-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK1: omp.loop.exit: -// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP4]]) +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP4]]) // CHECK1-NEXT: [[TMP13:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK1-NEXT: [[TMP14:%.*]] = icmp ne i32 [[TMP13]], 0 // CHECK1-NEXT: br i1 [[TMP14]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -792,7 +792,7 @@ int main (int argc, char **argv) { // CHECK1: omp.inner.for.end: // CHECK1-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK1: omp.loop.exit: -// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP4]]) +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP4]]) // CHECK1-NEXT: [[TMP13:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK1-NEXT: [[TMP14:%.*]] = icmp ne i32 [[TMP13]], 0 // CHECK1-NEXT: br i1 [[TMP14]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -978,7 +978,7 @@ int main (int argc, char **argv) { // CHECK1-NEXT: store i32 [[ADD8]], ptr [[DOTOMP_UB]], align 4 // CHECK1-NEXT: br label [[OMP_DISPATCH_COND]] // CHECK1: omp.dispatch.end: -// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP4]]) +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP4]]) // CHECK1-NEXT: [[TMP21:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK1-NEXT: [[TMP22:%.*]] = icmp ne i32 [[TMP21]], 0 // CHECK1-NEXT: br i1 [[TMP22]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -1724,7 +1724,7 @@ int main (int argc, char **argv) { // CHECK2: omp.inner.for.end: // CHECK2-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK2: omp.loop.exit: -// CHECK2-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP4]]) +// CHECK2-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP4]]) // CHECK2-NEXT: [[TMP13:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK2-NEXT: [[TMP14:%.*]] = icmp ne i32 [[TMP13]], 0 // CHECK2-NEXT: br i1 [[TMP14]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -1889,7 +1889,7 @@ int main (int argc, char **argv) { // CHECK2: omp.inner.for.end: // CHECK2-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK2: omp.loop.exit: -// CHECK2-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP4]]) +// CHECK2-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP4]]) // CHECK2-NEXT: [[TMP13:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK2-NEXT: [[TMP14:%.*]] = icmp ne i32 [[TMP13]], 0 // CHECK2-NEXT: br i1 [[TMP14]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -2075,7 +2075,7 @@ int main (int argc, char **argv) { // CHECK2-NEXT: store i32 [[ADD8]], ptr [[DOTOMP_UB]], align 4 // CHECK2-NEXT: br label [[OMP_DISPATCH_COND]] // CHECK2: omp.dispatch.end: -// CHECK2-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP4]]) +// CHECK2-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP4]]) // CHECK2-NEXT: [[TMP21:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK2-NEXT: [[TMP22:%.*]] = icmp ne i32 [[TMP21]], 0 // CHECK2-NEXT: br i1 [[TMP22]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -2816,7 +2816,7 @@ int main (int argc, char **argv) { // CHECK5: omp.inner.for.end: // CHECK5-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK5: omp.loop.exit: -// CHECK5-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP4]]) +// CHECK5-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP4]]) // CHECK5-NEXT: [[TMP13:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK5-NEXT: [[TMP14:%.*]] = icmp ne i32 [[TMP13]], 0 // CHECK5-NEXT: br i1 [[TMP14]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -2976,7 +2976,7 @@ int main (int argc, char **argv) { // CHECK5: omp.inner.for.end: // CHECK5-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK5: omp.loop.exit: -// CHECK5-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP4]]) +// CHECK5-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP4]]) // CHECK5-NEXT: [[TMP13:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK5-NEXT: [[TMP14:%.*]] = icmp ne i32 [[TMP13]], 0 // CHECK5-NEXT: br i1 [[TMP14]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -3155,7 +3155,7 @@ int main (int argc, char **argv) { // CHECK5-NEXT: store i32 [[ADD5]], ptr [[DOTOMP_UB]], align 4 // CHECK5-NEXT: br label [[OMP_DISPATCH_COND]] // CHECK5: omp.dispatch.end: -// CHECK5-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP4]]) +// CHECK5-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP4]]) // CHECK5-NEXT: [[TMP21:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK5-NEXT: [[TMP22:%.*]] = icmp ne i32 [[TMP21]], 0 // CHECK5-NEXT: br i1 [[TMP22]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -3886,7 +3886,7 @@ int main (int argc, char **argv) { // CHECK6: omp.inner.for.end: // CHECK6-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK6: omp.loop.exit: -// CHECK6-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP4]]) +// CHECK6-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP4]]) // CHECK6-NEXT: [[TMP13:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK6-NEXT: [[TMP14:%.*]] = icmp ne i32 [[TMP13]], 0 // CHECK6-NEXT: br i1 [[TMP14]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -4046,7 +4046,7 @@ int main (int argc, char **argv) { // CHECK6: omp.inner.for.end: // CHECK6-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK6: omp.loop.exit: -// CHECK6-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP4]]) +// CHECK6-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP4]]) // CHECK6-NEXT: [[TMP13:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK6-NEXT: [[TMP14:%.*]] = icmp ne i32 [[TMP13]], 0 // CHECK6-NEXT: br i1 [[TMP14]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -4225,7 +4225,7 @@ int main (int argc, char **argv) { // CHECK6-NEXT: store i32 [[ADD5]], ptr [[DOTOMP_UB]], align 4 // CHECK6-NEXT: br label [[OMP_DISPATCH_COND]] // CHECK6: omp.dispatch.end: -// CHECK6-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP4]]) +// CHECK6-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP4]]) // CHECK6-NEXT: [[TMP21:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK6-NEXT: [[TMP22:%.*]] = icmp ne i32 [[TMP21]], 0 // CHECK6-NEXT: br i1 [[TMP22]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -5604,7 +5604,7 @@ int main (int argc, char **argv) { // CHECK13: omp.loop.exit: // CHECK13-NEXT: [[TMP21:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 // CHECK13-NEXT: [[TMP22:%.*]] = load i32, ptr [[TMP21]], align 4 -// CHECK13-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP22]]) +// CHECK13-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP22]]) // CHECK13-NEXT: [[TMP23:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK13-NEXT: [[TMP24:%.*]] = icmp ne i32 [[TMP23]], 0 // CHECK13-NEXT: br i1 [[TMP24]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -5839,7 +5839,7 @@ int main (int argc, char **argv) { // CHECK13: omp.loop.exit: // CHECK13-NEXT: [[TMP21:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 // CHECK13-NEXT: [[TMP22:%.*]] = load i32, ptr [[TMP21]], align 4 -// CHECK13-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP22]]) +// CHECK13-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP22]]) // CHECK13-NEXT: [[TMP23:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK13-NEXT: [[TMP24:%.*]] = icmp ne i32 [[TMP23]], 0 // CHECK13-NEXT: br i1 [[TMP24]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -6116,7 +6116,7 @@ int main (int argc, char **argv) { // CHECK13: omp.loop.exit: // CHECK13-NEXT: [[TMP21:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 // CHECK13-NEXT: [[TMP22:%.*]] = load i32, ptr [[TMP21]], align 4 -// CHECK13-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP22]]) +// CHECK13-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP22]]) // CHECK13-NEXT: [[TMP23:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK13-NEXT: [[TMP24:%.*]] = icmp ne i32 [[TMP23]], 0 // CHECK13-NEXT: br i1 [[TMP24]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -7028,7 +7028,7 @@ int main (int argc, char **argv) { // CHECK13: omp.inner.for.end: // CHECK13-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK13: omp.loop.exit: -// CHECK13-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP4]]) +// CHECK13-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP4]]) // CHECK13-NEXT: [[TMP13:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK13-NEXT: [[TMP14:%.*]] = icmp ne i32 [[TMP13]], 0 // CHECK13-NEXT: br i1 [[TMP14]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -7192,7 +7192,7 @@ int main (int argc, char **argv) { // CHECK13: omp.inner.for.end: // CHECK13-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK13: omp.loop.exit: -// CHECK13-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP4]]) +// CHECK13-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP4]]) // CHECK13-NEXT: [[TMP13:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK13-NEXT: [[TMP14:%.*]] = icmp ne i32 [[TMP13]], 0 // CHECK13-NEXT: br i1 [[TMP14]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -7395,7 +7395,7 @@ int main (int argc, char **argv) { // CHECK13-NEXT: store i32 [[ADD8]], ptr [[DOTOMP_UB]], align 4 // CHECK13-NEXT: br label [[OMP_DISPATCH_COND]] // CHECK13: omp.dispatch.end: -// CHECK13-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP5]]) +// CHECK13-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP5]]) // CHECK13-NEXT: [[TMP22:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK13-NEXT: [[TMP23:%.*]] = icmp ne i32 [[TMP22]], 0 // CHECK13-NEXT: br i1 [[TMP23]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -8415,7 +8415,7 @@ int main (int argc, char **argv) { // CHECK14: omp.loop.exit: // CHECK14-NEXT: [[TMP21:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 // CHECK14-NEXT: [[TMP22:%.*]] = load i32, ptr [[TMP21]], align 4 -// CHECK14-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP22]]) +// CHECK14-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP22]]) // CHECK14-NEXT: [[TMP23:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK14-NEXT: [[TMP24:%.*]] = icmp ne i32 [[TMP23]], 0 // CHECK14-NEXT: br i1 [[TMP24]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -8650,7 +8650,7 @@ int main (int argc, char **argv) { // CHECK14: omp.loop.exit: // CHECK14-NEXT: [[TMP21:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 // CHECK14-NEXT: [[TMP22:%.*]] = load i32, ptr [[TMP21]], align 4 -// CHECK14-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP22]]) +// CHECK14-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP22]]) // CHECK14-NEXT: [[TMP23:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK14-NEXT: [[TMP24:%.*]] = icmp ne i32 [[TMP23]], 0 // CHECK14-NEXT: br i1 [[TMP24]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -8927,7 +8927,7 @@ int main (int argc, char **argv) { // CHECK14: omp.loop.exit: // CHECK14-NEXT: [[TMP21:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 // CHECK14-NEXT: [[TMP22:%.*]] = load i32, ptr [[TMP21]], align 4 -// CHECK14-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP22]]) +// CHECK14-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP22]]) // CHECK14-NEXT: [[TMP23:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK14-NEXT: [[TMP24:%.*]] = icmp ne i32 [[TMP23]], 0 // CHECK14-NEXT: br i1 [[TMP24]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -9839,7 +9839,7 @@ int main (int argc, char **argv) { // CHECK14: omp.inner.for.end: // CHECK14-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK14: omp.loop.exit: -// CHECK14-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP4]]) +// CHECK14-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP4]]) // CHECK14-NEXT: [[TMP13:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK14-NEXT: [[TMP14:%.*]] = icmp ne i32 [[TMP13]], 0 // CHECK14-NEXT: br i1 [[TMP14]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -10003,7 +10003,7 @@ int main (int argc, char **argv) { // CHECK14: omp.inner.for.end: // CHECK14-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK14: omp.loop.exit: -// CHECK14-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP4]]) +// CHECK14-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP4]]) // CHECK14-NEXT: [[TMP13:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK14-NEXT: [[TMP14:%.*]] = icmp ne i32 [[TMP13]], 0 // CHECK14-NEXT: br i1 [[TMP14]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -10206,7 +10206,7 @@ int main (int argc, char **argv) { // CHECK14-NEXT: store i32 [[ADD8]], ptr [[DOTOMP_UB]], align 4 // CHECK14-NEXT: br label [[OMP_DISPATCH_COND]] // CHECK14: omp.dispatch.end: -// CHECK14-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP5]]) +// CHECK14-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP5]]) // CHECK14-NEXT: [[TMP22:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK14-NEXT: [[TMP23:%.*]] = icmp ne i32 [[TMP22]], 0 // CHECK14-NEXT: br i1 [[TMP23]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -11225,7 +11225,7 @@ int main (int argc, char **argv) { // CHECK17: omp.loop.exit: // CHECK17-NEXT: [[TMP21:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 4 // CHECK17-NEXT: [[TMP22:%.*]] = load i32, ptr [[TMP21]], align 4 -// CHECK17-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP22]]) +// CHECK17-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP22]]) // CHECK17-NEXT: [[TMP23:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK17-NEXT: [[TMP24:%.*]] = icmp ne i32 [[TMP23]], 0 // CHECK17-NEXT: br i1 [[TMP24]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -11455,7 +11455,7 @@ int main (int argc, char **argv) { // CHECK17: omp.loop.exit: // CHECK17-NEXT: [[TMP21:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 4 // CHECK17-NEXT: [[TMP22:%.*]] = load i32, ptr [[TMP21]], align 4 -// CHECK17-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP22]]) +// CHECK17-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP22]]) // CHECK17-NEXT: [[TMP23:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK17-NEXT: [[TMP24:%.*]] = icmp ne i32 [[TMP23]], 0 // CHECK17-NEXT: br i1 [[TMP24]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -11727,7 +11727,7 @@ int main (int argc, char **argv) { // CHECK17: omp.loop.exit: // CHECK17-NEXT: [[TMP21:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 4 // CHECK17-NEXT: [[TMP22:%.*]] = load i32, ptr [[TMP21]], align 4 -// CHECK17-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP22]]) +// CHECK17-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP22]]) // CHECK17-NEXT: [[TMP23:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK17-NEXT: [[TMP24:%.*]] = icmp ne i32 [[TMP23]], 0 // CHECK17-NEXT: br i1 [[TMP24]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -12624,7 +12624,7 @@ int main (int argc, char **argv) { // CHECK17: omp.inner.for.end: // CHECK17-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK17: omp.loop.exit: -// CHECK17-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP4]]) +// CHECK17-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP4]]) // CHECK17-NEXT: [[TMP13:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK17-NEXT: [[TMP14:%.*]] = icmp ne i32 [[TMP13]], 0 // CHECK17-NEXT: br i1 [[TMP14]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -12783,7 +12783,7 @@ int main (int argc, char **argv) { // CHECK17: omp.inner.for.end: // CHECK17-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK17: omp.loop.exit: -// CHECK17-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP4]]) +// CHECK17-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP4]]) // CHECK17-NEXT: [[TMP13:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK17-NEXT: [[TMP14:%.*]] = icmp ne i32 [[TMP13]], 0 // CHECK17-NEXT: br i1 [[TMP14]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -12979,7 +12979,7 @@ int main (int argc, char **argv) { // CHECK17-NEXT: store i32 [[ADD5]], ptr [[DOTOMP_UB]], align 4 // CHECK17-NEXT: br label [[OMP_DISPATCH_COND]] // CHECK17: omp.dispatch.end: -// CHECK17-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP5]]) +// CHECK17-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP5]]) // CHECK17-NEXT: [[TMP22:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK17-NEXT: [[TMP23:%.*]] = icmp ne i32 [[TMP22]], 0 // CHECK17-NEXT: br i1 [[TMP23]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -13988,7 +13988,7 @@ int main (int argc, char **argv) { // CHECK19: omp.loop.exit: // CHECK19-NEXT: [[TMP21:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 4 // CHECK19-NEXT: [[TMP22:%.*]] = load i32, ptr [[TMP21]], align 4 -// CHECK19-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP22]]) +// CHECK19-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP22]]) // CHECK19-NEXT: [[TMP23:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK19-NEXT: [[TMP24:%.*]] = icmp ne i32 [[TMP23]], 0 // CHECK19-NEXT: br i1 [[TMP24]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -14218,7 +14218,7 @@ int main (int argc, char **argv) { // CHECK19: omp.loop.exit: // CHECK19-NEXT: [[TMP21:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 4 // CHECK19-NEXT: [[TMP22:%.*]] = load i32, ptr [[TMP21]], align 4 -// CHECK19-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP22]]) +// CHECK19-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP22]]) // CHECK19-NEXT: [[TMP23:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK19-NEXT: [[TMP24:%.*]] = icmp ne i32 [[TMP23]], 0 // CHECK19-NEXT: br i1 [[TMP24]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -14490,7 +14490,7 @@ int main (int argc, char **argv) { // CHECK19: omp.loop.exit: // CHECK19-NEXT: [[TMP21:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 4 // CHECK19-NEXT: [[TMP22:%.*]] = load i32, ptr [[TMP21]], align 4 -// CHECK19-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP22]]) +// CHECK19-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP22]]) // CHECK19-NEXT: [[TMP23:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK19-NEXT: [[TMP24:%.*]] = icmp ne i32 [[TMP23]], 0 // CHECK19-NEXT: br i1 [[TMP24]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -15387,7 +15387,7 @@ int main (int argc, char **argv) { // CHECK19: omp.inner.for.end: // CHECK19-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK19: omp.loop.exit: -// CHECK19-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP4]]) +// CHECK19-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP4]]) // CHECK19-NEXT: [[TMP13:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK19-NEXT: [[TMP14:%.*]] = icmp ne i32 [[TMP13]], 0 // CHECK19-NEXT: br i1 [[TMP14]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -15546,7 +15546,7 @@ int main (int argc, char **argv) { // CHECK19: omp.inner.for.end: // CHECK19-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK19: omp.loop.exit: -// CHECK19-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP4]]) +// CHECK19-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP4]]) // CHECK19-NEXT: [[TMP13:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK19-NEXT: [[TMP14:%.*]] = icmp ne i32 [[TMP13]], 0 // CHECK19-NEXT: br i1 [[TMP14]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] @@ -15742,7 +15742,7 @@ int main (int argc, char **argv) { // CHECK19-NEXT: store i32 [[ADD5]], ptr [[DOTOMP_UB]], align 4 // CHECK19-NEXT: br label [[OMP_DISPATCH_COND]] // CHECK19: omp.dispatch.end: -// CHECK19-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP5]]) +// CHECK19-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP5]]) // CHECK19-NEXT: [[TMP22:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK19-NEXT: [[TMP23:%.*]] = icmp ne i32 [[TMP22]], 0 // CHECK19-NEXT: br i1 [[TMP23]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] diff --git a/clang/test/OpenMP/teams_generic_loop_codegen-1.cpp b/clang/test/OpenMP/teams_generic_loop_codegen-1.cpp index 041a28bd87e7c2707278177fcca03c4327f0fb2b..85a4dfea91a21aa5ba251d36fd9ae71d8555899b 100644 --- a/clang/test/OpenMP/teams_generic_loop_codegen-1.cpp +++ b/clang/test/OpenMP/teams_generic_loop_codegen-1.cpp @@ -451,7 +451,7 @@ int main (int argc, char **argv) { // CHECK1: omp.loop.exit: // CHECK1-NEXT: [[TMP21:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 // CHECK1-NEXT: [[TMP22:%.*]] = load i32, ptr [[TMP21]], align 4 -// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2:[0-9]+]], i32 [[TMP22]]) +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP22]]) // CHECK1-NEXT: br label [[OMP_PRECOND_END]] // CHECK1: omp.precond.end: // CHECK1-NEXT: ret void @@ -509,7 +509,7 @@ int main (int argc, char **argv) { // CHECK1-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK1-NEXT: [[TMP8:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 // CHECK1-NEXT: [[TMP9:%.*]] = load i32, ptr [[TMP8]], align 4 -// CHECK1-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB2]], i32 [[TMP9]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK1-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB2:[0-9]+]], i32 [[TMP9]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) // CHECK1-NEXT: [[TMP10:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 // CHECK1-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_1]], align 4 // CHECK1-NEXT: [[CMP5:%.*]] = icmp sgt i32 [[TMP10]], [[TMP11]] @@ -653,7 +653,7 @@ int main (int argc, char **argv) { // CHECK1: omp.loop.exit: // CHECK1-NEXT: [[TMP21:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 // CHECK1-NEXT: [[TMP22:%.*]] = load i32, ptr [[TMP21]], align 4 -// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP22]]) +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP22]]) // CHECK1-NEXT: br label [[OMP_PRECOND_END]] // CHECK1: omp.precond.end: // CHECK1-NEXT: ret void @@ -1036,7 +1036,7 @@ int main (int argc, char **argv) { // CHECK3: omp.loop.exit: // CHECK3-NEXT: [[TMP19:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 4 // CHECK3-NEXT: [[TMP20:%.*]] = load i32, ptr [[TMP19]], align 4 -// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2:[0-9]+]], i32 [[TMP20]]) +// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP20]]) // CHECK3-NEXT: br label [[OMP_PRECOND_END]] // CHECK3: omp.precond.end: // CHECK3-NEXT: ret void @@ -1092,7 +1092,7 @@ int main (int argc, char **argv) { // CHECK3-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK3-NEXT: [[TMP8:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 4 // CHECK3-NEXT: [[TMP9:%.*]] = load i32, ptr [[TMP8]], align 4 -// CHECK3-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB2]], i32 [[TMP9]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK3-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB2:[0-9]+]], i32 [[TMP9]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) // CHECK3-NEXT: [[TMP10:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 // CHECK3-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_1]], align 4 // CHECK3-NEXT: [[CMP4:%.*]] = icmp sgt i32 [[TMP10]], [[TMP11]] @@ -1233,7 +1233,7 @@ int main (int argc, char **argv) { // CHECK3: omp.loop.exit: // CHECK3-NEXT: [[TMP19:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 4 // CHECK3-NEXT: [[TMP20:%.*]] = load i32, ptr [[TMP19]], align 4 -// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP20]]) +// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP20]]) // CHECK3-NEXT: br label [[OMP_PRECOND_END]] // CHECK3: omp.precond.end: // CHECK3-NEXT: ret void @@ -1538,7 +1538,7 @@ int main (int argc, char **argv) { // CHECK9: omp.loop.exit: // CHECK9-NEXT: [[TMP22:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 // CHECK9-NEXT: [[TMP23:%.*]] = load i32, ptr [[TMP22]], align 4 -// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2:[0-9]+]], i32 [[TMP23]]) +// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP23]]) // CHECK9-NEXT: br label [[OMP_PRECOND_END]] // CHECK9: omp.precond.end: // CHECK9-NEXT: ret void @@ -1599,7 +1599,7 @@ int main (int argc, char **argv) { // CHECK9-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK9-NEXT: [[TMP9:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 // CHECK9-NEXT: [[TMP10:%.*]] = load i32, ptr [[TMP9]], align 4 -// CHECK9-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB2]], i32 [[TMP10]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK9-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB2:[0-9]+]], i32 [[TMP10]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) // CHECK9-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 // CHECK9-NEXT: [[TMP12:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_1]], align 4 // CHECK9-NEXT: [[CMP5:%.*]] = icmp sgt i32 [[TMP11]], [[TMP12]] @@ -1847,7 +1847,7 @@ int main (int argc, char **argv) { // CHECK11: omp.loop.exit: // CHECK11-NEXT: [[TMP20:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 4 // CHECK11-NEXT: [[TMP21:%.*]] = load i32, ptr [[TMP20]], align 4 -// CHECK11-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2:[0-9]+]], i32 [[TMP21]]) +// CHECK11-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP21]]) // CHECK11-NEXT: br label [[OMP_PRECOND_END]] // CHECK11: omp.precond.end: // CHECK11-NEXT: ret void @@ -1906,7 +1906,7 @@ int main (int argc, char **argv) { // CHECK11-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK11-NEXT: [[TMP9:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 4 // CHECK11-NEXT: [[TMP10:%.*]] = load i32, ptr [[TMP9]], align 4 -// CHECK11-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB2]], i32 [[TMP10]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK11-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB2:[0-9]+]], i32 [[TMP10]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) // CHECK11-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 // CHECK11-NEXT: [[TMP12:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_1]], align 4 // CHECK11-NEXT: [[CMP4:%.*]] = icmp sgt i32 [[TMP11]], [[TMP12]] @@ -2091,7 +2091,7 @@ int main (int argc, char **argv) { // CHECK17: omp.inner.for.end: // CHECK17-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK17: omp.loop.exit: -// CHECK17-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2:[0-9]+]], i32 [[TMP2]]) +// CHECK17-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP2]]) // CHECK17-NEXT: ret void // // @@ -2128,7 +2128,7 @@ int main (int argc, char **argv) { // CHECK17-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK17-NEXT: [[TMP3:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 // CHECK17-NEXT: [[TMP4:%.*]] = load i32, ptr [[TMP3]], align 4 -// CHECK17-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB2]], i32 [[TMP4]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK17-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB2:[0-9]+]], i32 [[TMP4]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) // CHECK17-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 // CHECK17-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP5]], 122 // CHECK17-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] @@ -2307,7 +2307,7 @@ int main (int argc, char **argv) { // CHECK19: omp.inner.for.end: // CHECK19-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK19: omp.loop.exit: -// CHECK19-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2:[0-9]+]], i32 [[TMP2]]) +// CHECK19-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP2]]) // CHECK19-NEXT: ret void // // @@ -2342,7 +2342,7 @@ int main (int argc, char **argv) { // CHECK19-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK19-NEXT: [[TMP3:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 4 // CHECK19-NEXT: [[TMP4:%.*]] = load i32, ptr [[TMP3]], align 4 -// CHECK19-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB2]], i32 [[TMP4]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK19-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB2:[0-9]+]], i32 [[TMP4]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) // CHECK19-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 // CHECK19-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP5]], 122 // CHECK19-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] @@ -2594,7 +2594,7 @@ int main (int argc, char **argv) { // CHECK25: omp.loop.exit: // CHECK25-NEXT: [[TMP22:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 // CHECK25-NEXT: [[TMP23:%.*]] = load i32, ptr [[TMP22]], align 4 -// CHECK25-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2:[0-9]+]], i32 [[TMP23]]) +// CHECK25-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP23]]) // CHECK25-NEXT: br label [[OMP_PRECOND_END]] // CHECK25: omp.precond.end: // CHECK25-NEXT: ret void @@ -2655,7 +2655,7 @@ int main (int argc, char **argv) { // CHECK25-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK25-NEXT: [[TMP9:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 // CHECK25-NEXT: [[TMP10:%.*]] = load i32, ptr [[TMP9]], align 4 -// CHECK25-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB2]], i32 [[TMP10]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK25-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB2:[0-9]+]], i32 [[TMP10]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) // CHECK25-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 // CHECK25-NEXT: [[TMP12:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_1]], align 4 // CHECK25-NEXT: [[CMP5:%.*]] = icmp sgt i32 [[TMP11]], [[TMP12]] @@ -2865,7 +2865,7 @@ int main (int argc, char **argv) { // CHECK25: omp.inner.for.end: // CHECK25-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK25: omp.loop.exit: -// CHECK25-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP2]]) +// CHECK25-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP2]]) // CHECK25-NEXT: ret void // // @@ -3152,7 +3152,7 @@ int main (int argc, char **argv) { // CHECK27: omp.loop.exit: // CHECK27-NEXT: [[TMP20:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 4 // CHECK27-NEXT: [[TMP21:%.*]] = load i32, ptr [[TMP20]], align 4 -// CHECK27-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2:[0-9]+]], i32 [[TMP21]]) +// CHECK27-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP21]]) // CHECK27-NEXT: br label [[OMP_PRECOND_END]] // CHECK27: omp.precond.end: // CHECK27-NEXT: ret void @@ -3211,7 +3211,7 @@ int main (int argc, char **argv) { // CHECK27-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK27-NEXT: [[TMP9:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 4 // CHECK27-NEXT: [[TMP10:%.*]] = load i32, ptr [[TMP9]], align 4 -// CHECK27-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB2]], i32 [[TMP10]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK27-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB2:[0-9]+]], i32 [[TMP10]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) // CHECK27-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 // CHECK27-NEXT: [[TMP12:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_1]], align 4 // CHECK27-NEXT: [[CMP4:%.*]] = icmp sgt i32 [[TMP11]], [[TMP12]] @@ -3418,7 +3418,7 @@ int main (int argc, char **argv) { // CHECK27: omp.inner.for.end: // CHECK27-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK27: omp.loop.exit: -// CHECK27-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP2]]) +// CHECK27-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP2]]) // CHECK27-NEXT: ret void // // diff --git a/clang/test/OpenMP/teams_generic_loop_codegen.cpp b/clang/test/OpenMP/teams_generic_loop_codegen.cpp index 2f3e70b1de582932aebf1e84bcd9cbe656a039ea..2499fbb6811c93b0e71035dbd3820e406e996840 100644 --- a/clang/test/OpenMP/teams_generic_loop_codegen.cpp +++ b/clang/test/OpenMP/teams_generic_loop_codegen.cpp @@ -113,7 +113,7 @@ int foo() { // IR: omp.loop.exit: // IR-NEXT: [[TMP16:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 // IR-NEXT: [[TMP17:%.*]] = load i32, ptr [[TMP16]], align 4 -// IR-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2:[0-9]+]], i32 [[TMP17]]) +// IR-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP17]]) // IR-NEXT: [[TMP18:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // IR-NEXT: [[TMP19:%.*]] = icmp ne i32 [[TMP18]], 0 // IR-NEXT: br i1 [[TMP19]], label [[DOTOMP_LASTPRIVATE_THEN:%.*]], label [[DOTOMP_LASTPRIVATE_DONE:%.*]] @@ -129,8 +129,8 @@ int foo() { // IR-NEXT: [[TMP23:%.*]] = load i32, ptr [[TMP22]], align 4 // IR-NEXT: [[TMP24:%.*]] = call i32 @__kmpc_reduce_nowait(ptr @[[GLOB3:[0-9]+]], i32 [[TMP23]], i32 1, i64 8, ptr [[DOTOMP_REDUCTION_RED_LIST]], ptr @_Z3foov.omp_outlined.omp.reduction.reduction_func, ptr @.gomp_critical_user_.reduction.var) // IR-NEXT: switch i32 [[TMP24]], label [[DOTOMP_REDUCTION_DEFAULT:%.*]] [ -// IR-NEXT: i32 1, label [[DOTOMP_REDUCTION_CASE1:%.*]] -// IR-NEXT: i32 2, label [[DOTOMP_REDUCTION_CASE2:%.*]] +// IR-NEXT: i32 1, label [[DOTOMP_REDUCTION_CASE1:%.*]] +// IR-NEXT: i32 2, label [[DOTOMP_REDUCTION_CASE2:%.*]] // IR-NEXT: ] // IR: .omp.reduction.case1: // IR-NEXT: [[TMP25:%.*]] = getelementptr i32, ptr [[TMP1]], i64 100 @@ -221,7 +221,7 @@ int foo() { // IR: omp.arrayinit.done: // IR-NEXT: [[TMP5:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 // IR-NEXT: [[TMP6:%.*]] = load i32, ptr [[TMP5]], align 4 -// IR-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB2]], i32 [[TMP6]], 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_4(ptr @[[GLOB2:[0-9]+]], i32 [[TMP6]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) // IR-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 // IR-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP7]], 99 // IR-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] @@ -285,8 +285,8 @@ int foo() { // IR-NEXT: [[TMP24:%.*]] = load i32, ptr [[TMP23]], align 4 // IR-NEXT: [[TMP25:%.*]] = call i32 @__kmpc_reduce_nowait(ptr @[[GLOB3]], i32 [[TMP24]], i32 1, i64 8, ptr [[DOTOMP_REDUCTION_RED_LIST]], ptr @_Z3foov.omp_outlined.omp_outlined.omp.reduction.reduction_func, ptr @.gomp_critical_user_.reduction.var) // IR-NEXT: switch i32 [[TMP25]], label [[DOTOMP_REDUCTION_DEFAULT:%.*]] [ -// IR-NEXT: i32 1, label [[DOTOMP_REDUCTION_CASE1:%.*]] -// IR-NEXT: i32 2, label [[DOTOMP_REDUCTION_CASE2:%.*]] +// IR-NEXT: i32 1, label [[DOTOMP_REDUCTION_CASE1:%.*]] +// IR-NEXT: i32 2, label [[DOTOMP_REDUCTION_CASE2:%.*]] // IR-NEXT: ] // IR: .omp.reduction.case1: // IR-NEXT: [[TMP26:%.*]] = getelementptr i32, ptr [[TMP1]], i64 100 @@ -486,7 +486,7 @@ int foo() { // IR-PCH: omp.loop.exit: // IR-PCH-NEXT: [[TMP16:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 // IR-PCH-NEXT: [[TMP17:%.*]] = load i32, ptr [[TMP16]], align 4 -// IR-PCH-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2:[0-9]+]], i32 [[TMP17]]) +// IR-PCH-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP17]]) // IR-PCH-NEXT: [[TMP18:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 // IR-PCH-NEXT: [[TMP19:%.*]] = icmp ne i32 [[TMP18]], 0 // IR-PCH-NEXT: br i1 [[TMP19]], label [[DOTOMP_LASTPRIVATE_THEN:%.*]], label [[DOTOMP_LASTPRIVATE_DONE:%.*]] @@ -502,8 +502,8 @@ int foo() { // IR-PCH-NEXT: [[TMP23:%.*]] = load i32, ptr [[TMP22]], align 4 // IR-PCH-NEXT: [[TMP24:%.*]] = call i32 @__kmpc_reduce_nowait(ptr @[[GLOB3:[0-9]+]], i32 [[TMP23]], i32 1, i64 8, ptr [[DOTOMP_REDUCTION_RED_LIST]], ptr @_Z3foov.omp_outlined.omp.reduction.reduction_func, ptr @.gomp_critical_user_.reduction.var) // IR-PCH-NEXT: switch i32 [[TMP24]], label [[DOTOMP_REDUCTION_DEFAULT:%.*]] [ -// IR-PCH-NEXT: i32 1, label [[DOTOMP_REDUCTION_CASE1:%.*]] -// IR-PCH-NEXT: i32 2, label [[DOTOMP_REDUCTION_CASE2:%.*]] +// IR-PCH-NEXT: i32 1, label [[DOTOMP_REDUCTION_CASE1:%.*]] +// IR-PCH-NEXT: i32 2, label [[DOTOMP_REDUCTION_CASE2:%.*]] // IR-PCH-NEXT: ] // IR-PCH: .omp.reduction.case1: // IR-PCH-NEXT: [[TMP25:%.*]] = getelementptr i32, ptr [[TMP1]], i64 100 @@ -594,7 +594,7 @@ int foo() { // IR-PCH: omp.arrayinit.done: // IR-PCH-NEXT: [[TMP5:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 // IR-PCH-NEXT: [[TMP6:%.*]] = load i32, ptr [[TMP5]], align 4 -// IR-PCH-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB2]], i32 [[TMP6]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// IR-PCH-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB2:[0-9]+]], i32 [[TMP6]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) // IR-PCH-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 // IR-PCH-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP7]], 99 // IR-PCH-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] @@ -658,8 +658,8 @@ int foo() { // IR-PCH-NEXT: [[TMP24:%.*]] = load i32, ptr [[TMP23]], align 4 // IR-PCH-NEXT: [[TMP25:%.*]] = call i32 @__kmpc_reduce_nowait(ptr @[[GLOB3]], i32 [[TMP24]], i32 1, i64 8, ptr [[DOTOMP_REDUCTION_RED_LIST]], ptr @_Z3foov.omp_outlined.omp_outlined.omp.reduction.reduction_func, ptr @.gomp_critical_user_.reduction.var) // IR-PCH-NEXT: switch i32 [[TMP25]], label [[DOTOMP_REDUCTION_DEFAULT:%.*]] [ -// IR-PCH-NEXT: i32 1, label [[DOTOMP_REDUCTION_CASE1:%.*]] -// IR-PCH-NEXT: i32 2, label [[DOTOMP_REDUCTION_CASE2:%.*]] +// IR-PCH-NEXT: i32 1, label [[DOTOMP_REDUCTION_CASE1:%.*]] +// IR-PCH-NEXT: i32 2, label [[DOTOMP_REDUCTION_CASE2:%.*]] // IR-PCH-NEXT: ] // IR-PCH: .omp.reduction.case1: // IR-PCH-NEXT: [[TMP26:%.*]] = getelementptr i32, ptr [[TMP1]], i64 100 diff --git a/clang/test/OpenMP/teams_generic_loop_collapse_codegen.cpp b/clang/test/OpenMP/teams_generic_loop_collapse_codegen.cpp index 4cf8f88b4c084a43cc5baf460f24c83e1eac86ea..49df83c9c765cfad07207ea1f799fbb602359ef7 100644 --- a/clang/test/OpenMP/teams_generic_loop_collapse_codegen.cpp +++ b/clang/test/OpenMP/teams_generic_loop_collapse_codegen.cpp @@ -242,7 +242,7 @@ int main (int argc, char **argv) { // CHECK1: omp.inner.for.end: // CHECK1-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK1: omp.loop.exit: -// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2:[0-9]+]], i32 [[TMP2]]) +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP2]]) // CHECK1-NEXT: ret void // // @@ -281,7 +281,7 @@ int main (int argc, char **argv) { // CHECK1-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK1-NEXT: [[TMP3:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 // CHECK1-NEXT: [[TMP4:%.*]] = load i32, ptr [[TMP3]], align 4 -// CHECK1-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB2]], i32 [[TMP4]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK1-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB2:[0-9]+]], i32 [[TMP4]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) // CHECK1-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 // CHECK1-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP5]], 56087 // CHECK1-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] @@ -476,7 +476,7 @@ int main (int argc, char **argv) { // CHECK3: omp.inner.for.end: // CHECK3-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK3: omp.loop.exit: -// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2:[0-9]+]], i32 [[TMP2]]) +// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP2]]) // CHECK3-NEXT: ret void // // @@ -513,7 +513,7 @@ int main (int argc, char **argv) { // CHECK3-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK3-NEXT: [[TMP3:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 4 // CHECK3-NEXT: [[TMP4:%.*]] = load i32, ptr [[TMP3]], align 4 -// CHECK3-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB2]], i32 [[TMP4]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK3-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB2:[0-9]+]], i32 [[TMP4]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) // CHECK3-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 // CHECK3-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP5]], 56087 // CHECK3-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] @@ -835,7 +835,7 @@ int main (int argc, char **argv) { // CHECK9: omp.loop.exit: // CHECK9-NEXT: [[TMP25:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 // CHECK9-NEXT: [[TMP26:%.*]] = load i32, ptr [[TMP25]], align 4 -// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2:[0-9]+]], i32 [[TMP26]]) +// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP26]]) // CHECK9-NEXT: br label [[OMP_PRECOND_END]] // CHECK9: omp.precond.end: // CHECK9-NEXT: ret void @@ -917,7 +917,7 @@ int main (int argc, char **argv) { // CHECK9-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK9-NEXT: [[TMP14:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 // CHECK9-NEXT: [[TMP15:%.*]] = load i32, ptr [[TMP14]], align 4 -// CHECK9-NEXT: call void @__kmpc_for_static_init_8(ptr @[[GLOB2]], i32 [[TMP15]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i64 1, i64 1) +// CHECK9-NEXT: call void @__kmpc_for_static_init_8(ptr @[[GLOB2:[0-9]+]], i32 [[TMP15]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i64 1, i64 1) // CHECK9-NEXT: [[TMP16:%.*]] = load i64, ptr [[DOTOMP_UB]], align 8 // CHECK9-NEXT: [[TMP17:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR_5]], align 8 // CHECK9-NEXT: [[CMP13:%.*]] = icmp sgt i64 [[TMP16]], [[TMP17]] @@ -1124,7 +1124,7 @@ int main (int argc, char **argv) { // CHECK9: omp.inner.for.end: // CHECK9-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK9: omp.loop.exit: -// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP2]]) +// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP2]]) // CHECK9-NEXT: ret void // // @@ -1487,7 +1487,7 @@ int main (int argc, char **argv) { // CHECK11: omp.loop.exit: // CHECK11-NEXT: [[TMP27:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 4 // CHECK11-NEXT: [[TMP28:%.*]] = load i32, ptr [[TMP27]], align 4 -// CHECK11-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2:[0-9]+]], i32 [[TMP28]]) +// CHECK11-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP28]]) // CHECK11-NEXT: br label [[OMP_PRECOND_END]] // CHECK11: omp.precond.end: // CHECK11-NEXT: ret void @@ -1571,7 +1571,7 @@ int main (int argc, char **argv) { // CHECK11-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 // CHECK11-NEXT: [[TMP14:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 4 // CHECK11-NEXT: [[TMP15:%.*]] = load i32, ptr [[TMP14]], align 4 -// CHECK11-NEXT: call void @__kmpc_for_static_init_8(ptr @[[GLOB2]], i32 [[TMP15]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i64 1, i64 1) +// CHECK11-NEXT: call void @__kmpc_for_static_init_8(ptr @[[GLOB2:[0-9]+]], i32 [[TMP15]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i64 1, i64 1) // CHECK11-NEXT: [[TMP16:%.*]] = load i64, ptr [[DOTOMP_UB]], align 8 // CHECK11-NEXT: [[TMP17:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR_5]], align 8 // CHECK11-NEXT: [[CMP15:%.*]] = icmp sgt i64 [[TMP16]], [[TMP17]] @@ -1774,7 +1774,7 @@ int main (int argc, char **argv) { // CHECK11: omp.inner.for.end: // CHECK11-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK11: omp.loop.exit: -// CHECK11-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP2]]) +// CHECK11-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP2]]) // CHECK11-NEXT: ret void // // diff --git a/clang/test/OpenMP/teams_generic_loop_private_codegen.cpp b/clang/test/OpenMP/teams_generic_loop_private_codegen.cpp index ab5cbdf1b8c9e415ddcfa09ff5da854d86000a2a..5ef729f044e09708a860fe1d49c3cb96d425b4fb 100644 --- a/clang/test/OpenMP/teams_generic_loop_private_codegen.cpp +++ b/clang/test/OpenMP/teams_generic_loop_private_codegen.cpp @@ -382,7 +382,7 @@ int main() { // CHECK1: omp.loop.exit: // CHECK1-NEXT: [[TMP13:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 // CHECK1-NEXT: [[TMP14:%.*]] = load i32, ptr [[TMP13]], align 4 -// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2:[0-9]+]], i32 [[TMP14]]) +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP14]]) // CHECK1-NEXT: call void @_ZN1SIfED1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[VAR]]) #[[ATTR2]] // CHECK1-NEXT: [[ARRAY_BEGIN2:%.*]] = getelementptr inbounds [2 x %struct.S], ptr [[S_ARR]], i32 0, i32 0 // CHECK1-NEXT: [[TMP15:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[ARRAY_BEGIN2]], i64 2 @@ -443,7 +443,7 @@ int main() { // CHECK1-NEXT: call void @_ZN1SIfEC1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[VAR]]) // CHECK1-NEXT: [[TMP2:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 // CHECK1-NEXT: [[TMP3:%.*]] = load i32, ptr [[TMP2]], align 4 -// CHECK1-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB2]], i32 [[TMP3]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK1-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB2:[0-9]+]], i32 [[TMP3]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) // CHECK1-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 // CHECK1-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP4]], 1 // CHECK1-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] @@ -690,7 +690,7 @@ int main() { // CHECK1: omp.loop.exit: // CHECK1-NEXT: [[TMP13:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 // CHECK1-NEXT: [[TMP14:%.*]] = load i32, ptr [[TMP13]], align 4 -// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP14]]) +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP14]]) // CHECK1-NEXT: call void @_ZN1SIiED1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[VAR]]) #[[ATTR2]] // CHECK1-NEXT: [[ARRAY_BEGIN4:%.*]] = getelementptr inbounds [2 x %struct.S.0], ptr [[S_ARR]], i32 0, i32 0 // CHECK1-NEXT: [[TMP15:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[ARRAY_BEGIN4]], i64 2 @@ -1113,7 +1113,7 @@ int main() { // CHECK3: omp.loop.exit: // CHECK3-NEXT: [[TMP11:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 4 // CHECK3-NEXT: [[TMP12:%.*]] = load i32, ptr [[TMP11]], align 4 -// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2:[0-9]+]], i32 [[TMP12]]) +// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP12]]) // CHECK3-NEXT: call void @_ZN1SIfED1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[VAR]]) #[[ATTR2]] // CHECK3-NEXT: [[ARRAY_BEGIN2:%.*]] = getelementptr inbounds [2 x %struct.S], ptr [[S_ARR]], i32 0, i32 0 // CHECK3-NEXT: [[TMP13:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[ARRAY_BEGIN2]], i32 2 @@ -1172,7 +1172,7 @@ int main() { // CHECK3-NEXT: call void @_ZN1SIfEC1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[VAR]]) // CHECK3-NEXT: [[TMP2:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 4 // CHECK3-NEXT: [[TMP3:%.*]] = load i32, ptr [[TMP2]], align 4 -// CHECK3-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB2]], i32 [[TMP3]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK3-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB2:[0-9]+]], i32 [[TMP3]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) // CHECK3-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 // CHECK3-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP4]], 1 // CHECK3-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] @@ -1415,7 +1415,7 @@ int main() { // CHECK3: omp.loop.exit: // CHECK3-NEXT: [[TMP11:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 4 // CHECK3-NEXT: [[TMP12:%.*]] = load i32, ptr [[TMP11]], align 4 -// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP12]]) +// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP12]]) // CHECK3-NEXT: call void @_ZN1SIiED1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[VAR]]) #[[ATTR2]] // CHECK3-NEXT: [[ARRAY_BEGIN4:%.*]] = getelementptr inbounds [2 x %struct.S.0], ptr [[S_ARR]], i32 0, i32 0 // CHECK3-NEXT: [[TMP13:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[ARRAY_BEGIN4]], i32 2 @@ -1793,7 +1793,7 @@ int main() { // CHECK9: omp.inner.for.end: // CHECK9-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK9: omp.loop.exit: -// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2:[0-9]+]], i32 [[TMP1]]) +// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP1]]) // CHECK9-NEXT: ret void // // @@ -1835,7 +1835,7 @@ int main() { // CHECK9-NEXT: store ptr [[G1]], ptr [[_TMP3]], align 8 // CHECK9-NEXT: [[TMP2:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 // CHECK9-NEXT: [[TMP3:%.*]] = load i32, ptr [[TMP2]], align 4 -// CHECK9-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB2]], i32 [[TMP3]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK9-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB2:[0-9]+]], i32 [[TMP3]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) // CHECK9-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 // CHECK9-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP4]], 1 // CHECK9-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] diff --git a/clang/test/OpenMP/teams_generic_loop_reduction_codegen.cpp b/clang/test/OpenMP/teams_generic_loop_reduction_codegen.cpp index f91ee759cddf0d3712e135450a2e8f95133d8f9a..4da49eed32efd2dfcd9b6bb0b8e0c0f7db51d4b4 100644 --- a/clang/test/OpenMP/teams_generic_loop_reduction_codegen.cpp +++ b/clang/test/OpenMP/teams_generic_loop_reduction_codegen.cpp @@ -223,7 +223,7 @@ int main() { // CHECK1: omp.inner.for.end: // CHECK1-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK1: omp.loop.exit: -// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2:[0-9]+]], i32 [[TMP2]]) +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP2]]) // CHECK1-NEXT: [[TMP14:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOMP_REDUCTION_RED_LIST]], i64 0, i64 0 // CHECK1-NEXT: store ptr [[SIVAR1]], ptr [[TMP14]], align 8 // CHECK1-NEXT: [[TMP15:%.*]] = call i32 @__kmpc_reduce_nowait(ptr @[[GLOB3:[0-9]+]], i32 [[TMP2]], i32 1, i64 8, ptr [[DOTOMP_REDUCTION_RED_LIST]], ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l68.omp_outlined.omp.reduction.reduction_func, ptr @.gomp_critical_user_.reduction.var) @@ -282,7 +282,7 @@ int main() { // CHECK1-NEXT: store i32 0, ptr [[SIVAR2]], align 4 // CHECK1-NEXT: [[TMP3:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 // CHECK1-NEXT: [[TMP4:%.*]] = load i32, ptr [[TMP3]], align 4 -// CHECK1-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB2]], i32 [[TMP4]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK1-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB2:[0-9]+]], i32 [[TMP4]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) // CHECK1-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 // CHECK1-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP5]], 1 // CHECK1-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] @@ -516,7 +516,7 @@ int main() { // CHECK1: omp.inner.for.end: // CHECK1-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK1: omp.loop.exit: -// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP2]]) +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP2]]) // CHECK1-NEXT: [[TMP14:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOMP_REDUCTION_RED_LIST]], i64 0, i64 0 // CHECK1-NEXT: store ptr [[T_VAR1]], ptr [[TMP14]], align 8 // CHECK1-NEXT: [[TMP15:%.*]] = call i32 @__kmpc_reduce_nowait(ptr @[[GLOB3]], i32 [[TMP2]], i32 1, i64 8, ptr [[DOTOMP_REDUCTION_RED_LIST]], ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiET_v_l32.omp_outlined.omp.reduction.reduction_func, ptr @.gomp_critical_user_.reduction.var) @@ -806,7 +806,7 @@ int main() { // CHECK3: omp.inner.for.end: // CHECK3-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK3: omp.loop.exit: -// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2:[0-9]+]], i32 [[TMP2]]) +// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP2]]) // CHECK3-NEXT: [[TMP12:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOMP_REDUCTION_RED_LIST]], i32 0, i32 0 // CHECK3-NEXT: store ptr [[SIVAR1]], ptr [[TMP12]], align 4 // CHECK3-NEXT: [[TMP13:%.*]] = call i32 @__kmpc_reduce_nowait(ptr @[[GLOB3:[0-9]+]], i32 [[TMP2]], i32 1, i32 4, ptr [[DOTOMP_REDUCTION_RED_LIST]], ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l68.omp_outlined.omp.reduction.reduction_func, ptr @.gomp_critical_user_.reduction.var) @@ -863,7 +863,7 @@ int main() { // CHECK3-NEXT: store i32 0, ptr [[SIVAR1]], align 4 // CHECK3-NEXT: [[TMP3:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 4 // CHECK3-NEXT: [[TMP4:%.*]] = load i32, ptr [[TMP3]], align 4 -// CHECK3-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB2]], i32 [[TMP4]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK3-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB2:[0-9]+]], i32 [[TMP4]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) // CHECK3-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 // CHECK3-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP5]], 1 // CHECK3-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] @@ -1095,7 +1095,7 @@ int main() { // CHECK3: omp.inner.for.end: // CHECK3-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK3: omp.loop.exit: -// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP2]]) +// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP2]]) // CHECK3-NEXT: [[TMP12:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOMP_REDUCTION_RED_LIST]], i32 0, i32 0 // CHECK3-NEXT: store ptr [[T_VAR1]], ptr [[TMP12]], align 4 // CHECK3-NEXT: [[TMP13:%.*]] = call i32 @__kmpc_reduce_nowait(ptr @[[GLOB3]], i32 [[TMP2]], i32 1, i32 4, ptr [[DOTOMP_REDUCTION_RED_LIST]], ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiET_v_l32.omp_outlined.omp.reduction.reduction_func, ptr @.gomp_critical_user_.reduction.var) @@ -1336,7 +1336,7 @@ int main() { // CHECK9: omp.inner.for.end: // CHECK9-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK9: omp.loop.exit: -// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2:[0-9]+]], i32 [[TMP2]]) +// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP2]]) // CHECK9-NEXT: [[TMP14:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOMP_REDUCTION_RED_LIST]], i64 0, i64 0 // CHECK9-NEXT: store ptr [[SIVAR1]], ptr [[TMP14]], align 8 // CHECK9-NEXT: [[TMP15:%.*]] = call i32 @__kmpc_reduce_nowait(ptr @[[GLOB3:[0-9]+]], i32 [[TMP2]], i32 1, i64 8, ptr [[DOTOMP_REDUCTION_RED_LIST]], ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l45.omp_outlined.omp.reduction.reduction_func, ptr @.gomp_critical_user_.reduction.var) @@ -1396,7 +1396,7 @@ int main() { // CHECK9-NEXT: store i32 0, ptr [[SIVAR2]], align 4 // CHECK9-NEXT: [[TMP3:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 // CHECK9-NEXT: [[TMP4:%.*]] = load i32, ptr [[TMP3]], align 4 -// CHECK9-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB2]], i32 [[TMP4]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK9-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB2:[0-9]+]], i32 [[TMP4]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) // CHECK9-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 // CHECK9-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP5]], 1 // CHECK9-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] diff --git a/clang/test/Options/HV.hlsl b/clang/test/Options/HV.hlsl new file mode 100644 index 0000000000000000000000000000000000000000..9f7e1ebc02f25179681a5cfb08453b4bb2b809c9 --- /dev/null +++ b/clang/test/Options/HV.hlsl @@ -0,0 +1,20 @@ +// RUN: %clang_dxc -T lib_6_4 -HV 2016 %s 2>&1 -### | FileCheck -check-prefix=2016 %s +// RUN: %clang_dxc -T lib_6_4 -HV 2017 %s 2>&1 -### | FileCheck -check-prefix=2017 %s +// RUN: %clang_dxc -T lib_6_4 /HV 2018 %s 2>&1 -### | FileCheck -check-prefix=2018 %s +// RUN: %clang_dxc -T lib_6_4 /HV 2021 %s 2>&1 -### | FileCheck -check-prefix=2021 %s +// RUN: %clang_dxc -T lib_6_4 /HV 202x %s 2>&1 -### | FileCheck -check-prefix=202x %s +// RUN: %clang_dxc -T lib_6_4 %s 2>&1 -### | FileCheck -check-prefix=NO_HV %s +// RUN: not %clang_dxc -T lib_6_4 /HV gibberish -### %s 2>&1 | FileCheck -check-prefix=CHECK-ERR %s + +// 2016: "-std=hlsl2016" +// 2017: "-std=hlsl2017" +// 2018: "-std=hlsl2018" +// 2021: "-std=hlsl2021" +// 202x: "-std=hlsl202x" +// NO_HV-NOT: "-std=" +// CHECK-ERR: error: invalid value 'gibberish' in 'HV' +float4 main(float4 a : A) : SV_TARGET +{ + return -a.yxxx; +} + diff --git a/clang/test/Parser/cxx23-assume.cpp b/clang/test/Parser/cxx23-assume.cpp new file mode 100644 index 0000000000000000000000000000000000000000..269fb7e599443e188b6e285cea9bfadf38cb8e0a --- /dev/null +++ b/clang/test/Parser/cxx23-assume.cpp @@ -0,0 +1,18 @@ +// RUN: %clang_cc1 -std=c++23 -x c++ %s -verify + +void f(int x, int y) { + [[assume(true)]]; + [[assume(1)]]; + [[assume(1.0)]]; + [[assume(1 + 2 == 3)]]; + [[assume(x ? 1 : 2)]]; + [[assume(x && y)]]; + [[assume(true)]] [[assume(true)]]; + + [[assume]]; // expected-error {{takes one argument}} + [[assume(]]; // expected-error {{expected expression}} + [[assume()]]; // expected-error {{expected expression}} + [[assume(2]]; // expected-error {{expected ')'}} expected-note {{to match this '('}} + [[assume(x = 2)]]; // expected-error {{requires parentheses}} + [[assume(2, 3)]]; // expected-error {{requires parentheses}} expected-warning {{has no effect}} +} diff --git a/clang/test/Preprocessor/bpf-predefined-macros.c b/clang/test/Preprocessor/bpf-predefined-macros.c index ff4d00ac3bcfcc1d4c36571e559199a661588f92..246cbfa2d6ab7db1d52c925e69c72c9e2aac0ba3 100644 --- a/clang/test/Preprocessor/bpf-predefined-macros.c +++ b/clang/test/Preprocessor/bpf-predefined-macros.c @@ -61,6 +61,9 @@ int r; #ifdef __BPF_FEATURE_ST int s; #endif +#ifdef __BPF_FEATURE_ADDR_SPACE_CAST +int t; +#endif // CHECK: int b; // CHECK: int c; @@ -90,6 +93,11 @@ int s; // CPU_V4: int r; // CPU_V4: int s; +// CPU_V1: int t; +// CPU_V2: int t; +// CPU_V3: int t; +// CPU_V4: int t; + // CPU_GENERIC: int g; // CPU_PROBE: int f; diff --git a/clang/test/Preprocessor/ptrauth_feature.c b/clang/test/Preprocessor/ptrauth_feature.c new file mode 100644 index 0000000000000000000000000000000000000000..e45c6ea90fd11f611de5a3be8cfb37c20ace1d10 --- /dev/null +++ b/clang/test/Preprocessor/ptrauth_feature.c @@ -0,0 +1,10 @@ +// RUN: %clang_cc1 %s -E -triple=arm64-- | FileCheck %s --check-prefixes=NOINTRIN +// RUN: %clang_cc1 %s -E -triple=arm64-- -fptrauth-intrinsics | FileCheck %s --check-prefixes=INTRIN + +#if __has_feature(ptrauth_intrinsics) +// INTRIN: has_ptrauth_intrinsics +void has_ptrauth_intrinsics() {} +#else +// NOINTRIN: no_ptrauth_intrinsics +void no_ptrauth_intrinsics() {} +#endif diff --git a/clang/test/Preprocessor/riscv-target-features.c b/clang/test/Preprocessor/riscv-target-features.c index 1a15be1c6e4dc13642db0a4b315f688fc2d8eac1..dfc6d18dee504ee942c380a6844c325e97b519a5 100644 --- a/clang/test/Preprocessor/riscv-target-features.c +++ b/clang/test/Preprocessor/riscv-target-features.c @@ -56,11 +56,14 @@ // CHECK-NOT: __riscv_xcvmac {{.*$}} // CHECK-NOT: __riscv_xcvmem {{.*$}} // CHECK-NOT: __riscv_xcvsimd {{.*$}} +// CHECK-NOT: __riscv_xsfcease {{.*$}} // CHECK-NOT: __riscv_xsfvcp {{.*$}} // CHECK-NOT: __riscv_xsfvfnrclipxfqf {{.*$}} // CHECK-NOT: __riscv_xsfvfwmaccqqq {{.*$}} // CHECK-NOT: __riscv_xsfqmaccdod {{.*$}} // CHECK-NOT: __riscv_xsfvqmaccqoq {{.*$}} +// CHECK-NOT: __riscv_xsifivecdiscarddlone {{.*$}} +// CHECK-NOT: __riscv_xsifivecflushdlone {{.*$}} // CHECK-NOT: __riscv_xtheadba {{.*$}} // CHECK-NOT: __riscv_xtheadbb {{.*$}} // CHECK-NOT: __riscv_xtheadbs {{.*$}} @@ -517,6 +520,14 @@ // RUN: -o - | FileCheck --check-prefix=CHECK-XCVSIMD-EXT %s // CHECK-XCVSIMD-EXT: __riscv_xcvsimd 1000000{{$}} +// RUN: %clang --target=riscv32-unknown-linux-gnu \ +// RUN: -march=rv32ixsfcease -E -dM %s \ +// RUN: -o - | FileCheck --check-prefix=CHECK-XSFCEASE-EXT %s +// RUN: %clang --target=riscv64-unknown-linux-gnu \ +// RUN: -march=rv64ixsfcease -E -dM %s \ +// RUN: -o - | FileCheck --check-prefix=CHECK-XSFCEASE-EXT %s +// CHECK-XSFCEASE-EXT: __riscv_xsfcease 1000000{{$}} + // RUN: %clang --target=riscv32-unknown-linux-gnu \ // RUN: -march=rv32ixsfvcp -E -dM %s \ // RUN: -o - | FileCheck --check-prefix=CHECK-XSFVCP-EXT %s @@ -557,6 +568,22 @@ // RUN: -o - | FileCheck --check-prefix=CHECK-XSFVQMACCQOQ-EXT %s // CHECK-XSFVQMACCQOQ-EXT: __riscv_xsfvqmaccqoq 1000000{{$}} +// RUN: %clang --target=riscv32-unknown-linux-gnu \ +// RUN: -march=rv32ixsifivecdiscarddlone -E -dM %s \ +// RUN: -o - | FileCheck --check-prefix=CHECK-XSIFIVECDISCARDDLONE-EXT %s +// RUN: %clang --target=riscv64-unknown-linux-gnu \ +// RUN: -march=rv64ixsifivecdiscarddlone -E -dM %s \ +// RUN: -o - | FileCheck --check-prefix=CHECK-XSIFIVECDISCARDDLONE-EXT %s +// CHECK-XSIFIVECDISCARDDLONE-EXT: __riscv_xsifivecdiscarddlone 1000000{{$}} + +// RUN: %clang --target=riscv32-unknown-linux-gnu \ +// RUN: -march=rv32ixsifivecflushdlone -E -dM %s \ +// RUN: -o - | FileCheck --check-prefix=CHECK-XSIFIVECFLUSHDLONE-EXT %s +// RUN: %clang --target=riscv64-unknown-linux-gnu \ +// RUN: -march=rv64ixsifivecflushdlone -E -dM %s \ +// RUN: -o - | FileCheck --check-prefix=CHECK-XSIFIVECFLUSHDLONE-EXT %s +// CHECK-XSIFIVECFLUSHDLONE-EXT: __riscv_xsifivecflushdlone 1000000{{$}} + // RUN: %clang --target=riscv32-unknown-linux-gnu \ // RUN: -march=rv32ixtheadba -E -dM %s \ // RUN: -o - | FileCheck --check-prefix=CHECK-XTHEADBA-EXT %s @@ -1639,9 +1666,9 @@ // CHECK-MISALIGNED-AVOID: __riscv_misaligned_avoid 1 // RUN: %clang --target=riscv32-unknown-linux-gnu -march=rv32i -E -dM %s \ -// RUN: -munaligned-access -o - | FileCheck %s --check-prefix=CHECK-MISALIGNED-FAST +// RUN: -mno-strict-align -o - | FileCheck %s --check-prefix=CHECK-MISALIGNED-FAST // RUN: %clang --target=riscv64-unknown-linux-gnu -march=rv64i -E -dM %s \ -// RUN: -munaligned-access -o - | FileCheck %s --check-prefix=CHECK-MISALIGNED-FAST +// RUN: -mno-strict-align -o - | FileCheck %s --check-prefix=CHECK-MISALIGNED-FAST // RUN: %clang --target=riscv64-unknown-linux-gnu -mcpu=sifive-p450 -E -dM %s \ // RUN: -o - | FileCheck %s --check-prefix=CHECK-MISALIGNED-FAST // CHECK-MISALIGNED-FAST: __riscv_misaligned_fast 1 diff --git a/clang/test/Sema/PR84368.cpp b/clang/test/Sema/PR84368.cpp new file mode 100644 index 0000000000000000000000000000000000000000..6551df29358920b2719e8843185e24add437d83e --- /dev/null +++ b/clang/test/Sema/PR84368.cpp @@ -0,0 +1,16 @@ +// RUN: %clang_cc1 -std=c++20 -verify %s +// RUN: %clang_cc1 -std=c++23 -verify %s +// expected-no-diagnostics + +template concept IsOk = requires() { typename T::Float; }; + +template struct Thing; + +template struct Foobar { + template struct Inner { + template friend struct Thing; + }; +}; + +struct MyType { using Float=float; }; +Foobar::Inner<0> foobar; diff --git a/clang/test/Sema/attr-cleanup.c b/clang/test/Sema/attr-cleanup.c index 2c38687622c2bbc3ccaf148b7d9ef577b93e6990..95baf2e675a086695d159f41cafeccc2da74e7b8 100644 --- a/clang/test/Sema/attr-cleanup.c +++ b/clang/test/Sema/attr-cleanup.c @@ -1,7 +1,7 @@ -// RUN: %clang_cc1 %s -verify -fsyntax-only +// RUN: %clang_cc1 -Wfree-nonheap-object -fsyntax-only -verify %s void c1(int *a); - +typedef __typeof__(sizeof(0)) size_t; extern int g1 __attribute((cleanup(c1))); // expected-warning {{'cleanup' attribute only applies to local variables}} int g2 __attribute((cleanup(c1))); // expected-warning {{'cleanup' attribute only applies to local variables}} static int g3 __attribute((cleanup(c1))); // expected-warning {{'cleanup' attribute only applies to local variables}} @@ -48,3 +48,27 @@ void t6(void) { } void t7(__attribute__((cleanup(c4))) int a) {} // expected-warning {{'cleanup' attribute only applies to local variables}} + +extern void free(void *); +extern void *malloc(size_t size); +void t8(void) { + void *p + __attribute__(( + cleanup( + free // expected-warning{{attempt to call free on non-heap object 'p'}} + ) + )) + = malloc(10); +} +typedef __attribute__((aligned(2))) int Aligned2Int; +void t9(void){ + Aligned2Int __attribute__((cleanup(c1))) xwarn; // expected-warning{{passing 2-byte aligned argument to 4-byte aligned parameter 1 of 'c1' may result in an unaligned pointer access}} +} + +__attribute__((enforce_tcb("TCB1"))) void func1(int *x) { + *x = 5; +} +__attribute__((enforce_tcb("TCB2"))) void t10() { + int __attribute__((cleanup(func1))) x = 5; // expected-warning{{calling 'func1' is a violation of trusted computing base 'TCB2'}} +} + diff --git a/clang/test/Sema/builtins-arm64.c b/clang/test/Sema/builtins-arm64.c index e711121f7260ffcdeac230b77697fa2879b07a13..f094162b3aadc98700ab850b5e9c5b2eb9259b34 100644 --- a/clang/test/Sema/builtins-arm64.c +++ b/clang/test/Sema/builtins-arm64.c @@ -29,3 +29,12 @@ void test_prefetch(void) { __builtin_arm_prefetch(0, 0, 0, 2, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}} __builtin_arm_prefetch(0, 0, 0, 0, 2); // expected-error-re {{argument value {{.*}} is outside the valid range}} } + +void test_trap(short s, unsigned short us) { + __builtin_arm_trap(42); + __builtin_arm_trap(65535); + __builtin_arm_trap(-1); + __builtin_arm_trap(65536); // expected-warning {{implicit conversion from 'int' to 'unsigned short' changes value from 65536 to 0}} + __builtin_arm_trap(s); // expected-error {{argument to '__builtin_arm_trap' must be a constant integer}} + __builtin_arm_trap(us); // expected-error {{argument to '__builtin_arm_trap' must be a constant integer}} +} \ No newline at end of file diff --git a/clang/test/Sema/complex-arithmetic.c b/clang/test/Sema/complex-arithmetic.c new file mode 100644 index 0000000000000000000000000000000000000000..c9e84da6daa9dcc3bfefff9bc3848e1d74cc8ce4 --- /dev/null +++ b/clang/test/Sema/complex-arithmetic.c @@ -0,0 +1,115 @@ +// RUN: %clang_cc1 -verify %s +// expected-no-diagnostics + +// This tests evaluation of _Complex arithmetic at compile time. + +#define APPROX_EQ(a, b) ( \ + __builtin_fabs(__real (a) - __real (b)) < 0.0001 && \ + __builtin_fabs(__imag (a) - __imag (b)) < 0.0001 \ +) + +#define EVAL(a, b) _Static_assert(a == b, "") +#define EVALF(a, b) _Static_assert(APPROX_EQ(a, b), "") + +// _Complex float + _Complex float +void a() { + EVALF((2.f + 3i) + (4.f + 5i), 6.f + 8i); + EVALF((2.f + 3i) - (4.f + 5i), -2.f - 2i); + EVALF((2.f + 3i) * (4.f + 5i), -7.f + 22i); + EVALF((2.f + 3i) / (4.f + 5i), 0.5609f + 0.0487i); + + EVALF((2. + 3i) + (4. + 5i), 6. + 8i); + EVALF((2. + 3i) - (4. + 5i), -2. - 2i); + EVALF((2. + 3i) * (4. + 5i), -7. + 22i); + EVALF((2. + 3i) / (4. + 5i), .5609 + .0487i); +} + +// _Complex int + _Complex int +void b() { + EVAL((2 + 3i) + (4 + 5i), 6 + 8i); + EVAL((2 + 3i) - (4 + 5i), -2 - 2i); + EVAL((2 + 3i) * (4 + 5i), -7 + 22i); + EVAL((8 + 30i) / (4 + 5i), 4 + 1i); +} + +// _Complex float + float +void c() { + EVALF((2.f + 4i) + 3.f, 5.f + 4i); + EVALF((2.f + 4i) - 3.f, -1.f + 4i); + EVALF((2.f + 4i) * 3.f, 6.f + 12i); + EVALF((2.f + 4i) / 2.f, 1.f + 2i); + + EVALF(3.f + (2.f + 4i), 5.f + 4i); + EVALF(3.f - (2.f + 4i), 1.f - 4i); + EVALF(3.f * (2.f + 4i), 6.f + 12i); + EVALF(3.f / (2.f + 4i), .3f - 0.6i); + + EVALF((2. + 4i) + 3., 5. + 4i); + EVALF((2. + 4i) - 3., -1. + 4i); + EVALF((2. + 4i) * 3., 6. + 12i); + EVALF((2. + 4i) / 2., 1. + 2i); + + EVALF(3. + (2. + 4i), 5. + 4i); + EVALF(3. - (2. + 4i), 1. - 4i); + EVALF(3. * (2. + 4i), 6. + 12i); + EVALF(3. / (2. + 4i), .3 - 0.6i); +} + +// _Complex int + int +void d() { + EVAL((2 + 4i) + 3, 5 + 4i); + EVAL((2 + 4i) - 3, -1 + 4i); + EVAL((2 + 4i) * 3, 6 + 12i); + EVAL((2 + 4i) / 2, 1 + 2i); + + EVAL(3 + (2 + 4i), 5 + 4i); + EVAL(3 - (2 + 4i), 1 - 4i); + EVAL(3 * (2 + 4i), 6 + 12i); + EVAL(20 / (2 + 4i), 2 - 4i); +} + +// _Complex float + int +void e() { + EVALF((2.f + 4i) + 3, 5.f + 4i); + EVALF((2.f + 4i) - 3, -1.f + 4i); + EVALF((2.f + 4i) * 3, 6.f + 12i); + EVALF((2.f + 4i) / 2, 1.f + 2i); + + EVALF(3 + (2.f + 4i), 5.f + 4i); + EVALF(3 - (2.f + 4i), 1.f - 4i); + EVALF(3 * (2.f + 4i), 6.f + 12i); + EVALF(3 / (2.f + 4i), .3f - 0.6i); + + EVALF((2. + 4i) + 3, 5. + 4i); + EVALF((2. + 4i) - 3, -1. + 4i); + EVALF((2. + 4i) * 3, 6. + 12i); + EVALF((2. + 4i) / 2, 1. + 2i); + + EVALF(3 + (2. + 4i), 5. + 4i); + EVALF(3 - (2. + 4i), 1. - 4i); + EVALF(3 * (2. + 4i), 6. + 12i); + EVALF(3 / (2. + 4i), .3 - 0.6i); +} + +// _Complex int + float +void f() { + EVALF((2 + 4i) + 3.f, 5.f + 4i); + EVALF((2 + 4i) - 3.f, -1.f + 4i); + EVALF((2 + 4i) * 3.f, 6.f + 12i); + EVALF((2 + 4i) / 2.f, 1.f + 2i); + + EVALF(3.f + (2 + 4i), 5.f + 4i); + EVALF(3.f - (2 + 4i), 1.f - 4i); + EVALF(3.f * (2 + 4i), 6.f + 12i); + EVALF(3.f / (2 + 4i), .3f - 0.6i); + + EVALF((2 + 4i) + 3., 5. + 4i); + EVALF((2 + 4i) - 3., -1. + 4i); + EVALF((2 + 4i) * 3., 6. + 12i); + EVALF((2 + 4i) / 2., 1. + 2i); + + EVALF(3. + (2 + 4i), 5. + 4i); + EVALF(3. - (2 + 4i), 1. - 4i); + EVALF(3. * (2 + 4i), 6. + 12i); + EVALF(3. / (2 + 4i), .3 - 0.6i); +} diff --git a/clang/test/Sema/const-eval.c b/clang/test/Sema/const-eval.c index 2e38d5e23c208acc5028b566783b064214c82a03..e358aceaad5a43bca19bc590b76b838a2810048a 100644 --- a/clang/test/Sema/const-eval.c +++ b/clang/test/Sema/const-eval.c @@ -134,8 +134,7 @@ void PR21945(void) { int i = (({}), 0l); } void PR24622(void); struct PR24622 {} pr24622; -EVAL_EXPR(52, &pr24622 == (void *)&PR24622); // expected-error {{not an integer constant expression}} - // expected-note@-1 {{past the end}} +EVAL_EXPR(52, &pr24622 == (void *)&PR24622); // We evaluate these by providing 2s' complement semantics in constant // expressions, like we do for integers. diff --git a/clang/test/Sema/const-init.c b/clang/test/Sema/const-init.c new file mode 100644 index 0000000000000000000000000000000000000000..5b07ede747ebc4ba2b66e2e287406311d99d5c84 --- /dev/null +++ b/clang/test/Sema/const-init.c @@ -0,0 +1,6 @@ +// RUN: %clang_cc1 -fsyntax-only -verify -std=c23 %s + +// Division by 0 here is an error iff the variable is 'constexpr'. +const _Bool inf1 = (1.0/0.0 == __builtin_inf()); +constexpr _Bool inf2 = (1.0/0.0 == __builtin_inf()); // expected-error {{must be initialized by a constant expression}} expected-note {{division by zero}} +constexpr _Bool inf3 = __builtin_inf() == __builtin_inf(); diff --git a/clang/test/Sema/constexpr-void-cast.c b/clang/test/Sema/constexpr-void-cast.c new file mode 100644 index 0000000000000000000000000000000000000000..91e4027f67fe387850891099e773b490d74e5c26 --- /dev/null +++ b/clang/test/Sema/constexpr-void-cast.c @@ -0,0 +1,14 @@ +// RUN: %clang_cc1 -x c -fsyntax-only %s -verify=c -std=c11 +// RUN: %clang_cc1 -x c -fsyntax-only %s -pedantic -verify=c-pedantic -std=c11 +// +// RUN: %clang_cc1 -x c++ -fsyntax-only %s -verify=cxx +// RUN: %clang_cc1 -x c++ -fsyntax-only %s -pedantic -verify=cxx-pedantic + +// c-no-diagnostics +// cxx-no-diagnostics + +void f(void); +struct S {char c;} s; +_Static_assert(&s != (void *)&f, ""); // c-pedantic-warning {{not an integer constant expression}} \ + // c-pedantic-note {{this conversion is not allowed in a constant expression}} \ + // cxx-pedantic-warning {{'_Static_assert' is a C11 extension}} diff --git a/clang/test/Sema/enum-constant-type.cpp b/clang/test/Sema/enum-constant-type.cpp new file mode 100644 index 0000000000000000000000000000000000000000..5db3a859a39599ce44c10b9d4bcc5f84d01515b4 --- /dev/null +++ b/clang/test/Sema/enum-constant-type.cpp @@ -0,0 +1,12 @@ +// RUN: %clang_cc1 -x c++ -fsyntax-only -verify %s -Wenum-compare +// expected-no-diagnostics + +enum E1 { + E11 = 0 +}; + +enum E2 { + E21 = 0, + E22 = E11, + E23 = E21 + E22 +}; diff --git a/clang/test/Sema/ptrauth-intrinsics-macro.c b/clang/test/Sema/ptrauth-intrinsics-macro.c new file mode 100644 index 0000000000000000000000000000000000000000..07d63740451452302a5e78a90d372a46020bd02c --- /dev/null +++ b/clang/test/Sema/ptrauth-intrinsics-macro.c @@ -0,0 +1,34 @@ +// RUN: %clang_cc1 -triple arm64-apple-ios -Wall -fsyntax-only -verify -fptrauth-intrinsics %s +// RUN: %clang_cc1 -triple arm64-apple-ios -Wall -fsyntax-only -verify %s + +// expected-no-diagnostics + +#include + +#define VALID_CODE_KEY 0 +#define VALID_DATA_KEY 2 + +extern int dv; + +void test(int *dp, int value) { + dp = ptrauth_strip(dp, VALID_DATA_KEY); + ptrauth_extra_data_t t0 = ptrauth_blend_discriminator(dp, value); + (void)t0; + dp = ptrauth_sign_unauthenticated(dp, VALID_DATA_KEY, 0); + dp = ptrauth_auth_and_resign(dp, VALID_DATA_KEY, dp, VALID_DATA_KEY, dp); + dp = ptrauth_auth_data(dp, VALID_DATA_KEY, 0); + int pu0 = 0, pu1 = 0, pu2 = 0, pu3 = 0, pu4 = 0, pu5 = 0, pu6 = 0, pu7 = 0; + ptrauth_blend_discriminator(&pu0, value); + ptrauth_auth_and_resign(&pu1, VALID_DATA_KEY, dp, VALID_DATA_KEY, dp); + ptrauth_auth_and_resign(dp, VALID_DATA_KEY, &pu2, VALID_DATA_KEY, dp); + ptrauth_auth_and_resign(dp, VALID_DATA_KEY, dp, VALID_DATA_KEY, &pu3); + ptrauth_sign_generic_data(pu4, dp); + ptrauth_sign_generic_data(dp, pu5); + ptrauth_auth_data(&pu6, VALID_DATA_KEY, value); + ptrauth_auth_data(dp, VALID_DATA_KEY, pu7); + + + + int t2 = ptrauth_sign_generic_data(dp, 0); + (void)t2; +} diff --git a/clang/test/Sema/ptrauth.c b/clang/test/Sema/ptrauth.c new file mode 100644 index 0000000000000000000000000000000000000000..3ad3d70c24e4130b9747b25af1030576316e10d9 --- /dev/null +++ b/clang/test/Sema/ptrauth.c @@ -0,0 +1,126 @@ +// RUN: %clang_cc1 -triple arm64-apple-ios -fsyntax-only -verify -fptrauth-intrinsics %s + +#if __has_feature(ptrauth_intrinsics) +#warning Pointer authentication enabled! +// expected-warning@-1 {{Pointer authentication enabled!}} +#endif + +#if __aarch64__ +#define VALID_CODE_KEY 0 +#define VALID_DATA_KEY 2 +#define INVALID_KEY 200 +#else +#error Provide these constants if you port this test +#endif + +#define NULL ((void*) 0) +struct A { int x; } mismatched_type; + +extern int dv; +extern int fv(int); + +void test_strip(int *dp, int (*fp)(int)) { + __builtin_ptrauth_strip(dp); // expected-error {{too few arguments}} + __builtin_ptrauth_strip(dp, VALID_DATA_KEY, dp); // expected-error {{too many arguments}} + (void) __builtin_ptrauth_strip(NULL, VALID_DATA_KEY); // no warning + + __builtin_ptrauth_strip(mismatched_type, VALID_DATA_KEY); // expected-error {{signed value must have pointer type; type here is 'struct A'}} + __builtin_ptrauth_strip(dp, mismatched_type); // expected-error {{passing 'struct A' to parameter of incompatible type 'int'}} + + int *dr = __builtin_ptrauth_strip(dp, VALID_DATA_KEY); + dr = __builtin_ptrauth_strip(dp, INVALID_KEY); // expected-error {{does not identify a valid pointer authentication key for the current target}} + + int (*fr)(int) = __builtin_ptrauth_strip(fp, VALID_CODE_KEY); + fr = __builtin_ptrauth_strip(fp, INVALID_KEY); // expected-error {{does not identify a valid pointer authentication key for the current target}} + + float *mismatch = __builtin_ptrauth_strip(dp, VALID_DATA_KEY); // expected-warning {{incompatible pointer types initializing 'float *' with an expression of type 'int *'}} +} + +void test_blend_discriminator(int *dp, int (*fp)(int), int value) { + __builtin_ptrauth_blend_discriminator(dp); // expected-error {{too few arguments}} + __builtin_ptrauth_blend_discriminator(dp, dp, dp); // expected-error {{too many arguments}} + (void) __builtin_ptrauth_blend_discriminator(dp, value); // no warning + + __builtin_ptrauth_blend_discriminator(mismatched_type, value); // expected-error {{blended pointer must have pointer type; type here is 'struct A'}} + __builtin_ptrauth_blend_discriminator(dp, mismatched_type); // expected-error {{blended integer must have integer type; type here is 'struct A'}} + + float *mismatch = __builtin_ptrauth_blend_discriminator(dp, value); // expected-error {{incompatible integer to pointer conversion initializing 'float *' with an expression of type}} +} + +void test_sign_unauthenticated(int *dp, int (*fp)(int)) { + __builtin_ptrauth_sign_unauthenticated(dp, VALID_DATA_KEY); // expected-error {{too few arguments}} + __builtin_ptrauth_sign_unauthenticated(dp, VALID_DATA_KEY, dp, dp); // expected-error {{too many arguments}} + + __builtin_ptrauth_sign_unauthenticated(mismatched_type, VALID_DATA_KEY, 0); // expected-error {{signed value must have pointer type; type here is 'struct A'}} + __builtin_ptrauth_sign_unauthenticated(dp, mismatched_type, 0); // expected-error {{passing 'struct A' to parameter of incompatible type 'int'}} + __builtin_ptrauth_sign_unauthenticated(dp, VALID_DATA_KEY, mismatched_type); // expected-error {{extra discriminator must have pointer or integer type; type here is 'struct A'}} + + (void) __builtin_ptrauth_sign_unauthenticated(NULL, VALID_DATA_KEY, 0); // expected-warning {{signing a null pointer will yield a non-null pointer}} + + int *dr = __builtin_ptrauth_sign_unauthenticated(dp, VALID_DATA_KEY, 0); + dr = __builtin_ptrauth_sign_unauthenticated(dp, INVALID_KEY, 0); // expected-error {{does not identify a valid pointer authentication key for the current target}} + + int (*fr)(int) = __builtin_ptrauth_sign_unauthenticated(fp, VALID_CODE_KEY, 0); + fr = __builtin_ptrauth_sign_unauthenticated(fp, INVALID_KEY, 0); // expected-error {{does not identify a valid pointer authentication key for the current target}} + + float *mismatch = __builtin_ptrauth_sign_unauthenticated(dp, VALID_DATA_KEY, 0); // expected-warning {{incompatible pointer types initializing 'float *' with an expression of type 'int *'}} +} + +void test_auth(int *dp, int (*fp)(int)) { + __builtin_ptrauth_auth(dp, VALID_DATA_KEY); // expected-error {{too few arguments}} + __builtin_ptrauth_auth(dp, VALID_DATA_KEY, dp, dp); // expected-error {{too many arguments}} + + __builtin_ptrauth_auth(mismatched_type, VALID_DATA_KEY, 0); // expected-error {{signed value must have pointer type; type here is 'struct A'}} + __builtin_ptrauth_auth(dp, mismatched_type, 0); // expected-error {{passing 'struct A' to parameter of incompatible type 'int'}} + __builtin_ptrauth_auth(dp, VALID_DATA_KEY, mismatched_type); // expected-error {{extra discriminator must have pointer or integer type; type here is 'struct A'}} + + (void) __builtin_ptrauth_auth(NULL, VALID_DATA_KEY, 0); // expected-warning {{authenticating a null pointer will almost certainly trap}} + + int *dr = __builtin_ptrauth_auth(dp, VALID_DATA_KEY, 0); + dr = __builtin_ptrauth_auth(dp, INVALID_KEY, 0); // expected-error {{does not identify a valid pointer authentication key for the current target}} + + int (*fr)(int) = __builtin_ptrauth_auth(fp, VALID_CODE_KEY, 0); + fr = __builtin_ptrauth_auth(fp, INVALID_KEY, 0); // expected-error {{does not identify a valid pointer authentication key for the current target}} + + float *mismatch = __builtin_ptrauth_auth(dp, VALID_DATA_KEY, 0); // expected-warning {{incompatible pointer types initializing 'float *' with an expression of type 'int *'}} +} + +void test_auth_and_resign(int *dp, int (*fp)(int)) { + __builtin_ptrauth_auth_and_resign(dp, VALID_DATA_KEY, 0, VALID_DATA_KEY); // expected-error {{too few arguments}} + __builtin_ptrauth_auth_and_resign(dp, VALID_DATA_KEY, dp, VALID_DATA_KEY, dp, 0); // expected-error {{too many arguments}} + + __builtin_ptrauth_auth_and_resign(mismatched_type, VALID_DATA_KEY, 0, VALID_DATA_KEY, dp); // expected-error {{signed value must have pointer type; type here is 'struct A'}} + __builtin_ptrauth_auth_and_resign(dp, mismatched_type, 0, VALID_DATA_KEY, dp); // expected-error {{passing 'struct A' to parameter of incompatible type 'int'}} + __builtin_ptrauth_auth_and_resign(dp, VALID_DATA_KEY, mismatched_type, VALID_DATA_KEY, dp); // expected-error {{extra discriminator must have pointer or integer type; type here is 'struct A'}} + __builtin_ptrauth_auth_and_resign(dp, VALID_DATA_KEY, 0, mismatched_type, dp); // expected-error {{passing 'struct A' to parameter of incompatible type 'int'}} + __builtin_ptrauth_auth_and_resign(dp, VALID_DATA_KEY, 0, VALID_DATA_KEY, mismatched_type); // expected-error {{extra discriminator must have pointer or integer type; type here is 'struct A'}} + + (void) __builtin_ptrauth_auth_and_resign(NULL, VALID_DATA_KEY, 0, VALID_DATA_KEY, dp); // expected-warning {{authenticating a null pointer will almost certainly trap}} + + int *dr = __builtin_ptrauth_auth_and_resign(dp, VALID_DATA_KEY, 0, VALID_DATA_KEY, dp); + dr = __builtin_ptrauth_auth_and_resign(dp, INVALID_KEY, 0, VALID_DATA_KEY, dp); // expected-error {{does not identify a valid pointer authentication key for the current target}} + dr = __builtin_ptrauth_auth_and_resign(dp, VALID_DATA_KEY, 0, INVALID_KEY, dp); // expected-error {{does not identify a valid pointer authentication key for the current target}} + + int (*fr)(int) = __builtin_ptrauth_auth_and_resign(fp, VALID_CODE_KEY, 0, VALID_CODE_KEY, dp); + fr = __builtin_ptrauth_auth_and_resign(fp, INVALID_KEY, 0, VALID_CODE_KEY, dp); // expected-error {{does not identify a valid pointer authentication key for the current target}} + fr = __builtin_ptrauth_auth_and_resign(fp, VALID_CODE_KEY, 0, INVALID_KEY, dp); // expected-error {{does not identify a valid pointer authentication key for the current target}} + + float *mismatch = __builtin_ptrauth_auth_and_resign(dp, VALID_DATA_KEY, 0, VALID_DATA_KEY, dp); // expected-warning {{incompatible pointer types initializing 'float *' with an expression of type 'int *'}} +} + +void test_sign_generic_data(int *dp) { + __builtin_ptrauth_sign_generic_data(dp); // expected-error {{too few arguments}} + __builtin_ptrauth_sign_generic_data(dp, 0, 0); // expected-error {{too many arguments}} + + __builtin_ptrauth_sign_generic_data(mismatched_type, 0); // expected-error {{signed value must have pointer or integer type; type here is 'struct A'}} + __builtin_ptrauth_sign_generic_data(dp, mismatched_type); // expected-error {{extra discriminator must have pointer or integer type; type here is 'struct A'}} + + (void) __builtin_ptrauth_sign_generic_data(NULL, 0); // no warning + + unsigned long dr = __builtin_ptrauth_sign_generic_data(dp, 0); + dr = __builtin_ptrauth_sign_generic_data(dp, &dv); + dr = __builtin_ptrauth_sign_generic_data(12314, 0); + dr = __builtin_ptrauth_sign_generic_data(12314, &dv); + + int *mismatch = __builtin_ptrauth_sign_generic_data(dp, 0); // expected-error {{incompatible integer to pointer conversion initializing 'int *' with an expression of type}} +} diff --git a/clang/test/Sema/return-type-mismatch.c b/clang/test/Sema/return-type-mismatch.c new file mode 100644 index 0000000000000000000000000000000000000000..79a625d7df1f54e83853f0d8c1e40fabb907bd05 --- /dev/null +++ b/clang/test/Sema/return-type-mismatch.c @@ -0,0 +1,36 @@ +// RUN: %clang_cc1 -Wreturn-type -Wno-return-mismatch -fsyntax-only -verify=return-type %s +// RUN: %clang_cc1 -Wno-return-type -Wreturn-mismatch -fsyntax-only -verify=return-mismatch %s + +int foo(void) __attribute__((noreturn)); +int bar(void); + +void test1(void) { + return 1; // return-mismatch-warning{{void function 'test1' should not return a value}} +} + +int test2(void) { + return; // return-mismatch-warning{{non-void function 'test2' should return a value}} +} + +int test3(void) { + // return-type-warning@+1 {{non-void function does not return a value}} +} + +int test4(void) { + (void)(bar() || foo()); // return-type-warning@+1 {{non-void function does not return a value in all control paths}} +} + +void test5(void) { +} // no-warning + +int test6(void) { + return 0; // no-warning +} + +int test7(void) { + foo(); // no warning +} + +int test8(void) { + bar(); // return-type-warning@+1 {{non-void function does not return a value}} +} diff --git a/clang/test/Sema/warn-bitwise-and-bool.c b/clang/test/Sema/warn-bitwise-and-bool.c index 6bec1be1abdef6600969c275327133de06cead4f..c30498e2bd8d1ab52fcdf5eb6540cd6c38db79c9 100644 --- a/clang/test/Sema/warn-bitwise-and-bool.c +++ b/clang/test/Sema/warn-bitwise-and-bool.c @@ -19,6 +19,8 @@ boolean baz(void) __attribute__((const)); void sink(boolean); #define FOO foo() +#define MY_AND & +#define My_BITAND bitand void test(boolean a, boolean b, int *p, volatile int *q, int i) { b = a & b; @@ -44,9 +46,12 @@ void test(boolean a, boolean b, int *p, volatile int *q, int i) { b = b & foo(); b = bar() & (i > 4); b = (i == 7) & foo(); + b = b MY_AND foo(); // OK, no warning expected + #ifdef __cplusplus - b = foo() bitand bar(); // expected-warning {{use of bitwise '&' with boolean operands}} - // expected-note@-1 {{cast one or both operands to int to silence this warning}} + b = foo() bitand bar(); // Ok, no warning expected + b = foo() My_BITAND bar(); // Ok, no warning expected + #endif if (foo() & bar()) // expected-warning {{use of bitwise '&' with boolean operands}} @@ -60,4 +65,5 @@ void test(boolean a, boolean b, int *p, volatile int *q, int i) { int n = i + 10; b = (n & (n - 1)); + } diff --git a/clang/test/Sema/warn-bitwise-or-bool.c b/clang/test/Sema/warn-bitwise-or-bool.c index ae86790901aac53a0581434385c17949ca190e11..e45ef28da0a70da0b9425075f4953d365d07a102 100644 --- a/clang/test/Sema/warn-bitwise-or-bool.c +++ b/clang/test/Sema/warn-bitwise-or-bool.c @@ -19,6 +19,8 @@ boolean baz(void) __attribute__((const)); void sink(boolean); #define FOO foo() +#define MY_OR | +#define My_BITOR bitor void test(boolean a, boolean b, int *p, volatile int *q, int i) { b = a | b; @@ -44,9 +46,11 @@ void test(boolean a, boolean b, int *p, volatile int *q, int i) { b = b | foo(); b = bar() | (i > 4); b = (i == 7) | foo(); + b = b MY_OR foo(); // OK, no warning expected #ifdef __cplusplus - b = foo() bitor bar(); // expected-warning {{use of bitwise '|' with boolean operands}} - // expected-note@-1 {{cast one or both operands to int to silence this warning}} + b = foo() bitor bar(); //Ok, no warning expected + b = foo() My_BITOR bar(); // Ok, no warning expected + #endif if (foo() | bar()) // expected-warning {{use of bitwise '|' with boolean operands}} diff --git a/clang/test/Sema/warn-compare-enum-types-mismatch.c b/clang/test/Sema/warn-compare-enum-types-mismatch.c index 2b72aae16b977a80cc9af2c83d57fb6b1104ba00..47dd592488e6dce440e0a70442dfb276474a2f90 100644 --- a/clang/test/Sema/warn-compare-enum-types-mismatch.c +++ b/clang/test/Sema/warn-compare-enum-types-mismatch.c @@ -1,12 +1,21 @@ // RUN: %clang_cc1 -x c -fsyntax-only -verify -Wenum-compare -Wno-unused-comparison %s // RUN: %clang_cc1 -x c++ -fsyntax-only -verify -Wenum-compare -Wno-unused-comparison %s +// In C enumerators (i.e enumeration constants) have type int (until C23). In +// order to support diagnostics such as -Wenum-compare we pretend they have the +// type of their enumeration. + typedef enum EnumA { A } EnumA; enum EnumB { - B + B, + B1 = 1, + // In C++ this comparison doesnt warn as enumerators dont have the type of + // their enumeration before the closing brace. We mantain the same behavior + // in C. + B2 = A == B1 }; enum { diff --git a/clang/test/SemaCUDA/amdgpu-attrs.cu b/clang/test/SemaCUDA/amdgpu-attrs.cu index 4811ef796c66b39a7ccebd30508310be53bd8aa4..e04b32d121bc8cd959ded0abfaf061238762c742 100644 --- a/clang/test/SemaCUDA/amdgpu-attrs.cu +++ b/clang/test/SemaCUDA/amdgpu-attrs.cu @@ -63,6 +63,16 @@ __global__ void flat_work_group_size_32_64_waves_per_eu_2_num_sgpr_32_num_vgpr_6 __attribute__((amdgpu_flat_work_group_size(32, 64), amdgpu_waves_per_eu(2, 4), amdgpu_num_sgpr(32), amdgpu_num_vgpr(64))) __global__ void flat_work_group_size_32_64_waves_per_eu_2_4_num_sgpr_32_num_vgpr_64() {} +__attribute__((amdgpu_max_num_work_groups(32, 1, 1))) +__global__ void max_num_work_groups_32_1_1() {} + +__attribute__((amdgpu_max_num_work_groups(32, 1, 1), amdgpu_flat_work_group_size(32, 64))) +__global__ void max_num_work_groups_32_1_1_flat_work_group_size_32_64() {} + +__attribute__((amdgpu_max_num_work_groups(32, 1, 1), amdgpu_flat_work_group_size(32, 64), amdgpu_waves_per_eu(2, 4), amdgpu_num_sgpr(32), amdgpu_num_vgpr(64))) +__global__ void max_num_work_groups_32_1_1_flat_work_group_size_32_64_waves_per_eu_2_4_num_sgpr_32_num_vgpr_64() {} + + // expected-error@+2{{attribute 'reqd_work_group_size' can only be applied to an OpenCL kernel function}} __attribute__((reqd_work_group_size(32, 64, 64))) __global__ void reqd_work_group_size_32_64_64() {} @@ -194,3 +204,125 @@ __global__ void non_cexpr_waves_per_eu_2() {} // expected-error@+1{{'amdgpu_waves_per_eu' attribute requires parameter 1 to be an integer constant}} __attribute__((amdgpu_waves_per_eu(2, ipow2(2)))) __global__ void non_cexpr_waves_per_eu_2_4() {} + +__attribute__((amdgpu_max_num_work_groups(32))) +__global__ void max_num_work_groups_32() {} + +__attribute__((amdgpu_max_num_work_groups(32, 1))) +__global__ void max_num_work_groups_32_1() {} + +// expected-error@+1{{'amdgpu_max_num_work_groups' attribute takes no more than 3 arguments}} +__attribute__((amdgpu_max_num_work_groups(32, 1, 1, 1))) +__global__ void max_num_work_groups_32_1_1_1() {} + +// expected-error@+1{{'amdgpu_max_num_work_groups' attribute takes at least 1 argument}} +__attribute__((amdgpu_max_num_work_groups())) +__global__ void max_num_work_groups_no_arg() {} + +// expected-error@+1{{expected expression}} +__attribute__((amdgpu_max_num_work_groups(,1,1))) +__global__ void max_num_work_groups_empty_1_1() {} + +// expected-error@+1{{expected expression}} +__attribute__((amdgpu_max_num_work_groups(32,,1))) +__global__ void max_num_work_groups_32_empty_1() {} + +// expected-error@+1{{'amdgpu_max_num_work_groups' attribute requires parameter 0 to be an integer constant}} +__attribute__((amdgpu_max_num_work_groups(ipow2(5), 1, 1))) +__global__ void max_num_work_groups_32_1_1_non_int_arg0() {} + +// expected-error@+1{{'amdgpu_max_num_work_groups' attribute requires parameter 1 to be an integer constant}} +__attribute__((amdgpu_max_num_work_groups(32, "1", 1))) +__global__ void max_num_work_groups_32_1_1_non_int_arg1() {} + +// expected-error@+1{{'amdgpu_max_num_work_groups' attribute requires a non-negative integral compile time constant expression}} +__attribute__((amdgpu_max_num_work_groups(-32, 1, 1))) +__global__ void max_num_work_groups_32_1_1_neg_int_arg0() {} + +// expected-error@+1{{'amdgpu_max_num_work_groups' attribute requires a non-negative integral compile time constant expression}} +__attribute__((amdgpu_max_num_work_groups(32, -1, 1))) +__global__ void max_num_work_groups_32_1_1_neg_int_arg1() {} + +// expected-error@+1{{'amdgpu_max_num_work_groups' attribute requires a non-negative integral compile time constant expression}} +__attribute__((amdgpu_max_num_work_groups(32, 1, -1))) +__global__ void max_num_work_groups_32_1_1_neg_int_arg2() {} + +// expected-error@+1{{'amdgpu_max_num_work_groups' attribute must be greater than 0}} +__attribute__((amdgpu_max_num_work_groups(0, 1, 1))) +__global__ void max_num_work_groups_0_1_1() {} + +// expected-error@+1{{'amdgpu_max_num_work_groups' attribute must be greater than 0}} +__attribute__((amdgpu_max_num_work_groups(32, 0, 1))) +__global__ void max_num_work_groups_32_0_1() {} + +// expected-error@+1{{'amdgpu_max_num_work_groups' attribute must be greater than 0}} +__attribute__((amdgpu_max_num_work_groups(32, 1, 0))) +__global__ void max_num_work_groups_32_1_0() {} + +__attribute__((amdgpu_max_num_work_groups(4294967295))) +__global__ void max_num_work_groups_max_unsigned_int() {} + +// expected-error@+1{{integer constant expression evaluates to value 4294967296 that cannot be represented in a 32-bit unsigned integer type}} +__attribute__((amdgpu_max_num_work_groups(4294967296))) +__global__ void max_num_work_groups_max_unsigned_int_plus1() {} + +// expected-error@+1{{integer constant expression evaluates to value 10000000000 that cannot be represented in a 32-bit unsigned integer type}} +__attribute__((amdgpu_max_num_work_groups(10000000000))) +__global__ void max_num_work_groups_too_large() {} + +int num_wg_x = 32; +int num_wg_y = 1; +int num_wg_z = 1; +// expected-error@+1{{'amdgpu_max_num_work_groups' attribute requires parameter 0 to be an integer constant}} +__attribute__((amdgpu_max_num_work_groups(num_wg_x, 1, 1))) +__global__ void max_num_work_groups_32_1_1_non_const_arg0() {} + +// expected-error@+1{{'amdgpu_max_num_work_groups' attribute requires parameter 1 to be an integer constant}} +__attribute__((amdgpu_max_num_work_groups(32, num_wg_y, 1))) +__global__ void max_num_work_groups_32_1_1_non_const_arg1() {} + +// expected-error@+1{{'amdgpu_max_num_work_groups' attribute requires parameter 2 to be an integer constant}} +__attribute__((amdgpu_max_num_work_groups(32, 1, num_wg_z))) +__global__ void max_num_work_groups_32_1_1_non_const_arg2() {} + +const int c_num_wg_x = 32; +__attribute__((amdgpu_max_num_work_groups(c_num_wg_x, 1, 1))) +__global__ void max_num_work_groups_32_1_1_const_arg0() {} + +template +__attribute__((amdgpu_max_num_work_groups(a, 1, 1))) +__global__ void template_a_1_1_max_num_work_groups() {} +template __global__ void template_a_1_1_max_num_work_groups<32>(); + +template +__attribute__((amdgpu_max_num_work_groups(32, a, 1))) +__global__ void template_32_a_1_max_num_work_groups() {} +template __global__ void template_32_a_1_max_num_work_groups<1>(); + +template +__attribute__((amdgpu_max_num_work_groups(32, 1, a))) +__global__ void template_32_1_a_max_num_work_groups() {} +template __global__ void template_32_1_a_max_num_work_groups<1>(); + +// expected-error@+3{{'amdgpu_max_num_work_groups' attribute must be greater than 0}} +// expected-note@+4{{in instantiation of}} +template +__attribute__((amdgpu_max_num_work_groups(b, 1, 1))) +__global__ void template_b_1_1_max_num_work_groups() {} +template __global__ void template_b_1_1_max_num_work_groups<0>(); + +// expected-error@+3{{'amdgpu_max_num_work_groups' attribute must be greater than 0}} +// expected-note@+4{{in instantiation of}} +template +__attribute__((amdgpu_max_num_work_groups(32, b, 1))) +__global__ void template_32_b_1_max_num_work_groups() {} +template __global__ void template_32_b_1_max_num_work_groups<0>(); + +// expected-error@+3{{'amdgpu_max_num_work_groups' attribute must be greater than 0}} +// expected-note@+4{{in instantiation of}} +template +__attribute__((amdgpu_max_num_work_groups(32, 1, b))) +__global__ void template_32_1_b_max_num_work_groups() {} +template __global__ void template_32_1_b_max_num_work_groups<0>(); + + diff --git a/clang/test/SemaCXX/constexpr-builtin-bit-cast.cpp b/clang/test/SemaCXX/constexpr-builtin-bit-cast.cpp index c5b8032f40b131a9940a4c78534d2e567a8d34a0..7520b43a194aba6860febbac01f0ad2858abbaa0 100644 --- a/clang/test/SemaCXX/constexpr-builtin-bit-cast.cpp +++ b/clang/test/SemaCXX/constexpr-builtin-bit-cast.cpp @@ -90,7 +90,8 @@ void test_record() { struct tuple4 { unsigned x, y, z, doublez; - constexpr bool operator==(tuple4 const &other) const { + bool operator==(tuple4 const &other) const = default; + constexpr bool operator==(bases const &other) const { return x == other.x && y == other.y && z == other.z && doublez == other.doublez; } @@ -99,6 +100,9 @@ void test_record() { constexpr tuple4 t4 = bit_cast(b); static_assert(t4 == tuple4{1, 2, 3, 4}); static_assert(round_trip(b)); + + constexpr auto b2 = bit_cast(t4); + static_assert(t4 == b2); } void test_partially_initialized() { diff --git a/clang/test/SemaCXX/constexpr-explicit-object-lambda.cpp b/clang/test/SemaCXX/constexpr-explicit-object-lambda.cpp new file mode 100644 index 0000000000000000000000000000000000000000..4e8e94d428d071f8a738bbb352b4592ea67eeff3 --- /dev/null +++ b/clang/test/SemaCXX/constexpr-explicit-object-lambda.cpp @@ -0,0 +1,34 @@ +// RUN: %clang_cc1 -std=c++23 -verify %s +// expected-no-diagnostics + +struct S { + int i = 42; + constexpr auto f1() { + return [this](this auto) { + return this->i; + }(); + }; + + constexpr auto f2() { + return [this](this auto&&) { + return this->i; + }(); + }; + + constexpr auto f3() { + return [i = this->i](this auto) { + return i; + }(); + }; + + constexpr auto f4() { + return [i = this->i](this auto&&) { + return i; + }(); + }; +}; + +static_assert(S().f1() == 42); +static_assert(S().f2() == 42); +static_assert(S().f3() == 42); +static_assert(S().f4() == 42); diff --git a/clang/test/SemaCXX/cxx20-ctad-type-alias.cpp b/clang/test/SemaCXX/cxx20-ctad-type-alias.cpp index 794496ed418489ecb3440a2246a61f6f926fb51f..3ce26c8fcd984ec8cd5407d08b6b55b7cd7380c9 100644 --- a/clang/test/SemaCXX/cxx20-ctad-type-alias.cpp +++ b/clang/test/SemaCXX/cxx20-ctad-type-alias.cpp @@ -230,3 +230,20 @@ using AFoo = Foo*; // expected-note {{template is declared here}} AFoo s = {1}; // expected-error {{alias template 'AFoo' requires template arguments; argument deduction only allowed for}} } // namespace test17 + +namespace test18 { +template +concept False = false; // expected-note {{because 'false' evaluated to false}} + +template struct Foo { T t; }; + +template requires False // expected-note {{because 'int' does not satisfy 'False'}} +Foo(T) -> Foo; + +template +using Bar = Foo; // expected-note {{could not match 'Foo' against 'int'}} \ + // expected-note {{candidate template ignored: constraints not satisfied}} \ + // expected-note {{candidate function template not viable}} + +Bar s = {1}; // expected-error {{no viable constructor or deduction guide for deduction of template arguments}} +} // namespace test18 diff --git a/clang/test/SemaCXX/cxx23-assume-disabled.cpp b/clang/test/SemaCXX/cxx23-assume-disabled.cpp new file mode 100644 index 0000000000000000000000000000000000000000..4233a2f7f433840244a6bf75c92ff4dc1cd50db4 --- /dev/null +++ b/clang/test/SemaCXX/cxx23-assume-disabled.cpp @@ -0,0 +1,14 @@ +// RUN: %clang_cc1 -std=c++23 -x c++ %s -fno-assumptions -verify +// RUN: %clang_cc1 -std=c++23 -x c++ %s -fms-compatibility -verify +// expected-no-diagnostics + +// We don't check assumptions at compile time if '-fno-assumptions' is passed, +// or if we're in MSVCCompat mode + +constexpr bool f(bool x) { + [[assume(x)]]; + return true; +} + +static_assert(f(false)); + diff --git a/clang/test/SemaCXX/cxx23-assume-print.cpp b/clang/test/SemaCXX/cxx23-assume-print.cpp new file mode 100644 index 0000000000000000000000000000000000000000..37db015fcc39095a58500c43e586d1efb02fc447 --- /dev/null +++ b/clang/test/SemaCXX/cxx23-assume-print.cpp @@ -0,0 +1,13 @@ +// RUN: %clang_cc1 -std=c++23 -ast-print %s | FileCheck %s + +// CHECK: void f(int x, int y) { +void f(int x, int y) { + // CHECK-NEXT: {{\[}}[assume(true)]] + [[assume(true)]]; + + // CHECK-NEXT: {{\[}}[assume(2 + 4)]] + [[assume(2 + 4)]]; + + // CHECK-NEXT: {{\[}}[assume(x == y)]] + [[assume(x == y)]]; +} diff --git a/clang/test/SemaCXX/cxx23-assume.cpp b/clang/test/SemaCXX/cxx23-assume.cpp new file mode 100644 index 0000000000000000000000000000000000000000..478da092471affa037b12dcf0d6441281e2d4e3e --- /dev/null +++ b/clang/test/SemaCXX/cxx23-assume.cpp @@ -0,0 +1,138 @@ +// RUN: %clang_cc1 -std=c++23 -x c++ %s -verify +// RUN: %clang_cc1 -std=c++20 -pedantic -x c++ %s -verify=ext,expected + +struct A{}; +struct B{ explicit operator bool() { return true; } }; + +template +void f() { + [[assume(cond)]]; // ext-warning {{C++23 extension}} +} + +template +struct S { + void f() { + [[assume(cond)]]; // ext-warning {{C++23 extension}} + } + + template + constexpr bool g() { + [[assume(cond == sizeof(T))]]; // expected-note {{assumption evaluated to false}} ext-warning {{C++23 extension}} + return true; + } +}; + +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}} +} + +void g(int x) { + f(); + f(); + S{}.f(); + S{}.f(); + S{}.g(); + S{}.g(); + [[assume(f2())]]; // expected-warning {{side effects that will be discarded}} 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((1, 2))]]; // expected-warning {{has no effect}} // ext-warning {{C++23 extension}} + + f3(); // expected-note {{in instantiation of}} + f3(); // expected-note {{in instantiation of}} + [[assume]]; // expected-error {{takes one argument}} + [[assume(z)]]; // expected-error {{undeclared identifier}} + [[assume(A{})]]; // expected-error {{not contextually convertible to 'bool'}} + [[assume(true)]] if (true) {} // expected-error {{only applies to empty statements}} + [[assume(true)]] {} // expected-error {{only applies to empty statements}} + [[assume(true)]] for (;false;) {} // expected-error {{only applies to empty statements}} + [[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}} +} + +// Check that 'x' is ODR-used here. +constexpr int h(int x) { return sizeof([=] { [[assume(x)]]; }); } // ext-warning {{C++23 extension}} +static_assert(h(4) == sizeof(int)); + +static_assert(__has_cpp_attribute(assume) == 202207L); +static_assert(__has_attribute(assume)); + +constexpr bool i() { // ext-error {{never produces a constant expression}} + [[assume(false)]]; // ext-note {{assumption evaluated to false}} expected-note {{assumption evaluated to false}} ext-warning {{C++23 extension}} + return true; +} + +constexpr bool j(bool b) { + [[assume(b)]]; // expected-note {{assumption evaluated to false}} ext-warning {{C++23 extension}} + return true; +} + +static_assert(i()); // expected-error {{not an integral constant expression}} expected-note {{in call to}} +static_assert(j(true)); +static_assert(j(false)); // expected-error {{not an integral constant expression}} expected-note {{in call to}} +static_assert(S{}.g()); +static_assert(S{}.g()); // expected-error {{not an integral constant expression}} expected-note {{in call to}} + + +template +constexpr bool f4() { + [[assume(!T{})]]; // expected-error {{invalid argument type 'D'}} // expected-warning 2 {{side effects}} ext-warning {{C++23 extension}} + return sizeof(T) == sizeof(int); +} + +template +concept C = f4(); // expected-note 3 {{in instantiation of}} + // expected-note@-1 3 {{while substituting}} + // expected-error@-2 2 {{resulted in a non-constant expression}} + +struct D { + int x; +}; + +struct E { + int x; + constexpr explicit operator bool() { return false; } +}; + +struct F { + int x; + int y; + constexpr explicit operator bool() { return false; } +}; + +template +constexpr int f5() requires C { return 1; } // expected-note {{while checking the satisfaction}} + // expected-note@-1 {{while substituting template arguments}} + // expected-note@-2 {{candidate template ignored}} + +template +constexpr int f5() requires (!C) { return 2; } // expected-note 4 {{while checking the satisfaction}} + // expected-note@-1 4 {{while substituting template arguments}} + // expected-note@-2 {{candidate template ignored}} + +static_assert(f5() == 1); +static_assert(f5() == 1); // expected-note 3 {{while checking constraint satisfaction}} + // expected-note@-1 3 {{in instantiation of}} + // expected-error@-2 {{no matching function for call}} + +static_assert(f5() == 2); +static_assert(f5() == 1); // expected-note {{while checking constraint satisfaction}} expected-note {{in instantiation of}} +static_assert(f5() == 2); // expected-note {{while checking constraint satisfaction}} expected-note {{in instantiation of}} + +// 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}} + return a; +} + +static_assert(foo() == 0); diff --git a/clang/test/SemaCXX/datasizeof.cpp b/clang/test/SemaCXX/datasizeof.cpp index 5baf2ecb24ed7a8405f43c3265ce2bcd2e25ecae..43135c00496638148b6d17dd46ba51223a56fcf8 100644 --- a/clang/test/SemaCXX/datasizeof.cpp +++ b/clang/test/SemaCXX/datasizeof.cpp @@ -1,4 +1,5 @@ // RUN: %clang_cc1 -fsyntax-only -triple x86_64-linux-gnu -verify %s +// RUN: %clang_cc1 -fsyntax-only -triple x86_64-linux-gnu -verify %s -fexperimental-new-constant-interpreter #if !__has_extension(datasizeof) # error "Expected datasizeof extension" diff --git a/clang/test/SemaCXX/decomposed-condition.cpp b/clang/test/SemaCXX/decomposed-condition.cpp index ab011f6ae4ba437caddcc89c193e4315e2160b70..e55bbee3134ca205c98c6bda4d186ed8b8c321cc 100644 --- a/clang/test/SemaCXX/decomposed-condition.cpp +++ b/clang/test/SemaCXX/decomposed-condition.cpp @@ -1,4 +1,5 @@ // RUN: %clang_cc1 -std=c++1z -Wno-binding-in-condition -verify %s +// RUN: %clang_cc1 -std=c++1z -Wno-binding-in-condition -verify %s -fexperimental-new-constant-interpreter struct X { bool flag; diff --git a/clang/test/SemaCXX/gh84064-1.cpp b/clang/test/SemaCXX/gh84064-1.cpp deleted file mode 100644 index d9c2738a002b8da4cd0ba3bc192898238795b32b..0000000000000000000000000000000000000000 --- a/clang/test/SemaCXX/gh84064-1.cpp +++ /dev/null @@ -1,79 +0,0 @@ -// RUN: %clang_cc1 -fsyntax-only -verify -I%S/Inputs -std=c++20 %s - -// expected-no-diagnostics - -#include "std-coroutine.h" - -using size_t = decltype(sizeof(0)); - -struct Generator { - struct promise_type { - int _val{}; - - Generator get_return_object() noexcept - { - return {}; - } - - std::suspend_never initial_suspend() noexcept - { - return {}; - } - - std::suspend_always final_suspend() noexcept - { - return {}; - } - - void return_void() noexcept {} - void unhandled_exception() noexcept {} - - template - static void* - operator new(size_t size, - This&, - TheRest&&...) noexcept - { - return nullptr; - } - - static void operator delete(void*, size_t) - { - } - }; -}; - -struct CapturingThisTest -{ - int x{}; - - void AsPointer() - { - auto lamb = [=,this]() -> Generator { - int y = x; - co_return; - }; - - static_assert(sizeof(decltype(lamb)) == sizeof(void*)); - } - - void AsStarThis() - { - auto lamb = [*this]() -> Generator { - int y = x; - co_return; - }; - - static_assert(sizeof(decltype(lamb)) == sizeof(int)); - } -}; - -int main() -{ - auto lamb = []() -> Generator { - co_return; - }; - - static_assert(sizeof(decltype(lamb)) == 1); -} - diff --git a/clang/test/SemaCXX/gh84064-2.cpp b/clang/test/SemaCXX/gh84064-2.cpp deleted file mode 100644 index 457de43eab6d9ec5a667d90194ff7fdd140b1c34..0000000000000000000000000000000000000000 --- a/clang/test/SemaCXX/gh84064-2.cpp +++ /dev/null @@ -1,53 +0,0 @@ -// RUN: %clang_cc1 -fsyntax-only -verify -I%S/Inputs -std=c++23 %s - -// expected-no-diagnostics - -#include "std-coroutine.h" - -using size_t = decltype(sizeof(0)); - -struct GeneratorStatic { - struct promise_type { - int _val{}; - - GeneratorStatic get_return_object() noexcept - { - return {}; - } - - std::suspend_never initial_suspend() noexcept - { - return {}; - } - - std::suspend_always final_suspend() noexcept - { - return {}; - } - - void return_void() noexcept {} - void unhandled_exception() noexcept {} - - template - static void* - operator new(size_t size, - TheRest&&...) noexcept - { - return nullptr; - } - - static void operator delete(void*, size_t) - { - } - }; -}; - - -int main() -{ - auto lambCpp23 = []() static -> GeneratorStatic { - co_return; - }; - - static_assert(sizeof(decltype(lambCpp23)) == 1); -} diff --git a/clang/test/SemaCXX/lambda-expressions.cpp b/clang/test/SemaCXX/lambda-expressions.cpp index 0516a5da31ae9a94f7c2da454f15189daf2a8b6f..389002ab0e349bd9f38c04e994a12fd1f7bdf8a7 100644 --- a/clang/test/SemaCXX/lambda-expressions.cpp +++ b/clang/test/SemaCXX/lambda-expressions.cpp @@ -1,3 +1,4 @@ +// RUN: %clang_cc1 -std=c++11 -Wno-unused-value -fsyntax-only -verify=expected,expected-cxx14,cxx11 -fblocks %s // RUN: %clang_cc1 -std=c++14 -Wno-unused-value -fsyntax-only -verify -verify=expected-cxx14 -fblocks %s // RUN: %clang_cc1 -std=c++17 -Wno-unused-value -verify -ast-dump -fblocks %s | FileCheck %s @@ -558,8 +559,8 @@ struct B { int x; A a = [&] { int y = x; }; A b = [&] { [&] { [&] { int y = x; }; }; }; - A d = [&](auto param) { int y = x; }; - A e = [&](auto param) { [&] { [&](auto param2) { int y = x; }; }; }; + A d = [&](auto param) { int y = x; }; // cxx11-error {{'auto' not allowed in lambda parameter}} + A e = [&](auto param) { [&] { [&](auto param2) { int y = x; }; }; }; // cxx11-error 2 {{'auto' not allowed in lambda parameter}} }; B b; @@ -589,6 +590,7 @@ struct S1 { void foo1() { auto s0 = S1{[name=]() {}}; // expected-error 2 {{expected expression}} auto s1 = S1{[name=name]() {}}; // expected-error {{use of undeclared identifier 'name'; did you mean 'name1'?}} + // cxx11-warning@-1 {{initialized lambda captures are a C++14 extension}} } } @@ -604,7 +606,7 @@ namespace PR25627_dont_odr_use_local_consts { namespace ConversionOperatorDoesNotHaveDeducedReturnType { auto x = [](int){}; - auto y = [](auto &v) -> void { v.n = 0; }; + auto y = [](auto &v) -> void { v.n = 0; }; // cxx11-error {{'auto' not allowed in lambda parameter}} cxx11-note {{candidate function not viable}} cxx11-note {{conversion candidate}} using T = decltype(x); using U = decltype(y); using ExpectedTypeT = void (*)(int); @@ -624,22 +626,22 @@ namespace ConversionOperatorDoesNotHaveDeducedReturnType { template friend constexpr U::operator ExpectedTypeU() const noexcept; #else - friend auto T::operator()(int) const; + friend auto T::operator()(int) const; // cxx11-error {{'auto' return without trailing return type; deduced return types are a C++14 extension}} friend T::operator ExpectedTypeT() const; template - friend void U::operator()(T&) const; + friend void U::operator()(T&) const; // cxx11-error {{friend declaration of 'operator()' does not match any declaration}} // FIXME: This should not match, as above. template - friend U::operator ExpectedTypeU() const; + friend U::operator ExpectedTypeU() const; // cxx11-error {{friend declaration of 'operator void (*)(type-parameter-0-0 &)' does not match any declaration}} #endif private: int n; }; - // Should be OK: lambda's call operator is a friend. - void use(X &x) { y(x); } + // Should be OK in C++14 and later: lambda's call operator is a friend. + void use(X &x) { y(x); } // cxx11-error {{no matching function for call to object}} // This used to crash in return type deduction for the conversion opreator. struct A { int n; void f() { +[](decltype(n)) {}; } }; @@ -733,6 +735,8 @@ void GH67492() { auto lambda = (test, []() noexcept(true) {}); } +// FIXME: This currently causes clang to crash in C++11 mode. +#if __cplusplus >= 201402L namespace GH83267 { auto l = [](auto a) { return 1; }; using type = decltype(l); @@ -747,3 +751,4 @@ using t = decltype(ll); template auto t::operator()(int a) const; // expected-note {{in instantiation}} } +#endif diff --git a/clang/test/SemaCXX/overload-bitint.cpp b/clang/test/SemaCXX/overload-bitint.cpp new file mode 100644 index 0000000000000000000000000000000000000000..b834a3b01fede6c84fc673f51ac9c1c37496fc52 --- /dev/null +++ b/clang/test/SemaCXX/overload-bitint.cpp @@ -0,0 +1,42 @@ +// RUN: %clang_cc1 -std=c++20 %s -verify +// expected-no-diagnostics + +#include "Inputs/std-compare.h" + +struct S { + _BitInt(12) a; + + constexpr operator _BitInt(12)() const { return a; } +}; + +// None of these used to compile because we weren't adding _BitInt types to the +// overload set for builtin operators. See GH82998. +static_assert(S{10} < 11); +static_assert(S{10} <= 11); +static_assert(S{12} > 11); +static_assert(S{12} >= 11); +static_assert(S{10} == 10); +static_assert((S{10} <=> 10) == 0); +static_assert(S{10} != 11); +static_assert(S{10} + 0 == 10); +static_assert(S{10} - 0 == 10); +static_assert(S{10} * 1 == 10); +static_assert(S{10} / 1 == 10); +static_assert(S{10} % 1 == 0); +static_assert(S{10} << 0 == 10); +static_assert(S{10} >> 0 == 10); +static_assert((S{10} | 0) == 10); +static_assert((S{10} & 10) == 10); +static_assert((S{10} ^ 0) == 10); +static_assert(-S{10} == -10); +static_assert(+S{10} == +10); +static_assert(~S{10} == ~10); + +struct A { + _BitInt(12) a; + + bool operator==(const A&) const = default; + bool operator!=(const A&) const = default; + std::strong_ordering operator<=>(const A&) const = default; +}; + diff --git a/clang/test/SemaCXX/type-traits.cpp b/clang/test/SemaCXX/type-traits.cpp index f50f51cc70982e479df9298bb262cef95aee30a4..14ec17989ec7c75a4c2edf6b823646a8bf63309c 100644 --- a/clang/test/SemaCXX/type-traits.cpp +++ b/clang/test/SemaCXX/type-traits.cpp @@ -1722,91 +1722,91 @@ struct StructWithAnonUnion3 { void is_layout_compatible(int n) { - static_assert(__is_layout_compatible(void, void), ""); - static_assert(!__is_layout_compatible(void, int), ""); - static_assert(__is_layout_compatible(void, const void), ""); - static_assert(__is_layout_compatible(void, volatile void), ""); - static_assert(__is_layout_compatible(const int, volatile int), ""); - static_assert(__is_layout_compatible(int, int), ""); - static_assert(__is_layout_compatible(int, const int), ""); - static_assert(__is_layout_compatible(int, volatile int), ""); - static_assert(__is_layout_compatible(const int, volatile int), ""); - static_assert(__is_layout_compatible(int *, int * __restrict), ""); + static_assert(__is_layout_compatible(void, void)); + static_assert(!__is_layout_compatible(void, int)); + static_assert(__is_layout_compatible(void, const void)); + static_assert(__is_layout_compatible(void, volatile void)); + static_assert(__is_layout_compatible(const int, volatile int)); + static_assert(__is_layout_compatible(int, int)); + static_assert(__is_layout_compatible(int, const int)); + static_assert(__is_layout_compatible(int, volatile int)); + static_assert(__is_layout_compatible(const int, volatile int)); + static_assert(__is_layout_compatible(int *, int * __restrict)); // Note: atomic qualification matters for layout compatibility. - static_assert(!__is_layout_compatible(int, _Atomic int), ""); - static_assert(__is_layout_compatible(_Atomic(int), _Atomic int), ""); - static_assert(!__is_layout_compatible(int, unsigned int), ""); - static_assert(!__is_layout_compatible(char, unsigned char), ""); - static_assert(!__is_layout_compatible(char, signed char), ""); - static_assert(!__is_layout_compatible(unsigned char, signed char), ""); - static_assert(__is_layout_compatible(int[], int[]), ""); - static_assert(__is_layout_compatible(int[2], int[2]), ""); - static_assert(!__is_layout_compatible(int[n], int[2]), ""); // FIXME: VLAs should be rejected - static_assert(!__is_layout_compatible(int[n], int[n]), ""); // FIXME: VLAs should be rejected - static_assert(__is_layout_compatible(int&, int&), ""); - static_assert(!__is_layout_compatible(int&, char&), ""); - static_assert(__is_layout_compatible(void(int), void(int)), ""); - static_assert(!__is_layout_compatible(void(int), void(char)), ""); - static_assert(__is_layout_compatible(void(&)(int), void(&)(int)), ""); - static_assert(!__is_layout_compatible(void(&)(int), void(&)(char)), ""); - static_assert(__is_layout_compatible(void(*)(int), void(*)(int)), ""); - static_assert(!__is_layout_compatible(void(*)(int), void(*)(char)), ""); + static_assert(!__is_layout_compatible(int, _Atomic int)); + static_assert(__is_layout_compatible(_Atomic(int), _Atomic int)); + static_assert(!__is_layout_compatible(int, unsigned int)); + static_assert(!__is_layout_compatible(char, unsigned char)); + static_assert(!__is_layout_compatible(char, signed char)); + static_assert(!__is_layout_compatible(unsigned char, signed char)); + static_assert(__is_layout_compatible(int[], int[])); + static_assert(__is_layout_compatible(int[2], int[2])); + static_assert(!__is_layout_compatible(int[n], int[2])); // FIXME: VLAs should be rejected + static_assert(!__is_layout_compatible(int[n], int[n])); // FIXME: VLAs should be rejected + static_assert(__is_layout_compatible(int&, int&)); + static_assert(!__is_layout_compatible(int&, char&)); + static_assert(__is_layout_compatible(void(int), void(int))); + static_assert(!__is_layout_compatible(void(int), void(char))); + static_assert(__is_layout_compatible(void(&)(int), void(&)(int))); + static_assert(!__is_layout_compatible(void(&)(int), void(&)(char))); + static_assert(__is_layout_compatible(void(*)(int), void(*)(int))); + static_assert(!__is_layout_compatible(void(*)(int), void(*)(char))); using function_type = void(); using function_type2 = void(char); - static_assert(__is_layout_compatible(const function_type, const function_type), ""); + static_assert(__is_layout_compatible(const function_type, const function_type)); // expected-warning@-1 {{'const' qualifier on function type 'function_type' (aka 'void ()') has no effect}} // expected-warning@-2 {{'const' qualifier on function type 'function_type' (aka 'void ()') has no effect}} - static_assert(__is_layout_compatible(function_type, const function_type), ""); + static_assert(__is_layout_compatible(function_type, const function_type)); // expected-warning@-1 {{'const' qualifier on function type 'function_type' (aka 'void ()') has no effect}} - static_assert(!__is_layout_compatible(const function_type, const function_type2), ""); + static_assert(!__is_layout_compatible(const function_type, const function_type2)); // expected-warning@-1 {{'const' qualifier on function type 'function_type' (aka 'void ()') has no effect}} // expected-warning@-2 {{'const' qualifier on function type 'function_type2' (aka 'void (char)') has no effect}} - static_assert(__is_layout_compatible(CStruct, CStruct2), ""); - static_assert(__is_layout_compatible(CStruct, const CStruct2), ""); - static_assert(__is_layout_compatible(CStruct, volatile CStruct2), ""); - static_assert(__is_layout_compatible(const CStruct, volatile CStruct2), ""); - static_assert(__is_layout_compatible(CEmptyStruct, CEmptyStruct2), ""); - static_assert(__is_layout_compatible(CppEmptyStruct, CppEmptyStruct2), ""); - static_assert(__is_layout_compatible(CppStructStandard, CppStructStandard2), ""); - static_assert(!__is_layout_compatible(CppStructNonStandardByBase, CppStructNonStandardByBase2), ""); - static_assert(!__is_layout_compatible(CppStructNonStandardByVirt, CppStructNonStandardByVirt2), ""); - static_assert(!__is_layout_compatible(CppStructNonStandardByMemb, CppStructNonStandardByMemb2), ""); - static_assert(!__is_layout_compatible(CppStructNonStandardByProt, CppStructNonStandardByProt2), ""); - static_assert(!__is_layout_compatible(CppStructNonStandardByVirtBase, CppStructNonStandardByVirtBase2), ""); - static_assert(!__is_layout_compatible(CppStructNonStandardBySameBase, CppStructNonStandardBySameBase2), ""); - static_assert(!__is_layout_compatible(CppStructNonStandardBy2ndVirtBase, CppStructNonStandardBy2ndVirtBase2), ""); - static_assert(__is_layout_compatible(CStruct, CStructWithQualifiers), ""); - static_assert(__is_layout_compatible(CStruct, CStructNoUniqueAddress) != bool(__has_cpp_attribute(no_unique_address)), ""); - static_assert(__is_layout_compatible(CStructNoUniqueAddress, CStructNoUniqueAddress2) != bool(__has_cpp_attribute(no_unique_address)), ""); - static_assert(__is_layout_compatible(CStruct, CStructAlignment), ""); - static_assert(!__is_layout_compatible(CStruct, CStructAlignedMembers), ""); - static_assert(__is_layout_compatible(UnionNoOveralignedMembers, UnionWithOveralignedMembers), ""); - static_assert(__is_layout_compatible(CStructWithBitfelds, CStructWithBitfelds), ""); - static_assert(__is_layout_compatible(CStructWithBitfelds, CStructWithBitfelds2), ""); - static_assert(!__is_layout_compatible(CStructWithBitfelds, CStructWithBitfelds3), ""); - static_assert(!__is_layout_compatible(CStructWithBitfelds, CStructWithBitfelds4), ""); - static_assert(__is_layout_compatible(int CStruct2::*, int CStruct2::*), ""); - static_assert(!__is_layout_compatible(int CStruct2::*, char CStruct2::*), ""); - static_assert(__is_layout_compatible(void(CStruct2::*)(int), void(CStruct2::*)(int)), ""); - static_assert(!__is_layout_compatible(void(CStruct2::*)(int), void(CStruct2::*)(char)), ""); - static_assert(__is_layout_compatible(CStructNested, CStructNested2), ""); - static_assert(__is_layout_compatible(UnionLayout, UnionLayout), ""); - static_assert(!__is_layout_compatible(UnionLayout, UnionLayout2), ""); - static_assert(!__is_layout_compatible(UnionLayout, UnionLayout3), ""); - static_assert(!__is_layout_compatible(StructWithAnonUnion, StructWithAnonUnion2), ""); - static_assert(!__is_layout_compatible(StructWithAnonUnion, StructWithAnonUnion3), ""); - static_assert(__is_layout_compatible(EnumLayout, EnumClassLayout), ""); - static_assert(__is_layout_compatible(EnumForward, EnumForward), ""); - static_assert(__is_layout_compatible(EnumForward, EnumClassForward), ""); + static_assert(__is_layout_compatible(CStruct, CStruct2)); + static_assert(__is_layout_compatible(CStruct, const CStruct2)); + static_assert(__is_layout_compatible(CStruct, volatile CStruct2)); + static_assert(__is_layout_compatible(const CStruct, volatile CStruct2)); + static_assert(__is_layout_compatible(CEmptyStruct, CEmptyStruct2)); + static_assert(__is_layout_compatible(CppEmptyStruct, CppEmptyStruct2)); + static_assert(__is_layout_compatible(CppStructStandard, CppStructStandard2)); + static_assert(!__is_layout_compatible(CppStructNonStandardByBase, CppStructNonStandardByBase2)); + static_assert(!__is_layout_compatible(CppStructNonStandardByVirt, CppStructNonStandardByVirt2)); + static_assert(!__is_layout_compatible(CppStructNonStandardByMemb, CppStructNonStandardByMemb2)); + static_assert(!__is_layout_compatible(CppStructNonStandardByProt, CppStructNonStandardByProt2)); + static_assert(!__is_layout_compatible(CppStructNonStandardByVirtBase, CppStructNonStandardByVirtBase2)); + static_assert(!__is_layout_compatible(CppStructNonStandardBySameBase, CppStructNonStandardBySameBase2)); + static_assert(!__is_layout_compatible(CppStructNonStandardBy2ndVirtBase, CppStructNonStandardBy2ndVirtBase2)); + static_assert(__is_layout_compatible(CStruct, CStructWithQualifiers)); + static_assert(__is_layout_compatible(CStruct, CStructNoUniqueAddress) != bool(__has_cpp_attribute(no_unique_address))); + static_assert(__is_layout_compatible(CStructNoUniqueAddress, CStructNoUniqueAddress2) != bool(__has_cpp_attribute(no_unique_address))); + static_assert(__is_layout_compatible(CStruct, CStructAlignment)); + static_assert(!__is_layout_compatible(CStruct, CStructAlignedMembers)); + static_assert(__is_layout_compatible(UnionNoOveralignedMembers, UnionWithOveralignedMembers)); + static_assert(__is_layout_compatible(CStructWithBitfelds, CStructWithBitfelds)); + static_assert(__is_layout_compatible(CStructWithBitfelds, CStructWithBitfelds2)); + static_assert(!__is_layout_compatible(CStructWithBitfelds, CStructWithBitfelds3)); + static_assert(!__is_layout_compatible(CStructWithBitfelds, CStructWithBitfelds4)); + static_assert(__is_layout_compatible(int CStruct2::*, int CStruct2::*)); + static_assert(!__is_layout_compatible(int CStruct2::*, char CStruct2::*)); + static_assert(__is_layout_compatible(void(CStruct2::*)(int), void(CStruct2::*)(int))); + static_assert(!__is_layout_compatible(void(CStruct2::*)(int), void(CStruct2::*)(char))); + static_assert(__is_layout_compatible(CStructNested, CStructNested2)); + static_assert(__is_layout_compatible(UnionLayout, UnionLayout)); + static_assert(!__is_layout_compatible(UnionLayout, UnionLayout2)); + static_assert(!__is_layout_compatible(UnionLayout, UnionLayout3)); + static_assert(!__is_layout_compatible(StructWithAnonUnion, StructWithAnonUnion2)); + static_assert(!__is_layout_compatible(StructWithAnonUnion, StructWithAnonUnion3)); + static_assert(__is_layout_compatible(EnumLayout, EnumClassLayout)); + static_assert(__is_layout_compatible(EnumForward, EnumForward)); + static_assert(__is_layout_compatible(EnumForward, EnumClassForward)); // Layout compatibility for enums might be relaxed in the future. See https://github.com/cplusplus/CWG/issues/39#issuecomment-1184791364 - static_assert(!__is_layout_compatible(EnumLayout, int), ""); - static_assert(!__is_layout_compatible(EnumClassLayout, int), ""); - static_assert(!__is_layout_compatible(EnumForward, int), ""); - static_assert(!__is_layout_compatible(EnumClassForward, int), ""); + static_assert(!__is_layout_compatible(EnumLayout, int)); + static_assert(!__is_layout_compatible(EnumClassLayout, int)); + static_assert(!__is_layout_compatible(EnumForward, int)); + static_assert(!__is_layout_compatible(EnumClassForward, int)); // FIXME: the following should be rejected (array of unknown bound and void are the only allowed incomplete types) - static_assert(__is_layout_compatible(CStructIncomplete, CStructIncomplete), ""); - static_assert(!__is_layout_compatible(CStruct, CStructIncomplete), ""); - static_assert(__is_layout_compatible(CStructIncomplete[2], CStructIncomplete[2]), ""); + static_assert(__is_layout_compatible(CStructIncomplete, CStructIncomplete)); + static_assert(!__is_layout_compatible(CStruct, CStructIncomplete)); + static_assert(__is_layout_compatible(CStructIncomplete[2], CStructIncomplete[2])); } void is_signed() @@ -3340,6 +3340,8 @@ namespace is_trivially_relocatable { static_assert(!__is_trivially_relocatable(void)); static_assert(__is_trivially_relocatable(int)); static_assert(__is_trivially_relocatable(int[])); +static_assert(__is_trivially_relocatable(const int)); +static_assert(__is_trivially_relocatable(volatile int)); enum Enum {}; static_assert(__is_trivially_relocatable(Enum)); @@ -3351,7 +3353,28 @@ static_assert(__is_trivially_relocatable(Union[])); struct Trivial {}; static_assert(__is_trivially_relocatable(Trivial)); +static_assert(__is_trivially_relocatable(const Trivial)); +static_assert(__is_trivially_relocatable(volatile Trivial)); + static_assert(__is_trivially_relocatable(Trivial[])); +static_assert(__is_trivially_relocatable(const Trivial[])); +static_assert(__is_trivially_relocatable(volatile Trivial[])); + +static_assert(__is_trivially_relocatable(int[10])); +static_assert(__is_trivially_relocatable(const int[10])); +static_assert(__is_trivially_relocatable(volatile int[10])); + +static_assert(__is_trivially_relocatable(int[10][10])); +static_assert(__is_trivially_relocatable(const int[10][10])); +static_assert(__is_trivially_relocatable(volatile int[10][10])); + +static_assert(__is_trivially_relocatable(int[])); +static_assert(__is_trivially_relocatable(const int[])); +static_assert(__is_trivially_relocatable(volatile int[])); + +static_assert(__is_trivially_relocatable(int[][10])); +static_assert(__is_trivially_relocatable(const int[][10])); +static_assert(__is_trivially_relocatable(volatile int[][10])); struct Incomplete; // expected-note {{forward declaration of 'is_trivially_relocatable::Incomplete'}} bool unused = __is_trivially_relocatable(Incomplete); // expected-error {{incomplete type}} @@ -3361,6 +3384,8 @@ struct NontrivialDtor { }; static_assert(!__is_trivially_relocatable(NontrivialDtor)); static_assert(!__is_trivially_relocatable(NontrivialDtor[])); +static_assert(!__is_trivially_relocatable(const NontrivialDtor)); +static_assert(!__is_trivially_relocatable(volatile NontrivialDtor)); struct NontrivialCopyCtor { NontrivialCopyCtor(const NontrivialCopyCtor&) {} @@ -3379,12 +3404,16 @@ struct [[clang::trivial_abi]] TrivialAbiNontrivialDtor { }; static_assert(__is_trivially_relocatable(TrivialAbiNontrivialDtor)); static_assert(__is_trivially_relocatable(TrivialAbiNontrivialDtor[])); +static_assert(__is_trivially_relocatable(const TrivialAbiNontrivialDtor)); +static_assert(__is_trivially_relocatable(volatile TrivialAbiNontrivialDtor)); struct [[clang::trivial_abi]] TrivialAbiNontrivialCopyCtor { TrivialAbiNontrivialCopyCtor(const TrivialAbiNontrivialCopyCtor&) {} }; static_assert(__is_trivially_relocatable(TrivialAbiNontrivialCopyCtor)); static_assert(__is_trivially_relocatable(TrivialAbiNontrivialCopyCtor[])); +static_assert(__is_trivially_relocatable(const TrivialAbiNontrivialCopyCtor)); +static_assert(__is_trivially_relocatable(volatile TrivialAbiNontrivialCopyCtor)); // A more complete set of tests for the behavior of trivial_abi can be found in // clang/test/SemaCXX/attr-trivial-abi.cpp @@ -3393,6 +3422,8 @@ struct [[clang::trivial_abi]] TrivialAbiNontrivialMoveCtor { }; static_assert(__is_trivially_relocatable(TrivialAbiNontrivialMoveCtor)); static_assert(__is_trivially_relocatable(TrivialAbiNontrivialMoveCtor[])); +static_assert(__is_trivially_relocatable(const TrivialAbiNontrivialMoveCtor)); +static_assert(__is_trivially_relocatable(volatile TrivialAbiNontrivialMoveCtor)); } // namespace is_trivially_relocatable diff --git a/clang/test/SemaCXX/warn-constant-evaluated-constexpr.cpp b/clang/test/SemaCXX/warn-constant-evaluated-constexpr.cpp index 35dc69cccb3a2e299d72386610c9fb2257bf0278..fa40c13971118da4564c7d3c1691183b5deb701b 100644 --- a/clang/test/SemaCXX/warn-constant-evaluated-constexpr.cpp +++ b/clang/test/SemaCXX/warn-constant-evaluated-constexpr.cpp @@ -1,4 +1,5 @@ // RUN: %clang_cc1 -std=c++2a -fsyntax-only -verify %s +// RUN: %clang_cc1 -std=c++2a -fsyntax-only -verify %s -fexperimental-new-constant-interpreter namespace std { constexpr bool is_constant_evaluated() noexcept { diff --git a/clang/test/SemaHLSL/BuiltIns/clamp-errors.hlsl b/clang/test/SemaHLSL/BuiltIns/clamp-errors.hlsl new file mode 100644 index 0000000000000000000000000000000000000000..4c0e5315ce532e14360d5ca899a6e559d899e640 --- /dev/null +++ b/clang/test/SemaHLSL/BuiltIns/clamp-errors.hlsl @@ -0,0 +1,91 @@ +// RUN: %clang_cc1 -finclude-default-header -triple dxil-pc-shadermodel6.6-library %s -fnative-half-type -emit-llvm -disable-llvm-passes -verify -verify-ignore-unexpected + +float2 test_no_second_arg(float2 p0) { + return __builtin_hlsl_elementwise_clamp(p0); + // expected-error@-1 {{too few arguments to function call, expected 3, have 1}} +} + +float2 test_no_third_arg(float2 p0) { + return __builtin_hlsl_elementwise_clamp(p0, p0); + // expected-error@-1 {{too few arguments to function call, expected 3, have 2}} +} + +float2 test_too_many_arg(float2 p0) { + return __builtin_hlsl_elementwise_clamp(p0, p0, p0, p0); + // expected-error@-1 {{too many arguments to function call, expected 3, have 4}} +} + +float2 test_clamp_no_second_arg(float2 p0) { + return clamp(p0); + // expected-error@-1 {{no matching function for call to 'clamp'}} +} + +float2 test_clamp_vector_size_mismatch(float3 p0, float2 p1) { + return clamp(p0, p0, p1); + // expected-warning@-1 {{implicit conversion truncates vector: 'float3' (aka 'vector') to 'float __attribute__((ext_vector_type(2)))' (vector of 2 'float' values)}} +} + +float2 test_clamp_builtin_vector_size_mismatch(float3 p0, float2 p1) { + return __builtin_hlsl_elementwise_clamp(p0, p1, p1); + // expected-error@-1 {{all arguments to '__builtin_hlsl_elementwise_clamp' must have the same type}} +} + +float test_clamp_scalar_mismatch(float p0, half p1) { + return clamp(p1, p0, p1); + // expected-error@-1 {{call to 'clamp' is ambiguous}} +} + +float2 test_clamp_element_type_mismatch(half2 p0, float2 p1) { + return clamp(p1, p0, p1); + // expected-error@-1 {{call to 'clamp' is ambiguous}} +} + +float2 test_builtin_clamp_float2_splat(float p0, float2 p1) { + return __builtin_hlsl_elementwise_clamp(p0, p1, p1); + // expected-error@-1 {{all arguments to '__builtin_hlsl_elementwise_clamp' must be vectors}} +} + +float3 test_builtin_clamp_float3_splat(float p0, float3 p1) { + return __builtin_hlsl_elementwise_clamp(p0, p1, p1); + // expected-error@-1 {{all arguments to '__builtin_hlsl_elementwise_clamp' must be vectors}} +} + +float4 test_builtin_clamp_float4_splat(float p0, float4 p1) { + return __builtin_hlsl_elementwise_clamp(p0, p1, p1); + // expected-error@-1 {{all arguments to '__builtin_hlsl_elementwise_clamp' must be vectors}} +} + +float2 test_clamp_float2_int_splat(float2 p0, int p1) { + return __builtin_hlsl_elementwise_clamp(p0, p1, p1); + // expected-error@-1 {{all arguments to '__builtin_hlsl_elementwise_clamp' must be vectors}} +} + +float3 test_clamp_float3_int_splat(float3 p0, int p1) { + return __builtin_hlsl_elementwise_clamp(p0, p1, p1); + // expected-error@-1 {{all arguments to '__builtin_hlsl_elementwise_clamp' must be vectors}} +} + +float2 test_builtin_clamp_int_vect_to_float_vec_promotion(int2 p0, float p1) { + return __builtin_hlsl_elementwise_clamp(p0, p1, p1); + // expected-error@-1 {{all arguments to '__builtin_hlsl_elementwise_clamp' must be vectors}} +} + +float test_builtin_clamp_bool_type_promotion(bool p0) { + return __builtin_hlsl_elementwise_clamp(p0, p0, p0); + // expected-error@-1 {{1st argument must be a vector, integer or floating point type (was 'bool')}} +} + +float builtin_bool_to_float_type_promotion(float p0, bool p1) { + return __builtin_hlsl_elementwise_clamp(p0, p0, p1); + // expected-error@-1 {{3rd argument must be a floating point type (was 'bool')}} +} + +float builtin_bool_to_float_type_promotion2(bool p0, float p1) { + return __builtin_hlsl_elementwise_clamp(p1, p0, p1); + // expected-error@-1 {{2nd argument must be a floating point type (was 'bool')}} +} + +float builtin_clamp_int_to_float_promotion(float p0, int p1) { + return __builtin_hlsl_elementwise_clamp(p0, p0, p1); + // expected-error@-1 {{3rd argument must be a floating point type (was 'int')}} +} diff --git a/clang/test/SemaHLSL/BuiltIns/frac-errors.hlsl b/clang/test/SemaHLSL/BuiltIns/frac-errors.hlsl index 06dbdf0a68dfc1cb0cad471b36008d2472a53a47..f82b5942fd46b6112f153e7538dd4d9cd362b7d6 100644 --- a/clang/test/SemaHLSL/BuiltIns/frac-errors.hlsl +++ b/clang/test/SemaHLSL/BuiltIns/frac-errors.hlsl @@ -13,7 +13,7 @@ float2 test_too_many_arg(float2 p0) { float builtin_bool_to_float_type_promotion(bool p1) { return __builtin_hlsl_elementwise_frac(p1); - // expected-error@-1 {{1st argument must be a vector, integer or floating point type (was 'bool')}} + // expected-error@-1 {{passing 'bool' to parameter of incompatible type 'float'}} } float builtin_frac_int_to_float_promotion(int p1) { @@ -25,3 +25,15 @@ float2 builtin_frac_int2_to_float2_promotion(int2 p1) { return __builtin_hlsl_elementwise_frac(p1); // expected-error@-1 {{passing 'int2' (aka 'vector') to parameter of incompatible type '__attribute__((__vector_size__(2 * sizeof(float)))) float' (vector of 2 'float' values)}} } + +// builtins are variadic functions and so are subject to DefaultVariadicArgumentPromotion +half builtin_frac_half_scalar (half p0) { + return __builtin_hlsl_elementwise_frac (p0); + // expected-error@-1 {{passing 'double' to parameter of incompatible type 'float'}} +} + +float builtin_frac_float_scalar ( float p0) { + return __builtin_hlsl_elementwise_frac (p0); + // expected-error@-1 {{passing 'double' to parameter of incompatible type 'float'}} +} + diff --git a/clang/test/SemaHLSL/BuiltIns/isinf-errors.hlsl b/clang/test/SemaHLSL/BuiltIns/isinf-errors.hlsl new file mode 100644 index 0000000000000000000000000000000000000000..7ddfd56638273bdf0aecf1fef9dd5bf4cd4ab036 --- /dev/null +++ b/clang/test/SemaHLSL/BuiltIns/isinf-errors.hlsl @@ -0,0 +1,38 @@ + +// RUN: %clang_cc1 -finclude-default-header -triple dxil-pc-shadermodel6.6-library %s -fnative-half-type -emit-llvm -disable-llvm-passes -verify -verify-ignore-unexpected + +bool test_too_few_arg() { + return __builtin_hlsl_elementwise_isinf(); + // expected-error@-1 {{too few arguments to function call, expected 1, have 0}} +} + +bool2 test_too_many_arg(float2 p0) { + return __builtin_hlsl_elementwise_isinf(p0, p0); + // expected-error@-1 {{too many arguments to function call, expected 1, have 2}} +} + +bool builtin_bool_to_float_type_promotion(bool p1) { + return __builtin_hlsl_elementwise_isinf(p1); + // expected-error@-1 {passing 'bool' to parameter of incompatible type 'float'}} +} + +bool builtin_isinf_int_to_float_promotion(int p1) { + return __builtin_hlsl_elementwise_isinf(p1); + // expected-error@-1 {{passing 'int' to parameter of incompatible type 'float'}} +} + +bool2 builtin_isinf_int2_to_float2_promotion(int2 p1) { + return __builtin_hlsl_elementwise_isinf(p1); + // expected-error@-1 {{passing 'int2' (aka 'vector') to parameter of incompatible type '__attribute__((__vector_size__(2 * sizeof(float)))) float' (vector of 2 'float' values)}} +} + +// builtins are variadic functions and so are subject to DefaultVariadicArgumentPromotion +half builtin_isinf_half_scalar (half p0) { + return __builtin_hlsl_elementwise_isinf (p0); + // expected-error@-1 {{passing 'double' to parameter of incompatible type 'float'}} +} + +float builtin_isinf_float_scalar ( float p0) { + return __builtin_hlsl_elementwise_isinf (p0); + // expected-error@-1 {{passing 'double' to parameter of incompatible type 'float'}} +} diff --git a/clang/test/SemaHLSL/BuiltIns/lerp-errors.hlsl b/clang/test/SemaHLSL/BuiltIns/lerp-errors.hlsl index f6ce87e7c33e3eca3eef74f21d07fb7ebc92d545..83751f68357edf36c3135107353c07061fd8fede 100644 --- a/clang/test/SemaHLSL/BuiltIns/lerp-errors.hlsl +++ b/clang/test/SemaHLSL/BuiltIns/lerp-errors.hlsl @@ -92,5 +92,18 @@ float builtin_lerp_int_to_float_promotion(float p0, int p1) { float4 test_lerp_int4(int4 p0, int4 p1, int4 p2) { return __builtin_hlsl_lerp(p0, p1, p2); - // expected-error@-1 {{1st argument must be a floating point type (was 'int4' (aka 'vector'))}} -} \ No newline at end of file + // expected-error@-1 {{1st argument must be a floating point type (was 'int4' (aka 'vector'))}} +} + +// note: DefaultVariadicArgumentPromotion --> DefaultArgumentPromotion has already promoted to double +// we don't know anymore that the input was half when __builtin_hlsl_lerp is called so we default to float +// for expected type +half builtin_lerp_half_scalar (half p0) { + return __builtin_hlsl_lerp ( p0, p0, p0 ); + // expected-error@-1 {{passing 'double' to parameter of incompatible type 'float'}} +} + +float builtin_lerp_float_scalar ( float p0) { + return __builtin_hlsl_lerp ( p0, p0, p0 ); + // expected-error@-1 {{passing 'double' to parameter of incompatible type 'float'}} +} diff --git a/clang/test/SemaHLSL/BuiltIns/mad-errors.hlsl b/clang/test/SemaHLSL/BuiltIns/mad-errors.hlsl index 0b6843591455bd3ff89e58456aa26a89079b5db2..97ce931bf1b5b591de99c91609829462e8a27ea2 100644 --- a/clang/test/SemaHLSL/BuiltIns/mad-errors.hlsl +++ b/clang/test/SemaHLSL/BuiltIns/mad-errors.hlsl @@ -72,15 +72,15 @@ float2 test_builtin_mad_int_vect_to_float_vec_promotion(int2 p0, float p1) { float builtin_bool_to_float_type_promotion(float p0, bool p1) { return __builtin_hlsl_mad(p0, p0, p1); - // expected-error@-1 {{3rd argument must be a vector, integer or floating point type (was 'bool')}} + // expected-error@-1 {{3rd argument must be a floating point type (was 'bool')}} } float builtin_bool_to_float_type_promotion2(bool p0, float p1) { return __builtin_hlsl_mad(p1, p0, p1); - // expected-error@-1 {{2nd argument must be a vector, integer or floating point type (was 'bool')}} + // expected-error@-1 {{2nd argument must be a floating point type (was 'bool')}} } float builtin_mad_int_to_float_promotion(float p0, int p1) { return __builtin_hlsl_mad(p0, p0, p1); - // expected-error@-1 {{arguments are of different types ('double' vs 'int')}} + // expected-error@-1 {{3rd argument must be a floating point type (was 'int')}} } diff --git a/clang/test/SemaHLSL/BuiltIns/rcp-errors.hlsl b/clang/test/SemaHLSL/BuiltIns/rcp-errors.hlsl index dc4501dbd6d15a48e56ba8d7207d77348b23f19b..fa6fd813f19e64e6b13b5eda1717385d101bce96 100644 --- a/clang/test/SemaHLSL/BuiltIns/rcp-errors.hlsl +++ b/clang/test/SemaHLSL/BuiltIns/rcp-errors.hlsl @@ -13,7 +13,7 @@ float2 test_too_many_arg(float2 p0) { float builtin_bool_to_float_type_promotion(bool p1) { return __builtin_hlsl_elementwise_rcp(p1); - // expected-error@-1 {{1st argument must be a vector, integer or floating point type (was 'bool')}} + // expected-error@-1 {passing 'bool' to parameter of incompatible type 'float'}} } float builtin_rcp_int_to_float_promotion(int p1) { diff --git a/clang/test/SemaHLSL/BuiltIns/rsqrt-errors.hlsl b/clang/test/SemaHLSL/BuiltIns/rsqrt-errors.hlsl new file mode 100644 index 0000000000000000000000000000000000000000..c027a698c5e58fd576f19e0cc6604519110a9eca --- /dev/null +++ b/clang/test/SemaHLSL/BuiltIns/rsqrt-errors.hlsl @@ -0,0 +1,38 @@ + +// RUN: %clang_cc1 -finclude-default-header -triple dxil-pc-shadermodel6.6-library %s -fnative-half-type -emit-llvm -disable-llvm-passes -verify -verify-ignore-unexpected + +float test_too_few_arg() { + return __builtin_hlsl_elementwise_rsqrt(); + // expected-error@-1 {{too few arguments to function call, expected 1, have 0}} +} + +float2 test_too_many_arg(float2 p0) { + return __builtin_hlsl_elementwise_rsqrt(p0, p0); + // expected-error@-1 {{too many arguments to function call, expected 1, have 2}} +} + +float builtin_bool_to_float_type_promotion(bool p1) { + return __builtin_hlsl_elementwise_rsqrt(p1); + // expected-error@-1 {{passing 'bool' to parameter of incompatible type 'float'}} +} + +float builtin_rsqrt_int_to_float_promotion(int p1) { + return __builtin_hlsl_elementwise_rsqrt(p1); + // expected-error@-1 {{passing 'int' to parameter of incompatible type 'float'}} +} + +float2 builtin_rsqrt_int2_to_float2_promotion(int2 p1) { + return __builtin_hlsl_elementwise_rsqrt(p1); + // expected-error@-1 {{passing 'int2' (aka 'vector') to parameter of incompatible type '__attribute__((__vector_size__(2 * sizeof(float)))) float' (vector of 2 'float' values)}} +} + +// builtins are variadic functions and so are subject to DefaultVariadicArgumentPromotion +half builtin_rsqrt_half_scalar (half p0) { + return __builtin_hlsl_elementwise_rsqrt (p0); + // expected-error@-1 {{passing 'double' to parameter of incompatible type 'float'}} +} + +float builtin_rsqrt_float_scalar ( float p0) { + return __builtin_hlsl_elementwise_rsqrt (p0); + // expected-error@-1 {{passing 'double' to parameter of incompatible type 'float'}} +} diff --git a/clang/test/SemaTemplate/PR25708.cpp b/clang/test/SemaTemplate/PR25708.cpp new file mode 100644 index 0000000000000000000000000000000000000000..6a214fc6b43bc1d285c453b2b5cfb793983b98d0 --- /dev/null +++ b/clang/test/SemaTemplate/PR25708.cpp @@ -0,0 +1,20 @@ +// RUN: %clang_cc1 -std=c++11 -verify %s +// expected-no-diagnostics + +struct FooAccessor +{ + template + using Foo = typename T::Foo; +}; + +class Type +{ + friend struct FooAccessor; + + using Foo = int; +}; + +int main() +{ + FooAccessor::Foo t; +} diff --git a/clang/test/SemaTemplate/concepts.cpp b/clang/test/SemaTemplate/concepts.cpp index bac209a28da912e1e14f29f9313710cf1f749c87..b7ea0d003a52d74a3baf53292fbb505c1d63097c 100644 --- a/clang/test/SemaTemplate/concepts.cpp +++ b/clang/test/SemaTemplate/concepts.cpp @@ -1085,3 +1085,32 @@ template void Struct::bar<>(); template int Struct::field<1, 2>; } + +namespace GH64808 { + +template struct basic_sender { + T func; + basic_sender(T) : func(T()) {} +}; + +auto a = basic_sender{[](auto... __captures) { + return []() // #note-a-1 + requires((__captures, ...), false) // #note-a-2 + {}; +}()}; + +auto b = basic_sender{[](auto... __captures) { + return []() + requires([](int, double) { return true; }(decltype(__captures)()...)) + {}; +}(1, 2.33)}; + +void foo() { + a.func(); + // expected-error@-1{{no matching function for call}} + // expected-note@#note-a-1{{constraints not satisfied}} + // expected-note@#note-a-2{{evaluated to false}} + b.func(); +} + +} // namespace GH64808 diff --git a/clang/tools/clang-format/.clang-format b/clang/tools/clang-format/.clang-format index f95602cab0f7fcdf5d34c485d52b65993dbb83d9..d7331b3c8cf02ef7944e83a4280476627e33b31d 100644 --- a/clang/tools/clang-format/.clang-format +++ b/clang/tools/clang-format/.clang-format @@ -1,6 +1 @@ -BasedOnStyle: LLVM -InsertBraces: true -InsertNewlineAtEOF: true -LineEnding: LF -RemoveBracesLLVM: true -RemoveParentheses: ReturnStatement +BasedOnStyle: clang-format diff --git a/clang/tools/clang-format/ClangFormat.cpp b/clang/tools/clang-format/ClangFormat.cpp index e122cea50f7268c9aa50961a37f95fc1af22bd23..60b0f5d1a0f4140b64cee7358a121b28ca12e458 100644 --- a/clang/tools/clang-format/ClangFormat.cpp +++ b/clang/tools/clang-format/ClangFormat.cpp @@ -13,18 +13,12 @@ //===----------------------------------------------------------------------===// #include "../../lib/Format/MatchFilePath.h" -#include "clang/Basic/Diagnostic.h" -#include "clang/Basic/DiagnosticOptions.h" -#include "clang/Basic/FileManager.h" #include "clang/Basic/SourceManager.h" #include "clang/Basic/Version.h" #include "clang/Format/Format.h" #include "clang/Rewrite/Core/Rewriter.h" -#include "llvm/ADT/StringSwitch.h" #include "llvm/Support/CommandLine.h" -#include "llvm/Support/FileSystem.h" #include "llvm/Support/InitLLVM.h" -#include "llvm/Support/Process.h" #include using namespace llvm; diff --git a/clang/tools/clang-installapi/CMakeLists.txt b/clang/tools/clang-installapi/CMakeLists.txt index e05f4eac3ad198358f96f053ab990f8fe35aef4f..b90ffc847b155829189ae524a415b35bb04603fc 100644 --- a/clang/tools/clang-installapi/CMakeLists.txt +++ b/clang/tools/clang-installapi/CMakeLists.txt @@ -2,13 +2,20 @@ set(LLVM_LINK_COMPONENTS Support TargetParser TextAPI + TextAPIBinaryReader Option ) +set(LLVM_TARGET_DEFINITIONS InstallAPIOpts.td) +tablegen(LLVM InstallAPIOpts.inc -gen-opt-parser-defs) +add_public_tablegen_target(InstallAPIDriverOptions) + add_clang_tool(clang-installapi ClangInstallAPI.cpp Options.cpp + DEPENDS + InstallAPIDriverOptions GENERATE_DRIVER ) @@ -22,3 +29,4 @@ clang_target_link_libraries(clang-installapi clangTooling clangSerialization ) + diff --git a/clang/tools/clang-installapi/ClangInstallAPI.cpp b/clang/tools/clang-installapi/ClangInstallAPI.cpp index c6da1c80a673f91b6ee9a18d6241da328e3bae28..d758f73117900884721db11080a99d20f9d09d59 100644 --- a/clang/tools/clang-installapi/ClangInstallAPI.cpp +++ b/clang/tools/clang-installapi/ClangInstallAPI.cpp @@ -14,11 +14,13 @@ #include "Options.h" #include "clang/Basic/Diagnostic.h" #include "clang/Basic/DiagnosticFrontend.h" -#include "clang/Driver/Driver.h" #include "clang/Driver/DriverDiagnostic.h" #include "clang/Driver/Tool.h" #include "clang/Frontend/TextDiagnosticPrinter.h" #include "clang/InstallAPI/Frontend.h" +#include "clang/InstallAPI/FrontendRecords.h" +#include "clang/InstallAPI/InstallAPIDiagnostic.h" +#include "clang/InstallAPI/MachO.h" #include "clang/Tooling/Tooling.h" #include "llvm/ADT/ArrayRef.h" #include "llvm/Option/Option.h" @@ -29,8 +31,6 @@ #include "llvm/Support/Process.h" #include "llvm/Support/Signals.h" #include "llvm/TargetParser/Host.h" -#include "llvm/TextAPI/RecordVisitor.h" -#include "llvm/TextAPI/TextAPIWriter.h" #include using namespace clang; @@ -92,22 +92,8 @@ static bool run(ArrayRef Args, const char *ProgName) { IntrusiveRefCntPtr FM( new FileManager(clang::FileSystemOptions(), OverlayFileSystem)); - // Set up driver to parse input arguments. - auto DriverArgs = llvm::ArrayRef(Args).slice(1); - clang::driver::Driver Driver(ProgName, llvm::sys::getDefaultTargetTriple(), - *Diag, "clang installapi tool"); - auto TargetAndMode = - clang::driver::ToolChain::getTargetAndModeFromProgramName(ProgName); - Driver.setTargetAndMode(TargetAndMode); - bool HasError = false; - llvm::opt::InputArgList ArgList = - Driver.ParseArgStrings(DriverArgs, /*UseDriverMode=*/true, HasError); - if (HasError) - return EXIT_FAILURE; - Driver.setCheckInputsExist(false); - - // Capture InstallAPI specific options and diagnose any option errors. - Options Opts(*Diag, FM.get(), ArgList); + // Capture all options and diagnose any errors. + Options Opts(*Diag, FM.get(), Args, ProgName); if (Diag->hasErrorOccurred()) return EXIT_FAILURE; @@ -125,11 +111,12 @@ static bool run(ArrayRef Args, const char *ProgName) { // Execute and gather AST results. // An invocation is ran for each unique target triple and for each header // access level. - llvm::MachO::Records FrontendResults; + Records FrontendResults; for (const auto &[Targ, Trip] : Opts.DriverOpts.Targets) { for (const HeaderType Type : {HeaderType::Public, HeaderType::Private, HeaderType::Project}) { Ctx.Slice = std::make_shared(Trip); + Ctx.Verifier->setTarget(Targ); Ctx.Type = Type; if (!runFrontend(ProgName, Opts.DriverOpts.Verbose, Ctx, InMemoryFileSystem.get(), Opts.getClangFrontendArgs())) @@ -138,6 +125,9 @@ static bool run(ArrayRef Args, const char *ProgName) { } } + if (Ctx.Verifier->getState() == DylibVerifier::Result::Invalid) + return EXIT_FAILURE; + // After symbols have been collected, prepare to write output. auto Out = CI->createOutputFile(Ctx.OutputLoc, /*Binary=*/false, /*RemoveFileOnSignal=*/false, @@ -147,13 +137,7 @@ static bool run(ArrayRef Args, const char *ProgName) { return EXIT_FAILURE; // Assign attributes for serialization. - auto Symbols = std::make_unique(); - for (const auto &FR : FrontendResults) { - SymbolConverter Converter(Symbols.get(), FR->getTarget()); - FR->visit(Converter); - } - - InterfaceFile IF(std::move(Symbols)); + InterfaceFile IF(Ctx.Verifier->getExports()); for (const auto &TargetInfo : Opts.DriverOpts.Targets) { IF.addTarget(TargetInfo.first); IF.setFromBinaryAttrs(Ctx.BA, TargetInfo.first); @@ -161,7 +145,8 @@ static bool run(ArrayRef Args, const char *ProgName) { // Write output file and perform CI cleanup. if (auto Err = TextAPIWriter::writeToStream(*Out, IF, Ctx.FT)) { - Diag->Report(diag::err_cannot_open_file) << Ctx.OutputLoc; + Diag->Report(diag::err_cannot_write_file) + << Ctx.OutputLoc << std::move(Err); CI->clearOutputFiles(/*EraseFiles=*/true); return EXIT_FAILURE; } diff --git a/clang/tools/clang-installapi/InstallAPIOpts.td b/clang/tools/clang-installapi/InstallAPIOpts.td new file mode 100644 index 0000000000000000000000000000000000000000..87f4c3327e8409bd2771ca79802efa36b59039e0 --- /dev/null +++ b/clang/tools/clang-installapi/InstallAPIOpts.td @@ -0,0 +1,31 @@ +//===--- InstallAPIOpts.td ------------------------------------------------===// +// +// 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 the specific options for InstallAPI. +// +//===----------------------------------------------------------------------===// + +// Include the common option parsing interfaces. +include "llvm/Option/OptParser.td" + + +///////// +// Options + +// TextAPI options. +def filetype : Joined<["--"], "filetype=">, + HelpText<"Specify the output file type (tbd-v4 or tbd-v5)">; + +// Verification options. +def verify_against : Separate<["-"], "verify-against">, + HelpText<"Verify the specified dynamic library/framework against the headers">; +def verify_against_EQ : Joined<["--"], "verify-against=">, Alias; +def verify_mode_EQ : Joined<["--"], "verify-mode=">, + HelpText<"Specify the severity and extend of the validation. Valid modes are ErrorsOnly, ErrorsAndWarnings, and Pedantic.">; +def demangle : Flag<["--", "-"], "demangle">, + HelpText<"Demangle symbols when printing warnings and errors">; diff --git a/clang/tools/clang-installapi/Options.cpp b/clang/tools/clang-installapi/Options.cpp index b9c36eab2ad3b7869b2c6360cfc3d8e517db4572..e5ff8a1aaa4fe54b1945f98741186ce501efb795 100644 --- a/clang/tools/clang-installapi/Options.cpp +++ b/clang/tools/clang-installapi/Options.cpp @@ -10,35 +10,85 @@ #include "clang/Driver/Driver.h" #include "clang/Frontend/FrontendDiagnostic.h" #include "clang/InstallAPI/FileList.h" +#include "clang/InstallAPI/InstallAPIDiagnostic.h" #include "llvm/Support/Program.h" #include "llvm/TargetParser/Host.h" +#include "llvm/TextAPI/DylibReader.h" +#include "llvm/TextAPI/TextAPIWriter.h" -using namespace clang::driver; -using namespace clang::driver::options; +using namespace llvm; using namespace llvm::opt; using namespace llvm::MachO; +namespace drv = clang::driver::options; + namespace clang { namespace installapi { +/// Create prefix string literals used in InstallAPIOpts.td. +#define PREFIX(NAME, VALUE) \ + static constexpr llvm::StringLiteral NAME##_init[] = VALUE; \ + static constexpr llvm::ArrayRef NAME( \ + NAME##_init, std::size(NAME##_init) - 1); +#include "InstallAPIOpts.inc" +#undef PREFIX + +static constexpr const llvm::StringLiteral PrefixTable_init[] = +#define PREFIX_UNION(VALUES) VALUES +#include "InstallAPIOpts.inc" +#undef PREFIX_UNION + ; +static constexpr const ArrayRef + PrefixTable(PrefixTable_init, std::size(PrefixTable_init) - 1); + +/// Create table mapping all options defined in InstallAPIOpts.td. +static constexpr OptTable::Info InfoTable[] = { +#define OPTION(PREFIX, NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, \ + VISIBILITY, PARAM, HELPTEXT, METAVAR, VALUES) \ + {PREFIX, NAME, HELPTEXT, METAVAR, OPT_##ID, Option::KIND##Class, \ + PARAM, FLAGS, VISIBILITY, OPT_##GROUP, OPT_##ALIAS, ALIASARGS, \ + VALUES}, +#include "InstallAPIOpts.inc" +#undef OPTION +}; + +namespace { + +/// \brief Create OptTable class for parsing actual command line arguments. +class DriverOptTable : public opt::PrecomputedOptTable { +public: + DriverOptTable() : PrecomputedOptTable(InfoTable, PrefixTable) {} +}; + +} // end anonymous namespace. + +static llvm::opt::OptTable *createDriverOptTable() { + return new DriverOptTable(); +} + bool Options::processDriverOptions(InputArgList &Args) { // Handle inputs. - llvm::append_range(DriverOpts.FileLists, Args.getAllArgValues(OPT_INPUT)); + llvm::append_range(DriverOpts.FileLists, + Args.getAllArgValues(drv::OPT_INPUT)); // Handle output. SmallString OutputPath; - if (auto *Arg = Args.getLastArg(OPT_o)) { + if (auto *Arg = Args.getLastArg(drv::OPT_o)) { OutputPath = Arg->getValue(); if (OutputPath != "-") FM->makeAbsolutePath(OutputPath); DriverOpts.OutputPath = std::string(OutputPath); } + if (DriverOpts.OutputPath.empty()) { + Diags->Report(diag::err_no_output_file); + return false; + } // Do basic error checking first for mixing -target and -arch options. - auto *ArgArch = Args.getLastArgNoClaim(OPT_arch); - auto *ArgTarget = Args.getLastArgNoClaim(OPT_target); + auto *ArgArch = Args.getLastArgNoClaim(drv::OPT_arch); + auto *ArgTarget = Args.getLastArgNoClaim(drv::OPT_target); auto *ArgTargetVariant = - Args.getLastArgNoClaim(OPT_darwin_target_variant_triple); + Args.getLastArgNoClaim(drv::OPT_darwin_target_variant_triple); if (ArgArch && (ArgTarget || ArgTargetVariant)) { Diags->Report(clang::diag::err_drv_argument_not_allowed_with) << ArgArch->getAsString(Args) @@ -46,7 +96,7 @@ bool Options::processDriverOptions(InputArgList &Args) { return false; } - auto *ArgMinTargetOS = Args.getLastArgNoClaim(OPT_mtargetos_EQ); + auto *ArgMinTargetOS = Args.getLastArgNoClaim(drv::OPT_mtargetos_EQ); if ((ArgTarget || ArgTargetVariant) && ArgMinTargetOS) { Diags->Report(clang::diag::err_drv_cannot_mix_options) << ArgTarget->getAsString(Args) << ArgMinTargetOS->getAsString(Args); @@ -55,7 +105,7 @@ bool Options::processDriverOptions(InputArgList &Args) { // Capture target triples first. if (ArgTarget) { - for (const Arg *A : Args.filtered(OPT_target)) { + for (const Arg *A : Args.filtered(drv::OPT_target)) { A->claim(); llvm::Triple TargetTriple(A->getValue()); Target TAPITarget = Target(TargetTriple); @@ -69,27 +119,32 @@ bool Options::processDriverOptions(InputArgList &Args) { } } - DriverOpts.Verbose = Args.hasArgNoClaim(OPT_v); + DriverOpts.Verbose = Args.hasArgNoClaim(drv::OPT_v); return true; } bool Options::processLinkerOptions(InputArgList &Args) { - // TODO: add error handling. - - // Required arguments. - if (const Arg *A = Args.getLastArg(options::OPT_install__name)) + // Handle required arguments. + if (const Arg *A = Args.getLastArg(drv::OPT_install__name)) LinkerOpts.InstallName = A->getValue(); + if (LinkerOpts.InstallName.empty()) { + Diags->Report(diag::err_no_install_name); + return false; + } // Defaulted or optional arguments. - if (auto *Arg = Args.getLastArg(OPT_current__version)) + if (auto *Arg = Args.getLastArg(drv::OPT_current__version)) LinkerOpts.CurrentVersion.parse64(Arg->getValue()); - LinkerOpts.IsDylib = Args.hasArg(OPT_dynamiclib); + if (auto *Arg = Args.getLastArg(drv::OPT_compatibility__version)) + LinkerOpts.CompatVersion.parse64(Arg->getValue()); - LinkerOpts.AppExtensionSafe = - Args.hasFlag(OPT_fapplication_extension, OPT_fno_application_extension, - /*Default=*/LinkerOpts.AppExtensionSafe); + LinkerOpts.IsDylib = Args.hasArg(drv::OPT_dynamiclib); + + LinkerOpts.AppExtensionSafe = Args.hasFlag( + drv::OPT_fapplication_extension, drv::OPT_fno_application_extension, + /*Default=*/LinkerOpts.AppExtensionSafe); if (::getenv("LD_NO_ENCRYPT") != nullptr) LinkerOpts.AppExtensionSafe = true; @@ -99,20 +154,117 @@ bool Options::processLinkerOptions(InputArgList &Args) { return true; } +bool Options::processFrontendOptions(InputArgList &Args) { + // Do not claim any arguments, as they will be passed along for CC1 + // invocations. + if (auto *A = Args.getLastArgNoClaim(drv::OPT_x)) { + FEOpts.LangMode = llvm::StringSwitch(A->getValue()) + .Case("c", clang::Language::C) + .Case("c++", clang::Language::CXX) + .Case("objective-c", clang::Language::ObjC) + .Case("objective-c++", clang::Language::ObjCXX) + .Default(clang::Language::Unknown); + + if (FEOpts.LangMode == clang::Language::Unknown) { + Diags->Report(clang::diag::err_drv_invalid_value) + << A->getAsString(Args) << A->getValue(); + return false; + } + } + for (auto *A : Args.filtered(drv::OPT_ObjC, drv::OPT_ObjCXX)) { + if (A->getOption().matches(drv::OPT_ObjC)) + FEOpts.LangMode = clang::Language::ObjC; + else + FEOpts.LangMode = clang::Language::ObjCXX; + } + + return true; +} + +std::vector +Options::processAndFilterOutInstallAPIOptions(ArrayRef Args) { + std::unique_ptr Table; + Table.reset(createDriverOptTable()); + + unsigned MissingArgIndex, MissingArgCount; + auto ParsedArgs = Table->ParseArgs(Args.slice(1), MissingArgIndex, + MissingArgCount, Visibility()); + + // Capture InstallAPI only driver options. + DriverOpts.Demangle = ParsedArgs.hasArg(OPT_demangle); + + if (auto *A = ParsedArgs.getLastArg(OPT_filetype)) { + DriverOpts.OutFT = TextAPIWriter::parseFileType(A->getValue()); + if (DriverOpts.OutFT == FileType::Invalid) { + Diags->Report(clang::diag::err_drv_invalid_value) + << A->getAsString(ParsedArgs) << A->getValue(); + return {}; + } + } + + if (const Arg *A = ParsedArgs.getLastArg(OPT_verify_mode_EQ)) { + DriverOpts.VerifyMode = + StringSwitch(A->getValue()) + .Case("ErrorsOnly", VerificationMode::ErrorsOnly) + .Case("ErrorsAndWarnings", VerificationMode::ErrorsAndWarnings) + .Case("Pedantic", VerificationMode::Pedantic) + .Default(VerificationMode::Invalid); + + if (DriverOpts.VerifyMode == VerificationMode::Invalid) { + Diags->Report(clang::diag::err_drv_invalid_value) + << A->getAsString(ParsedArgs) << A->getValue(); + return {}; + } + } + + if (const Arg *A = ParsedArgs.getLastArg(OPT_verify_against)) + DriverOpts.DylibToVerify = A->getValue(); + + /// Any unclaimed arguments should be forwarded to the clang driver. + std::vector ClangDriverArgs(ParsedArgs.size()); + for (const Arg *A : ParsedArgs) { + if (A->isClaimed()) + continue; + llvm::copy(A->getValues(), std::back_inserter(ClangDriverArgs)); + } + return ClangDriverArgs; +} + Options::Options(DiagnosticsEngine &Diag, FileManager *FM, - InputArgList &ArgList) + ArrayRef Args, const StringRef ProgName) : Diags(&Diag), FM(FM) { + + // First process InstallAPI specific options. + auto DriverArgs = processAndFilterOutInstallAPIOptions(Args); + if (Diags->hasErrorOccurred()) + return; + + // Set up driver to parse remaining input arguments. + clang::driver::Driver Driver(ProgName, llvm::sys::getDefaultTargetTriple(), + *Diags, "clang installapi tool"); + auto TargetAndMode = + clang::driver::ToolChain::getTargetAndModeFromProgramName(ProgName); + Driver.setTargetAndMode(TargetAndMode); + bool HasError = false; + llvm::opt::InputArgList ArgList = + Driver.ParseArgStrings(DriverArgs, /*UseDriverMode=*/true, HasError); + if (HasError) + return; + Driver.setCheckInputsExist(false); + if (!processDriverOptions(ArgList)) return; if (!processLinkerOptions(ArgList)) return; - /// Any remaining arguments should be handled by invoking the clang frontend. + if (!processFrontendOptions(ArgList)) + return; + + /// Any unclaimed arguments should be handled by invoking the clang frontend. for (const Arg *A : ArgList) { if (A->isClaimed()) continue; - FrontendArgs.emplace_back(A->getSpelling()); llvm::copy(A->getValues(), std::back_inserter(FrontendArgs)); } @@ -129,24 +281,50 @@ InstallAPIContext Options::createContext() { Ctx.BA.InstallName = LinkerOpts.InstallName; Ctx.BA.CurrentVersion = LinkerOpts.CurrentVersion; + Ctx.BA.CompatVersion = LinkerOpts.CompatVersion; Ctx.BA.AppExtensionSafe = LinkerOpts.AppExtensionSafe; Ctx.FT = DriverOpts.OutFT; Ctx.OutputLoc = DriverOpts.OutputPath; + Ctx.LangMode = FEOpts.LangMode; // Process inputs. for (const std::string &ListPath : DriverOpts.FileLists) { auto Buffer = FM->getBufferForFile(ListPath); if (auto Err = Buffer.getError()) { - Diags->Report(diag::err_cannot_open_file) << ListPath; + Diags->Report(diag::err_cannot_open_file) << ListPath << Err.message(); return Ctx; } if (auto Err = FileListReader::loadHeaders(std::move(Buffer.get()), Ctx.InputHeaders)) { - Diags->Report(diag::err_cannot_open_file) << ListPath; + Diags->Report(diag::err_cannot_open_file) << ListPath << std::move(Err); return Ctx; } } + // Parse binary dylib and initialize verifier. + if (DriverOpts.DylibToVerify.empty()) { + Ctx.Verifier = std::make_unique(); + return Ctx; + } + + auto Buffer = FM->getBufferForFile(DriverOpts.DylibToVerify); + if (auto Err = Buffer.getError()) { + Diags->Report(diag::err_cannot_open_file) + << DriverOpts.DylibToVerify << Err.message(); + return Ctx; + } + + DylibReader::ParseOption PO; + PO.Undefineds = false; + Expected Slices = + DylibReader::readFile((*Buffer)->getMemBufferRef(), PO); + if (auto Err = Slices.takeError()) { + Diags->Report(diag::err_cannot_open_file) << DriverOpts.DylibToVerify; + return Ctx; + } + + Ctx.Verifier = std::make_unique( + std::move(*Slices), Diags, DriverOpts.VerifyMode, DriverOpts.Demangle); return Ctx; } diff --git a/clang/tools/clang-installapi/Options.h b/clang/tools/clang-installapi/Options.h index f68addf1972880917f7e8465a93c6441f99d33dc..2beeafc86bb086ef888990dee6373d17ae13b409 100644 --- a/clang/tools/clang-installapi/Options.h +++ b/clang/tools/clang-installapi/Options.h @@ -11,25 +11,21 @@ #include "clang/Basic/Diagnostic.h" #include "clang/Basic/FileManager.h" +#include "clang/Driver/Driver.h" #include "clang/Frontend/FrontendOptions.h" #include "clang/InstallAPI/Context.h" +#include "clang/InstallAPI/DylibVerifier.h" +#include "clang/InstallAPI/MachO.h" #include "llvm/Option/ArgList.h" #include "llvm/Option/Option.h" #include "llvm/Support/Program.h" #include "llvm/TargetParser/Triple.h" -#include "llvm/TextAPI/Architecture.h" -#include "llvm/TextAPI/InterfaceFile.h" -#include "llvm/TextAPI/PackedVersion.h" -#include "llvm/TextAPI/Platform.h" -#include "llvm/TextAPI/Target.h" -#include "llvm/TextAPI/Utils.h" #include #include #include namespace clang { namespace installapi { -using Macro = std::pair; struct DriverOptions { /// \brief Path to input file lists (JSON). @@ -38,11 +34,20 @@ struct DriverOptions { /// \brief Mappings of target triples & tapi targets to build for. std::map Targets; + /// \brief Path to binary dylib for comparing. + std::string DylibToVerify; + /// \brief Output path. std::string OutputPath; /// \brief File encoding to print. - llvm::MachO::FileType OutFT = llvm::MachO::FileType::TBD_V5; + FileType OutFT = FileType::TBD_V5; + + /// \brief Verification mode for comparing symbols. + VerificationMode VerifyMode = VerificationMode::Pedantic; + + /// \brief Print demangled symbols when reporting errors. + bool Demangle = false; /// \brief Print verbose output. bool Verbose = false; @@ -53,7 +58,10 @@ struct LinkerOptions { std::string InstallName; /// \brief The current version to use for the dynamic library. - llvm::MachO::PackedVersion CurrentVersion; + PackedVersion CurrentVersion; + + /// \brief The compatibility version to use for the dynamic library. + PackedVersion CompatVersion; /// \brief Is application extension safe. bool AppExtensionSafe = false; @@ -62,15 +70,24 @@ struct LinkerOptions { bool IsDylib = false; }; +struct FrontendOptions { + /// \brief The language mode to parse headers in. + Language LangMode = Language::ObjC; +}; + class Options { private: bool processDriverOptions(llvm::opt::InputArgList &Args); bool processLinkerOptions(llvm::opt::InputArgList &Args); + bool processFrontendOptions(llvm::opt::InputArgList &Args); + std::vector + processAndFilterOutInstallAPIOptions(ArrayRef Args); public: /// The various options grouped together. DriverOptions DriverOpts; LinkerOptions LinkerOpts; + FrontendOptions FEOpts; Options() = delete; @@ -79,7 +96,7 @@ public: /// \brief Constructor for options. Options(clang::DiagnosticsEngine &Diag, FileManager *FM, - llvm::opt::InputArgList &Args); + ArrayRef Args, const StringRef ProgName); /// \brief Get CC1 arguments after extracting out the irrelevant /// ones. @@ -91,6 +108,16 @@ private: std::vector FrontendArgs; }; +enum ID { + OPT_INVALID = 0, // This is not an option ID. +#define OPTION(PREFIX, NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, \ + VISIBILITY, PARAM, HELPTEXT, METAVAR, VALUES) \ + OPT_##ID, +#include "InstallAPIOpts.inc" + LastOption +#undef OPTION +}; + } // namespace installapi } // namespace clang #endif diff --git a/clang/tools/clang-linker-wrapper/ClangLinkerWrapper.cpp b/clang/tools/clang-linker-wrapper/ClangLinkerWrapper.cpp index 7e6e289c50d8722e83c91210faea1b04e6235c85..c60be2789bd61e9c09258a795536ed8e505ed64f 100644 --- a/clang/tools/clang-linker-wrapper/ClangLinkerWrapper.cpp +++ b/clang/tools/clang-linker-wrapper/ClangLinkerWrapper.cpp @@ -407,6 +407,9 @@ fatbinary(ArrayRef> InputFiles, if (Args.hasArg(OPT_compress)) CmdArgs.push_back("-compress"); + if (auto *Arg = Args.getLastArg(OPT_compression_level_eq)) + CmdArgs.push_back( + Args.MakeArgString(Twine("-compression-level=") + Arg->getValue())); SmallVector Targets = {"-targets=host-x86_64-unknown-linux"}; for (const auto &[File, Arch] : InputFiles) @@ -559,6 +562,7 @@ Expected linkDevice(ArrayRef InputFiles, case Triple::aarch64_be: case Triple::ppc64: case Triple::ppc64le: + case Triple::systemz: return generic::clang(InputFiles, Args); default: return createStringError(inconvertibleErrorCode(), diff --git a/clang/tools/clang-linker-wrapper/LinkerWrapperOpts.td b/clang/tools/clang-linker-wrapper/LinkerWrapperOpts.td index 473fb19d9223854781b66f049ba4a91d0574f84d..0a8bd541c4524221837c6262e7af35906b241e8d 100644 --- a/clang/tools/clang-linker-wrapper/LinkerWrapperOpts.td +++ b/clang/tools/clang-linker-wrapper/LinkerWrapperOpts.td @@ -60,6 +60,8 @@ def save_temps : Flag<["--"], "save-temps">, Flags<[WrapperOnlyOption]>, HelpText<"Save intermediate results">; def compress : Flag<["--"], "compress">, Flags<[WrapperOnlyOption]>, HelpText<"Compress bundled files">; +def compression_level_eq : Joined<["--"], "compression-level=">, + Flags<[WrapperOnlyOption]>, HelpText<"Specify the compression level (integer)">; def wrapper_time_trace_eq : Joined<["--"], "wrapper-time-trace=">, Flags<[WrapperOnlyOption]>, MetaVarName<"">, diff --git a/clang/tools/clang-offload-bundler/ClangOffloadBundler.cpp b/clang/tools/clang-offload-bundler/ClangOffloadBundler.cpp index ec67e24552e9c9633485545f1d53aceceff2a8c4..e336417586f70bd9fe030d3167f45584866fbc28 100644 --- a/clang/tools/clang-offload-bundler/ClangOffloadBundler.cpp +++ b/clang/tools/clang-offload-bundler/ClangOffloadBundler.cpp @@ -145,6 +145,9 @@ int main(int argc, const char **argv) { cl::init(false), cl::cat(ClangOffloadBundlerCategory)); cl::opt Verbose("verbose", cl::desc("Print debug information.\n"), cl::init(false), cl::cat(ClangOffloadBundlerCategory)); + cl::opt CompressionLevel( + "compression-level", cl::desc("Specify the compression level (integer)"), + cl::value_desc("n"), cl::Optional, cl::cat(ClangOffloadBundlerCategory)); // Process commandline options and report errors sys::PrintStackTraceOnErrorSignal(argv[0]); @@ -178,6 +181,8 @@ int main(int argc, const char **argv) { BundlerConfig.Compress = Compress; if (Verbose.getNumOccurrences() > 0) BundlerConfig.Verbose = Verbose; + if (CompressionLevel.getNumOccurrences() > 0) + BundlerConfig.CompressionLevel = CompressionLevel; BundlerConfig.TargetNames = TargetNames; BundlerConfig.InputFileNames = InputFileNames; diff --git a/clang/tools/clang-scan-deps/ClangScanDeps.cpp b/clang/tools/clang-scan-deps/ClangScanDeps.cpp index d042fecc3dbe63af73ebedf3930c24888f3f4b47..eaa76dd43e41dd8856a8495613754aad82e7966e 100644 --- a/clang/tools/clang-scan-deps/ClangScanDeps.cpp +++ b/clang/tools/clang-scan-deps/ClangScanDeps.cpp @@ -867,13 +867,6 @@ int clang_scan_deps_main(int argc, char **argv, const llvm::ToolContext &) { // Print out the dependency results to STDOUT by default. SharedStream DependencyOS(llvm::outs()); - DependencyScanningService Service(ScanMode, Format, OptimizeArgs, - EagerLoadModules); - llvm::DefaultThreadPool Pool(llvm::hardware_concurrency(NumThreads)); - std::vector> WorkerTools; - for (unsigned I = 0; I < Pool.getMaxConcurrency(); ++I) - WorkerTools.push_back(std::make_unique(Service)); - std::vector Inputs = AdjustingCompilations->getAllCompileCommands(); @@ -893,102 +886,114 @@ int clang_scan_deps_main(int argc, char **argv, const llvm::ToolContext &) { if (Format == ScanningOutputFormat::Full) FD.emplace(ModuleName.empty() ? Inputs.size() : 0); - if (Verbose) { - llvm::outs() << "Running clang-scan-deps on " << Inputs.size() - << " files using " << Pool.getMaxConcurrency() << " workers\n"; - } + auto ScanningTask = [&](DependencyScanningService &Service) { + DependencyScanningTool WorkerTool(Service); + + llvm::DenseSet AlreadySeenModules; + while (auto MaybeInputIndex = GetNextInputIndex()) { + size_t LocalIndex = *MaybeInputIndex; + const tooling::CompileCommand *Input = &Inputs[LocalIndex]; + std::string Filename = std::move(Input->Filename); + std::string CWD = std::move(Input->Directory); + + std::optional MaybeModuleName; + if (!ModuleName.empty()) + MaybeModuleName = ModuleName; + + std::string OutputDir(ModuleFilesDir); + if (OutputDir.empty()) + OutputDir = getModuleCachePath(Input->CommandLine); + auto LookupOutput = [&](const ModuleID &MID, ModuleOutputKind MOK) { + return ::lookupModuleOutput(MID, MOK, OutputDir); + }; + + // Run the tool on it. + if (Format == ScanningOutputFormat::Make) { + auto MaybeFile = WorkerTool.getDependencyFile(Input->CommandLine, CWD); + if (handleMakeDependencyToolResult(Filename, MaybeFile, DependencyOS, + Errs)) + HadErrors = true; + } else if (Format == ScanningOutputFormat::P1689) { + // It is useful to generate the make-format dependency output during + // the scanning for P1689. Otherwise the users need to scan again for + // it. We will generate the make-format dependency output if we find + // `-MF` in the command lines. + std::string MakeformatOutputPath; + std::string MakeformatOutput; + + auto MaybeRule = WorkerTool.getP1689ModuleDependencyFile( + *Input, CWD, MakeformatOutput, MakeformatOutputPath); + + if (handleP1689DependencyToolResult(Filename, MaybeRule, PD, Errs)) + HadErrors = true; + + if (!MakeformatOutputPath.empty() && !MakeformatOutput.empty() && + !HadErrors) { + static std::mutex Lock; + // With compilation database, we may open different files + // concurrently or we may write the same file concurrently. So we + // use a map here to allow multiple compile commands to write to the + // same file. Also we need a lock here to avoid data race. + static llvm::StringMap OSs; + std::unique_lock LockGuard(Lock); + + auto OSIter = OSs.find(MakeformatOutputPath); + if (OSIter == OSs.end()) { + std::error_code EC; + OSIter = + OSs.try_emplace(MakeformatOutputPath, MakeformatOutputPath, EC) + .first; + if (EC) + llvm::errs() << "Failed to open P1689 make format output file \"" + << MakeformatOutputPath << "\" for " << EC.message() + << "\n"; + } + + SharedStream MakeformatOS(OSIter->second); + llvm::Expected MaybeOutput(MakeformatOutput); + if (handleMakeDependencyToolResult(Filename, MaybeOutput, + MakeformatOS, Errs)) + HadErrors = true; + } + } else if (MaybeModuleName) { + auto MaybeModuleDepsGraph = WorkerTool.getModuleDependencies( + *MaybeModuleName, Input->CommandLine, CWD, AlreadySeenModules, + LookupOutput); + if (handleModuleResult(*MaybeModuleName, MaybeModuleDepsGraph, *FD, + LocalIndex, DependencyOS, Errs)) + HadErrors = true; + } else { + auto MaybeTUDeps = WorkerTool.getTranslationUnitDependencies( + Input->CommandLine, CWD, AlreadySeenModules, LookupOutput); + if (handleTranslationUnitResult(Filename, MaybeTUDeps, *FD, LocalIndex, + DependencyOS, Errs)) + HadErrors = true; + } + } + }; + + DependencyScanningService Service(ScanMode, Format, OptimizeArgs, + EagerLoadModules); llvm::Timer T; T.startTimer(); - for (unsigned I = 0; I < Pool.getMaxConcurrency(); ++I) { - Pool.async([&, I]() { - llvm::DenseSet AlreadySeenModules; - while (auto MaybeInputIndex = GetNextInputIndex()) { - size_t LocalIndex = *MaybeInputIndex; - const tooling::CompileCommand *Input = &Inputs[LocalIndex]; - std::string Filename = std::move(Input->Filename); - std::string CWD = std::move(Input->Directory); - - std::optional MaybeModuleName; - if (!ModuleName.empty()) - MaybeModuleName = ModuleName; - - std::string OutputDir(ModuleFilesDir); - if (OutputDir.empty()) - OutputDir = getModuleCachePath(Input->CommandLine); - auto LookupOutput = [&](const ModuleID &MID, ModuleOutputKind MOK) { - return ::lookupModuleOutput(MID, MOK, OutputDir); - }; + if (Inputs.size() == 1) { + ScanningTask(Service); + } else { + llvm::DefaultThreadPool Pool(llvm::hardware_concurrency(NumThreads)); - // Run the tool on it. - if (Format == ScanningOutputFormat::Make) { - auto MaybeFile = - WorkerTools[I]->getDependencyFile(Input->CommandLine, CWD); - if (handleMakeDependencyToolResult(Filename, MaybeFile, DependencyOS, - Errs)) - HadErrors = true; - } else if (Format == ScanningOutputFormat::P1689) { - // It is useful to generate the make-format dependency output during - // the scanning for P1689. Otherwise the users need to scan again for - // it. We will generate the make-format dependency output if we find - // `-MF` in the command lines. - std::string MakeformatOutputPath; - std::string MakeformatOutput; - - auto MaybeRule = WorkerTools[I]->getP1689ModuleDependencyFile( - *Input, CWD, MakeformatOutput, MakeformatOutputPath); - - if (handleP1689DependencyToolResult(Filename, MaybeRule, PD, Errs)) - HadErrors = true; + if (Verbose) { + llvm::outs() << "Running clang-scan-deps on " << Inputs.size() + << " files using " << Pool.getMaxConcurrency() + << " workers\n"; + } - if (!MakeformatOutputPath.empty() && !MakeformatOutput.empty() && - !HadErrors) { - static std::mutex Lock; - // With compilation database, we may open different files - // concurrently or we may write the same file concurrently. So we - // use a map here to allow multiple compile commands to write to the - // same file. Also we need a lock here to avoid data race. - static llvm::StringMap OSs; - std::unique_lock LockGuard(Lock); - - auto OSIter = OSs.find(MakeformatOutputPath); - if (OSIter == OSs.end()) { - std::error_code EC; - OSIter = OSs.try_emplace(MakeformatOutputPath, - MakeformatOutputPath, EC) - .first; - if (EC) - llvm::errs() - << "Failed to open P1689 make format output file \"" - << MakeformatOutputPath << "\" for " << EC.message() - << "\n"; - } + for (unsigned I = 0; I < Pool.getMaxConcurrency(); ++I) + Pool.async([ScanningTask, &Service]() { ScanningTask(Service); }); - SharedStream MakeformatOS(OSIter->second); - llvm::Expected MaybeOutput(MakeformatOutput); - if (handleMakeDependencyToolResult(Filename, MaybeOutput, - MakeformatOS, Errs)) - HadErrors = true; - } - } else if (MaybeModuleName) { - auto MaybeModuleDepsGraph = WorkerTools[I]->getModuleDependencies( - *MaybeModuleName, Input->CommandLine, CWD, AlreadySeenModules, - LookupOutput); - if (handleModuleResult(*MaybeModuleName, MaybeModuleDepsGraph, *FD, - LocalIndex, DependencyOS, Errs)) - HadErrors = true; - } else { - auto MaybeTUDeps = WorkerTools[I]->getTranslationUnitDependencies( - Input->CommandLine, CWD, AlreadySeenModules, LookupOutput); - if (handleTranslationUnitResult(Filename, MaybeTUDeps, *FD, - LocalIndex, DependencyOS, Errs)) - HadErrors = true; - } - } - }); + Pool.wait(); } - Pool.wait(); T.stopTimer(); if (PrintTiming) diff --git a/clang/tools/driver/driver.cpp b/clang/tools/driver/driver.cpp index 376025e3605be897c5478b44e1e049c5d2cce572..83b5bbb71f5212375170085b6bb0f29a0ecaff85 100644 --- a/clang/tools/driver/driver.cpp +++ b/clang/tools/driver/driver.cpp @@ -28,6 +28,7 @@ #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/SmallString.h" #include "llvm/ADT/SmallVector.h" +#include "llvm/ADT/StringSet.h" #include "llvm/Option/ArgList.h" #include "llvm/Option/OptTable.h" #include "llvm/Option/Option.h" @@ -41,7 +42,6 @@ #include "llvm/Support/PrettyStackTrace.h" #include "llvm/Support/Process.h" #include "llvm/Support/Program.h" -#include "llvm/Support/Regex.h" #include "llvm/Support/Signals.h" #include "llvm/Support/StringSaver.h" #include "llvm/Support/TargetSelect.h" @@ -73,136 +73,8 @@ std::string GetExecutablePath(const char *Argv0, bool CanonicalPrefixes) { return llvm::sys::fs::getMainExecutable(Argv0, P); } -static const char *GetStableCStr(std::set &SavedStrings, - StringRef S) { - return SavedStrings.insert(std::string(S)).first->c_str(); -} - -/// ApplyOneQAOverride - Apply a list of edits to the input argument lists. -/// -/// The input string is a space separated list of edits to perform, -/// they are applied in order to the input argument lists. Edits -/// should be one of the following forms: -/// -/// '#': Silence information about the changes to the command line arguments. -/// -/// '^': Add FOO as a new argument at the beginning of the command line. -/// -/// '+': Add FOO as a new argument at the end of the command line. -/// -/// 's/XXX/YYY/': Substitute the regular expression XXX with YYY in the command -/// line. -/// -/// 'xOPTION': Removes all instances of the literal argument OPTION. -/// -/// 'XOPTION': Removes all instances of the literal argument OPTION, -/// and the following argument. -/// -/// 'Ox': Removes all flags matching 'O' or 'O[sz0-9]' and adds 'Ox' -/// at the end of the command line. -/// -/// \param OS - The stream to write edit information to. -/// \param Args - The vector of command line arguments. -/// \param Edit - The override command to perform. -/// \param SavedStrings - Set to use for storing string representations. -static void ApplyOneQAOverride(raw_ostream &OS, - SmallVectorImpl &Args, - StringRef Edit, - std::set &SavedStrings) { - // This does not need to be efficient. - - if (Edit[0] == '^') { - const char *Str = - GetStableCStr(SavedStrings, Edit.substr(1)); - OS << "### Adding argument " << Str << " at beginning\n"; - Args.insert(Args.begin() + 1, Str); - } else if (Edit[0] == '+') { - const char *Str = - GetStableCStr(SavedStrings, Edit.substr(1)); - OS << "### Adding argument " << Str << " at end\n"; - Args.push_back(Str); - } else if (Edit[0] == 's' && Edit[1] == '/' && Edit.ends_with("/") && - Edit.slice(2, Edit.size() - 1).contains('/')) { - StringRef MatchPattern = Edit.substr(2).split('/').first; - StringRef ReplPattern = Edit.substr(2).split('/').second; - ReplPattern = ReplPattern.slice(0, ReplPattern.size()-1); - - for (unsigned i = 1, e = Args.size(); i != e; ++i) { - // Ignore end-of-line response file markers - if (Args[i] == nullptr) - continue; - std::string Repl = llvm::Regex(MatchPattern).sub(ReplPattern, Args[i]); - - if (Repl != Args[i]) { - OS << "### Replacing '" << Args[i] << "' with '" << Repl << "'\n"; - Args[i] = GetStableCStr(SavedStrings, Repl); - } - } - } else if (Edit[0] == 'x' || Edit[0] == 'X') { - auto Option = Edit.substr(1); - for (unsigned i = 1; i < Args.size();) { - if (Option == Args[i]) { - OS << "### Deleting argument " << Args[i] << '\n'; - Args.erase(Args.begin() + i); - if (Edit[0] == 'X') { - if (i < Args.size()) { - OS << "### Deleting argument " << Args[i] << '\n'; - Args.erase(Args.begin() + i); - } else - OS << "### Invalid X edit, end of command line!\n"; - } - } else - ++i; - } - } else if (Edit[0] == 'O') { - for (unsigned i = 1; i < Args.size();) { - const char *A = Args[i]; - // Ignore end-of-line response file markers - if (A == nullptr) - continue; - if (A[0] == '-' && A[1] == 'O' && - (A[2] == '\0' || - (A[3] == '\0' && (A[2] == 's' || A[2] == 'z' || - ('0' <= A[2] && A[2] <= '9'))))) { - OS << "### Deleting argument " << Args[i] << '\n'; - Args.erase(Args.begin() + i); - } else - ++i; - } - OS << "### Adding argument " << Edit << " at end\n"; - Args.push_back(GetStableCStr(SavedStrings, '-' + Edit.str())); - } else { - OS << "### Unrecognized edit: " << Edit << "\n"; - } -} - -/// ApplyQAOverride - Apply a space separated list of edits to the -/// input argument lists. See ApplyOneQAOverride. -static void ApplyQAOverride(SmallVectorImpl &Args, - const char *OverrideStr, - std::set &SavedStrings) { - raw_ostream *OS = &llvm::errs(); - - if (OverrideStr[0] == '#') { - ++OverrideStr; - OS = &llvm::nulls(); - } - - *OS << "### CCC_OVERRIDE_OPTIONS: " << OverrideStr << "\n"; - - // This does not need to be efficient. - - const char *S = OverrideStr; - while (*S) { - const char *End = ::strchr(S, ' '); - if (!End) - End = S + strlen(S); - if (End != S) - ApplyOneQAOverride(*OS, Args, std::string(S, End), SavedStrings); - S = End; - if (*S != '\0') - ++S; - } +static const char *GetStableCStr(llvm::StringSet<> &SavedStrings, StringRef S) { + return SavedStrings.insert(S).first->getKeyData(); } extern int cc1_main(ArrayRef Argv, const char *Argv0, @@ -215,7 +87,7 @@ extern int cc1gen_reproducer_main(ArrayRef Argv, static void insertTargetAndModeArgs(const ParsedClangName &NameParts, SmallVectorImpl &ArgVector, - std::set &SavedStrings) { + llvm::StringSet<> &SavedStrings) { // Put target and mode arguments at the start of argument list so that // arguments specified in command line could override them. Avoid putting // them at index 0, as an option like '-cc1' must remain the first. @@ -419,12 +291,13 @@ int clang_main(int Argc, char **Argv, const llvm::ToolContext &ToolContext) { } } - std::set SavedStrings; + llvm::StringSet<> SavedStrings; // Handle CCC_OVERRIDE_OPTIONS, used for editing a command line behind the // scenes. if (const char *OverrideStr = ::getenv("CCC_OVERRIDE_OPTIONS")) { // FIXME: Driver shouldn't take extra initial argument. - ApplyQAOverride(Args, OverrideStr, SavedStrings); + driver::applyOverrideOptions(Args, OverrideStr, SavedStrings, + &llvm::errs()); } std::string Path = GetExecutablePath(ToolContext.Path, CanonicalPrefixes); diff --git a/clang/unittests/ASTMatchers/ASTMatchersTest.h b/clang/unittests/ASTMatchers/ASTMatchersTest.h index 1ed1b5958a8b3a10810fa59a2269fd9c75012f06..e98129953157418fb636d370a029f8295a052321 100644 --- a/clang/unittests/ASTMatchers/ASTMatchersTest.h +++ b/clang/unittests/ASTMatchers/ASTMatchersTest.h @@ -293,7 +293,8 @@ testing::AssertionResult notMatchesWithOpenMP51(const Twine &Code, template testing::AssertionResult matchAndVerifyResultConditionally( const Twine &Code, const T &AMatcher, - std::unique_ptr FindResultVerifier, bool ExpectResult) { + std::unique_ptr FindResultVerifier, bool ExpectResult, + ArrayRef Args = {}, StringRef Filename = "input.cc") { bool VerifiedResult = false; MatchFinder Finder; VerifyMatch VerifyVerifiedResult(std::move(FindResultVerifier), @@ -304,9 +305,13 @@ testing::AssertionResult matchAndVerifyResultConditionally( // Some tests use typeof, which is a gnu extension. Using an explicit // unknown-unknown triple is good for a large speedup, because it lets us // avoid constructing a full system triple. - std::vector Args = {"-std=gnu++11", "-target", - "i386-unknown-unknown"}; - if (!runToolOnCodeWithArgs(Factory->create(), Code, Args)) { + std::vector CompileArgs = {"-std=gnu++11", "-target", + "i386-unknown-unknown"}; + // Append additional arguments at the end to allow overriding the default + // choices that we made above. + llvm::copy(Args, std::back_inserter(CompileArgs)); + + if (!runToolOnCodeWithArgs(Factory->create(), Code, CompileArgs, Filename)) { return testing::AssertionFailure() << "Parsing error in \"" << Code << "\""; } if (!VerifiedResult && ExpectResult) { @@ -319,8 +324,8 @@ testing::AssertionResult matchAndVerifyResultConditionally( VerifiedResult = false; SmallString<256> Buffer; - std::unique_ptr AST( - buildASTFromCodeWithArgs(Code.toStringRef(Buffer), Args)); + std::unique_ptr AST(buildASTFromCodeWithArgs( + Code.toStringRef(Buffer), CompileArgs, Filename)); if (!AST.get()) return testing::AssertionFailure() << "Parsing error in \"" << Code << "\" while building AST"; @@ -339,19 +344,24 @@ testing::AssertionResult matchAndVerifyResultConditionally( // FIXME: Find better names for these functions (or document what they // do more precisely). template -testing::AssertionResult matchAndVerifyResultTrue( - const Twine &Code, const T &AMatcher, - std::unique_ptr FindResultVerifier) { - return matchAndVerifyResultConditionally(Code, AMatcher, - std::move(FindResultVerifier), true); +testing::AssertionResult +matchAndVerifyResultTrue(const Twine &Code, const T &AMatcher, + std::unique_ptr FindResultVerifier, + ArrayRef Args = {}, + StringRef Filename = "input.cc") { + return matchAndVerifyResultConditionally( + Code, AMatcher, std::move(FindResultVerifier), + /*ExpectResult=*/true, Args, Filename); } template testing::AssertionResult matchAndVerifyResultFalse( const Twine &Code, const T &AMatcher, - std::unique_ptr FindResultVerifier) { + std::unique_ptr FindResultVerifier, + ArrayRef Args = {}, StringRef Filename = "input.cc") { return matchAndVerifyResultConditionally( - Code, AMatcher, std::move(FindResultVerifier), false); + Code, AMatcher, std::move(FindResultVerifier), + /*ExpectResult=*/false, Args, Filename); } // Implements a run method that returns whether BoundNodes contains a diff --git a/clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp b/clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp index 6911d7600a718892cec5530b94b170fc2766cf7b..f198dc71eb8337ccba2e311a0809d2ff961fe14f 100644 --- a/clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp +++ b/clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp @@ -985,6 +985,38 @@ TEST(ForEachArgumentWithParam, HandlesBoundNodesForNonMatches) { std::make_unique>("v", 4))); } +TEST_P(ASTMatchersTest, + ForEachArgumentWithParamMatchesExplicitObjectParamOnOperatorCalls) { + if (!GetParam().isCXX23OrLater()) { + return; + } + + auto DeclRef = declRefExpr(to(varDecl().bind("declOfArg"))).bind("arg"); + auto SelfParam = parmVarDecl().bind("param"); + StatementMatcher CallExpr = + callExpr(forEachArgumentWithParam(DeclRef, SelfParam)); + + StringRef S = R"cpp( + struct A { + int operator()(this const A &self); + }; + A obj; + int global = obj(); + )cpp"; + + auto Args = GetParam().getCommandLineArgs(); + auto Filename = getFilenameForTesting(GetParam().Language); + + EXPECT_TRUE(matchAndVerifyResultTrue( + S, CallExpr, + std::make_unique>("param", "self"), Args, + Filename)); + EXPECT_TRUE(matchAndVerifyResultTrue( + S, CallExpr, + std::make_unique>("declOfArg", "obj"), Args, + Filename)); +} + TEST(ForEachArgumentWithParamType, ReportsNoFalsePositives) { StatementMatcher ArgumentY = declRefExpr(to(varDecl(hasName("y")))).bind("arg"); @@ -1168,6 +1200,37 @@ TEST(ForEachArgumentWithParamType, MatchesVariadicFunctionPtrCalls) { S, CallExpr, std::make_unique>("arg"))); } +TEST_P(ASTMatchersTest, + ForEachArgumentWithParamTypeMatchesExplicitObjectParamOnOperatorCalls) { + if (!GetParam().isCXX23OrLater()) { + return; + } + + auto DeclRef = declRefExpr(to(varDecl().bind("declOfArg"))).bind("arg"); + auto SelfTy = qualType(asString("const A &")).bind("selfType"); + StatementMatcher CallExpr = + callExpr(forEachArgumentWithParamType(DeclRef, SelfTy)); + + StringRef S = R"cpp( + struct A { + int operator()(this const A &self); + }; + A obj; + int global = obj(); + )cpp"; + + auto Args = GetParam().getCommandLineArgs(); + auto Filename = getFilenameForTesting(GetParam().Language); + + EXPECT_TRUE(matchAndVerifyResultTrue( + S, CallExpr, std::make_unique>("selfType"), + Args, Filename)); + EXPECT_TRUE(matchAndVerifyResultTrue( + S, CallExpr, + std::make_unique>("declOfArg", "obj"), Args, + Filename)); +} + TEST(QualType, hasCanonicalType) { EXPECT_TRUE(notMatches("typedef int &int_ref;" "int a;" diff --git a/clang/unittests/Analysis/FlowSensitive/TransferTest.cpp b/clang/unittests/Analysis/FlowSensitive/TransferTest.cpp index a8c282f140b4cd01b2de0cc2af030537f2c2965f..86c7f32f0104be2168cacc431cdcf6f831ceed4b 100644 --- a/clang/unittests/Analysis/FlowSensitive/TransferTest.cpp +++ b/clang/unittests/Analysis/FlowSensitive/TransferTest.cpp @@ -2924,6 +2924,36 @@ TEST(TransferTest, ResultObjectLocation) { }); } +TEST(TransferTest, ResultObjectLocationForDefaultArgExpr) { + std::string Code = R"( + struct S {}; + void funcWithDefaultArg(S s = S()); + void target() { + funcWithDefaultArg(); + // [[p]] + } + )"; + + using ast_matchers::cxxDefaultArgExpr; + using ast_matchers::match; + using ast_matchers::selectFirst; + runDataflow( + Code, + [](const llvm::StringMap> &Results, + ASTContext &ASTCtx) { + const Environment &Env = getEnvironmentAtAnnotation(Results, "p"); + + auto *DefaultArg = selectFirst( + "default_arg", + match(cxxDefaultArgExpr().bind("default_arg"), ASTCtx)); + ASSERT_NE(DefaultArg, nullptr); + + // The values for default arguments aren't modeled; we merely verify + // that we can get a result object location for a default arg. + Env.getResultObjectLocation(*DefaultArg); + }); +} + TEST(TransferTest, ResultObjectLocationForDefaultInitExpr) { std::string Code = R"( struct S {}; diff --git a/clang/unittests/Format/.clang-format b/clang/unittests/Format/.clang-format index f95602cab0f7fcdf5d34c485d52b65993dbb83d9..d7331b3c8cf02ef7944e83a4280476627e33b31d 100644 --- a/clang/unittests/Format/.clang-format +++ b/clang/unittests/Format/.clang-format @@ -1,6 +1 @@ -BasedOnStyle: LLVM -InsertBraces: true -InsertNewlineAtEOF: true -LineEnding: LF -RemoveBracesLLVM: true -RemoveParentheses: ReturnStatement +BasedOnStyle: clang-format diff --git a/clang/unittests/Format/FormatTest.cpp b/clang/unittests/Format/FormatTest.cpp index fc367a7a5a8981d99426bf9f29209170e57ff944..a14b002c37c63190d5d16a86aaba898e730b5301 100644 --- a/clang/unittests/Format/FormatTest.cpp +++ b/clang/unittests/Format/FormatTest.cpp @@ -3802,6 +3802,27 @@ TEST_F(FormatTest, FormatsEnum) { " // Comment 2\n" " TWO,\n" "};"); + verifyFormat("enum [[clang::enum_extensibility(open)]] E {\n" + " // Comment 1\n" + " ONE,\n" + " // Comment 2\n" + " TWO\n" + "};"); + verifyFormat("enum [[nodiscard]] [[clang::enum_extensibility(open)]] E {\n" + " // Comment 1\n" + " ONE,\n" + " // Comment 2\n" + " TWO\n" + "};"); + verifyFormat("enum [[clang::enum_extensibility(open)]] E { // foo\n" + " A,\n" + " // bar\n" + " B\n" + "};", + "enum [[clang::enum_extensibility(open)]] E{// foo\n" + " A,\n" + " // bar\n" + " B};"); // Not enums. verifyFormat("enum X f() {\n" @@ -6938,6 +6959,10 @@ TEST_F(FormatTest, PutEmptyBlocksIntoOneLine) { "else if (b) { }\n" "else { }", Style); + + Style = getLLVMStyle(FormatStyle::LK_CSharp); + Style.SpaceInEmptyBlock = true; + verifyFormat("Event += () => { };", Style); } TEST_F(FormatTest, FormatBeginBlockEndMacros) { @@ -11450,6 +11475,11 @@ TEST_F(FormatTest, UnderstandsNewAndDelete) { "void new (link p);\n" "void delete (link p);"); + verifyFormat("p->new();\n" + "p->delete();", + "p->new ();\n" + "p->delete ();"); + FormatStyle AfterPlacementOperator = getLLVMStyle(); AfterPlacementOperator.SpaceBeforeParens = FormatStyle::SBPO_Custom; EXPECT_TRUE( diff --git a/clang/unittests/Format/FormatTestTableGen.cpp b/clang/unittests/Format/FormatTestTableGen.cpp index 76b871e2e1a522b332230423a6e496c798780ba7..c96866f0840f00dff5c478fccf4b8c3a59d00261 100644 --- a/clang/unittests/Format/FormatTestTableGen.cpp +++ b/clang/unittests/Format/FormatTestTableGen.cpp @@ -332,6 +332,85 @@ TEST_F(FormatTestTableGen, Assert) { verifyFormat("assert !le(DefVar1, 0), \"Assert1\";\n"); } +TEST_F(FormatTestTableGen, DAGArgBreakElements) { + FormatStyle Style = getGoogleStyle(FormatStyle::LK_TableGen); + Style.ColumnLimit = 60; + // By default, the DAGArg does not have a break inside. + ASSERT_EQ(Style.TableGenBreakInsideDAGArg, FormatStyle::DAS_DontBreak); + verifyFormat("def Def : Parent {\n" + " let dagarg = (ins a:$src1, aa:$src2, aaa:$src3)\n" + "}\n", + Style); + // This option forces to break inside the DAGArg. + Style.TableGenBreakInsideDAGArg = FormatStyle::DAS_BreakElements; + verifyFormat("def Def : Parent {\n" + " let dagarg = (ins a:$src1,\n" + " aa:$src2,\n" + " aaa:$src3);\n" + "}\n", + Style); + verifyFormat("def Def : Parent {\n" + " let dagarg = (other a:$src1,\n" + " aa:$src2,\n" + " aaa:$src3);\n" + "}\n", + Style); + // Then, limit the DAGArg operator only to "ins". + Style.TableGenBreakingDAGArgOperators = {"ins"}; + verifyFormat("def Def : Parent {\n" + " let dagarg = (ins a:$src1,\n" + " aa:$src2,\n" + " aaa:$src3);\n" + "}\n", + Style); + verifyFormat("def Def : Parent {\n" + " let dagarg = (other a:$src1, aa:$src2, aaa:$src3)\n" + "}\n", + Style); +} + +TEST_F(FormatTestTableGen, DAGArgBreakAll) { + FormatStyle Style = getGoogleStyle(FormatStyle::LK_TableGen); + Style.ColumnLimit = 60; + // By default, the DAGArg does not have a break inside. + verifyFormat("def Def : Parent {\n" + " let dagarg = (ins a:$src1, aa:$src2, aaa:$src3)\n" + "}\n", + Style); + // This option forces to break inside the DAGArg. + Style.TableGenBreakInsideDAGArg = FormatStyle::DAS_BreakAll; + verifyFormat("def Def : Parent {\n" + " let dagarg = (ins\n" + " a:$src1,\n" + " aa:$src2,\n" + " aaa:$src3\n" + " );\n" + "}\n", + Style); + verifyFormat("def Def : Parent {\n" + " let dagarg = (other\n" + " a:$src1,\n" + " aa:$src2,\n" + " aaa:$src3\n" + " );\n" + "}\n", + Style); + // Then, limit the DAGArg operator only to "ins". + Style.TableGenBreakingDAGArgOperators = {"ins"}; + verifyFormat("def Def : Parent {\n" + " let dagarg = (ins\n" + " a:$src1,\n" + " aa:$src2,\n" + " aaa:$src3\n" + " );\n" + "}\n", + Style); + verifyFormat("def Def : Parent {\n" + " let dagarg = (other a:$src1, aa:$src2, aaa:$src3);\n" + "}\n", + Style); +} + TEST_F(FormatTestTableGen, CondOperatorAlignment) { FormatStyle Style = getGoogleStyle(FormatStyle::LK_TableGen); Style.ColumnLimit = 60; diff --git a/clang/unittests/Format/TokenAnnotatorTest.cpp b/clang/unittests/Format/TokenAnnotatorTest.cpp index c736dac8dabf2134e0f720f54bf79635a4659e7f..bfb71d1f7e97ea0cbed3b080e3c4472e56f1c78c 100644 --- a/clang/unittests/Format/TokenAnnotatorTest.cpp +++ b/clang/unittests/Format/TokenAnnotatorTest.cpp @@ -620,6 +620,24 @@ TEST_F(TokenAnnotatorTest, UnderstandsCasts) { ASSERT_EQ(Tokens.size(), 8u) << Tokens; EXPECT_TOKEN(Tokens[3], tok::r_paren, TT_Unknown); EXPECT_TOKEN(Tokens[4], tok::amp, TT_BinaryOperator); + + Tokens = annotate("#define FOO(bar) foo((uint64_t)&bar)"); + ASSERT_EQ(Tokens.size(), 15u) << Tokens; + EXPECT_TOKEN(Tokens[10], tok::r_paren, TT_CastRParen); + EXPECT_TOKEN(Tokens[11], tok::amp, TT_UnaryOperator); + + Tokens = annotate("#define FOO(bar) foo((Foo) & bar)"); + ASSERT_EQ(Tokens.size(), 15u) << Tokens; + EXPECT_TOKEN(Tokens[10], tok::r_paren, TT_Unknown); + EXPECT_TOKEN(Tokens[11], tok::amp, TT_BinaryOperator); + + auto Style = getLLVMStyle(); + Style.TypeNames.push_back("Foo"); + Tokens = annotate("#define FOO(bar) foo((Foo)&bar)", Style); + ASSERT_EQ(Tokens.size(), 15u) << Tokens; + EXPECT_TOKEN(Tokens[9], tok::identifier, TT_TypeName); + EXPECT_TOKEN(Tokens[10], tok::r_paren, TT_CastRParen); + EXPECT_TOKEN(Tokens[11], tok::amp, TT_UnaryOperator); } TEST_F(TokenAnnotatorTest, UnderstandsDynamicExceptionSpecifier) { @@ -1751,12 +1769,29 @@ TEST_F(TokenAnnotatorTest, UnderstandsFunctionDeclarationNames) { EXPECT_TOKEN(Tokens[3], tok::identifier, TT_Unknown); EXPECT_TOKEN(Tokens[4], tok::l_paren, TT_FunctionTypeLParen); + Tokens = annotate("int iso_time(time_t);"); + ASSERT_EQ(Tokens.size(), 7u) << Tokens; + EXPECT_TOKEN(Tokens[1], tok::identifier, TT_FunctionDeclarationName); + auto Style = getLLVMStyle(); - Style.TypeNames.push_back("time_t"); - Tokens = annotate("int iso_time(time_t);", Style); + Style.TypeNames.push_back("MyType"); + Tokens = annotate("int iso_time(MyType);", Style); + ASSERT_TRUE(IsCpp); ASSERT_EQ(Tokens.size(), 7u) << Tokens; EXPECT_TOKEN(Tokens[1], tok::identifier, TT_FunctionDeclarationName); EXPECT_TOKEN(Tokens[3], tok::identifier, TT_TypeName); + + Style.Language = FormatStyle::LK_CSharp; + Tokens = annotate("int iso_time(time_t);", Style); + ASSERT_FALSE(IsCpp); + ASSERT_EQ(Tokens.size(), 7u) << Tokens; + EXPECT_TOKEN(Tokens[1], tok::identifier, TT_StartOfName); + + Style.Language = FormatStyle::LK_ObjC; + Tokens = annotate("int iso_time(time_t);", Style); + ASSERT_TRUE(IsCpp); + ASSERT_EQ(Tokens.size(), 7u) << Tokens; + EXPECT_TOKEN(Tokens[1], tok::identifier, TT_FunctionDeclarationName); } TEST_F(TokenAnnotatorTest, UnderstandsCtorAndDtorDeclNames) { @@ -2332,6 +2367,76 @@ TEST_F(TokenAnnotatorTest, UnderstandTableGenTokens) { EXPECT_TOKEN(Tokens[4], tok::less, TT_TemplateOpener); EXPECT_TOKEN(Tokens[6], tok::greater, TT_TemplateCloser); EXPECT_TOKEN(Tokens[7], tok::l_brace, TT_FunctionLBrace); + + // DAGArg breaking options. They use different token types depending on what + // is specified. + Style.TableGenBreakInsideDAGArg = FormatStyle::DAS_BreakElements; + + // When TableGenBreakInsideDAGArg is DAS_BreakElements and + // TableGenBreakingDAGArgOperators is not specified, it makes all the DAGArg + // elements to have line break. + Tokens = AnnotateValue("(ins type1:$src1, type2:$src2)"); + ASSERT_EQ(Tokens.size(), 10u) << Tokens; + EXPECT_TOKEN(Tokens[0], tok::l_paren, TT_TableGenDAGArgOpenerToBreak); + EXPECT_TOKEN(Tokens[1], tok::identifier, + TT_TableGenDAGArgOperatorID); // ins + EXPECT_TOKEN(Tokens[5], tok::comma, TT_TableGenDAGArgListCommaToBreak); + EXPECT_TOKEN(Tokens[9], tok::r_paren, TT_TableGenDAGArgCloser); + + Tokens = AnnotateValue("(other type1:$src1, type2:$src2)"); + ASSERT_EQ(Tokens.size(), 10u) << Tokens; + EXPECT_TOKEN(Tokens[0], tok::l_paren, TT_TableGenDAGArgOpenerToBreak); + EXPECT_TOKEN(Tokens[1], tok::identifier, + TT_TableGenDAGArgOperatorID); // other + EXPECT_TOKEN(Tokens[5], tok::comma, TT_TableGenDAGArgListCommaToBreak); + EXPECT_TOKEN(Tokens[9], tok::r_paren, TT_TableGenDAGArgCloser); + + // For non-identifier operators, breaks after the operator. + Tokens = AnnotateValue("(!cast(\"Name\") type1:$src1, type2:$src2)"); + ASSERT_EQ(Tokens.size(), 16u) << Tokens; + EXPECT_TOKEN(Tokens[0], tok::l_paren, TT_TableGenDAGArgOpenerToBreak); + EXPECT_TOKEN(Tokens[7], tok::r_paren, TT_TableGenDAGArgOperatorToBreak); + EXPECT_TOKEN(Tokens[11], tok::comma, TT_TableGenDAGArgListCommaToBreak); + EXPECT_TOKEN(Tokens[15], tok::r_paren, TT_TableGenDAGArgCloser); + + Style.TableGenBreakInsideDAGArg = FormatStyle::DAS_BreakAll; + + // When TableGenBreakInsideDAGArg is DAS_BreakAll and + // TableGenBreakingDAGArgOperators is not specified, it makes all the DAGArg + // to have line break inside it. + Tokens = AnnotateValue("(ins type1:$src1, type2:$src2)"); + ASSERT_EQ(Tokens.size(), 10u) << Tokens; + EXPECT_TOKEN(Tokens[0], tok::l_paren, TT_TableGenDAGArgOpenerToBreak); + EXPECT_TOKEN(Tokens[1], tok::identifier, + TT_TableGenDAGArgOperatorToBreak); // ins + EXPECT_TOKEN(Tokens[5], tok::comma, TT_TableGenDAGArgListCommaToBreak); + EXPECT_TOKEN(Tokens[9], tok::r_paren, TT_TableGenDAGArgCloser); + + Tokens = AnnotateValue("(other type1:$src1, type2:$src2)"); + ASSERT_EQ(Tokens.size(), 10u) << Tokens; + EXPECT_TOKEN(Tokens[0], tok::l_paren, TT_TableGenDAGArgOpenerToBreak); + EXPECT_TOKEN(Tokens[1], tok::identifier, + TT_TableGenDAGArgOperatorToBreak); // other + EXPECT_TOKEN(Tokens[5], tok::comma, TT_TableGenDAGArgListCommaToBreak); + EXPECT_TOKEN(Tokens[9], tok::r_paren, TT_TableGenDAGArgCloser); + + // If TableGenBreakingDAGArgOperators is specified, it is limited to the + // specified operators. + Style.TableGenBreakingDAGArgOperators = {"ins", "outs"}; + Tokens = AnnotateValue("(ins type1:$src1, type2:$src2)"); + ASSERT_EQ(Tokens.size(), 10u) << Tokens; + EXPECT_TOKEN(Tokens[0], tok::l_paren, TT_TableGenDAGArgOpenerToBreak); + EXPECT_TOKEN(Tokens[1], tok::identifier, + TT_TableGenDAGArgOperatorToBreak); // ins + EXPECT_TOKEN(Tokens[5], tok::comma, TT_TableGenDAGArgListCommaToBreak); + EXPECT_TOKEN(Tokens[9], tok::r_paren, TT_TableGenDAGArgCloser); + + Tokens = AnnotateValue("(other type1:$src1, type2:$src2)"); + ASSERT_EQ(Tokens.size(), 10u) << Tokens; + EXPECT_TOKEN(Tokens[0], tok::l_paren, TT_TableGenDAGArgOpener); + EXPECT_TOKEN(Tokens[1], tok::identifier, TT_Unknown); // other + EXPECT_TOKEN(Tokens[5], tok::comma, TT_TableGenDAGArgListComma); + EXPECT_TOKEN(Tokens[9], tok::r_paren, TT_TableGenDAGArgCloser); } TEST_F(TokenAnnotatorTest, UnderstandConstructors) { @@ -2610,6 +2715,11 @@ TEST_F(TokenAnnotatorTest, StartOfName) { EXPECT_TOKEN(Tokens[2], tok::identifier, TT_Unknown); EXPECT_TOKEN(Tokens[3], tok::identifier, TT_Unknown); EXPECT_TOKEN(Tokens[4], tok::identifier, TT_StartOfName); + + Tokens = annotate("@interface NSCoder (TestCoder)"); + ASSERT_EQ(Tokens.size(), 7u) << Tokens; + EXPECT_TOKEN(Tokens[0], tok::at, TT_ObjCDecl); + EXPECT_TOKEN(Tokens[2], tok::identifier, TT_StartOfName); } TEST_F(TokenAnnotatorTest, BraceKind) { diff --git a/clang/unittests/Interpreter/CMakeLists.txt b/clang/unittests/Interpreter/CMakeLists.txt index 0ddedb283e07d152e476dadf9922315a2b6dd0df..b56e1e21015db91a85e6aa8a0a51b604eb057327 100644 --- a/clang/unittests/Interpreter/CMakeLists.txt +++ b/clang/unittests/Interpreter/CMakeLists.txt @@ -10,6 +10,7 @@ add_clang_unittest(ClangReplInterpreterTests IncrementalCompilerBuilderTest.cpp IncrementalProcessingTest.cpp InterpreterTest.cpp + InterpreterExtensionsTest.cpp CodeCompletionTest.cpp ) target_link_libraries(ClangReplInterpreterTests PUBLIC @@ -18,6 +19,7 @@ target_link_libraries(ClangReplInterpreterTests PUBLIC clangInterpreter clangFrontend clangSema + LLVMTestingSupport ) # Exceptions on Windows are not yet supported. diff --git a/clang/unittests/Interpreter/InterpreterExtensionsTest.cpp b/clang/unittests/Interpreter/InterpreterExtensionsTest.cpp new file mode 100644 index 0000000000000000000000000000000000000000..b7708616fd24d34a8fc2daed6a4d3a6332ff5cfd --- /dev/null +++ b/clang/unittests/Interpreter/InterpreterExtensionsTest.cpp @@ -0,0 +1,129 @@ +//===- unittests/Interpreter/InterpreterExtensionsTest.cpp ----------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// +// +// Unit tests for Clang's Interpreter library. +// +//===----------------------------------------------------------------------===// + +#include "clang/Interpreter/Interpreter.h" + +#include "clang/AST/Expr.h" +#include "clang/Frontend/CompilerInstance.h" +#include "clang/Sema/Lookup.h" +#include "clang/Sema/Sema.h" + +#include "llvm/ExecutionEngine/Orc/LLJIT.h" +#include "llvm/Support/Error.h" +#include "llvm/Support/TargetSelect.h" +#include "llvm/Testing/Support/Error.h" + +#include "gmock/gmock.h" +#include "gtest/gtest.h" +#include + +using namespace clang; +namespace { + +static bool HostSupportsJit() { + auto J = llvm::orc::LLJITBuilder().create(); + if (J) + return true; + LLVMConsumeError(llvm::wrap(J.takeError())); + return false; +} + +struct LLVMInitRAII { + LLVMInitRAII() { + llvm::InitializeNativeTarget(); + llvm::InitializeNativeTargetAsmPrinter(); + } + ~LLVMInitRAII() { llvm::llvm_shutdown(); } +} LLVMInit; + +class TestCreateResetExecutor : public Interpreter { +public: + TestCreateResetExecutor(std::unique_ptr CI, + llvm::Error &Err) + : Interpreter(std::move(CI), Err) {} + + llvm::Error testCreateExecutor() { return Interpreter::CreateExecutor(); } + + void resetExecutor() { Interpreter::ResetExecutor(); } +}; + +#ifdef _AIX +TEST(InterpreterExtensionsTest, DISABLED_ExecutorCreateReset) { +#else +TEST(InterpreterExtensionsTest, ExecutorCreateReset) { +#endif + // Make sure we can create the executer on the platform. + if (!HostSupportsJit()) + GTEST_SKIP(); + + clang::IncrementalCompilerBuilder CB; + llvm::Error ErrOut = llvm::Error::success(); + TestCreateResetExecutor Interp(cantFail(CB.CreateCpp()), ErrOut); + cantFail(std::move(ErrOut)); + cantFail(Interp.testCreateExecutor()); + Interp.resetExecutor(); + cantFail(Interp.testCreateExecutor()); + EXPECT_THAT_ERROR(Interp.testCreateExecutor(), + llvm::FailedWithMessage("Operation failed. " + "Execution engine exists")); +} + +class RecordRuntimeIBMetrics : public Interpreter { + struct NoopRuntimeInterfaceBuilder : public RuntimeInterfaceBuilder { + NoopRuntimeInterfaceBuilder(Sema &S) : S(S) {} + + TransformExprFunction *getPrintValueTransformer() override { + TransformerQueries += 1; + return &noop; + } + + static ExprResult noop(RuntimeInterfaceBuilder *Builder, Expr *E, + ArrayRef FixedArgs) { + auto *B = static_cast(Builder); + B->TransformedExprs += 1; + return B->S.ActOnFinishFullExpr(E, /*DiscardedValue=*/false); + } + + Sema &S; + size_t TransformedExprs = 0; + size_t TransformerQueries = 0; + }; + +public: + // Inherit with using wouldn't make it public + RecordRuntimeIBMetrics(std::unique_ptr CI, llvm::Error &Err) + : Interpreter(std::move(CI), Err) {} + + std::unique_ptr FindRuntimeInterface() override { + assert(RuntimeIBPtr == nullptr && "We create the builder only once"); + Sema &S = getCompilerInstance()->getSema(); + auto RuntimeIB = std::make_unique(S); + RuntimeIBPtr = RuntimeIB.get(); + return RuntimeIB; + } + + NoopRuntimeInterfaceBuilder *RuntimeIBPtr = nullptr; +}; + +TEST(InterpreterExtensionsTest, FindRuntimeInterface) { + clang::IncrementalCompilerBuilder CB; + llvm::Error ErrOut = llvm::Error::success(); + RecordRuntimeIBMetrics Interp(cantFail(CB.CreateCpp()), ErrOut); + cantFail(std::move(ErrOut)); + cantFail(Interp.Parse("int a = 1; a")); + cantFail(Interp.Parse("int b = 2; b")); + cantFail(Interp.Parse("int c = 3; c")); + EXPECT_EQ(3U, Interp.RuntimeIBPtr->TransformedExprs); + EXPECT_EQ(1U, Interp.RuntimeIBPtr->TransformerQueries); +} + +} // end anonymous namespace diff --git a/clang/www/cxx_status.html b/clang/www/cxx_status.html index a3090adb5d47ba45c6d5a4329e3f93a508bd8d01..1e36b90356c3e1abbb042b95fff95f0868c07b85 100755 --- a/clang/www/cxx_status.html +++ b/clang/www/cxx_status.html @@ -381,7 +381,7 @@ C++23, informally referred to as C++26.

Portable assumptions
P1774R8 - No + Clang 19 Support for UTF-8 as a portable source file encoding diff --git a/clang/www/get_started.html b/clang/www/get_started.html index dda914a46904e835e41bbc548b4c14a29f16f8e2..8e4d36640be7357a97d0923fd3964bd872658ba7 100755 --- a/clang/www/get_started.html +++ b/clang/www/get_started.html @@ -86,13 +86,16 @@ follows:

-
  • If you intend to use Clang's C++ support, you may need to tell it how - to find your C++ standard library headers. In general, Clang will detect - the best version of libstdc++ headers available and use them - it will - look both for system installations of libstdc++ as well as installations - adjacent to Clang itself. If your configuration fits neither of these - scenarios, you can use the -DGCC_INSTALL_PREFIX cmake option - to tell Clang where the gcc containing the desired libstdc++ is installed. +
  • On Linux, you may need GCC runtime libraries (e.g. crtbeginS.o, + libstdc++.so) and libstdc++ headers. In general, Clang will detect + well-known GCC installation paths matching the target triple (configured at + build time (see clang --version); overriden by + --target=) and use the largest version. If your configuration fits + none of the standard scenarios, you can set --gcc-install-dir= to + the GCC installation directory (something like + /usr/lib/gcc/$triple/$major). If your GCC installation is under + /usr/lib/gcc but uses a different triple, you can set + --gcc-triple=$triple.
  • Try it out (assuming you add llvm/build/bin to your path):
      diff --git a/cmake/Modules/CMakePolicy.cmake b/cmake/Modules/CMakePolicy.cmake index 0ec32ad8637f3dc237806719a4812528b82e31d4..1c18c1810dae6266f7bc8c306cbf33e7af8c5557 100644 --- a/cmake/Modules/CMakePolicy.cmake +++ b/cmake/Modules/CMakePolicy.cmake @@ -10,3 +10,16 @@ endif() if(POLICY CMP0116) cmake_policy(SET CMP0116 OLD) endif() + +# MSVC debug information format flags are selected via +# CMAKE_MSVC_DEBUG_INFORMATION_FORMAT, instead of +# embedding flags in e.g. CMAKE_CXX_FLAGS_RELEASE. +# New in CMake 3.25. +# +# Supports debug info with SCCache +# (https://github.com/mozilla/sccache?tab=readme-ov-file#usage) +# avoiding “fatal error C1041: cannot open program database; if +# multiple CL.EXE write to the same .PDB file, please use /FS" +if(POLICY CMP0141) + cmake_policy(SET CMP0141 NEW) +endif() diff --git a/cmake/Modules/LLVMVersion.cmake b/cmake/Modules/LLVMVersion.cmake new file mode 100644 index 0000000000000000000000000000000000000000..5e28283fbc1c60a0565f1e176087ae1a0eff0f6e --- /dev/null +++ b/cmake/Modules/LLVMVersion.cmake @@ -0,0 +1,15 @@ +# The LLVM Version number information + +if(NOT DEFINED LLVM_VERSION_MAJOR) + set(LLVM_VERSION_MAJOR 19) +endif() +if(NOT DEFINED LLVM_VERSION_MINOR) + set(LLVM_VERSION_MINOR 0) +endif() +if(NOT DEFINED LLVM_VERSION_PATCH) + set(LLVM_VERSION_PATCH 0) +endif() +if(NOT DEFINED LLVM_VERSION_SUFFIX) + set(LLVM_VERSION_SUFFIX git) +endif() + diff --git a/compiler-rt/CMakeLists.txt b/compiler-rt/CMakeLists.txt index 8a2b138d8d7020d510532780043c8feb96529337..d562a6206c00e7edd72ee6b559e5bd0a78338f73 100644 --- a/compiler-rt/CMakeLists.txt +++ b/compiler-rt/CMakeLists.txt @@ -502,7 +502,10 @@ append_list_if(MINGW -fms-extensions SANITIZER_COMMON_CFLAGS) # # Note that this type of issue was discovered with lsan, but can apply to other # sanitizers. -append_list_if(COMPILER_RT_HAS_TRIVIAL_AUTO_INIT -ftrivial-auto-var-init=pattern SANITIZER_COMMON_CFLAGS) +# Disable PowerPC because of https://github.com/llvm/llvm-project/issues/84654. +if(NOT "${COMPILER_RT_DEFAULT_TARGET_ARCH}" MATCHES "powerpc") + append_list_if(COMPILER_RT_HAS_TRIVIAL_AUTO_INIT -ftrivial-auto-var-init=pattern SANITIZER_COMMON_CFLAGS) +endif() # Set common link flags. # TODO: We should consider using the same model as libc++, that is use either diff --git a/compiler-rt/cmake/base-config-ix.cmake b/compiler-rt/cmake/base-config-ix.cmake index 908c8a40278cf0cd1ed95cf8225c182942152d5e..1e3317de80ac3a36dde1192be5bc82e2ed1208e1 100644 --- a/compiler-rt/cmake/base-config-ix.cmake +++ b/compiler-rt/cmake/base-config-ix.cmake @@ -156,6 +156,7 @@ if(APPLE) option(COMPILER_RT_ENABLE_WATCHOS "Enable building for watchOS - Experimental" Off) option(COMPILER_RT_ENABLE_TVOS "Enable building for tvOS - Experimental" Off) + option(COMPILER_RT_ENABLE_XROS "Enable building for xrOS - Experimental" Off) else() option(COMPILER_RT_DEFAULT_TARGET_ONLY "Build builtins only for the default target" Off) diff --git a/compiler-rt/cmake/builtin-config-ix.cmake b/compiler-rt/cmake/builtin-config-ix.cmake index b17c43bf6a68b89082167b1b47c11c1a3c6708b2..33c97b1ac28aff8d733c43bcc53486e7c1be0138 100644 --- a/compiler-rt/cmake/builtin-config-ix.cmake +++ b/compiler-rt/cmake/builtin-config-ix.cmake @@ -1,4 +1,5 @@ include(BuiltinTests) +include(CheckIncludeFiles) include(CheckCSourceCompiles) # Make all the tests only check the compiler @@ -43,6 +44,8 @@ void foo(void) __arm_streaming_compatible { } ") +check_include_files("sys/auxv.h" COMPILER_RT_HAS_AUXV) + if(ANDROID) set(OS_NAME "Android") else() @@ -92,6 +95,8 @@ if(APPLE) find_darwin_sdk_dir(DARWIN_watchos_SYSROOT watchos) find_darwin_sdk_dir(DARWIN_tvossim_SYSROOT appletvsimulator) find_darwin_sdk_dir(DARWIN_tvos_SYSROOT appletvos) + find_darwin_sdk_dir(DARWIN_xrossim_SYSROOT xrsimulator) + find_darwin_sdk_dir(DARWIN_xros_SYSROOT xros) # Get supported architecture from SDKSettings. function(sdk_has_arch_support sdk_path os arch has_support) @@ -162,6 +167,11 @@ if(APPLE) list(APPEND DARWIN_tvossim_BUILTIN_ALL_POSSIBLE_ARCHS arm64) endif() endif() + if(COMPILER_RT_ENABLE_XROS) + list(APPEND DARWIN_EMBEDDED_PLATFORMS xros) + set(DARWIN_xros_BUILTIN_ALL_POSSIBLE_ARCHS ${ARM64} ${ARM32}) + set(DARWIN_xrossim_BUILTIN_ALL_POSSIBLE_ARCHS arm64) + endif() set(BUILTIN_SUPPORTED_OS osx) diff --git a/compiler-rt/lib/asan/asan_interceptors.cpp b/compiler-rt/lib/asan/asan_interceptors.cpp index 9d383b9d37c4a1a686896aa2af2633389c48e915..da47317c0e57641fc9cca7a93ea6d847d5a80db9 100644 --- a/compiler-rt/lib/asan/asan_interceptors.cpp +++ b/compiler-rt/lib/asan/asan_interceptors.cpp @@ -570,6 +570,17 @@ INTERCEPTOR(char *, strcpy, char *to, const char *from) { return REAL(strcpy)(to, from); } +// Windows doesn't always define the strdup identifier, +// and when it does it's a macro defined to either _strdup +// or _strdup_dbg, _strdup_dbg ends up calling _strdup, so +// we want to intercept that. push/pop_macro are used to avoid problems +// if this file ends up including in the future. +# if SANITIZER_WINDOWS +# pragma push_macro("strdup") +# undef strdup +# define strdup _strdup +# endif + INTERCEPTOR(char*, strdup, const char *s) { void *ctx; ASAN_INTERCEPTOR_ENTER(ctx, strdup); @@ -587,7 +598,7 @@ INTERCEPTOR(char*, strdup, const char *s) { return reinterpret_cast(new_mem); } -#if ASAN_INTERCEPT___STRDUP +# if ASAN_INTERCEPT___STRDUP INTERCEPTOR(char*, __strdup, const char *s) { void *ctx; ASAN_INTERCEPTOR_ENTER(ctx, strdup); @@ -770,7 +781,7 @@ void InitializeAsanInterceptors() { ASAN_INTERCEPT_FUNC(strncat); ASAN_INTERCEPT_FUNC(strncpy); ASAN_INTERCEPT_FUNC(strdup); -#if ASAN_INTERCEPT___STRDUP +# if ASAN_INTERCEPT___STRDUP ASAN_INTERCEPT_FUNC(__strdup); #endif #if ASAN_INTERCEPT_INDEX && ASAN_USE_ALIAS_ATTRIBUTE_FOR_INDEX @@ -866,6 +877,10 @@ void InitializeAsanInterceptors() { VReport(1, "AddressSanitizer: libc interceptors initialized\n"); } +# if SANITIZER_WINDOWS +# pragma pop_macro("strdup") +# endif + } // namespace __asan #endif // !SANITIZER_FUCHSIA diff --git a/compiler-rt/lib/asan/asan_win_dll_thunk.cpp b/compiler-rt/lib/asan/asan_win_dll_thunk.cpp index 0fa636bec0d001af2da51608f1d580014318fa9c..35871a942a7a126d086d5b56e09bff20dbfe75b5 100644 --- a/compiler-rt/lib/asan/asan_win_dll_thunk.cpp +++ b/compiler-rt/lib/asan/asan_win_dll_thunk.cpp @@ -80,7 +80,7 @@ INTERCEPT_LIBRARY_FUNCTION(strchr); INTERCEPT_LIBRARY_FUNCTION(strcmp); INTERCEPT_LIBRARY_FUNCTION(strcpy); INTERCEPT_LIBRARY_FUNCTION(strcspn); -INTERCEPT_LIBRARY_FUNCTION(strdup); +INTERCEPT_LIBRARY_FUNCTION(_strdup); INTERCEPT_LIBRARY_FUNCTION(strlen); INTERCEPT_LIBRARY_FUNCTION(strncat); INTERCEPT_LIBRARY_FUNCTION(strncmp); diff --git a/compiler-rt/lib/asan/tests/CMakeLists.txt b/compiler-rt/lib/asan/tests/CMakeLists.txt index 6ee2fb01c0df4936422be24ea518d69993060e7c..bda47bd7fd6a2236c3ded87f0ce9b74d8d442946 100644 --- a/compiler-rt/lib/asan/tests/CMakeLists.txt +++ b/compiler-rt/lib/asan/tests/CMakeLists.txt @@ -172,7 +172,7 @@ function(add_asan_tests arch test_runtime) function(generate_asan_tests test_objects test_suite testname) generate_compiler_rt_tests(${test_objects} ${test_suite} ${testname} ${arch} COMPILE_DEPS ${ASAN_UNITTEST_HEADERS} ${ASAN_IGNORELIST_FILE} - DEPS llvm_gtest asan + DEPS asan KIND ${TEST_KIND} ${ARGN} ) diff --git a/compiler-rt/lib/builtins/CMakeLists.txt b/compiler-rt/lib/builtins/CMakeLists.txt index 3f2c0f0436393d2822b0fd24606bae5aac510c9e..f9611574a562b4c5927e413284b1734de7b72cea 100644 --- a/compiler-rt/lib/builtins/CMakeLists.txt +++ b/compiler-rt/lib/builtins/CMakeLists.txt @@ -917,7 +917,7 @@ cmake_dependent_option(COMPILER_RT_BUILD_CRT "Build crtbegin.o/crtend.o" ON "COM if (COMPILER_RT_BUILD_CRT) add_compiler_rt_component(crt) - option(COMPILER_RT_CRT_USE_EH_FRAME_REGISTRY "Use eh_frame in crtbegin.o/crtend.o" OFF) + option(COMPILER_RT_CRT_USE_EH_FRAME_REGISTRY "Use eh_frame in crtbegin.o/crtend.o" ON) include(CheckSectionExists) check_section_exists(".init_array" COMPILER_RT_HAS_INITFINI_ARRAY diff --git a/compiler-rt/lib/builtins/aarch64/sme-abi.S b/compiler-rt/lib/builtins/aarch64/sme-abi.S index d470ecaf7aaad1974963cd368728aaee0119a596..4c0ff66931db7b2ccd6fcb5c2131ff8250b3e85e 100644 --- a/compiler-rt/lib/builtins/aarch64/sme-abi.S +++ b/compiler-rt/lib/builtins/aarch64/sme-abi.S @@ -26,9 +26,10 @@ // abort(). Note that there is no need to preserve any state before the call, // because the function does not return. DEFINE_COMPILERRT_PRIVATE_FUNCTION(do_abort) -.cfi_startproc - .variant_pcs SYMBOL_NAME(do_abort) - stp x29, x30, [sp, #-32]! + .cfi_startproc + .variant_pcs SYMBOL_NAME(do_abort) + BTI_C + stp x29, x30, [sp, #-32]! cntd x0 // Store VG to a stack location that we describe with .cfi_offset str x0, [sp, #16] @@ -36,22 +37,23 @@ DEFINE_COMPILERRT_PRIVATE_FUNCTION(do_abort) .cfi_offset w30, -24 .cfi_offset w29, -32 .cfi_offset 46, -16 - bl __arm_sme_state - tbz x0, #0, 2f + bl __arm_sme_state + tbz x0, #0, 2f 1: - smstop sm + smstop sm 2: // We can't make this into a tail-call because the unwinder would // need to restore the value of VG. - bl SYMBOL_NAME(abort) -.cfi_endproc + bl SYMBOL_NAME(abort) + .cfi_endproc END_COMPILERRT_FUNCTION(do_abort) // __arm_sme_state fills the result registers based on a local // that is set as part of the compiler-rt startup code. // __aarch64_has_sme_and_tpidr2_el0 DEFINE_COMPILERRT_OUTLINE_FUNCTION_UNMANGLED(__arm_sme_state) - .variant_pcs __arm_sme_state + .variant_pcs __arm_sme_state + BTI_C mov x0, xzr mov x1, xzr @@ -68,7 +70,8 @@ DEFINE_COMPILERRT_OUTLINE_FUNCTION_UNMANGLED(__arm_sme_state) END_COMPILERRT_OUTLINE_FUNCTION(__arm_sme_state) DEFINE_COMPILERRT_OUTLINE_FUNCTION_UNMANGLED(__arm_tpidr2_restore) - .variant_pcs __arm_tpidr2_restore + .variant_pcs __arm_tpidr2_restore + BTI_C // If TPIDR2_EL0 is nonnull, the subroutine aborts in some platform-specific // manner. mrs x14, TPIDR2_EL0 @@ -103,7 +106,8 @@ DEFINE_COMPILERRT_OUTLINE_FUNCTION_UNMANGLED(__arm_tpidr2_restore) END_COMPILERRT_OUTLINE_FUNCTION(__arm_tpidr2_restore) DEFINE_COMPILERRT_OUTLINE_FUNCTION_UNMANGLED(__arm_tpidr2_save) - .variant_pcs __arm_tpidr2_restore + .variant_pcs __arm_tpidr2_restore + BTI_C // If the current thread does not have access to TPIDR2_EL0, the subroutine // does nothing. adrp x14, TPIDR2_SYMBOL @@ -143,7 +147,8 @@ DEFINE_COMPILERRT_OUTLINE_FUNCTION_UNMANGLED(__arm_tpidr2_save) END_COMPILERRT_OUTLINE_FUNCTION(__arm_tpidr2_save) DEFINE_COMPILERRT_OUTLINE_FUNCTION_UNMANGLED(__arm_za_disable) - .variant_pcs __arm_tpidr2_restore + .variant_pcs __arm_tpidr2_restore + BTI_C // If the current thread does not have access to SME, the subroutine does // nothing. adrp x14, TPIDR2_SYMBOL @@ -174,3 +179,8 @@ DEFINE_COMPILERRT_OUTLINE_FUNCTION_UNMANGLED(__arm_za_disable) 0: ret END_COMPILERRT_OUTLINE_FUNCTION(__arm_za_disable) + +NO_EXEC_STACK_DIRECTIVE + +// GNU property note for BTI and PAC +GNU_PROPERTY_BTI_PAC diff --git a/compiler-rt/lib/fuzzer/FuzzerUtilLinux.cpp b/compiler-rt/lib/fuzzer/FuzzerUtilLinux.cpp index 5729448b0beb13f7fda6f9be57f9c06d9c7522cb..e5409f22f0e3a2c98911c2bb5a15589af7288da3 100644 --- a/compiler-rt/lib/fuzzer/FuzzerUtilLinux.cpp +++ b/compiler-rt/lib/fuzzer/FuzzerUtilLinux.cpp @@ -44,7 +44,7 @@ void SetThreadName(std::thread &thread, const std::string &name) { #if LIBFUZZER_LINUX || LIBFUZZER_FREEBSD (void)pthread_setname_np(thread.native_handle(), name.c_str()); #elif LIBFUZZER_NETBSD - (void)pthread_set_name_np(thread.native_handle(), "%s", name.c_str()); + (void)pthread_setname_np(thread.native_handle(), "%s", const_cast(name.c_str())); #endif } diff --git a/compiler-rt/lib/fuzzer/tests/CMakeLists.txt b/compiler-rt/lib/fuzzer/tests/CMakeLists.txt index dd82c492e83a4567eb2936ac85f43e1de3c0cfd9..8f5707c687ac50329c7a18fd1b50fe32e645b617 100644 --- a/compiler-rt/lib/fuzzer/tests/CMakeLists.txt +++ b/compiler-rt/lib/fuzzer/tests/CMakeLists.txt @@ -74,7 +74,7 @@ if(COMPILER_RT_DEFAULT_TARGET_ARCH IN_LIST FUZZER_SUPPORTED_ARCH) FuzzerUnitTests "Fuzzer-${arch}-Test" ${arch} SOURCES FuzzerUnittest.cpp ${COMPILER_RT_GTEST_SOURCE} RUNTIME ${LIBFUZZER_TEST_RUNTIME} - DEPS llvm_gtest ${LIBFUZZER_TEST_RUNTIME_DEPS} + DEPS ${LIBFUZZER_TEST_RUNTIME_DEPS} CFLAGS ${LIBFUZZER_UNITTEST_CFLAGS} ${LIBFUZZER_TEST_RUNTIME_CFLAGS} LINK_FLAGS ${LIBFUZZER_UNITTEST_LINK_FLAGS} ${LIBFUZZER_TEST_RUNTIME_LINK_FLAGS}) set_target_properties(FuzzerUnitTests PROPERTIES @@ -84,7 +84,7 @@ if(COMPILER_RT_DEFAULT_TARGET_ARCH IN_LIST FUZZER_SUPPORTED_ARCH) generate_compiler_rt_tests(FuzzedDataProviderTestObjects FuzzedDataProviderUnitTests "FuzzerUtils-${arch}-Test" ${arch} SOURCES FuzzedDataProviderUnittest.cpp ${COMPILER_RT_GTEST_SOURCE} - DEPS llvm_gtest ${LIBFUZZER_TEST_RUNTIME_DEPS} ${COMPILER_RT_SOURCE_DIR}/include/fuzzer/FuzzedDataProvider.h + DEPS ${LIBFUZZER_TEST_RUNTIME_DEPS} ${COMPILER_RT_SOURCE_DIR}/include/fuzzer/FuzzedDataProvider.h CFLAGS ${LIBFUZZER_UNITTEST_CFLAGS} ${LIBFUZZER_TEST_RUNTIME_CFLAGS} LINK_FLAGS ${LIBFUZZER_UNITTEST_LINK_FLAGS} ${LIBFUZZER_TEST_RUNTIME_LINK_FLAGS}) set_target_properties(FuzzedDataProviderUnitTests PROPERTIES diff --git a/compiler-rt/lib/gwp_asan/tests/CMakeLists.txt b/compiler-rt/lib/gwp_asan/tests/CMakeLists.txt index 4915c83d49ca9e31416d3f7d2e5f3d5e089aee0c..2ec332ea74c1370daefe75e9b1cc9b846dd3b42a 100644 --- a/compiler-rt/lib/gwp_asan/tests/CMakeLists.txt +++ b/compiler-rt/lib/gwp_asan/tests/CMakeLists.txt @@ -74,7 +74,7 @@ if(COMPILER_RT_DEFAULT_TARGET_ARCH IN_LIST GWP_ASAN_SUPPORTED_ARCH) GwpAsanUnitTests "GwpAsan-${arch}-Test" ${arch} SOURCES ${GWP_ASAN_UNITTESTS} ${COMPILER_RT_GTEST_SOURCE} RUNTIME ${GWP_ASAN_TEST_RUNTIME} - DEPS llvm_gtest ${GWP_ASAN_UNIT_TEST_HEADERS} + DEPS ${GWP_ASAN_UNIT_TEST_HEADERS} CFLAGS ${GWP_ASAN_UNITTEST_CFLAGS} LINK_FLAGS ${GWP_ASAN_UNITTEST_LINK_FLAGS}) set_target_properties(GwpAsanUnitTests PROPERTIES diff --git a/compiler-rt/lib/hwasan/hwasan_checks.h b/compiler-rt/lib/hwasan/hwasan_checks.h index 0911af30dcb8fc4fba11b383fe689521d7cd2dbe..735d21a5db774687ce81058b4beddaf0cdaf5e11 100644 --- a/compiler-rt/lib/hwasan/hwasan_checks.h +++ b/compiler-rt/lib/hwasan/hwasan_checks.h @@ -140,7 +140,6 @@ __attribute__((always_inline, nodebug)) static inline uptr ShortTagSize( __attribute__((always_inline, nodebug)) static inline bool PossiblyShortTagMatches(tag_t mem_tag, uptr ptr, uptr sz) { - DCHECK(IsAligned(ptr, kShadowAlignment)); tag_t ptr_tag = GetTagFromPointer(ptr); if (ptr_tag == mem_tag) return true; diff --git a/compiler-rt/lib/hwasan/hwasan_interceptors.cpp b/compiler-rt/lib/hwasan/hwasan_interceptors.cpp index 96df4dd0c24d7d3db28fa2557cf63da0f295e33f..d519ac3a459b67b1b7e2900eacd5a6bc1329e042 100644 --- a/compiler-rt/lib/hwasan/hwasan_interceptors.cpp +++ b/compiler-rt/lib/hwasan/hwasan_interceptors.cpp @@ -520,6 +520,7 @@ void InitializeInterceptors() { CHECK_EQ(inited, 0); # if HWASAN_WITH_INTERCEPTORS + __interception::DoesNotSupportStaticLinking(); InitializeCommonInterceptors(); (void)(read_iovec); diff --git a/compiler-rt/lib/interception/interception.h b/compiler-rt/lib/interception/interception.h index 00bcd979638b537bdafb63140d0c9f1c8713a329..38c152952e323269af485ee386d621288d93f145 100644 --- a/compiler-rt/lib/interception/interception.h +++ b/compiler-rt/lib/interception/interception.h @@ -204,11 +204,11 @@ const interpose_substitution substitution_##func_name[] \ ".type " SANITIZER_STRINGIFY(TRAMPOLINE(func)) ", " \ ASM_TYPE_FUNCTION_STR "\n" \ SANITIZER_STRINGIFY(TRAMPOLINE(func)) ":\n" \ - SANITIZER_STRINGIFY(CFI_STARTPROC) "\n" \ + C_ASM_STARTPROC "\n" \ C_ASM_TAIL_CALL(SANITIZER_STRINGIFY(TRAMPOLINE(func)), \ "__interceptor_" \ SANITIZER_STRINGIFY(ASM_PREEMPTIBLE_SYM(func))) "\n" \ - SANITIZER_STRINGIFY(CFI_ENDPROC) "\n" \ + C_ASM_ENDPROC "\n" \ ".size " SANITIZER_STRINGIFY(TRAMPOLINE(func)) ", " \ ".-" SANITIZER_STRINGIFY(TRAMPOLINE(func)) "\n" \ ); diff --git a/compiler-rt/lib/interception/tests/CMakeLists.txt b/compiler-rt/lib/interception/tests/CMakeLists.txt index 644a57664cc490dc7757907470a5380248ae5e05..0a235c662af3b055e56fbc0b680d5be17a603fd5 100644 --- a/compiler-rt/lib/interception/tests/CMakeLists.txt +++ b/compiler-rt/lib/interception/tests/CMakeLists.txt @@ -107,7 +107,6 @@ macro(add_interception_tests_for_arch arch) RUNTIME ${INTERCEPTION_COMMON_LIB} SOURCES ${INTERCEPTION_UNITTESTS} ${COMPILER_RT_GTEST_SOURCE} COMPILE_DEPS ${INTERCEPTION_TEST_HEADERS} - DEPS llvm_gtest CFLAGS ${INTERCEPTION_TEST_CFLAGS_COMMON} LINK_FLAGS ${INTERCEPTION_TEST_LINK_FLAGS_COMMON}) endmacro() diff --git a/compiler-rt/lib/lsan/lsan_interceptors.cpp b/compiler-rt/lib/lsan/lsan_interceptors.cpp index 885f7ad5ddba96178fdf3d55df40922dab072cc5..1fd0010f9ea936002b034e5344f3704fd51a8e15 100644 --- a/compiler-rt/lib/lsan/lsan_interceptors.cpp +++ b/compiler-rt/lib/lsan/lsan_interceptors.cpp @@ -543,6 +543,7 @@ namespace __lsan { void InitializeInterceptors() { // Fuchsia doesn't use interceptors that require any setup. #if !SANITIZER_FUCHSIA + __interception::DoesNotSupportStaticLinking(); InitializeSignalInterceptors(); INTERCEPT_FUNCTION(malloc); diff --git a/compiler-rt/lib/msan/msan.cpp b/compiler-rt/lib/msan/msan.cpp index 3cdf10c149902c276282ff684fb1e864290dd3bd..a2fc27de1901b42ef596f084bb58a1239341d339 100644 --- a/compiler-rt/lib/msan/msan.cpp +++ b/compiler-rt/lib/msan/msan.cpp @@ -467,7 +467,7 @@ void __msan_init() { __msan_clear_on_return(); if (__msan_get_track_origins()) VPrintf(1, "msan_track_origins\n"); - if (!InitShadow(__msan_get_track_origins())) { + if (!InitShadowWithReExec(__msan_get_track_origins())) { Printf("FATAL: MemorySanitizer can not mmap the shadow memory.\n"); Printf("FATAL: Make sure to compile with -fPIE and to link with -pie.\n"); Printf("FATAL: Disabling ASLR is known to cause this error.\n"); diff --git a/compiler-rt/lib/msan/msan.h b/compiler-rt/lib/msan/msan.h index 710447a3e1a35709a6bb325836c78d8a7c6429e3..7fb58be67a02cdaed5173f196506e04fcb3669d6 100644 --- a/compiler-rt/lib/msan/msan.h +++ b/compiler-rt/lib/msan/msan.h @@ -33,12 +33,18 @@ struct MappingDesc { uptr start; uptr end; enum Type { - INVALID, APP, SHADOW, ORIGIN + INVALID = 1, + ALLOCATOR = 2, + APP = 4, + SHADOW = 8, + ORIGIN = 16, } type; const char *name; }; - +// Note: MappingDesc::ALLOCATOR entries are only used to check for memory +// layout compatibility. The actual allocation settings are in +// msan_allocator.cpp, which need to be kept in sync. #if SANITIZER_LINUX && defined(__mips64) // MIPS64 maps: @@ -84,7 +90,8 @@ const MappingDesc kMemoryLayout[] = { {0X0B00000000000, 0X0C00000000000, MappingDesc::SHADOW, "shadow-10-13"}, {0X0C00000000000, 0X0D00000000000, MappingDesc::INVALID, "invalid"}, {0X0D00000000000, 0X0E00000000000, MappingDesc::ORIGIN, "origin-10-13"}, - {0X0E00000000000, 0X1000000000000, MappingDesc::APP, "app-15"}, + {0x0E00000000000, 0x0E40000000000, MappingDesc::ALLOCATOR, "allocator"}, + {0X0E40000000000, 0X1000000000000, MappingDesc::APP, "app-15"}, }; # define MEM_TO_SHADOW(mem) ((uptr)mem ^ 0xB00000000000ULL) # define SHADOW_TO_ORIGIN(shadow) (((uptr)(shadow)) + 0x200000000000ULL) @@ -106,7 +113,8 @@ const MappingDesc kMemoryLayout[] = { {0x510000000000ULL, 0x600000000000ULL, MappingDesc::APP, "app-2"}, {0x600000000000ULL, 0x610000000000ULL, MappingDesc::ORIGIN, "origin-1"}, {0x610000000000ULL, 0x700000000000ULL, MappingDesc::INVALID, "invalid"}, - {0x700000000000ULL, 0x800000000000ULL, MappingDesc::APP, "app-3"}}; + {0x700000000000ULL, 0x740000000000ULL, MappingDesc::ALLOCATOR, "allocator"}, + {0x740000000000ULL, 0x800000000000ULL, MappingDesc::APP, "app-3"}}; # define MEM_TO_SHADOW(mem) (((uptr)(mem)) ^ 0x500000000000ULL) # define SHADOW_TO_ORIGIN(shadow) (((uptr)(shadow)) + 0x100000000000ULL) @@ -118,7 +126,8 @@ const MappingDesc kMemoryLayout[] = { {0x180200000000ULL, 0x1C0000000000ULL, MappingDesc::INVALID, "invalid"}, {0x1C0000000000ULL, 0x2C0200000000ULL, MappingDesc::ORIGIN, "origin"}, {0x2C0200000000ULL, 0x300000000000ULL, MappingDesc::INVALID, "invalid"}, - {0x300000000000ULL, 0x800000000000ULL, MappingDesc::APP, "high memory"}}; + {0x300000000000ULL, 0x320000000000ULL, MappingDesc::ALLOCATOR, "allocator"}, + {0x320000000000ULL, 0x800000000000ULL, MappingDesc::APP, "high memory"}}; // Various kernels use different low end ranges but we can combine them into one // big range. They also use different high end ranges but we can map them all to @@ -141,7 +150,8 @@ const MappingDesc kMemoryLayout[] = { {0x180000000000ULL, 0x1C0000000000ULL, MappingDesc::INVALID, "invalid"}, {0x1C0000000000ULL, 0x2C0000000000ULL, MappingDesc::ORIGIN, "origin"}, {0x2C0000000000ULL, 0x440000000000ULL, MappingDesc::INVALID, "invalid"}, - {0x440000000000ULL, 0x500000000000ULL, MappingDesc::APP, "high memory"}}; + {0x440000000000ULL, 0x460000000000ULL, MappingDesc::ALLOCATOR, "allocator"}, + {0x460000000000ULL, 0x500000000000ULL, MappingDesc::APP, "high memory"}}; #define MEM_TO_SHADOW(mem) \ ((((uptr)(mem)) & ~0xC00000000000ULL) + 0x080000000000ULL) @@ -208,7 +218,8 @@ const MappingDesc kMemoryLayout[] = { {0x510000000000ULL, 0x600000000000ULL, MappingDesc::APP, "app-2"}, {0x600000000000ULL, 0x610000000000ULL, MappingDesc::ORIGIN, "origin-1"}, {0x610000000000ULL, 0x700000000000ULL, MappingDesc::INVALID, "invalid"}, - {0x700000000000ULL, 0x800000000000ULL, MappingDesc::APP, "app-3"}}; + {0x700000000000ULL, 0x740000000000ULL, MappingDesc::ALLOCATOR, "allocator"}, + {0x740000000000ULL, 0x800000000000ULL, MappingDesc::APP, "app-3"}}; #define MEM_TO_SHADOW(mem) (((uptr)(mem)) ^ 0x500000000000ULL) #define SHADOW_TO_ORIGIN(mem) (((uptr)(mem)) + 0x100000000000ULL) @@ -223,20 +234,22 @@ const uptr kMemoryLayoutSize = sizeof(kMemoryLayout) / sizeof(kMemoryLayout[0]); #ifndef __clang__ __attribute__((optimize("unroll-loops"))) #endif -inline bool addr_is_type(uptr addr, MappingDesc::Type mapping_type) { +inline bool +addr_is_type(uptr addr, int mapping_types) { // It is critical for performance that this loop is unrolled (because then it is // simplified into just a few constant comparisons). #ifdef __clang__ #pragma unroll #endif for (unsigned i = 0; i < kMemoryLayoutSize; ++i) - if (kMemoryLayout[i].type == mapping_type && + if ((kMemoryLayout[i].type & mapping_types) && addr >= kMemoryLayout[i].start && addr < kMemoryLayout[i].end) return true; return false; } -#define MEM_IS_APP(mem) addr_is_type((uptr)(mem), MappingDesc::APP) +#define MEM_IS_APP(mem) \ + (addr_is_type((uptr)(mem), MappingDesc::APP | MappingDesc::ALLOCATOR)) #define MEM_IS_SHADOW(mem) addr_is_type((uptr)(mem), MappingDesc::SHADOW) #define MEM_IS_ORIGIN(mem) addr_is_type((uptr)(mem), MappingDesc::ORIGIN) @@ -250,7 +263,7 @@ extern bool msan_init_is_running; extern int msan_report_count; bool ProtectRange(uptr beg, uptr end); -bool InitShadow(bool init_origins); +bool InitShadowWithReExec(bool init_origins); char *GetProcSelfMaps(); void InitializeInterceptors(); diff --git a/compiler-rt/lib/msan/msan_allocator.cpp b/compiler-rt/lib/msan/msan_allocator.cpp index 0b2dd2b2f1883d7f235b66645267cc39134fd4b7..b1bc5b9390f75b5a70e2ac34e6ad7988552f9b5d 100644 --- a/compiler-rt/lib/msan/msan_allocator.cpp +++ b/compiler-rt/lib/msan/msan_allocator.cpp @@ -48,6 +48,9 @@ struct MsanMapUnmapCallback { } }; +// Note: to ensure that the allocator is compatible with the application memory +// layout (especially with high-entropy ASLR), kSpaceBeg and kSpaceSize must be +// duplicated as MappingDesc::ALLOCATOR in msan.h. #if defined(__mips64) static const uptr kMaxAllowedMallocSize = 2UL << 30; diff --git a/compiler-rt/lib/msan/msan_interceptors.cpp b/compiler-rt/lib/msan/msan_interceptors.cpp index 2c9f2c01e14b061be12e4effabfeb266d91bc875..6e0b2bf2ef5b6fb62a4aa9a44785329a3a72a09e 100644 --- a/compiler-rt/lib/msan/msan_interceptors.cpp +++ b/compiler-rt/lib/msan/msan_interceptors.cpp @@ -1762,6 +1762,8 @@ void InitializeInterceptors() { static int inited = 0; CHECK_EQ(inited, 0); + __interception::DoesNotSupportStaticLinking(); + new(interceptor_ctx()) InterceptorContext(); InitializeCommonInterceptors(); diff --git a/compiler-rt/lib/msan/msan_linux.cpp b/compiler-rt/lib/msan/msan_linux.cpp index c7ecb7cad56661901df0d9a30ba3bbf49b0cba3b..cd2d9f5c720c57523e6f013bb64bab841abfcabd 100644 --- a/compiler-rt/lib/msan/msan_linux.cpp +++ b/compiler-rt/lib/msan/msan_linux.cpp @@ -20,6 +20,9 @@ # include # include # include +# if SANITIZER_LINUX +# include +# endif # include # include # include @@ -43,11 +46,13 @@ void ReportMapRange(const char *descr, uptr beg, uptr size) { } } -static bool CheckMemoryRangeAvailability(uptr beg, uptr size) { +static bool CheckMemoryRangeAvailability(uptr beg, uptr size, bool verbose) { if (size > 0) { uptr end = beg + size - 1; if (!MemoryRangeIsAvailable(beg, end)) { - Printf("FATAL: Memory range 0x%zx - 0x%zx is not available.\n", beg, end); + if (verbose) + Printf("FATAL: Memory range 0x%zx - 0x%zx is not available.\n", beg, + end); return false; } } @@ -86,7 +91,7 @@ static void CheckMemoryLayoutSanity() { CHECK(addr_is_type(start, type)); CHECK(addr_is_type((start + end) / 2, type)); CHECK(addr_is_type(end - 1, type)); - if (type == MappingDesc::APP) { + if (type == MappingDesc::APP || type == MappingDesc::ALLOCATOR) { uptr addr = start; CHECK(MEM_IS_SHADOW(MEM_TO_SHADOW(addr))); CHECK(MEM_IS_ORIGIN(MEM_TO_ORIGIN(addr))); @@ -106,7 +111,7 @@ static void CheckMemoryLayoutSanity() { } } -bool InitShadow(bool init_origins) { +static bool InitShadow(bool init_origins, bool dry_run) { // Let user know mapping parameters first. VPrintf(1, "__msan_init %p\n", reinterpret_cast(&__msan_init)); for (unsigned i = 0; i < kMemoryLayoutSize; ++i) @@ -116,8 +121,9 @@ bool InitShadow(bool init_origins) { CheckMemoryLayoutSanity(); if (!MEM_IS_APP(&__msan_init)) { - Printf("FATAL: Code %p is out of application range. Non-PIE build?\n", - reinterpret_cast(&__msan_init)); + if (!dry_run) + Printf("FATAL: Code %p is out of application range. Non-PIE build?\n", + reinterpret_cast(&__msan_init)); return false; } @@ -138,20 +144,26 @@ bool InitShadow(bool init_origins) { bool protect = type == MappingDesc::INVALID || (!init_origins && type == MappingDesc::ORIGIN); CHECK(!(map && protect)); - if (!map && !protect) - CHECK(type == MappingDesc::APP); + if (!map && !protect) { + CHECK(type == MappingDesc::APP || type == MappingDesc::ALLOCATOR); + + if (dry_run && type == MappingDesc::ALLOCATOR && + !CheckMemoryRangeAvailability(start, size, !dry_run)) + return false; + } if (map) { - if (!CheckMemoryRangeAvailability(start, size)) + if (dry_run && !CheckMemoryRangeAvailability(start, size, !dry_run)) return false; - if (!MmapFixedSuperNoReserve(start, size, kMemoryLayout[i].name)) + if (!dry_run && + !MmapFixedSuperNoReserve(start, size, kMemoryLayout[i].name)) return false; - if (common_flags()->use_madv_dontdump) + if (!dry_run && common_flags()->use_madv_dontdump) DontDumpShadowMemory(start, size); } if (protect) { - if (!CheckMemoryRangeAvailability(start, size)) + if (dry_run && !CheckMemoryRangeAvailability(start, size, !dry_run)) return false; - if (!ProtectMemoryRange(start, size, kMemoryLayout[i].name)) + if (!dry_run && !ProtectMemoryRange(start, size, kMemoryLayout[i].name)) return false; } } @@ -159,6 +171,35 @@ bool InitShadow(bool init_origins) { return true; } +bool InitShadowWithReExec(bool init_origins) { + // Start with dry run: check layout is ok, but don't print warnings because + // warning messages will cause tests to fail (even if we successfully re-exec + // after the warning). + bool success = InitShadow(__msan_get_track_origins(), true); + if (!success) { +# if SANITIZER_LINUX + // Perhaps ASLR entropy is too high. If ASLR is enabled, re-exec without it. + int old_personality = personality(0xffffffff); + bool aslr_on = + (old_personality != -1) && ((old_personality & ADDR_NO_RANDOMIZE) == 0); + + if (aslr_on) { + VReport(1, + "WARNING: MemorySanitizer: memory layout is incompatible, " + "possibly due to high-entropy ASLR.\n" + "Re-execing with fixed virtual address space.\n" + "N.B. reducing ASLR entropy is preferable.\n"); + CHECK_NE(personality(old_personality | ADDR_NO_RANDOMIZE), -1); + ReExec(); + } +# endif + } + + // The earlier dry run didn't actually map or protect anything. Run again in + // non-dry run mode. + return success && InitShadow(__msan_get_track_origins(), false); +} + static void MsanAtExit(void) { if (flags()->print_stats && (flags()->atexit || msan_report_count > 0)) ReportStats(); diff --git a/compiler-rt/lib/msan/tests/CMakeLists.txt b/compiler-rt/lib/msan/tests/CMakeLists.txt index 412a0f6b3de7f20d979bb26d4489b5343b2878a3..bc58c0b9fabf8febb18d25993c2fd28869aa36dc 100644 --- a/compiler-rt/lib/msan/tests/CMakeLists.txt +++ b/compiler-rt/lib/msan/tests/CMakeLists.txt @@ -70,7 +70,7 @@ macro(msan_compile obj_list source arch kind cflags) ${obj_list} ${source} ${arch} KIND ${kind} COMPILE_DEPS ${MSAN_UNITTEST_HEADERS} - DEPS llvm_gtest msan + DEPS msan CFLAGS -isystem ${CMAKE_CURRENT_BINARY_DIR}/../libcxx_msan_${arch}/include/c++/v1 ${MSAN_UNITTEST_INSTRUMENTED_CFLAGS} ${cflags} ) diff --git a/compiler-rt/lib/orc/tests/CMakeLists.txt b/compiler-rt/lib/orc/tests/CMakeLists.txt index 2f1cb7657c2818b1e6f3290c7caa5c6a53fba187..e8f4c95b8a65775e7bf409740a5988a1e54a2afa 100644 --- a/compiler-rt/lib/orc/tests/CMakeLists.txt +++ b/compiler-rt/lib/orc/tests/CMakeLists.txt @@ -73,7 +73,7 @@ macro(add_orc_unittest testname) SOURCES ${TEST_SOURCES} ${COMPILER_RT_GTEST_SOURCE} RUNTIME "${ORC_RUNTIME_LIBS}" COMPILE_DEPS ${TEST_HEADERS} ${ORC_HEADERS} - DEPS llvm_gtest ${ORC_DEPS} + DEPS ${ORC_DEPS} CFLAGS ${ORC_UNITTEST_CFLAGS} ${COMPILER_RT_GTEST_CFLAGS} LINK_FLAGS ${ORC_UNITTEST_LINK_FLAGS}) endif() diff --git a/compiler-rt/lib/profile/InstrProfilingPlatformWindows.c b/compiler-rt/lib/profile/InstrProfilingPlatformWindows.c index 9421f67b768e0d45fd0dfdf89078c2a28aa5f09c..741b01faada4e27a33c3ebf336fa3abb7d585492 100644 --- a/compiler-rt/lib/profile/InstrProfilingPlatformWindows.c +++ b/compiler-rt/lib/profile/InstrProfilingPlatformWindows.c @@ -93,7 +93,7 @@ ValueProfNode *__llvm_profile_end_vnodes(void) { return &VNodesEnd; } ValueProfNode *CurrentVNode = &VNodesStart + 1; ValueProfNode *EndVNode = &VNodesEnd; -/* lld-link provides __buildid symbol which ponits to the 16 bytes build id when +/* lld-link provides __buildid symbol which points to the 16 bytes build id when * using /build-id flag. https://lld.llvm.org/windows_support.html#lld-flags */ #define BUILD_ID_LEN 16 COMPILER_RT_WEAK uint8_t __buildid[BUILD_ID_LEN] = {0}; diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_asm.h b/compiler-rt/lib/sanitizer_common/sanitizer_asm.h index 3af66a4e44998822dc300e308c53f9582cbd4088..30e9d15184e5d55690576306ec8eadde93424d80 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_asm.h +++ b/compiler-rt/lib/sanitizer_common/sanitizer_asm.h @@ -42,6 +42,16 @@ # define CFI_RESTORE(reg) #endif +#if defined(__aarch64__) && defined(__ARM_FEATURE_BTI_DEFAULT) +# define ASM_STARTPROC CFI_STARTPROC; hint #34 +# define C_ASM_STARTPROC SANITIZER_STRINGIFY(CFI_STARTPROC) "\nhint #34" +#else +# define ASM_STARTPROC CFI_STARTPROC +# define C_ASM_STARTPROC SANITIZER_STRINGIFY(CFI_STARTPROC) +#endif +#define ASM_ENDPROC CFI_ENDPROC +#define C_ASM_ENDPROC SANITIZER_STRINGIFY(CFI_ENDPROC) + #if defined(__x86_64__) || defined(__i386__) || defined(__sparc__) # define ASM_TAIL_CALL jmp #elif defined(__arm__) || defined(__aarch64__) || defined(__mips__) || \ @@ -114,9 +124,9 @@ .globl __interceptor_trampoline_##name; \ ASM_TYPE_FUNCTION(__interceptor_trampoline_##name); \ __interceptor_trampoline_##name: \ - CFI_STARTPROC; \ + ASM_STARTPROC; \ ASM_TAIL_CALL ASM_PREEMPTIBLE_SYM(__interceptor_##name); \ - CFI_ENDPROC; \ + ASM_ENDPROC; \ ASM_SIZE(__interceptor_trampoline_##name) # define ASM_INTERCEPTOR_TRAMPOLINE_SUPPORT 1 # endif // Architecture supports interceptor trampoline diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_common.h b/compiler-rt/lib/sanitizer_common/sanitizer_common.h index 47697ef280aa0d767a8395814e2e7de8c2e2b8c1..c451fc962c52940da2e200ed6f9a15650ceb233e 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_common.h +++ b/compiler-rt/lib/sanitizer_common/sanitizer_common.h @@ -1098,7 +1098,7 @@ inline u32 GetNumberOfCPUsCached() { } // namespace __sanitizer -inline void *operator new(__sanitizer::operator_new_size_type size, +inline void *operator new(__sanitizer::usize size, __sanitizer::LowLevelAllocator &alloc) { return alloc.Allocate(size); } diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc b/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc index 3ecdb55cdbf72f5b9599c10453aa8e932904bc9d..a1be676730a78688d12a2383837eb2fad9b9ba9f 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc +++ b/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc @@ -974,7 +974,7 @@ INTERCEPTOR(SSIZE_T, read, int fd, void *ptr, SIZE_T count) { // FIXME: under ASan the call below may write to freed memory and corrupt // its metadata. See // https://github.com/google/sanitizers/issues/321. - SSIZE_T res = REAL(read)(fd, ptr, count); + SSIZE_T res = COMMON_INTERCEPTOR_BLOCK_REAL(read)(fd, ptr, count); if (res > 0) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ptr, res); if (res >= 0 && fd >= 0) COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd); return res; @@ -1009,7 +1009,7 @@ INTERCEPTOR(SSIZE_T, pread, int fd, void *ptr, SIZE_T count, OFF_T offset) { // FIXME: under ASan the call below may write to freed memory and corrupt // its metadata. See // https://github.com/google/sanitizers/issues/321. - SSIZE_T res = REAL(pread)(fd, ptr, count, offset); + SSIZE_T res = COMMON_INTERCEPTOR_BLOCK_REAL(pread)(fd, ptr, count, offset); if (res > 0) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ptr, res); if (res >= 0 && fd >= 0) COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd); return res; @@ -1027,7 +1027,7 @@ INTERCEPTOR(SSIZE_T, pread64, int fd, void *ptr, SIZE_T count, OFF64_T offset) { // FIXME: under ASan the call below may write to freed memory and corrupt // its metadata. See // https://github.com/google/sanitizers/issues/321. - SSIZE_T res = REAL(pread64)(fd, ptr, count, offset); + SSIZE_T res = COMMON_INTERCEPTOR_BLOCK_REAL(pread64)(fd, ptr, count, offset); if (res > 0) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ptr, res); if (res >= 0 && fd >= 0) COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd); return res; @@ -1043,7 +1043,7 @@ INTERCEPTOR_WITH_SUFFIX(SSIZE_T, readv, int fd, __sanitizer_iovec *iov, void *ctx; COMMON_INTERCEPTOR_ENTER(ctx, readv, fd, iov, iovcnt); COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd); - SSIZE_T res = REAL(readv)(fd, iov, iovcnt); + SSIZE_T res = COMMON_INTERCEPTOR_BLOCK_REAL(readv)(fd, iov, iovcnt); if (res > 0) write_iovec(ctx, iov, iovcnt, res); if (res >= 0 && fd >= 0) COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd); return res; @@ -1059,7 +1059,7 @@ INTERCEPTOR(SSIZE_T, preadv, int fd, __sanitizer_iovec *iov, int iovcnt, void *ctx; COMMON_INTERCEPTOR_ENTER(ctx, preadv, fd, iov, iovcnt, offset); COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd); - SSIZE_T res = REAL(preadv)(fd, iov, iovcnt, offset); + SSIZE_T res = COMMON_INTERCEPTOR_BLOCK_REAL(preadv)(fd, iov, iovcnt, offset); if (res > 0) write_iovec(ctx, iov, iovcnt, res); if (res >= 0 && fd >= 0) COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd); return res; @@ -1075,7 +1075,8 @@ INTERCEPTOR(SSIZE_T, preadv64, int fd, __sanitizer_iovec *iov, int iovcnt, void *ctx; COMMON_INTERCEPTOR_ENTER(ctx, preadv64, fd, iov, iovcnt, offset); COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd); - SSIZE_T res = REAL(preadv64)(fd, iov, iovcnt, offset); + SSIZE_T res = + COMMON_INTERCEPTOR_BLOCK_REAL(preadv64)(fd, iov, iovcnt, offset); if (res > 0) write_iovec(ctx, iov, iovcnt, res); if (res >= 0 && fd >= 0) COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd); return res; @@ -1091,8 +1092,9 @@ INTERCEPTOR(SSIZE_T, write, int fd, void *ptr, SIZE_T count) { COMMON_INTERCEPTOR_ENTER(ctx, write, fd, ptr, count); COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd); if (fd >= 0) COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd); - SSIZE_T res = REAL(write)(fd, ptr, count); - // FIXME: this check should be _before_ the call to REAL(write), not after + SSIZE_T res = COMMON_INTERCEPTOR_BLOCK_REAL(write)(fd, ptr, count); + // FIXME: this check should be _before_ the call to + // COMMON_INTERCEPTOR_BLOCK_REAL(write), not after if (res > 0) COMMON_INTERCEPTOR_READ_RANGE(ctx, ptr, res); return res; } @@ -1121,7 +1123,7 @@ INTERCEPTOR(SSIZE_T, pwrite, int fd, void *ptr, SIZE_T count, OFF_T offset) { COMMON_INTERCEPTOR_ENTER(ctx, pwrite, fd, ptr, count, offset); COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd); if (fd >= 0) COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd); - SSIZE_T res = REAL(pwrite)(fd, ptr, count, offset); + SSIZE_T res = COMMON_INTERCEPTOR_BLOCK_REAL(pwrite)(fd, ptr, count, offset); if (res > 0) COMMON_INTERCEPTOR_READ_RANGE(ctx, ptr, res); return res; } @@ -1137,7 +1139,7 @@ INTERCEPTOR(SSIZE_T, pwrite64, int fd, void *ptr, OFF64_T count, COMMON_INTERCEPTOR_ENTER(ctx, pwrite64, fd, ptr, count, offset); COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd); if (fd >= 0) COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd); - SSIZE_T res = REAL(pwrite64)(fd, ptr, count, offset); + SSIZE_T res = COMMON_INTERCEPTOR_BLOCK_REAL(pwrite64)(fd, ptr, count, offset); if (res > 0) COMMON_INTERCEPTOR_READ_RANGE(ctx, ptr, res); return res; } @@ -1153,7 +1155,7 @@ INTERCEPTOR_WITH_SUFFIX(SSIZE_T, writev, int fd, __sanitizer_iovec *iov, COMMON_INTERCEPTOR_ENTER(ctx, writev, fd, iov, iovcnt); COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd); if (fd >= 0) COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd); - SSIZE_T res = REAL(writev)(fd, iov, iovcnt); + SSIZE_T res = COMMON_INTERCEPTOR_BLOCK_REAL(writev)(fd, iov, iovcnt); if (res > 0) read_iovec(ctx, iov, iovcnt, res); return res; } @@ -1169,7 +1171,7 @@ INTERCEPTOR(SSIZE_T, pwritev, int fd, __sanitizer_iovec *iov, int iovcnt, COMMON_INTERCEPTOR_ENTER(ctx, pwritev, fd, iov, iovcnt, offset); COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd); if (fd >= 0) COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd); - SSIZE_T res = REAL(pwritev)(fd, iov, iovcnt, offset); + SSIZE_T res = COMMON_INTERCEPTOR_BLOCK_REAL(pwritev)(fd, iov, iovcnt, offset); if (res > 0) read_iovec(ctx, iov, iovcnt, res); return res; } @@ -1185,7 +1187,8 @@ INTERCEPTOR(SSIZE_T, pwritev64, int fd, __sanitizer_iovec *iov, int iovcnt, COMMON_INTERCEPTOR_ENTER(ctx, pwritev64, fd, iov, iovcnt, offset); COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd); if (fd >= 0) COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd); - SSIZE_T res = REAL(pwritev64)(fd, iov, iovcnt, offset); + SSIZE_T res = + COMMON_INTERCEPTOR_BLOCK_REAL(pwritev64)(fd, iov, iovcnt, offset); if (res > 0) read_iovec(ctx, iov, iovcnt, res); return res; } @@ -2549,7 +2552,7 @@ INTERCEPTOR_WITH_SUFFIX(int, wait, int *status) { // FIXME: under ASan the call below may write to freed memory and corrupt // its metadata. See // https://github.com/google/sanitizers/issues/321. - int res = REAL(wait)(status); + int res = COMMON_INTERCEPTOR_BLOCK_REAL(wait)(status); if (res != -1 && status) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, status, sizeof(*status)); return res; @@ -2567,7 +2570,7 @@ INTERCEPTOR_WITH_SUFFIX(int, waitid, int idtype, int id, void *infop, // FIXME: under ASan the call below may write to freed memory and corrupt // its metadata. See // https://github.com/google/sanitizers/issues/321. - int res = REAL(waitid)(idtype, id, infop, options); + int res = COMMON_INTERCEPTOR_BLOCK_REAL(waitid)(idtype, id, infop, options); if (res != -1 && infop) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, infop, siginfo_t_sz); return res; @@ -2578,7 +2581,7 @@ INTERCEPTOR_WITH_SUFFIX(int, waitpid, int pid, int *status, int options) { // FIXME: under ASan the call below may write to freed memory and corrupt // its metadata. See // https://github.com/google/sanitizers/issues/321. - int res = REAL(waitpid)(pid, status, options); + int res = COMMON_INTERCEPTOR_BLOCK_REAL(waitpid)(pid, status, options); if (res != -1 && status) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, status, sizeof(*status)); return res; @@ -2589,7 +2592,7 @@ INTERCEPTOR(int, wait3, int *status, int options, void *rusage) { // FIXME: under ASan the call below may write to freed memory and corrupt // its metadata. See // https://github.com/google/sanitizers/issues/321. - int res = REAL(wait3)(status, options, rusage); + int res = COMMON_INTERCEPTOR_BLOCK_REAL(wait3)(status, options, rusage); if (res != -1) { if (status) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, status, sizeof(*status)); if (rusage) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, rusage, struct_rusage_sz); @@ -2603,7 +2606,8 @@ INTERCEPTOR(int, __wait4, int pid, int *status, int options, void *rusage) { // FIXME: under ASan the call below may write to freed memory and corrupt // its metadata. See // https://github.com/google/sanitizers/issues/321. - int res = REAL(__wait4)(pid, status, options, rusage); + int res = + COMMON_INTERCEPTOR_BLOCK_REAL(__wait4)(pid, status, options, rusage); if (res != -1) { if (status) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, status, sizeof(*status)); if (rusage) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, rusage, struct_rusage_sz); @@ -2618,7 +2622,7 @@ INTERCEPTOR(int, wait4, int pid, int *status, int options, void *rusage) { // FIXME: under ASan the call below may write to freed memory and corrupt // its metadata. See // https://github.com/google/sanitizers/issues/321. - int res = REAL(wait4)(pid, status, options, rusage); + int res = COMMON_INTERCEPTOR_BLOCK_REAL(wait4)(pid, status, options, rusage); if (res != -1) { if (status) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, status, sizeof(*status)); if (rusage) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, rusage, struct_rusage_sz); @@ -2996,7 +3000,7 @@ INTERCEPTOR(int, accept, int fd, void *addr, unsigned *addrlen) { COMMON_INTERCEPTOR_READ_RANGE(ctx, addrlen, sizeof(*addrlen)); addrlen0 = *addrlen; } - int fd2 = REAL(accept)(fd, addr, addrlen); + int fd2 = COMMON_INTERCEPTOR_BLOCK_REAL(accept)(fd, addr, addrlen); if (fd2 >= 0) { if (fd >= 0) COMMON_INTERCEPTOR_FD_SOCKET_ACCEPT(ctx, fd, fd2); if (addr && addrlen) @@ -3021,7 +3025,7 @@ INTERCEPTOR(int, accept4, int fd, void *addr, unsigned *addrlen, int f) { // FIXME: under ASan the call below may write to freed memory and corrupt // its metadata. See // https://github.com/google/sanitizers/issues/321. - int fd2 = REAL(accept4)(fd, addr, addrlen, f); + int fd2 = COMMON_INTERCEPTOR_BLOCK_REAL(accept4)(fd, addr, addrlen, f); if (fd2 >= 0) { if (fd >= 0) COMMON_INTERCEPTOR_FD_SOCKET_ACCEPT(ctx, fd, fd2); if (addr && addrlen) @@ -3045,7 +3049,7 @@ INTERCEPTOR(int, paccept, int fd, void *addr, unsigned *addrlen, addrlen0 = *addrlen; } if (set) COMMON_INTERCEPTOR_READ_RANGE(ctx, set, sizeof(*set)); - int fd2 = REAL(paccept)(fd, addr, addrlen, set, f); + int fd2 = COMMON_INTERCEPTOR_BLOCK_REAL(paccept)(fd, addr, addrlen, set, f); if (fd2 >= 0) { if (fd >= 0) COMMON_INTERCEPTOR_FD_SOCKET_ACCEPT(ctx, fd, fd2); if (addr && addrlen) @@ -3126,7 +3130,7 @@ INTERCEPTOR(SSIZE_T, recvmsg, int fd, struct __sanitizer_msghdr *msg, // FIXME: under ASan the call below may write to freed memory and corrupt // its metadata. See // https://github.com/google/sanitizers/issues/321. - SSIZE_T res = REAL(recvmsg)(fd, msg, flags); + SSIZE_T res = COMMON_INTERCEPTOR_BLOCK_REAL(recvmsg)(fd, msg, flags); if (res >= 0) { if (fd >= 0) COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd); if (msg) { @@ -3147,7 +3151,8 @@ INTERCEPTOR(int, recvmmsg, int fd, struct __sanitizer_mmsghdr *msgvec, void *ctx; COMMON_INTERCEPTOR_ENTER(ctx, recvmmsg, fd, msgvec, vlen, flags, timeout); if (timeout) COMMON_INTERCEPTOR_READ_RANGE(ctx, timeout, struct_timespec_sz); - int res = REAL(recvmmsg)(fd, msgvec, vlen, flags, timeout); + int res = + COMMON_INTERCEPTOR_BLOCK_REAL(recvmmsg)(fd, msgvec, vlen, flags, timeout); if (res >= 0) { if (fd >= 0) COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd); for (int i = 0; i < res; ++i) { @@ -3225,7 +3230,7 @@ INTERCEPTOR(SSIZE_T, sendmsg, int fd, struct __sanitizer_msghdr *msg, COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd); COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd); } - SSIZE_T res = REAL(sendmsg)(fd, msg, flags); + SSIZE_T res = COMMON_INTERCEPTOR_BLOCK_REAL(sendmsg)(fd, msg, flags); if (common_flags()->intercept_send && res >= 0 && msg) read_msghdr(ctx, msg, res); return res; @@ -3244,7 +3249,7 @@ INTERCEPTOR(int, sendmmsg, int fd, struct __sanitizer_mmsghdr *msgvec, COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd); COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd); } - int res = REAL(sendmmsg)(fd, msgvec, vlen, flags); + int res = COMMON_INTERCEPTOR_BLOCK_REAL(sendmmsg)(fd, msgvec, vlen, flags); if (res >= 0 && msgvec) { for (int i = 0; i < res; ++i) { COMMON_INTERCEPTOR_WRITE_RANGE(ctx, &msgvec[i].msg_len, @@ -3267,7 +3272,7 @@ INTERCEPTOR(int, msgsnd, int msqid, const void *msgp, SIZE_T msgsz, COMMON_INTERCEPTOR_ENTER(ctx, msgsnd, msqid, msgp, msgsz, msgflg); if (msgp) COMMON_INTERCEPTOR_READ_RANGE(ctx, msgp, sizeof(long) + msgsz); - int res = REAL(msgsnd)(msqid, msgp, msgsz, msgflg); + int res = COMMON_INTERCEPTOR_BLOCK_REAL(msgsnd)(msqid, msgp, msgsz, msgflg); return res; } @@ -3275,7 +3280,8 @@ INTERCEPTOR(SSIZE_T, msgrcv, int msqid, void *msgp, SIZE_T msgsz, long msgtyp, int msgflg) { void *ctx; COMMON_INTERCEPTOR_ENTER(ctx, msgrcv, msqid, msgp, msgsz, msgtyp, msgflg); - SSIZE_T len = REAL(msgrcv)(msqid, msgp, msgsz, msgtyp, msgflg); + SSIZE_T len = + COMMON_INTERCEPTOR_BLOCK_REAL(msgrcv)(msqid, msgp, msgsz, msgtyp, msgflg); if (len != -1) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, msgp, sizeof(long) + len); return len; @@ -6119,7 +6125,7 @@ INTERCEPTOR(int, flopen, const char *path, int flags, ...) { if (path) { COMMON_INTERCEPTOR_READ_RANGE(ctx, path, internal_strlen(path) + 1); } - return REAL(flopen)(path, flags, mode); + return COMMON_INTERCEPTOR_BLOCK_REAL(flopen)(path, flags, mode); } INTERCEPTOR(int, flopenat, int dirfd, const char *path, int flags, ...) { @@ -6132,7 +6138,7 @@ INTERCEPTOR(int, flopenat, int dirfd, const char *path, int flags, ...) { if (path) { COMMON_INTERCEPTOR_READ_RANGE(ctx, path, internal_strlen(path) + 1); } - return REAL(flopenat)(dirfd, path, flags, mode); + return COMMON_INTERCEPTOR_BLOCK_REAL(flopenat)(dirfd, path, flags, mode); } #define INIT_FLOPEN \ @@ -6717,7 +6723,7 @@ INTERCEPTOR(SSIZE_T, recv, int fd, void *buf, SIZE_T len, int flags) { void *ctx; COMMON_INTERCEPTOR_ENTER(ctx, recv, fd, buf, len, flags); COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd); - SSIZE_T res = REAL(recv)(fd, buf, len, flags); + SSIZE_T res = COMMON_INTERCEPTOR_BLOCK_REAL(recv)(fd, buf, len, flags); if (res > 0) { COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, Min((SIZE_T)res, len)); } @@ -6734,7 +6740,8 @@ INTERCEPTOR(SSIZE_T, recvfrom, int fd, void *buf, SIZE_T len, int flags, SIZE_T srcaddr_sz; if (srcaddr) srcaddr_sz = *addrlen; (void)srcaddr_sz; // prevent "set but not used" warning - SSIZE_T res = REAL(recvfrom)(fd, buf, len, flags, srcaddr, addrlen); + SSIZE_T res = COMMON_INTERCEPTOR_BLOCK_REAL(recvfrom)(fd, buf, len, flags, + srcaddr, addrlen); if (res > 0) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, Min((SIZE_T)res, len)); if (res >= 0 && srcaddr) @@ -6757,7 +6764,7 @@ INTERCEPTOR(SSIZE_T, send, int fd, void *buf, SIZE_T len, int flags) { COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd); COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd); } - SSIZE_T res = REAL(send)(fd, buf, len, flags); + SSIZE_T res = COMMON_INTERCEPTOR_BLOCK_REAL(send)(fd, buf, len, flags); if (common_flags()->intercept_send && res > 0) COMMON_INTERCEPTOR_READ_RANGE(ctx, buf, Min((SIZE_T)res, len)); return res; @@ -6772,7 +6779,8 @@ INTERCEPTOR(SSIZE_T, sendto, int fd, void *buf, SIZE_T len, int flags, COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd); } // Can't check dstaddr as it may have uninitialized padding at the end. - SSIZE_T res = REAL(sendto)(fd, buf, len, flags, dstaddr, addrlen); + SSIZE_T res = COMMON_INTERCEPTOR_BLOCK_REAL(sendto)(fd, buf, len, flags, + dstaddr, addrlen); if (common_flags()->intercept_send && res > 0) COMMON_INTERCEPTOR_READ_RANGE(ctx, buf, Min((SIZE_T)res, len)); return res; @@ -6789,7 +6797,7 @@ INTERCEPTOR(int, eventfd_read, int fd, __sanitizer_eventfd_t *value) { void *ctx; COMMON_INTERCEPTOR_ENTER(ctx, eventfd_read, fd, value); COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd); - int res = REAL(eventfd_read)(fd, value); + int res = COMMON_INTERCEPTOR_BLOCK_REAL(eventfd_read)(fd, value); if (res == 0) { COMMON_INTERCEPTOR_WRITE_RANGE(ctx, value, sizeof(*value)); if (fd >= 0) COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd); @@ -6803,7 +6811,7 @@ INTERCEPTOR(int, eventfd_write, int fd, __sanitizer_eventfd_t value) { COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd); COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd); } - int res = REAL(eventfd_write)(fd, value); + int res = COMMON_INTERCEPTOR_BLOCK_REAL(eventfd_write)(fd, value); return res; } #define INIT_EVENTFD_READ_WRITE \ @@ -7426,7 +7434,8 @@ INTERCEPTOR(int, open_by_handle_at, int mount_fd, struct file_handle* handle, COMMON_INTERCEPTOR_READ_RANGE( ctx, &sanitizer_handle->f_handle, sanitizer_handle->handle_bytes); - return REAL(open_by_handle_at)(mount_fd, handle, flags); + return COMMON_INTERCEPTOR_BLOCK_REAL(open_by_handle_at)(mount_fd, handle, + flags); } #define INIT_OPEN_BY_HANDLE_AT COMMON_INTERCEPT_FUNCTION(open_by_handle_at) diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_internal_defs.h b/compiler-rt/lib/sanitizer_common/sanitizer_internal_defs.h index 992721757e88da456590b2c5087e55fc304869d3..294e330c4d56117732b8bee5d8d325554ae006d3 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_internal_defs.h +++ b/compiler-rt/lib/sanitizer_common/sanitizer_internal_defs.h @@ -191,15 +191,10 @@ typedef uptr OFF_T; #endif typedef u64 OFF64_T; -#if (SANITIZER_WORDSIZE == 64) || SANITIZER_APPLE -typedef uptr operator_new_size_type; +#ifdef __SIZE_TYPE__ +typedef __SIZE_TYPE__ usize; #else -# if defined(__s390__) && !defined(__s390x__) -// Special case: 31-bit s390 has unsigned long as size_t. -typedef unsigned long operator_new_size_type; -# else -typedef u32 operator_new_size_type; -# endif +typedef uptr usize; #endif typedef u64 tid_t; diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_mutex.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_mutex.cpp index 40fe56661250e5a94cef4425f265d494bb54a338..97085e895a34b213b88fd86d0a1d696963945e95 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_mutex.cpp +++ b/compiler-rt/lib/sanitizer_common/sanitizer_mutex.cpp @@ -212,8 +212,10 @@ struct InternalDeadlockDetector { return initialized > 0; } }; - -static THREADLOCAL InternalDeadlockDetector deadlock_detector; +// This variable is used by the __tls_get_addr interceptor, so cannot use the +// global-dynamic TLS model, as that would result in crashes. +__attribute__((tls_model("initial-exec"))) static THREADLOCAL + InternalDeadlockDetector deadlock_detector; void CheckedMutex::LockImpl(uptr pc) { deadlock_detector.Lock(type_, pc); } diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_placement_new.h b/compiler-rt/lib/sanitizer_common/sanitizer_placement_new.h index 1ceb8b909268f3ebfc85941822609f55cf41ed89..c9b917b453461abd6be642aa07bc3766ce740265 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_placement_new.h +++ b/compiler-rt/lib/sanitizer_common/sanitizer_placement_new.h @@ -17,8 +17,6 @@ #include "sanitizer_internal_defs.h" -inline void *operator new(__sanitizer::operator_new_size_type sz, void *p) { - return p; -} +inline void *operator new(__sanitizer::usize sz, void *p) { return p; } #endif // SANITIZER_PLACEMENT_NEW_H diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_posix_libcdep.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_posix_libcdep.cpp index ef1fc35497439602ed469e13b23224ed437d5a9f..ece2d7d63dd6197741a4afa39f08c873520d9e91 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_posix_libcdep.cpp +++ b/compiler-rt/lib/sanitizer_common/sanitizer_posix_libcdep.cpp @@ -104,7 +104,27 @@ static void setlim(int res, rlim_t lim) { void DisableCoreDumperIfNecessary() { if (common_flags()->disable_coredump) { - setlim(RLIMIT_CORE, 0); + rlimit rlim; + CHECK_EQ(0, getrlimit(RLIMIT_CORE, &rlim)); + // On Linux, if the kernel.core_pattern sysctl starts with a '|' (i.e. it + // is being piped to a coredump handler such as systemd-coredumpd), the + // kernel ignores RLIMIT_CORE (since we aren't creating a file in the file + // system) except for the magic value of 1, which disables coredumps when + // piping. 1 byte is too small for any kind of valid core dump, so it + // also disables coredumps if kernel.core_pattern creates files directly. + // While most piped coredump handlers do respect the crashing processes' + // RLIMIT_CORE, this is notable not the case for Debian's systemd-coredump + // due to a local patch that changes sysctl.d/50-coredump.conf to ignore + // the specified limit and instead use RLIM_INFINITY. + // + // The alternative to using RLIMIT_CORE=1 would be to use prctl() with the + // PR_SET_DUMPABLE flag, however that also prevents ptrace(), so makes it + // impossible to attach a debugger. + // + // Note: we use rlim_max in the Min() call here since that is the upper + // limit for what can be set without getting an EINVAL error. + rlim.rlim_cur = Min(SANITIZER_LINUX ? 1 : 0, rlim.rlim_max); + CHECK_EQ(0, setrlimit(RLIMIT_CORE, &rlim)); } } diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_procmaps_bsd.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_procmaps_bsd.cpp index 7c2d8e6f1731311a3c3b2ea9781180ecc0188414..7d7c009f644426775b7c5805d4a1ab6daf5e369c 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_procmaps_bsd.cpp +++ b/compiler-rt/lib/sanitizer_common/sanitizer_procmaps_bsd.cpp @@ -42,6 +42,19 @@ void GetMemoryProfile(fill_profile_f cb, uptr *stats) { cb(0, InfoProc->ki_rssize * GetPageSizeCached(), false, stats); UnmapOrDie(InfoProc, Size, true); } +#elif SANITIZER_NETBSD +void GetMemoryProfile(fill_profile_f cb, uptr *stats) { + struct kinfo_proc2 *InfoProc; + uptr Len = sizeof(*InfoProc); + uptr Size = Len; + const int Mib[] = {CTL_KERN, KERN_PROC2, KERN_PROC_PID, getpid(), Size, 1}; + InfoProc = (struct kinfo_proc2 *)MmapOrDie(Size, "GetMemoryProfile()"); + CHECK_EQ( + internal_sysctl(Mib, ARRAY_SIZE(Mib), nullptr, (uptr *)InfoProc, &Len, 0), + 0); + cb(0, InfoProc->p_vm_rssize * GetPageSizeCached(), false, stats); + UnmapOrDie(InfoProc, Size, true); +} #endif void ReadProcMaps(ProcSelfMapsBuff *proc_maps) { diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_procmaps_common.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_procmaps_common.cpp index a7805ad1b083b0b5bb75056a339332675d75eb94..7214a2b9ea4681aaf007b20c6bb6636e7f4e3a05 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_procmaps_common.cpp +++ b/compiler-rt/lib/sanitizer_common/sanitizer_procmaps_common.cpp @@ -145,7 +145,7 @@ void MemoryMappingLayout::DumpListOfModules( } } -#if SANITIZER_LINUX || SANITIZER_ANDROID || SANITIZER_SOLARIS || SANITIZER_NETBSD +#if SANITIZER_LINUX || SANITIZER_ANDROID || SANITIZER_SOLARIS void GetMemoryProfile(fill_profile_f cb, uptr *stats) { char *smaps = nullptr; uptr smaps_cap = 0; diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_symbolizer_report.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_symbolizer_report.cpp index f6b157c07c6557c3ad17d294adf3d57925acdd6b..ffbaf1468ec8ff1a896548bbf2ff381d7033aec1 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_symbolizer_report.cpp +++ b/compiler-rt/lib/sanitizer_common/sanitizer_symbolizer_report.cpp @@ -39,8 +39,12 @@ static bool FrameIsInternal(const SymbolizedStack *frame) { internal_strstr(file, "/include/c++/") || internal_strstr(file, "/include/g++"))) return true; + if (file && internal_strstr(file, "\\compiler-rt\\lib\\")) + return true; if (module && (internal_strstr(module, "libclang_rt."))) return true; + if (module && (internal_strstr(module, "clang_rt."))) + return true; return false; } diff --git a/compiler-rt/lib/sanitizer_common/tests/CMakeLists.txt b/compiler-rt/lib/sanitizer_common/tests/CMakeLists.txt index 3c709e411e48be2dc90dd1ad62278ac0ad5a52b7..a3efe68715082301de774cb9308cbd10de4cd1ce 100644 --- a/compiler-rt/lib/sanitizer_common/tests/CMakeLists.txt +++ b/compiler-rt/lib/sanitizer_common/tests/CMakeLists.txt @@ -176,7 +176,6 @@ macro(add_sanitizer_tests_for_arch arch) RUNTIME "${SANITIZER_COMMON_LIB}" SOURCES ${SANITIZER_UNITTESTS} ${COMPILER_RT_GTEST_SOURCE} ${COMPILER_RT_GMOCK_SOURCE} COMPILE_DEPS ${SANITIZER_TEST_HEADERS} - DEPS llvm_gtest CFLAGS ${SANITIZER_TEST_CFLAGS_COMMON} ${extra_flags} LINK_FLAGS ${SANITIZER_TEST_LINK_FLAGS_COMMON} ${TARGET_LINK_FLAGS} ${extra_flags}) diff --git a/compiler-rt/lib/scudo/standalone/CMakeLists.txt b/compiler-rt/lib/scudo/standalone/CMakeLists.txt index 60092005cc33bbf2abefd5cea1f6dfe361e920f8..6fb4e88de3155f6b4a063a03c6ae5da42d5a2f38 100644 --- a/compiler-rt/lib/scudo/standalone/CMakeLists.txt +++ b/compiler-rt/lib/scudo/standalone/CMakeLists.txt @@ -58,6 +58,7 @@ endif() set(SCUDO_HEADERS allocator_common.h allocator_config.h + allocator_config_wrapper.h atomic_helpers.h bytemap.h checksum.h diff --git a/compiler-rt/lib/scudo/standalone/allocator_config.def b/compiler-rt/lib/scudo/standalone/allocator_config.def new file mode 100644 index 0000000000000000000000000000000000000000..92f4e39872d4c9ea0bfea2b2a8ed5c3773e6b15f --- /dev/null +++ b/compiler-rt/lib/scudo/standalone/allocator_config.def @@ -0,0 +1,124 @@ +//===-- allocator_config.def ------------------------------------*- 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 +// +//===----------------------------------------------------------------------===// +// +// This file defines all the flags and types supported in Scudo. For optional +// flags and types, only explicitly define them when interested (i.e., unused +// optional flags or types can be skipped). + +#ifndef BASE_REQUIRED_TEMPLATE_TYPE +#define BASE_REQUIRED_TEMPLATE_TYPE(...) +#endif +#ifndef BASE_OPTIONAL +#define BASE_OPTIONAL(...) +#endif +#ifndef PRIMARY_REQUIRED_TYPE +#define PRIMARY_REQUIRED_TYPE(...) +#endif +#ifndef PRIMARY_REQUIRED +#define PRIMARY_REQUIRED(...) +#endif +#ifndef PRIMARY_OPTIONAL +#define PRIMARY_OPTIONAL(...) +#endif +#ifndef PRIMARY_OPTIONAL_TYPE +#define PRIMARY_OPTIONAL_TYPE(...) +#endif +#ifndef SECONDARY_REQUIRED_TEMPLATE_TYPE +#define SECONDARY_REQUIRED_TEMPLATE_TYPE(...) +#endif +#ifndef SECONDARY_CACHE_OPTIONAL +#define SECONDARY_CACHE_OPTIONAL(...) +#endif + +// BASE_REQUIRED_TEMPLATE_TYPE(NAME) +// +// Thread-Specific Data Registry used, shared or exclusive. +BASE_REQUIRED_TEMPLATE_TYPE(TSDRegistryT) + +// Defines the type of Primary allocator to use. +BASE_REQUIRED_TEMPLATE_TYPE(PrimaryT) + +// Defines the type of Secondary allocator to use. +BASE_REQUIRED_TEMPLATE_TYPE(SecondaryT) + +// BASE_OPTIONAL(TYPE, NAME, DEFAULT) +// +// Indicates possible support for Memory Tagging. +BASE_OPTIONAL(const bool, MaySupportMemoryTagging, false) + +// PRIMARY_REQUIRED_TYPE(NAME) +// +// SizeClassMap to use with the Primary. +PRIMARY_REQUIRED_TYPE(SizeClassMap) + +// Defines the type and scale of a compact pointer. A compact pointer can +// be understood as the offset of a pointer within the region it belongs +// to, in increments of a power-of-2 scale. See `CompactPtrScale` also. +PRIMARY_REQUIRED_TYPE(CompactPtrT) + +// PRIMARY_REQUIRED(TYPE, NAME) +// +// The scale of a compact pointer. E.g., Ptr = Base + (CompactPtr << Scale). +PRIMARY_REQUIRED(const uptr, CompactPtrScale) + +// Log2 of the size of a size class region, as used by the Primary. +PRIMARY_REQUIRED(const uptr, RegionSizeLog) + +// Conceptually, a region will be divided into groups based on the address +// range. Each allocation consumes blocks in the same group until exhaustion +// then it pops out blocks in a new group. Therefore, `GroupSizeLog` is always +// smaller or equal to `RegionSizeLog`. Note that `GroupSizeLog` needs to be +// equal to `RegionSizeLog` for SizeClassAllocator32 because of certain +// constraints. +PRIMARY_REQUIRED(const uptr, GroupSizeLog) + +// Call map for user memory with at least this size. Only used with primary64. +PRIMARY_REQUIRED(const uptr, MapSizeIncrement) + +// Defines the minimal & maximal release interval that can be set. +PRIMARY_REQUIRED(const s32, MinReleaseToOsIntervalMs) +PRIMARY_REQUIRED(const s32, MaxReleaseToOsIntervalMs) + +// PRIMARY_OPTIONAL(TYPE, NAME, DEFAULT) +// +// Indicates support for offsetting the start of a region by a random number of +// pages. Only used with primary64. +PRIMARY_OPTIONAL(const bool, EnableRandomOffset, false) + +// PRIMARY_OPTIONAL_TYPE(NAME, DEFAULT) +// +// Use condition variable to shorten the waiting time of refillment of +// freelist. Note that this depends on the implementation of condition +// variable on each platform and the performance may vary so that it does not +// guarantee a performance benefit. +PRIMARY_OPTIONAL_TYPE(ConditionVariableT, ConditionVariableDummy) + +// SECONDARY_REQUIRED_TEMPLATE_TYPE(NAME) +// +// Defines the type of Secondary Cache to use. +SECONDARY_REQUIRED_TEMPLATE_TYPE(CacheT) + +// SECONDARY_CACHE_OPTIONAL(TYPE, NAME, DEFAULT) +// +// Defines the type of cache used by the Secondary. Some additional +// configuration entries can be necessary depending on the Cache. +SECONDARY_CACHE_OPTIONAL(const u32, EntriesArraySize, 0) +SECONDARY_CACHE_OPTIONAL(const u32, QuarantineSize, 0) +SECONDARY_CACHE_OPTIONAL(const u32, DefaultMaxEntriesCount, 0) +SECONDARY_CACHE_OPTIONAL(const u32, DefaultMaxEntrySize, 0) +SECONDARY_CACHE_OPTIONAL(const s32, MinReleaseToOsIntervalMs, INT32_MIN) +SECONDARY_CACHE_OPTIONAL(const s32, MaxReleaseToOsIntervalMs, INT32_MAX) + +#undef SECONDARY_CACHE_OPTIONAL +#undef SECONDARY_REQUIRED_TEMPLATE_TYPE +#undef PRIMARY_OPTIONAL_TYPE +#undef PRIMARY_OPTIONAL +#undef PRIMARY_REQUIRED +#undef PRIMARY_REQUIRED_TYPE +#undef BASE_OPTIONAL +#undef BASE_REQUIRED_TEMPLATE_TYPE diff --git a/compiler-rt/lib/scudo/standalone/allocator_config.h b/compiler-rt/lib/scudo/standalone/allocator_config.h index 3c6aa3acb0e45b4487f59538636622285eadc094..1e0cf1015ba67e8d9a40be609b21efdccbe22949 100644 --- a/compiler-rt/lib/scudo/standalone/allocator_config.h +++ b/compiler-rt/lib/scudo/standalone/allocator_config.h @@ -38,80 +38,10 @@ namespace scudo { -// The combined allocator uses a structure as a template argument that -// specifies the configuration options for the various subcomponents of the -// allocator. -// -// struct ExampleConfig { -// // Indicates possible support for Memory Tagging. -// static const bool MaySupportMemoryTagging = false; -// -// // Thread-Specific Data Registry used, shared or exclusive. -// template using TSDRegistryT = TSDRegistrySharedT; -// -// struct Primary { -// // SizeClassMap to use with the Primary. -// using SizeClassMap = DefaultSizeClassMap; -// -// // Log2 of the size of a size class region, as used by the Primary. -// static const uptr RegionSizeLog = 30U; -// -// // Log2 of the size of block group, as used by the Primary. Each group -// // contains a range of memory addresses, blocks in the range will belong -// // to the same group. In general, single region may have 1 or 2MB group -// // size. Multiple regions will have the group size equal to the region -// // size because the region size is usually smaller than 1 MB. -// // Smaller value gives fine-grained control of memory usage but the -// // trade-off is that it may take longer time of deallocation. -// static const uptr GroupSizeLog = 20U; -// -// // Defines the type and scale of a compact pointer. A compact pointer can -// // be understood as the offset of a pointer within the region it belongs -// // to, in increments of a power-of-2 scale. -// // eg: Ptr = Base + (CompactPtr << Scale). -// typedef u32 CompactPtrT; -// static const uptr CompactPtrScale = SCUDO_MIN_ALIGNMENT_LOG; -// -// // Indicates support for offsetting the start of a region by -// // a random number of pages. Only used with primary64. -// static const bool EnableRandomOffset = true; -// -// // Call map for user memory with at least this size. Only used with -// // primary64. -// static const uptr MapSizeIncrement = 1UL << 18; -// -// // Defines the minimal & maximal release interval that can be set. -// static const s32 MinReleaseToOsIntervalMs = INT32_MIN; -// static const s32 MaxReleaseToOsIntervalMs = INT32_MAX; -// -// // Use condition variable to shorten the waiting time of refillment of -// // freelist. Note that this depends on the implementation of condition -// // variable on each platform and the performance may vary so that it -// // doesn't guarantee a performance benefit. -// // Note that both variables have to be defined to enable it. -// static const bool UseConditionVariable = true; -// using ConditionVariableT = ConditionVariableLinux; -// }; -// // Defines the type of Primary allocator to use. -// template using PrimaryT = SizeClassAllocator64; -// -// // Defines the type of cache used by the Secondary. Some additional -// // configuration entries can be necessary depending on the Cache. -// struct Secondary { -// struct Cache { -// static const u32 EntriesArraySize = 32U; -// static const u32 QuarantineSize = 0U; -// static const u32 DefaultMaxEntriesCount = 32U; -// static const uptr DefaultMaxEntrySize = 1UL << 19; -// static const s32 MinReleaseToOsIntervalMs = INT32_MIN; -// static const s32 MaxReleaseToOsIntervalMs = INT32_MAX; -// }; -// // Defines the type of Secondary Cache to use. -// template using CacheT = MapAllocatorCache; -// }; -// // Defines the type of Secondary allocator to use. -// template using SecondaryT = MapAllocator; -// }; +// Scudo uses a structure as a template argument that specifies the +// configuration options for the various subcomponents of the allocator. See the +// following configs as examples and check `allocator_config.def` for all the +// available options. #ifndef SCUDO_USE_CUSTOM_CONFIG diff --git a/compiler-rt/lib/scudo/standalone/allocator_config_wrapper.h b/compiler-rt/lib/scudo/standalone/allocator_config_wrapper.h new file mode 100644 index 0000000000000000000000000000000000000000..a51d770b466466984042bfde86c66d268880f9c9 --- /dev/null +++ b/compiler-rt/lib/scudo/standalone/allocator_config_wrapper.h @@ -0,0 +1,135 @@ +//===-- allocator_config_wrapper.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 +// +//===----------------------------------------------------------------------===// + +#ifndef SCUDO_ALLOCATOR_CONFIG_WRAPPER_H_ +#define SCUDO_ALLOCATOR_CONFIG_WRAPPER_H_ + +#include "condition_variable.h" +#include "internal_defs.h" +#include "secondary.h" + +namespace { + +template struct removeConst { + using type = T; +}; +template struct removeConst { + using type = T; +}; + +// This is only used for SFINAE when detecting if a type is defined. +template struct voidAdaptor { + using type = void; +}; + +} // namespace + +namespace scudo { + +#define OPTIONAL_TEMPLATE(TYPE, NAME, DEFAULT, MEMBER) \ + template struct NAME##State { \ + static constexpr removeConst::type getValue() { return DEFAULT; } \ + }; \ + template \ + struct NAME##State { \ + static constexpr removeConst::type getValue() { \ + return Config::MEMBER; \ + } \ + }; + +#define OPTIONAL_TYPE_TEMPLATE(NAME, DEFAULT, MEMBER) \ + template struct NAME##Type { \ + static constexpr bool enabled() { return false; } \ + using NAME = DEFAULT; \ + }; \ + template \ + struct NAME##Type::type> { \ + static constexpr bool enabled() { return true; } \ + using NAME = typename Config::MEMBER; \ + }; + +template struct BaseConfig { +#define BASE_REQUIRED_TEMPLATE_TYPE(NAME) \ + template using NAME = typename AllocatorConfig::template NAME; + +#define BASE_OPTIONAL(TYPE, NAME, DEFAULT) \ + OPTIONAL_TEMPLATE(TYPE, NAME, DEFAULT, NAME) \ + static constexpr removeConst::type get##NAME() { \ + return NAME##State::getValue(); \ + } + +#include "allocator_config.def" +}; // BaseConfig + +template struct PrimaryConfig { + // TODO: Pass this flag through template argument to remove this hard-coded + // function. + static constexpr bool getMaySupportMemoryTagging() { + return BaseConfig::getMaySupportMemoryTagging(); + } + +#define PRIMARY_REQUIRED_TYPE(NAME) \ + using NAME = typename AllocatorConfig::Primary::NAME; + +#define PRIMARY_REQUIRED(TYPE, NAME) \ + static constexpr removeConst::type get##NAME() { \ + return AllocatorConfig::Primary::NAME; \ + } + +#define PRIMARY_OPTIONAL(TYPE, NAME, DEFAULT) \ + OPTIONAL_TEMPLATE(TYPE, NAME, DEFAULT, NAME) \ + static constexpr removeConst::type get##NAME() { \ + return NAME##State::getValue(); \ + } + +#define PRIMARY_OPTIONAL_TYPE(NAME, DEFAULT) \ + OPTIONAL_TYPE_TEMPLATE(NAME, DEFAULT, NAME) \ + static constexpr bool has##NAME() { \ + return NAME##Type::enabled(); \ + } \ + using NAME = typename NAME##Type::NAME; + +#include "allocator_config.def" + +}; // PrimaryConfig + +template struct SecondaryConfig { + // TODO: Pass this flag through template argument to remove this hard-coded + // function. + static constexpr bool getMaySupportMemoryTagging() { + return BaseConfig::getMaySupportMemoryTagging(); + } + +#define SECONDARY_REQUIRED_TEMPLATE_TYPE(NAME) \ + template \ + using NAME = typename AllocatorConfig::Secondary::template NAME; +#include "allocator_config.def" + + struct CacheConfig { + // TODO: Pass this flag through template argument to remove this hard-coded + // function. + static constexpr bool getMaySupportMemoryTagging() { + return BaseConfig::getMaySupportMemoryTagging(); + } + +#define SECONDARY_CACHE_OPTIONAL(TYPE, NAME, DEFAULT) \ + OPTIONAL_TEMPLATE(TYPE, NAME, DEFAULT, Cache::NAME) \ + static constexpr removeConst::type get##NAME() { \ + return NAME##State::getValue(); \ + } +#include "allocator_config.def" + }; // CacheConfig +}; // SecondaryConfig + +#undef OPTIONAL_TEMPLATE +#undef OPTIONAL_TEMPLATE_TYPE + +} // namespace scudo + +#endif // SCUDO_ALLOCATOR_CONFIG_WRAPPER_H_ diff --git a/compiler-rt/lib/scudo/standalone/combined.h b/compiler-rt/lib/scudo/standalone/combined.h index 069b5f64475db580dcd4474f17aa4afaf27ddbd8..f4dd90aac6655526fea4b9bdc2bf68e37d0525bb 100644 --- a/compiler-rt/lib/scudo/standalone/combined.h +++ b/compiler-rt/lib/scudo/standalone/combined.h @@ -9,6 +9,7 @@ #ifndef SCUDO_COMBINED_H_ #define SCUDO_COMBINED_H_ +#include "allocator_config_wrapper.h" #include "atomic_helpers.h" #include "chunk.h" #include "common.h" @@ -47,11 +48,14 @@ namespace scudo { template class Allocator { public: - using PrimaryT = typename Config::template PrimaryT; - using SecondaryT = typename Config::template SecondaryT; + using AllocatorConfig = BaseConfig; + using PrimaryT = + typename AllocatorConfig::template PrimaryT>; + using SecondaryT = + typename AllocatorConfig::template SecondaryT>; using CacheT = typename PrimaryT::CacheT; typedef Allocator ThisT; - typedef typename Config::template TSDRegistryT TSDRegistryT; + typedef typename AllocatorConfig::template TSDRegistryT TSDRegistryT; void callPostInitCallback() { pthread_once(&PostInitNonce, PostInitCallback); @@ -72,7 +76,7 @@ public: Header.State = Chunk::State::Available; Chunk::storeHeader(Allocator.Cookie, Ptr, &Header); - if (allocatorSupportsMemoryTagging()) + if (allocatorSupportsMemoryTagging()) Ptr = untagPointer(Ptr); void *BlockBegin = Allocator::getBlockBegin(Ptr, &Header); Cache.deallocate(Header.ClassId, BlockBegin); @@ -99,7 +103,8 @@ public: // Reset tag to 0 as this chunk may have been previously used for a tagged // user allocation. - if (UNLIKELY(useMemoryTagging(Allocator.Primary.Options.load()))) + if (UNLIKELY(useMemoryTagging( + Allocator.Primary.Options.load()))) storeTags(reinterpret_cast(Ptr), reinterpret_cast(Ptr) + sizeof(QuarantineBatch)); @@ -159,7 +164,7 @@ public: Primary.Options.set(OptionBit::DeallocTypeMismatch); if (getFlags()->delete_size_mismatch) Primary.Options.set(OptionBit::DeleteSizeMismatch); - if (allocatorSupportsMemoryTagging() && + if (allocatorSupportsMemoryTagging() && systemSupportsMemoryTagging()) Primary.Options.set(OptionBit::UseMemoryTagging); @@ -274,7 +279,7 @@ public: void drainCaches() { TSDRegistry.drainCaches(this); } ALWAYS_INLINE void *getHeaderTaggedPointer(void *Ptr) { - if (!allocatorSupportsMemoryTagging()) + if (!allocatorSupportsMemoryTagging()) return Ptr; auto UntaggedPtr = untagPointer(Ptr); if (UntaggedPtr != Ptr) @@ -286,7 +291,7 @@ public: } ALWAYS_INLINE uptr addHeaderTag(uptr Ptr) { - if (!allocatorSupportsMemoryTagging()) + if (!allocatorSupportsMemoryTagging()) return Ptr; return addFixedTag(Ptr, 2); } @@ -419,7 +424,7 @@ public: // // When memory tagging is enabled, zeroing the contents is done as part of // setting the tag. - if (UNLIKELY(useMemoryTagging(Options))) { + if (UNLIKELY(useMemoryTagging(Options))) { uptr PrevUserPtr; Chunk::UnpackedHeader Header; const uptr BlockSize = PrimaryT::getSizeByClassId(ClassId); @@ -501,7 +506,7 @@ public: } else { Block = addHeaderTag(Block); Ptr = addHeaderTag(Ptr); - if (UNLIKELY(useMemoryTagging(Options))) { + if (UNLIKELY(useMemoryTagging(Options))) { storeTags(reinterpret_cast(Block), reinterpret_cast(Ptr)); storeSecondaryAllocationStackMaybe(Options, Ptr, Size); } @@ -661,7 +666,7 @@ public: (reinterpret_cast(OldTaggedPtr) + NewSize)) & Chunk::SizeOrUnusedBytesMask; Chunk::storeHeader(Cookie, OldPtr, &Header); - if (UNLIKELY(useMemoryTagging(Options))) { + if (UNLIKELY(useMemoryTagging(Options))) { if (ClassId) { resizeTaggedChunk(reinterpret_cast(OldTaggedPtr) + OldSize, reinterpret_cast(OldTaggedPtr) + NewSize, @@ -764,8 +769,9 @@ public: Base = untagPointer(Base); const uptr From = Base; const uptr To = Base + Size; - bool MayHaveTaggedPrimary = allocatorSupportsMemoryTagging() && - systemSupportsMemoryTagging(); + bool MayHaveTaggedPrimary = + allocatorSupportsMemoryTagging() && + systemSupportsMemoryTagging(); auto Lambda = [this, From, To, MayHaveTaggedPrimary, Callback, Arg](uptr Block) { if (Block < From || Block >= To) @@ -786,9 +792,9 @@ public: } if (Header.State == Chunk::State::Allocated) { uptr TaggedChunk = Chunk; - if (allocatorSupportsMemoryTagging()) + if (allocatorSupportsMemoryTagging()) TaggedChunk = untagPointer(TaggedChunk); - if (useMemoryTagging(Primary.Options.load())) + if (useMemoryTagging(Primary.Options.load())) TaggedChunk = loadTag(Chunk); Callback(TaggedChunk, getSize(reinterpret_cast(Chunk), &Header), Arg); @@ -887,7 +893,7 @@ public: } bool useMemoryTaggingTestOnly() const { - return useMemoryTagging(Primary.Options.load()); + return useMemoryTagging(Primary.Options.load()); } void disableMemoryTagging() { // If we haven't been initialized yet, we need to initialize now in order to @@ -897,7 +903,7 @@ public: // callback), which may cause mappings to be created with memory tagging // enabled. TSDRegistry.initOnceMaybe(this); - if (allocatorSupportsMemoryTagging()) { + if (allocatorSupportsMemoryTagging()) { Secondary.disableMemoryTagging(); Primary.Options.clear(OptionBit::UseMemoryTagging); } @@ -983,7 +989,7 @@ public: // should not be able to crash the crash dumper (crash_dump on Android). // See also the get_error_info_fuzzer. *ErrorInfo = {}; - if (!allocatorSupportsMemoryTagging() || + if (!allocatorSupportsMemoryTagging() || MemoryAddr + MemorySize < MemoryAddr) return; @@ -1032,7 +1038,7 @@ private: static_assert(MinAlignment >= sizeof(Chunk::PackedHeader), "Minimal alignment must at least cover a chunk header."); - static_assert(!allocatorSupportsMemoryTagging() || + static_assert(!allocatorSupportsMemoryTagging() || MinAlignment >= archMemoryTagGranuleSize(), ""); @@ -1081,6 +1087,11 @@ private: // An array of Size (at least one) elements of type Entry is immediately // following to this struct. }; + static_assert(sizeof(AllocationRingBuffer) % + alignof(typename AllocationRingBuffer::Entry) == + 0, + "invalid alignment"); + // Pointer to memory mapped area starting with AllocationRingBuffer struct, // and immediately followed by Size elements of type Entry. atomic_uptr RingBufferAddress = {}; @@ -1137,7 +1148,7 @@ private: const uptr SizeOrUnusedBytes = Header->SizeOrUnusedBytes; if (LIKELY(Header->ClassId)) return SizeOrUnusedBytes; - if (allocatorSupportsMemoryTagging()) + if (allocatorSupportsMemoryTagging()) Ptr = untagPointer(const_cast(Ptr)); return SecondaryT::getBlockEnd(getBlockBegin(Ptr, Header)) - reinterpret_cast(Ptr) - SizeOrUnusedBytes; @@ -1157,12 +1168,12 @@ private: Header->State = Chunk::State::Available; else Header->State = Chunk::State::Quarantined; - Header->OriginOrWasZeroed = useMemoryTagging(Options) && + Header->OriginOrWasZeroed = useMemoryTagging(Options) && Header->ClassId && !TSDRegistry.getDisableMemInit(); Chunk::storeHeader(Cookie, Ptr, Header); - if (UNLIKELY(useMemoryTagging(Options))) { + if (UNLIKELY(useMemoryTagging(Options))) { u8 PrevTag = extractTag(reinterpret_cast(TaggedPtr)); storeDeallocationStackMaybe(Options, Ptr, PrevTag, Size); if (Header->ClassId) { @@ -1179,7 +1190,7 @@ private: } } if (BypassQuarantine) { - if (allocatorSupportsMemoryTagging()) + if (allocatorSupportsMemoryTagging()) Ptr = untagPointer(Ptr); void *BlockBegin = getBlockBegin(Ptr, Header); const uptr ClassId = Header->ClassId; @@ -1196,7 +1207,7 @@ private: if (CacheDrained) Primary.tryReleaseToOS(ClassId, ReleaseToOS::Normal); } else { - if (UNLIKELY(useMemoryTagging(Options))) + if (UNLIKELY(useMemoryTagging(Options))) storeTags(reinterpret_cast(BlockBegin), reinterpret_cast(Ptr)); Secondary.deallocate(Options, BlockBegin); @@ -1553,16 +1564,6 @@ private: constexpr u32 kFramesPerStack = 16; static_assert(isPowerOfTwo(kFramesPerStack)); - // We need StackDepot to be aligned to 8-bytes so the ring we store after - // is correctly assigned. - static_assert(sizeof(StackDepot) % alignof(atomic_u64) == 0); - - // Make sure the maximum sized StackDepot fits withint a uintptr_t to - // simplify the overflow checking. - static_assert(sizeof(StackDepot) + UINT32_MAX * sizeof(atomic_u64) * - UINT32_MAX * sizeof(atomic_u32) < - UINTPTR_MAX); - if (AllocationRingBufferSize > kMaxU32Pow2 / kStacksPerRingBufferEntry) return; u32 TabSize = static_cast(roundUpPowerOfTwo(kStacksPerRingBufferEntry * @@ -1595,10 +1596,6 @@ private: atomic_store(&RingBufferAddress, reinterpret_cast(RB), memory_order_release); - static_assert(sizeof(AllocationRingBuffer) % - alignof(typename AllocationRingBuffer::Entry) == - 0, - "invalid alignment"); } void unmapRingBuffer() { diff --git a/compiler-rt/lib/scudo/standalone/condition_variable.h b/compiler-rt/lib/scudo/standalone/condition_variable.h index 4afebdc9d04c2cf75f098e2638612c089315bd57..3f16c86651e7364cb9449c8f9bbf17227082e7d7 100644 --- a/compiler-rt/lib/scudo/standalone/condition_variable.h +++ b/compiler-rt/lib/scudo/standalone/condition_variable.h @@ -39,22 +39,6 @@ public: } }; -template -struct ConditionVariableState { - static constexpr bool enabled() { return false; } - // This is only used for compilation purpose so that we won't end up having - // many conditional compilations. If you want to use `ConditionVariableDummy`, - // define `ConditionVariableT` in your allocator configuration. See - // allocator_config.h for more details. - using ConditionVariableT = ConditionVariableDummy; -}; - -template -struct ConditionVariableState { - static constexpr bool enabled() { return Config::UseConditionVariable; } - using ConditionVariableT = typename Config::ConditionVariableT; -}; - } // namespace scudo #endif // SCUDO_CONDITION_VARIABLE_H_ diff --git a/compiler-rt/lib/scudo/standalone/memtag.h b/compiler-rt/lib/scudo/standalone/memtag.h index aaed2192ad7521a683a7236aca9cf56097b44646..1f6983e99404a2cbd520b3cd2b0597e683234dd9 100644 --- a/compiler-rt/lib/scudo/standalone/memtag.h +++ b/compiler-rt/lib/scudo/standalone/memtag.h @@ -326,7 +326,7 @@ inline void *addFixedTag(void *Ptr, uptr Tag) { template inline constexpr bool allocatorSupportsMemoryTagging() { - return archSupportsMemoryTagging() && Config::MaySupportMemoryTagging && + return archSupportsMemoryTagging() && Config::getMaySupportMemoryTagging() && (1 << SCUDO_MIN_ALIGNMENT_LOG) >= archMemoryTagGranuleSize(); } diff --git a/compiler-rt/lib/scudo/standalone/primary32.h b/compiler-rt/lib/scudo/standalone/primary32.h index c86e75b8fd66a8fcf2902ea8de87eb5fc7c4cf76..1d8a77b73e5c27b287760f7f62701765aa8ba8cf 100644 --- a/compiler-rt/lib/scudo/standalone/primary32.h +++ b/compiler-rt/lib/scudo/standalone/primary32.h @@ -43,14 +43,13 @@ namespace scudo { template class SizeClassAllocator32 { public: - typedef typename Config::Primary::CompactPtrT CompactPtrT; - typedef typename Config::Primary::SizeClassMap SizeClassMap; - static const uptr GroupSizeLog = Config::Primary::GroupSizeLog; + typedef typename Config::CompactPtrT CompactPtrT; + typedef typename Config::SizeClassMap SizeClassMap; + static const uptr GroupSizeLog = Config::getGroupSizeLog(); // The bytemap can only track UINT8_MAX - 1 classes. static_assert(SizeClassMap::LargestClassId <= (UINT8_MAX - 1), ""); // Regions should be large enough to hold the largest Block. - static_assert((1UL << Config::Primary::RegionSizeLog) >= - SizeClassMap::MaxSize, + static_assert((1UL << Config::getRegionSizeLog()) >= SizeClassMap::MaxSize, ""); typedef SizeClassAllocator32 ThisT; typedef SizeClassAllocatorLocalCache CacheT; @@ -331,9 +330,9 @@ public: bool setOption(Option O, sptr Value) { if (O == Option::ReleaseInterval) { - const s32 Interval = Max(Min(static_cast(Value), - Config::Primary::MaxReleaseToOsIntervalMs), - Config::Primary::MinReleaseToOsIntervalMs); + const s32 Interval = Max( + Min(static_cast(Value), Config::getMaxReleaseToOsIntervalMs()), + Config::getMinReleaseToOsIntervalMs()); atomic_store_relaxed(&ReleaseToOsIntervalMs, Interval); return true; } @@ -373,9 +372,9 @@ public: private: static const uptr NumClasses = SizeClassMap::NumClasses; - static const uptr RegionSize = 1UL << Config::Primary::RegionSizeLog; - static const uptr NumRegions = - SCUDO_MMAP_RANGE_SIZE >> Config::Primary::RegionSizeLog; + static const uptr RegionSize = 1UL << Config::getRegionSizeLog(); + static const uptr NumRegions = SCUDO_MMAP_RANGE_SIZE >> + Config::getRegionSizeLog(); static const u32 MaxNumBatches = SCUDO_ANDROID ? 4U : 8U; typedef FlatByteMap ByteMap; @@ -408,7 +407,7 @@ private: static_assert(sizeof(SizeClassInfo) % SCUDO_CACHE_LINE_SIZE == 0, ""); uptr computeRegionId(uptr Mem) { - const uptr Id = Mem >> Config::Primary::RegionSizeLog; + const uptr Id = Mem >> Config::getRegionSizeLog(); CHECK_LT(Id, NumRegions); return Id; } @@ -437,7 +436,7 @@ private: unmap(reinterpret_cast(End), MapEnd - End); DCHECK_EQ(Region % RegionSize, 0U); - static_assert(Config::Primary::RegionSizeLog == GroupSizeLog, + static_assert(Config::getRegionSizeLog() == GroupSizeLog, "Memory group should be the same size as Region"); return Region; diff --git a/compiler-rt/lib/scudo/standalone/primary64.h b/compiler-rt/lib/scudo/standalone/primary64.h index d89a2e6a4e5c8dff0f4a2ad6d6766d0dec05320b..f5e4ab57b4dfd5e526d3d81a36c60a9a1f26d12e 100644 --- a/compiler-rt/lib/scudo/standalone/primary64.h +++ b/compiler-rt/lib/scudo/standalone/primary64.h @@ -47,13 +47,12 @@ namespace scudo { template class SizeClassAllocator64 { public: - typedef typename Config::Primary::CompactPtrT CompactPtrT; - typedef typename Config::Primary::SizeClassMap SizeClassMap; - typedef typename ConditionVariableState< - typename Config::Primary>::ConditionVariableT ConditionVariableT; - static const uptr CompactPtrScale = Config::Primary::CompactPtrScale; - static const uptr RegionSizeLog = Config::Primary::RegionSizeLog; - static const uptr GroupSizeLog = Config::Primary::GroupSizeLog; + typedef typename Config::CompactPtrT CompactPtrT; + typedef typename Config::SizeClassMap SizeClassMap; + typedef typename Config::ConditionVariableT ConditionVariableT; + static const uptr CompactPtrScale = Config::getCompactPtrScale(); + static const uptr RegionSizeLog = Config::getRegionSizeLog(); + static const uptr GroupSizeLog = Config::getGroupSizeLog(); static_assert(RegionSizeLog >= GroupSizeLog, "Group size shouldn't be greater than the region size"); static const uptr GroupScale = GroupSizeLog - CompactPtrScale; @@ -74,7 +73,7 @@ public: static bool canAllocate(uptr Size) { return Size <= SizeClassMap::MaxSize; } static bool conditionVariableEnabled() { - return ConditionVariableState::enabled(); + return Config::hasConditionVariableT(); } void init(s32 ReleaseToOsInterval) NO_THREAD_SAFETY_ANALYSIS { @@ -135,7 +134,7 @@ public: // The actual start of a region is offset by a random number of pages // when PrimaryEnableRandomOffset is set. Region->RegionBeg = (PrimaryBase + (I << RegionSizeLog)) + - (Config::Primary::EnableRandomOffset + (Config::getEnableRandomOffset() ? ((getRandomModN(&Seed, 16) + 1) * PageSize) : 0); Region->RandState = getRandomU32(&Seed); @@ -400,9 +399,9 @@ public: bool setOption(Option O, sptr Value) { if (O == Option::ReleaseInterval) { - const s32 Interval = Max(Min(static_cast(Value), - Config::Primary::MaxReleaseToOsIntervalMs), - Config::Primary::MinReleaseToOsIntervalMs); + const s32 Interval = Max( + Min(static_cast(Value), Config::getMaxReleaseToOsIntervalMs()), + Config::getMinReleaseToOsIntervalMs()); atomic_store_relaxed(&ReleaseToOsIntervalMs, Interval); return true; } @@ -516,7 +515,7 @@ private: static const uptr NumClasses = SizeClassMap::NumClasses; static const uptr PrimarySize = RegionSize * NumClasses; - static const uptr MapSizeIncrement = Config::Primary::MapSizeIncrement; + static const uptr MapSizeIncrement = Config::getMapSizeIncrement(); // Fill at most this number of batches from the newly map'd memory. static const u32 MaxNumBatches = SCUDO_ANDROID ? 4U : 8U; diff --git a/compiler-rt/lib/scudo/standalone/secondary.h b/compiler-rt/lib/scudo/standalone/secondary.h index 732fd307ed2f434f02cc4bb17c2334b3ae8a8779..202c55cc1a92b2962643114afe6f8ed43a7851a5 100644 --- a/compiler-rt/lib/scudo/standalone/secondary.h +++ b/compiler-rt/lib/scudo/standalone/secondary.h @@ -173,8 +173,6 @@ public: template class MapAllocatorCache { public: - using CacheConfig = typename Config::Secondary::Cache; - void getStats(ScopedString *Str) { ScopedLock L(Mutex); uptr Integral; @@ -199,16 +197,16 @@ public: } // Ensure the default maximum specified fits the array. - static_assert(CacheConfig::DefaultMaxEntriesCount <= - CacheConfig::EntriesArraySize, + static_assert(Config::getDefaultMaxEntriesCount() <= + Config::getEntriesArraySize(), ""); void init(s32 ReleaseToOsInterval) NO_THREAD_SAFETY_ANALYSIS { DCHECK_EQ(EntriesCount, 0U); setOption(Option::MaxCacheEntriesCount, - static_cast(CacheConfig::DefaultMaxEntriesCount)); + static_cast(Config::getDefaultMaxEntriesCount())); setOption(Option::MaxCacheEntrySize, - static_cast(CacheConfig::DefaultMaxEntrySize)); + static_cast(Config::getDefaultMaxEntrySize())); setOption(Option::ReleaseInterval, static_cast(ReleaseToOsInterval)); } @@ -253,9 +251,9 @@ public: // just unmap it. break; } - if (CacheConfig::QuarantineSize && useMemoryTagging(Options)) { + if (Config::getQuarantineSize() && useMemoryTagging(Options)) { QuarantinePos = - (QuarantinePos + 1) % Max(CacheConfig::QuarantineSize, 1u); + (QuarantinePos + 1) % Max(Config::getQuarantineSize(), 1u); if (!Quarantine[QuarantinePos].isValid()) { Quarantine[QuarantinePos] = Entry; return; @@ -382,14 +380,14 @@ public: bool setOption(Option O, sptr Value) { if (O == Option::ReleaseInterval) { const s32 Interval = Max( - Min(static_cast(Value), CacheConfig::MaxReleaseToOsIntervalMs), - CacheConfig::MinReleaseToOsIntervalMs); + Min(static_cast(Value), Config::getMaxReleaseToOsIntervalMs()), + Config::getMinReleaseToOsIntervalMs()); atomic_store_relaxed(&ReleaseToOsIntervalMs, Interval); return true; } if (O == Option::MaxCacheEntriesCount) { const u32 MaxCount = static_cast(Value); - if (MaxCount > CacheConfig::EntriesArraySize) + if (MaxCount > Config::getEntriesArraySize()) return false; atomic_store_relaxed(&MaxEntriesCount, MaxCount); return true; @@ -406,7 +404,7 @@ public: void disableMemoryTagging() EXCLUDES(Mutex) { ScopedLock L(Mutex); - for (u32 I = 0; I != CacheConfig::QuarantineSize; ++I) { + for (u32 I = 0; I != Config::getQuarantineSize(); ++I) { if (Quarantine[I].isValid()) { MemMapT &MemMap = Quarantine[I].MemMap; MemMap.unmap(MemMap.getBase(), MemMap.getCapacity()); @@ -431,11 +429,11 @@ public: private: void empty() { - MemMapT MapInfo[CacheConfig::EntriesArraySize]; + MemMapT MapInfo[Config::getEntriesArraySize()]; uptr N = 0; { ScopedLock L(Mutex); - for (uptr I = 0; I < CacheConfig::EntriesArraySize; I++) { + for (uptr I = 0; I < Config::getEntriesArraySize(); I++) { if (!Entries[I].isValid()) continue; MapInfo[N] = Entries[I].MemMap; @@ -468,9 +466,9 @@ private: if (!EntriesCount || OldestTime == 0 || OldestTime > Time) return; OldestTime = 0; - for (uptr I = 0; I < CacheConfig::QuarantineSize; I++) + for (uptr I = 0; I < Config::getQuarantineSize(); I++) releaseIfOlderThan(Quarantine[I], Time); - for (uptr I = 0; I < CacheConfig::EntriesArraySize; I++) + for (uptr I = 0; I < Config::getEntriesArraySize(); I++) releaseIfOlderThan(Entries[I], Time); } @@ -485,8 +483,8 @@ private: u32 CallsToRetrieve GUARDED_BY(Mutex) = 0; u32 SuccessfulRetrieves GUARDED_BY(Mutex) = 0; - CachedBlock Entries[CacheConfig::EntriesArraySize] GUARDED_BY(Mutex) = {}; - NonZeroLengthArray + CachedBlock Entries[Config::getEntriesArraySize()] GUARDED_BY(Mutex) = {}; + NonZeroLengthArray Quarantine GUARDED_BY(Mutex) = {}; }; @@ -555,7 +553,7 @@ public: void getStats(ScopedString *Str); private: - typename Config::Secondary::template CacheT Cache; + typename Config::template CacheT Cache; mutable HybridMutex Mutex; DoublyLinkedList InUseBlocks GUARDED_BY(Mutex); diff --git a/compiler-rt/lib/scudo/standalone/stack_depot.h b/compiler-rt/lib/scudo/standalone/stack_depot.h index 620137e44f372309ea463cbb2e987b50203bf31a..cf3cabf7085b6034bc4ed4fb96bd76536e245a4c 100644 --- a/compiler-rt/lib/scudo/standalone/stack_depot.h +++ b/compiler-rt/lib/scudo/standalone/stack_depot.h @@ -199,6 +199,10 @@ public: void enable() NO_THREAD_SAFETY_ANALYSIS { RingEndMu.unlock(); } }; +// We need StackDepot to be aligned to 8-bytes so the ring we store after +// is correctly assigned. +static_assert(sizeof(StackDepot) % alignof(atomic_u64) == 0); + } // namespace scudo #endif // SCUDO_STACK_DEPOT_H_ diff --git a/compiler-rt/lib/scudo/standalone/tests/CMakeLists.txt b/compiler-rt/lib/scudo/standalone/tests/CMakeLists.txt index c6b6a1cb57ceea68d55ac6c9181c88028d2630f2..1786756fa5ea6855761ecc180c0ea0f7c855486f 100644 --- a/compiler-rt/lib/scudo/standalone/tests/CMakeLists.txt +++ b/compiler-rt/lib/scudo/standalone/tests/CMakeLists.txt @@ -81,7 +81,7 @@ macro(add_scudo_unittest testname) "${testname}-${arch}-Test" ${arch} SOURCES ${TEST_SOURCES} ${COMPILER_RT_GTEST_SOURCE} COMPILE_DEPS ${SCUDO_TEST_HEADERS} - DEPS llvm_gtest scudo_standalone + DEPS scudo_standalone RUNTIME ${RUNTIME} CFLAGS ${SCUDO_UNITTEST_CFLAGS} LINK_FLAGS ${SCUDO_UNITTEST_LINK_FLAGS}) @@ -90,6 +90,7 @@ macro(add_scudo_unittest testname) endmacro() set(SCUDO_UNIT_TEST_SOURCES + allocator_config_test.cpp atomic_test.cpp bytemap_test.cpp checksum_test.cpp diff --git a/compiler-rt/lib/scudo/standalone/tests/allocator_config_test.cpp b/compiler-rt/lib/scudo/standalone/tests/allocator_config_test.cpp new file mode 100644 index 0000000000000000000000000000000000000000..4c4ceb832e27b11f32fc433cfeade8882dfd5fb7 --- /dev/null +++ b/compiler-rt/lib/scudo/standalone/tests/allocator_config_test.cpp @@ -0,0 +1,119 @@ +//===-- allocator_config_test.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 +// +//===----------------------------------------------------------------------===// + +#include "tests/scudo_unit_test.h" + +#include "allocator_config.h" +#include "allocator_config_wrapper.h" +#include "common.h" +#include "secondary.h" + +#include + +struct TestBaseConfig { + template using TSDRegistryT = void; + template using PrimaryT = void; + template using SecondaryT = void; +}; + +struct TestBaseConfigEnableOptionalFlag : public TestBaseConfig { + static const bool MaySupportMemoryTagging = true; + // Use the getter to avoid the test to `use` the address of static const + // variable (which requires additional explicit definition). + static bool getMaySupportMemoryTagging() { return MaySupportMemoryTagging; } +}; + +struct TestBasePrimaryConfig { + using SizeClassMap = void; + static const scudo::uptr RegionSizeLog = 18U; + static const scudo::uptr GroupSizeLog = 18U; + static const scudo::s32 MinReleaseToOsIntervalMs = INT32_MIN; + static const scudo::s32 MaxReleaseToOsIntervalMs = INT32_MAX; + typedef scudo::uptr CompactPtrT; + static const scudo::uptr CompactPtrScale = 0; + static const scudo::uptr MapSizeIncrement = 1UL << 18; +}; + +struct TestPrimaryConfig : public TestBaseConfig { + struct Primary : TestBasePrimaryConfig {}; +}; + +struct TestPrimaryConfigEnableOptionalFlag : public TestBaseConfig { + struct Primary : TestBasePrimaryConfig { + static const bool EnableRandomOffset = true; + static bool getEnableRandomOffset() { return EnableRandomOffset; } + }; +}; + +struct TestPrimaryConfigEnableOptionalType : public TestBaseConfig { + struct DummyConditionVariable {}; + + struct Primary : TestBasePrimaryConfig { + using ConditionVariableT = DummyConditionVariable; + }; +}; + +struct TestSecondaryConfig : public TestPrimaryConfig { + struct Secondary { + template + using CacheT = scudo::MapAllocatorNoCache; + }; +}; + +struct TestSecondaryCacheConfigEnableOptionalFlag : public TestPrimaryConfig { + struct Secondary { + struct Cache { + static const scudo::u32 EntriesArraySize = 256U; + static scudo::u32 getEntriesArraySize() { return EntriesArraySize; } + }; + template using CacheT = scudo::MapAllocatorCache; + }; +}; + +TEST(ScudoAllocatorConfigTest, VerifyOptionalFlags) { + // Test the top level allocator optional config. + // + // `MaySupportMemoryTagging` is default off. + EXPECT_FALSE(scudo::BaseConfig::getMaySupportMemoryTagging()); + EXPECT_EQ(scudo::BaseConfig< + TestBaseConfigEnableOptionalFlag>::getMaySupportMemoryTagging(), + TestBaseConfigEnableOptionalFlag::getMaySupportMemoryTagging()); + + // Test primary optional config. + // + // `EnableRandomeOffset` is default off. + EXPECT_FALSE( + scudo::PrimaryConfig::getEnableRandomOffset()); + EXPECT_EQ( + scudo::PrimaryConfig< + TestPrimaryConfigEnableOptionalFlag>::getEnableRandomOffset(), + TestPrimaryConfigEnableOptionalFlag::Primary::getEnableRandomOffset()); + + // `ConditionVariableT` is default off. + EXPECT_FALSE( + scudo::PrimaryConfig::hasConditionVariableT()); + EXPECT_TRUE(scudo::PrimaryConfig< + TestPrimaryConfigEnableOptionalType>::hasConditionVariableT()); + EXPECT_TRUE((std::is_same_v< + typename scudo::PrimaryConfig< + TestPrimaryConfigEnableOptionalType>::ConditionVariableT, + typename TestPrimaryConfigEnableOptionalType::Primary:: + ConditionVariableT>)); + + // Test secondary cache optional config. + using NoCacheConfig = + scudo::SecondaryConfig::CacheConfig; + // `EntriesArraySize` is default 0. + EXPECT_EQ(NoCacheConfig::getEntriesArraySize(), 0U); + + using CacheConfig = scudo::SecondaryConfig< + TestSecondaryCacheConfigEnableOptionalFlag>::CacheConfig; + EXPECT_EQ(CacheConfig::getEntriesArraySize(), + TestSecondaryCacheConfigEnableOptionalFlag::Secondary::Cache:: + getEntriesArraySize()); +} diff --git a/compiler-rt/lib/scudo/standalone/tests/combined_test.cpp b/compiler-rt/lib/scudo/standalone/tests/combined_test.cpp index 13d627b116809b371de5a28666e14cc62797e2b1..6a311adc55e4bd3e0d67c3c18fcdfdab7978f5b5 100644 --- a/compiler-rt/lib/scudo/standalone/tests/combined_test.cpp +++ b/compiler-rt/lib/scudo/standalone/tests/combined_test.cpp @@ -190,7 +190,6 @@ struct TestConditionVariableConfig { #endif static const scudo::s32 MinReleaseToOsIntervalMs = 1000; static const scudo::s32 MaxReleaseToOsIntervalMs = 1000; - static const bool UseConditionVariable = true; #if SCUDO_LINUX using ConditionVariableT = scudo::ConditionVariableLinux; #else diff --git a/compiler-rt/lib/scudo/standalone/tests/memtag_test.cpp b/compiler-rt/lib/scudo/standalone/tests/memtag_test.cpp index fd277f962a9aaacc1d848b180b9fc00a571d99ca..37a18858e67c2cfcf074b0a8de05fb3377ba8024 100644 --- a/compiler-rt/lib/scudo/standalone/tests/memtag_test.cpp +++ b/compiler-rt/lib/scudo/standalone/tests/memtag_test.cpp @@ -12,12 +12,17 @@ #include "platform.h" #include "tests/scudo_unit_test.h" +extern "C" void __hwasan_init() __attribute__((weak)); + #if SCUDO_LINUX namespace scudo { TEST(MemtagBasicDeathTest, Unsupported) { if (archSupportsMemoryTagging()) GTEST_SKIP(); + // Skip when running with HWASan. + if (&__hwasan_init != 0) + GTEST_SKIP(); EXPECT_DEATH(archMemoryTagGranuleSize(), "not supported"); EXPECT_DEATH(untagPointer((uptr)0), "not supported"); diff --git a/compiler-rt/lib/scudo/standalone/tests/primary_test.cpp b/compiler-rt/lib/scudo/standalone/tests/primary_test.cpp index f64a5143b30d4649b70dbd5820c28f8803eff45f..683ce3e596596d4dad6d9eb96228157ad3227395 100644 --- a/compiler-rt/lib/scudo/standalone/tests/primary_test.cpp +++ b/compiler-rt/lib/scudo/standalone/tests/primary_test.cpp @@ -9,6 +9,7 @@ #include "tests/scudo_unit_test.h" #include "allocator_config.h" +#include "allocator_config_wrapper.h" #include "condition_variable.h" #include "primary32.h" #include "primary64.h" @@ -29,6 +30,9 @@ template struct TestConfig1 { static const bool MaySupportMemoryTagging = false; + template using TSDRegistryT = void; + template using PrimaryT = void; + template using SecondaryT = void; struct Primary { using SizeClassMap = SizeClassMapT; @@ -45,6 +49,9 @@ template struct TestConfig1 { template struct TestConfig2 { static const bool MaySupportMemoryTagging = false; + template using TSDRegistryT = void; + template using PrimaryT = void; + template using SecondaryT = void; struct Primary { using SizeClassMap = SizeClassMapT; @@ -66,6 +73,9 @@ template struct TestConfig2 { template struct TestConfig3 { static const bool MaySupportMemoryTagging = true; + template using TSDRegistryT = void; + template using PrimaryT = void; + template using SecondaryT = void; struct Primary { using SizeClassMap = SizeClassMapT; @@ -87,6 +97,9 @@ template struct TestConfig3 { template struct TestConfig4 { static const bool MaySupportMemoryTagging = true; + template using TSDRegistryT = void; + template using PrimaryT = void; + template using SecondaryT = void; struct Primary { using SizeClassMap = SizeClassMapT; @@ -109,6 +122,9 @@ template struct TestConfig4 { // This is the only test config that enables the condition variable. template struct TestConfig5 { static const bool MaySupportMemoryTagging = true; + template using TSDRegistryT = void; + template using PrimaryT = void; + template using SecondaryT = void; struct Primary { using SizeClassMap = SizeClassMapT; @@ -125,7 +141,6 @@ template struct TestConfig5 { typedef scudo::u32 CompactPtrT; static const bool EnableRandomOffset = true; static const scudo::uptr MapSizeIncrement = 1UL << 18; - static const bool UseConditionVariable = true; #if SCUDO_LINUX using ConditionVariableT = scudo::ConditionVariableLinux; #else @@ -139,10 +154,12 @@ struct Config : public BaseConfig {}; template