diff --git a/.ci/generate-buildkite-pipeline-premerge b/.ci/generate-buildkite-pipeline-premerge index 033ab804b165eada6c0de4972b102360d75d8525..fd603de611e56203ab7fcdb32c9ff6ad7111a2a9 100755 --- a/.ci/generate-buildkite-pipeline-premerge +++ b/.ci/generate-buildkite-pipeline-premerge @@ -153,7 +153,6 @@ function exclude-linux() { for project in ${projects}; do case ${project} in cross-project-tests) ;; # tests failing - lldb) ;; # tests failing openmp) ;; # https://github.com/google/llvm-premerge-checks/issues/410 *) echo "${project}" @@ -170,7 +169,7 @@ function exclude-windows() { compiler-rt) ;; # tests taking too long openmp) ;; # TODO: having trouble with the Perl installation libc) ;; # no Windows support - lldb) ;; # tests failing + lldb) ;; # custom environment requirements (https://github.com/llvm/llvm-project/pull/94208#issuecomment-2146256857) bolt) ;; # tests are not supported yet *) echo "${project}" @@ -213,7 +212,7 @@ function check-targets() { echo "check-unwind" ;; lldb) - echo "check-all" # TODO: check-lldb may not include all the LLDB tests? + echo "check-lldb" ;; pstl) echo "check-all" diff --git a/.ci/monolithic-linux.sh b/.ci/monolithic-linux.sh index 38d7128f241b6756f6b20652261a6f055a244915..b78dc59432b65c9dcdf5130fe6aea85fb2d03148 100755 --- a/.ci/monolithic-linux.sh +++ b/.ci/monolithic-linux.sh @@ -39,6 +39,7 @@ targets="${2}" echo "--- cmake" pip install -q -r "${MONOREPO_ROOT}"/mlir/python/requirements.txt +pip install -q -r "${MONOREPO_ROOT}"/lldb/test/requirements.txt cmake -S "${MONOREPO_ROOT}"/llvm -B "${BUILD_DIR}" \ -D LLVM_ENABLE_PROJECTS="${projects}" \ -G Ninja \ diff --git a/.github/workflows/ci-post-commit-analyzer-run.py b/.github/workflows/ci-post-commit-analyzer-run.py new file mode 100644 index 0000000000000000000000000000000000000000..e5f52d3b2fa6719ac741866dd1a7f678189e94a5 --- /dev/null +++ b/.github/workflows/ci-post-commit-analyzer-run.py @@ -0,0 +1,34 @@ +import json +import multiprocessing +import os +import re +import subprocess +import sys + + +def run_analyzer(data): + os.chdir(data["directory"]) + command = ( + data["command"] + + f" --analyze --analyzer-output html -o analyzer-results -Xclang -analyzer-config -Xclang max-nodes=75000" + ) + print(command) + subprocess.run(command, shell=True, check=True) + + +def pool_error(e): + print("Error analyzing file:", e) + + +def main(): + db_path = sys.argv[1] + database = json.load(open(db_path)) + + with multiprocessing.Pool() as pool: + pool.map_async(run_analyzer, [k for k in database], error_callback=pool_error) + pool.close() + pool.join() + + +if __name__ == "__main__": + main() diff --git a/.github/workflows/ci-post-commit-analyzer.yml b/.github/workflows/ci-post-commit-analyzer.yml new file mode 100644 index 0000000000000000000000000000000000000000..d614dd07b3a493efe6412165304a3c6f2a22940b --- /dev/null +++ b/.github/workflows/ci-post-commit-analyzer.yml @@ -0,0 +1,95 @@ +name: Post-Commit Static Analyzer + +permissions: + contents: read + +on: + push: + branches: + - 'release/**' + paths: + - 'clang/**' + - 'llvm/**' + - '.github/workflows/ci-post-commit-analyzer.yml' + pull_request: + types: + - opened + - synchronize + - reopened + - closed + paths: + - '.github/workflows/ci-post-commit-analyzer.yml' + - '.github/workflows/ci-post-commit-analyzer-run.py' + schedule: + - cron: '30 0 * * *' + +concurrency: + group: >- + llvm-project-${{ github.workflow }}-${{ github.event_name == 'pull_request' && + ( github.event.pull_request.number || github.ref) }} + cancel-in-progress: ${{ startsWith(github.ref, 'refs/pull/') }} + +jobs: + post-commit-analyzer: + if: >- + github.repository_owner == 'llvm' && + github.event.action != 'closed' + runs-on: ubuntu-22.04 + container: + image: 'ghcr.io/llvm/ci-ubuntu-22.04:latest' + env: + LLVM_VERSION: 18 + steps: + - name: Checkout Source + uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 + + - name: Setup ccache + uses: hendrikmuhs/ccache-action@v1 + with: + # A full build of llvm, clang, lld, and lldb takes about 250MB + # of ccache space. There's not much reason to have more than this, + # because we usually won't need to save cache entries from older + # builds. Also, there is an overall 10GB cache limit, and each + # run creates a new cache entry so we want to ensure that we have + # enough cache space for all the tests to run at once and still + # fit under the 10 GB limit. + # Default to 2G to workaround: https://github.com/hendrikmuhs/ccache-action/issues/174 + max-size: 2G + key: post-commit-analyzer + variant: sccache + + - name: Configure + run: | + cmake -B build -S llvm -G Ninja \ + -DLLVM_ENABLE_ASSERTIONS=ON \ + -DLLVM_ENABLE_PROJECTS=clang \ + -DLLVM_BUILD_LLVM_DYLIB=ON \ + -DLLVM_LINK_LLVM_DYLIB=ON \ + -DCMAKE_CXX_COMPILER=clang++ \ + -DCMAKE_C_COMPILER=clang \ + -DCMAKE_CXX_COMPILER_LAUNCHER=sccache \ + -DCMAKE_C_COMPILER_LAUNCHER=sccache \ + -DCMAKE_EXPORT_COMPILE_COMMANDS=ON \ + -DLLVM_INCLUDE_TESTS=OFF \ + -DCLANG_INCLUDE_TESTS=OFF \ + -DCMAKE_BUILD_TYPE=Release + + - name: Build + run: | + # FIXME: We need to build all the generated header files in order to be able to run + # the analyzer on every file. Building libLLVM and libclang is probably overkill for + # this, but it's better than building every target. + ninja -v -C build libLLVM.so libclang.so + + # Run the analyzer. + python3 .github/workflows/ci-post-commit-analyzer-run.py build/compile_commands.json + + scan-build --generate-index-only build/analyzer-results + + - name: Upload Results + uses: actions/upload-artifact@26f96dfa697d77e81fd5907df203aa23a56210a8 #v4.3.0 + if: always() + with: + name: analyzer-results + path: 'build/analyzer-results/*' + diff --git a/.github/workflows/containers/github-action-ci/stage1.Dockerfile b/.github/workflows/containers/github-action-ci/stage1.Dockerfile index fbc4548e6636e8f8c7313c27bfea12ae03556736..8c6bcf46384105a291250efa99b9a5362dcd52f8 100644 --- a/.github/workflows/containers/github-action-ci/stage1.Dockerfile +++ b/.github/workflows/containers/github-action-ci/stage1.Dockerfile @@ -37,7 +37,7 @@ RUN cmake -B ./build -G Ninja ./llvm \ -DLLVM_ENABLE_RUNTIMES="compiler-rt" \ -DCMAKE_INSTALL_PREFIX="$LLVM_SYSROOT" \ -DLLVM_ENABLE_PROJECTS="bolt;clang;lld;clang-tools-extra" \ - -DLLVM_DISTRIBUTION_COMPONENTS="lld;compiler-rt;clang-format" \ + -DLLVM_DISTRIBUTION_COMPONENTS="lld;compiler-rt;clang-format;scan-build" \ -DCLANG_DEFAULT_LINKER="lld" \ -DBOOTSTRAP_CLANG_PGO_TRAINING_DATA_SOURCE_DIR=/llvm-project-llvmorg-$LLVM_VERSION/llvm diff --git a/.github/workflows/release-binaries.yml b/.github/workflows/release-binaries.yml index fc497a7de94f7a629c71d0908ed2fbd6193bd4ea..7de4d00334d14a5b9914b6c2f54b41b2be58ac07 100644 --- a/.github/workflows/release-binaries.yml +++ b/.github/workflows/release-binaries.yml @@ -156,6 +156,8 @@ jobs: rm build.tar.zst - name: Build Stage 2 + # Re-enable once PGO builds are supported. + if: false run: | ninja -C /mnt/build stage2-instrumented @@ -214,7 +216,7 @@ jobs: - id: package-info run: | - filename="LLVM-${{ needs.prepare.outputs.release-version }}-Linux.tar.gz" + filename="LLVM-${{ needs.prepare.outputs.release-version }}-Linux.tar.xz" echo "filename=$filename" >> $GITHUB_OUTPUT echo "path=/mnt/build/tools/clang/stage2-bins/$filename" >> $GITHUB_OUTPUT diff --git a/bolt/include/bolt/Core/DIEBuilder.h b/bolt/include/bolt/Core/DIEBuilder.h index c5ad0ac18339ab6fd667e27dd5ac95e46c8d625f..c562373c718baf5be05cf7144d311000bf6aecc9 100644 --- a/bolt/include/bolt/Core/DIEBuilder.h +++ b/bolt/include/bolt/Core/DIEBuilder.h @@ -215,10 +215,9 @@ private: /// 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); + uint32_t finalizeDIEs(DWARFUnit &CU, DIE &Die, + std::optional Parent, + uint32_t NumberParentsInChain, 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 a4fdde7c396ad886e3d8c96bb92d25a657a4a0e1..a14a30529fad52d9a465f46d1c942f01e22e74eb 100644 --- a/bolt/include/bolt/Core/DebugNames.h +++ b/bolt/include/bolt/Core/DebugNames.h @@ -24,16 +24,17 @@ public: BOLTDWARF5AccelTableData(const uint64_t DieOffset, const std::optional DefiningParentOffset, const unsigned DieTag, const unsigned UnitID, - const bool IsTU, + const bool IsParentRoot, const bool IsTU, const std::optional SecondUnitID) : DWARF5AccelTableData(DieOffset, DefiningParentOffset, DieTag, UnitID, IsTU), - SecondUnitID(SecondUnitID) {} + SecondUnitID(SecondUnitID), IsParentRoot(IsParentRoot) {} uint64_t getDieOffset() const { return DWARF5AccelTableData::getDieOffset(); } unsigned getDieTag() const { return DWARF5AccelTableData::getDieTag(); } unsigned getUnitID() const { return DWARF5AccelTableData::getUnitID(); } bool isTU() const { return DWARF5AccelTableData::isTU(); } + bool isParentRoot() const { return IsParentRoot; } std::optional getSecondUnitID() const { return SecondUnitID; } void setPatchOffset(uint64_t PatchOffset) { OffsetVal = PatchOffset; } @@ -41,6 +42,7 @@ public: private: std::optional SecondUnitID; + bool IsParentRoot; }; class DWARF5AcceleratorTable { @@ -57,6 +59,7 @@ public: std::optional addAccelTableEntry(DWARFUnit &Unit, const DIE &Die, const std::optional &DWOID, + const uint32_t NumberParentsInChain, std::optional &Parent); /// Set current unit being processed. void setCurrentUnit(DWARFUnit &Unit, const uint64_t UnitStartOffset); diff --git a/bolt/include/bolt/Core/GDBIndex.h b/bolt/include/bolt/Core/GDBIndex.h new file mode 100644 index 0000000000000000000000000000000000000000..6604c2a11472d47c8070b3cc4a1c5a26c71b47e0 --- /dev/null +++ b/bolt/include/bolt/Core/GDBIndex.h @@ -0,0 +1,61 @@ +//===-- bolt/Core/GDBIndex.h - GDB Index support ----------------*- 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 contains declaration of classes required for generation of +/// .gdb_index section. +/// +//===----------------------------------------------------------------------===// + +#ifndef BOLT_CORE_GDB_INDEX_H +#define BOLT_CORE_GDB_INDEX_H + +#include "bolt/Core/BinaryContext.h" +#include + +namespace llvm { +namespace bolt { + +class GDBIndex { +public: + /// Contains information about TU so we can write out correct entries in GDB + /// index. + struct GDBIndexTUEntry { + uint64_t UnitOffset; + uint64_t TypeHash; + uint64_t TypeDIERelativeOffset; + }; + +private: + BinaryContext &BC; + + /// Entries for GDB Index Types CU List. + using GDBIndexTUEntryType = std::vector; + GDBIndexTUEntryType GDBIndexTUEntryVector; + +public: + GDBIndex(BinaryContext &BC) : BC(BC) {} + + std::mutex GDBIndexMutex; + + /// Adds an GDBIndexTUEntry if .gdb_index section exists. + void addGDBTypeUnitEntry(const GDBIndexTUEntry &&Entry); + + /// Rewrite .gdb_index section if present. + void updateGdbIndexSection(const CUOffsetMap &CUMap, const uint32_t NumCUs, + DebugARangesSectionWriter &ARangesSectionWriter); + + /// Returns all entries needed for Types CU list. + const GDBIndexTUEntryType &getGDBIndexTUEntryVector() const { + return GDBIndexTUEntryVector; + } +}; + +} // namespace bolt +} // namespace llvm + +#endif diff --git a/bolt/include/bolt/Core/MCPlusBuilder.h b/bolt/include/bolt/Core/MCPlusBuilder.h index f7cf538bd0e867eba4f11636b45361a2280c4706..a5fb3901428d9d393cca8dd881318e6c5401dbf9 100644 --- a/bolt/include/bolt/Core/MCPlusBuilder.h +++ b/bolt/include/bolt/Core/MCPlusBuilder.h @@ -1706,12 +1706,9 @@ public: } /// Reverses the branch condition in Inst and update its taken target to TBB. - /// - /// Returns true on success. - virtual bool reverseBranchCondition(MCInst &Inst, const MCSymbol *TBB, + virtual void reverseBranchCondition(MCInst &Inst, const MCSymbol *TBB, MCContext *Ctx) const { llvm_unreachable("not implemented"); - return false; } virtual bool replaceBranchCondition(MCInst &Inst, const MCSymbol *TBB, @@ -1751,12 +1748,9 @@ public: } /// Sets the taken target of the branch instruction to Target. - /// - /// Returns true on success. - virtual bool replaceBranchTarget(MCInst &Inst, const MCSymbol *TBB, + virtual void replaceBranchTarget(MCInst &Inst, const MCSymbol *TBB, MCContext *Ctx) const { llvm_unreachable("not implemented"); - return false; } /// Extract a symbol and an addend out of the fixup value expression. diff --git a/bolt/include/bolt/Rewrite/DWARFRewriter.h b/bolt/include/bolt/Rewrite/DWARFRewriter.h index 8dec32de9008e5e692a3f61a8ac1b655a3af6d66..3cc9d823c815b22769ba769706864ee1c64b11c7 100644 --- a/bolt/include/bolt/Rewrite/DWARFRewriter.h +++ b/bolt/include/bolt/Rewrite/DWARFRewriter.h @@ -12,6 +12,7 @@ #include "bolt/Core/DIEBuilder.h" #include "bolt/Core/DebugData.h" #include "bolt/Core/DebugNames.h" +#include "bolt/Core/GDBIndex.h" #include "llvm/ADT/StringRef.h" #include "llvm/CodeGen/DIE.h" #include "llvm/DWP/DWP.h" @@ -131,7 +132,8 @@ private: makeFinalLocListsSection(DWARFVersion Version); /// Finalize type sections in the main binary. - CUOffsetMap finalizeTypeSections(DIEBuilder &DIEBlder, DIEStreamer &Streamer); + CUOffsetMap finalizeTypeSections(DIEBuilder &DIEBlder, DIEStreamer &Streamer, + GDBIndex &GDBIndexSection); /// Process and write out CUs that are passsed in. void finalizeCompileUnits(DIEBuilder &DIEBlder, DIEStreamer &Streamer, diff --git a/bolt/lib/Core/BinaryEmitter.cpp b/bolt/lib/Core/BinaryEmitter.cpp index 0b44acb0816f2fab0c627ae7e451a7782732de53..5793963f9b80de23712e227a30a3c34acabb18b2 100644 --- a/bolt/lib/Core/BinaryEmitter.cpp +++ b/bolt/lib/Core/BinaryEmitter.cpp @@ -194,6 +194,7 @@ private: void BinaryEmitter::emitAll(StringRef OrgSecPrefix) { Streamer.initSections(false, *BC.STI); + Streamer.setUseAssemblerInfoForParsing(false); if (opts::UpdateDebugSections && BC.isELF()) { // Force the emission of debug line info into allocatable section to ensure @@ -226,6 +227,7 @@ void BinaryEmitter::emitAll(StringRef OrgSecPrefix) { // TODO Enable for Mach-O once BinaryContext::getDataSection supports it. if (BC.isELF()) AddressMap::emit(Streamer, BC); + Streamer.setUseAssemblerInfoForParsing(true); } void BinaryEmitter::emitFunctions() { diff --git a/bolt/lib/Core/CMakeLists.txt b/bolt/lib/Core/CMakeLists.txt index 441df9fe0846481c8e88eb74f9d1cbff96b4d594..873cf67a56291f7a1f760f83e4f81c5dcb3fe056 100644 --- a/bolt/lib/Core/CMakeLists.txt +++ b/bolt/lib/Core/CMakeLists.txt @@ -25,6 +25,7 @@ add_llvm_library(LLVMBOLTCore DynoStats.cpp Exceptions.cpp FunctionLayout.cpp + GDBIndex.cpp HashUtilities.cpp JumpTable.cpp MCPlusBuilder.cpp diff --git a/bolt/lib/Core/DIEBuilder.cpp b/bolt/lib/Core/DIEBuilder.cpp index 34c455a36cce4c98fa302d27a3071d5a3bfa09ff..6633eaa9574216bc266acd2b18622b2ed29a0ed0 100644 --- a/bolt/lib/Core/DIEBuilder.cpp +++ b/bolt/lib/Core/DIEBuilder.cpp @@ -461,32 +461,42 @@ getUnitForOffset(DIEBuilder &Builder, DWARFContext &DWCtx, return nullptr; } -uint32_t DIEBuilder::finalizeDIEs( - DWARFUnit &CU, DIE &Die, - std::vector> &Parents, - uint32_t &CurOffset) { +uint32_t +DIEBuilder::finalizeDIEs(DWARFUnit &CU, DIE &Die, + std::optional Parent, + uint32_t NumberParentsInChain, uint32_t &CurOffset) { getState().DWARFDieAddressesParsed.erase(Die.getOffset()); uint32_t CurSize = 0; Die.setOffset(CurOffset); std::optional NameEntry = DebugNamesTable.addAccelTableEntry( CU, Die, SkeletonCU ? SkeletonCU->getDWOId() : std::nullopt, - Parents.back()); + NumberParentsInChain, Parent); // 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. + // Skipping entry is not very useful for LLDB. This follows clang where + // children of forward declaration won't have DW_IDX_parent. + // https://github.com/llvm/llvm-project/pull/91808 + + // If Parent is nullopt and NumberParentsInChain is not zero, then forward + // declaration was encountered in this DF traversal. Propagating nullopt for + // Parent to children. + if (!Parent && NumberParentsInChain) + NameEntry = std::nullopt; if (NameEntry) - Parents.push_back(std::move(NameEntry)); + ++NumberParentsInChain; 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, Parents, CurOffset); + uint32_t ChildSize = + finalizeDIEs(CU, Child, NameEntry, NumberParentsInChain, CurOffset); CurSize += ChildSize; } // for children end mark. @@ -496,9 +506,6 @@ uint32_t DIEBuilder::finalizeDIEs( } Die.setSize(CurSize); - if (NameEntry) - Parents.pop_back(); - return CurSize; } @@ -510,7 +517,7 @@ void DIEBuilder::finish() { DebugNamesTable.setCurrentUnit(CU, UnitStartOffset); std::vector> Parents; Parents.push_back(std::nullopt); - finalizeDIEs(CU, *UnitDIE, Parents, CurOffset); + finalizeDIEs(CU, *UnitDIE, std::nullopt, 0, CurOffset); DWARFUnitInfo &CurUnitInfo = getUnitInfoByDwarfUnit(CU); CurUnitInfo.UnitOffset = UnitStartOffset; diff --git a/bolt/lib/Core/DebugNames.cpp b/bolt/lib/Core/DebugNames.cpp index 791cbc6df0828ada34d465e38dcfeeafa3eb51e1..ebe895e019ccb4c0ad11963e65a60cc06c9217e2 100644 --- a/bolt/lib/Core/DebugNames.cpp +++ b/bolt/lib/Core/DebugNames.cpp @@ -220,6 +220,7 @@ static uint64_t getEntryID(const BOLTDWARF5AccelTableData &Entry) { std::optional DWARF5AcceleratorTable::addAccelTableEntry( DWARFUnit &Unit, const DIE &Die, const std::optional &DWOID, + const uint32_t NumberParentsInChain, std::optional &Parent) { if (Unit.getVersion() < 5 || !NeedToCreate) return std::nullopt; @@ -312,8 +313,14 @@ DWARF5AcceleratorTable::addAccelTableEntry( // Keeping memory footprint down. if (ParentOffset) EntryRelativeOffsets.insert({*ParentOffset, 0}); + bool IsParentRoot = false; + // If there is no parent and no valid Entries in parent chain this is a root + // to be marked with a flag. + if (!Parent && !NumberParentsInChain) + IsParentRoot = true; It.Values.push_back(new (Allocator) BOLTDWARF5AccelTableData( - Die.getOffset(), ParentOffset, DieTag, UnitID, IsTU, SecondIndex)); + Die.getOffset(), ParentOffset, DieTag, UnitID, IsParentRoot, IsTU, + SecondIndex)); return It.Values.back(); }; @@ -462,7 +469,7 @@ void DWARF5AcceleratorTable::populateAbbrevsMap() { 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 + else if (Value->isParentRoot()) Abbrev.addAttribute( {dwarf::DW_IDX_parent, dwarf::DW_FORM_flag_present}); FoldingSetNodeID ID; diff --git a/bolt/lib/Core/GDBIndex.cpp b/bolt/lib/Core/GDBIndex.cpp new file mode 100644 index 0000000000000000000000000000000000000000..9e6d24167d559e96f81c646775082523c88b4a73 --- /dev/null +++ b/bolt/lib/Core/GDBIndex.cpp @@ -0,0 +1,185 @@ +//===- bolt/Core/GDBIndex.cpp - GDB Index support ------------------------===// +// +// 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 "bolt/Core/GDBIndex.h" + +using namespace llvm::bolt; +using namespace llvm::support::endian; + +void GDBIndex::addGDBTypeUnitEntry(const GDBIndexTUEntry &&Entry) { + std::lock_guard Lock(GDBIndexMutex); + if (!BC.getGdbIndexSection()) + return; + GDBIndexTUEntryVector.emplace_back(Entry); +} + +void GDBIndex::updateGdbIndexSection( + const CUOffsetMap &CUMap, const uint32_t NumCUs, + DebugARangesSectionWriter &ARangesSectionWriter) { + if (!BC.getGdbIndexSection()) + return; + + // See https://sourceware.org/gdb/onlinedocs/gdb/Index-Section-Format.html + // for .gdb_index section format. + + StringRef GdbIndexContents = BC.getGdbIndexSection()->getContents(); + + const char *Data = GdbIndexContents.data(); + + // Parse the header. + const uint32_t Version = read32le(Data); + if (Version != 7 && Version != 8) { + errs() << "BOLT-ERROR: can only process .gdb_index versions 7 and 8\n"; + exit(1); + } + + // Some .gdb_index generators use file offsets while others use section + // offsets. Hence we can only rely on offsets relative to each other, + // and ignore their absolute values. + const uint32_t CUListOffset = read32le(Data + 4); + const uint32_t CUTypesOffset = read32le(Data + 8); + const uint32_t AddressTableOffset = read32le(Data + 12); + const uint32_t SymbolTableOffset = read32le(Data + 16); + const uint32_t ConstantPoolOffset = read32le(Data + 20); + Data += 24; + + // Map CUs offsets to indices and verify existing index table. + std::map OffsetToIndexMap; + const uint32_t CUListSize = CUTypesOffset - CUListOffset; + const uint32_t TUListSize = AddressTableOffset - CUTypesOffset; + const unsigned NUmCUsEncoded = CUListSize / 16; + unsigned MaxDWARFVersion = BC.DwCtx->getMaxVersion(); + unsigned NumDWARF5TUs = + getGDBIndexTUEntryVector().size() - BC.DwCtx->getNumTypeUnits(); + bool SkipTypeUnits = false; + // For DWARF5 Types are in .debug_info. + // LLD doesn't generate Types CU List, and in CU list offset + // only includes CUs. + // GDB 11+ includes only CUs in CU list and generates Types + // list. + // GDB 9 includes CUs and TUs in CU list and generates TYpes + // list. The NumCUs is CUs + TUs, so need to modify the check. + // For split-dwarf + // GDB-11, DWARF5: TU units from dwo are not included. + // GDB-11, DWARF4: TU units from dwo are included. + if (MaxDWARFVersion >= 5) + SkipTypeUnits = !TUListSize ? true + : ((NUmCUsEncoded + NumDWARF5TUs) == + BC.DwCtx->getNumCompileUnits()); + + if (!((CUListSize == NumCUs * 16) || + (CUListSize == (NumCUs + NumDWARF5TUs) * 16))) { + errs() << "BOLT-ERROR: .gdb_index: CU count mismatch\n"; + exit(1); + } + DenseSet OriginalOffsets; + for (unsigned Index = 0, Units = BC.DwCtx->getNumCompileUnits(); + Index < Units; ++Index) { + const DWARFUnit *CU = BC.DwCtx->getUnitAtIndex(Index); + if (SkipTypeUnits && CU->isTypeUnit()) + continue; + const uint64_t Offset = read64le(Data); + Data += 16; + if (CU->getOffset() != Offset) { + errs() << "BOLT-ERROR: .gdb_index CU offset mismatch\n"; + exit(1); + } + + OriginalOffsets.insert(Offset); + OffsetToIndexMap[Offset] = Index; + } + + // Ignore old address table. + const uint32_t OldAddressTableSize = SymbolTableOffset - AddressTableOffset; + // Move Data to the beginning of symbol table. + Data += SymbolTableOffset - CUTypesOffset; + + // Calculate the size of the new address table. + uint32_t NewAddressTableSize = 0; + for (const auto &CURangesPair : ARangesSectionWriter.getCUAddressRanges()) { + const SmallVector &Ranges = CURangesPair.second; + NewAddressTableSize += Ranges.size() * 20; + } + + // Difference between old and new table (and section) sizes. + // Could be negative. + int32_t Delta = NewAddressTableSize - OldAddressTableSize; + + size_t NewGdbIndexSize = GdbIndexContents.size() + Delta; + + // Free'd by ExecutableFileMemoryManager. + auto *NewGdbIndexContents = new uint8_t[NewGdbIndexSize]; + uint8_t *Buffer = NewGdbIndexContents; + + write32le(Buffer, Version); + write32le(Buffer + 4, CUListOffset); + write32le(Buffer + 8, CUTypesOffset); + write32le(Buffer + 12, AddressTableOffset); + write32le(Buffer + 16, SymbolTableOffset + Delta); + write32le(Buffer + 20, ConstantPoolOffset + Delta); + Buffer += 24; + + using MapEntry = std::pair; + std::vector CUVector(CUMap.begin(), CUMap.end()); + // Need to sort since we write out all of TUs in .debug_info before CUs. + std::sort(CUVector.begin(), CUVector.end(), + [](const MapEntry &E1, const MapEntry &E2) -> bool { + return E1.second.Offset < E2.second.Offset; + }); + // Writing out CU List + for (auto &CUInfo : CUVector) { + // Skipping TU for DWARF5 when they are not included in CU list. + if (!OriginalOffsets.count(CUInfo.first)) + continue; + write64le(Buffer, CUInfo.second.Offset); + // Length encoded in CU doesn't contain first 4 bytes that encode length. + write64le(Buffer + 8, CUInfo.second.Length + 4); + Buffer += 16; + } + + // Rewrite TU CU List, since abbrevs can be different. + // Entry example: + // 0: offset = 0x00000000, type_offset = 0x0000001e, type_signature = + // 0x418503b8111e9a7b Spec says " triplet, the first value is the CU offset, + // the second value is the type offset in the CU, and the third value is the + // type signature" Looking at what is being generated by gdb-add-index. The + // first entry is TU offset, second entry is offset from it, and third entry + // is the type signature. + if (TUListSize) + for (const GDBIndexTUEntry &Entry : getGDBIndexTUEntryVector()) { + write64le(Buffer, Entry.UnitOffset); + write64le(Buffer + 8, Entry.TypeDIERelativeOffset); + write64le(Buffer + 16, Entry.TypeHash); + Buffer += sizeof(GDBIndexTUEntry); + } + + // Generate new address table. + for (const std::pair &CURangesPair : + ARangesSectionWriter.getCUAddressRanges()) { + const uint32_t CUIndex = OffsetToIndexMap[CURangesPair.first]; + const DebugAddressRangesVector &Ranges = CURangesPair.second; + for (const DebugAddressRange &Range : Ranges) { + write64le(Buffer, Range.LowPC); + write64le(Buffer + 8, Range.HighPC); + write32le(Buffer + 16, CUIndex); + Buffer += 20; + } + } + + const size_t TrailingSize = + GdbIndexContents.data() + GdbIndexContents.size() - Data; + assert(Buffer + TrailingSize == NewGdbIndexContents + NewGdbIndexSize && + "size calculation error"); + + // Copy over the rest of the original data. + memcpy(Buffer, Data, TrailingSize); + + // Register the new section. + BC.registerOrUpdateNoteSection(".gdb_index", NewGdbIndexContents, + NewGdbIndexSize); +} diff --git a/bolt/lib/Passes/VeneerElimination.cpp b/bolt/lib/Passes/VeneerElimination.cpp index 0bec11128c7cea91b1a802e465476a2981be2bd7..87fe625e8c3b3e02a76139db4faaf00f089bd982 100644 --- a/bolt/lib/Passes/VeneerElimination.cpp +++ b/bolt/lib/Passes/VeneerElimination.cpp @@ -77,11 +77,8 @@ Error VeneerElimination::runOnFunctions(BinaryContext &BC) { continue; VeneerCallers++; - if (!BC.MIB->replaceBranchTarget( - Instr, VeneerDestinations[TargetSymbol], BC.Ctx.get())) { - return createFatalBOLTError( - "BOLT-ERROR: updating veneer call destination failed\n"); - } + BC.MIB->replaceBranchTarget(Instr, VeneerDestinations[TargetSymbol], + BC.Ctx.get()); } } } diff --git a/bolt/lib/Profile/BoltAddressTranslation.cpp b/bolt/lib/Profile/BoltAddressTranslation.cpp index cdfca2b9871acfa6dee5adc57fedcb65557afb20..519f282a2351c2fb3653ce804b100bb223e9a12d 100644 --- a/bolt/lib/Profile/BoltAddressTranslation.cpp +++ b/bolt/lib/Profile/BoltAddressTranslation.cpp @@ -304,7 +304,7 @@ std::error_code BoltAddressTranslation::parse(raw_ostream &OS, StringRef Buf) { StringRef Name = Buf.slice(Offset, Offset + NameSz); Offset = alignTo(Offset + NameSz, 4); - if (Name.substr(0, 4) != "BOLT") + if (!Name.starts_with("BOLT")) return make_error_code(llvm::errc::io_error); Error Err(Error::success()); diff --git a/bolt/lib/Rewrite/DWARFRewriter.cpp b/bolt/lib/Rewrite/DWARFRewriter.cpp index 8814ebbd10aa500cc168b2e2633d10b13cc8343b..e1b3762a316606f5eaca0370ac81505c0cfb5555 100644 --- a/bolt/lib/Rewrite/DWARFRewriter.cpp +++ b/bolt/lib/Rewrite/DWARFRewriter.cpp @@ -184,7 +184,7 @@ namespace bolt { /// Emits debug information into .debug_info or .debug_types section. class DIEStreamer : public DwarfStreamer { DIEBuilder *DIEBldr; - DWARFRewriter &Rewriter; + GDBIndex &GDBIndexSection; private: /// Emit the compilation unit header for \p Unit in the debug_info @@ -247,7 +247,7 @@ private: const uint64_t TypeSignature = cast(Unit).getTypeHash(); DIE *TypeDIE = DIEBldr->getTypeDIE(Unit); const DIEBuilder::DWARFUnitInfo &UI = DIEBldr->getUnitInfoByDwarfUnit(Unit); - Rewriter.addGDBTypeUnitEntry( + GDBIndexSection.addGDBTypeUnitEntry( {UI.UnitOffset, TypeSignature, TypeDIE->getOffset()}); if (Unit.getVersion() < 5) { // Switch the section to .debug_types section. @@ -278,12 +278,12 @@ private: } public: - DIEStreamer(DIEBuilder *DIEBldr, DWARFRewriter &Rewriter, + DIEStreamer(DIEBuilder *DIEBldr, GDBIndex &GDBIndexSection, DWARFLinkerBase::OutputFileType OutFileType, raw_pwrite_stream &OutFile, DWARFLinkerBase::MessageHandlerTy Warning) : DwarfStreamer(OutFileType, OutFile, Warning), DIEBldr(DIEBldr), - Rewriter(Rewriter){}; + GDBIndexSection(GDBIndexSection) {}; using DwarfStreamer::emitCompileUnitHeader; @@ -326,12 +326,11 @@ static cl::opt KeepARanges( "keep or generate .debug_aranges section if .gdb_index is written"), cl::Hidden, cl::cat(BoltCategory)); -static cl::opt -DeterministicDebugInfo("deterministic-debuginfo", - cl::desc("disables parallel execution of tasks that may produce " - "nondeterministic debug info"), - cl::init(true), - cl::cat(BoltCategory)); +static cl::opt DeterministicDebugInfo( + "deterministic-debuginfo", + cl::desc("disables parallel execution of tasks that may produce " + "nondeterministic debug info"), + cl::init(true), cl::cat(BoltCategory)); static cl::opt DwarfOutputPath( "dwarf-output-path", @@ -460,10 +459,11 @@ static std::optional getAsAddress(const DWARFUnit &DU, static std::unique_ptr createDIEStreamer(const Triple &TheTriple, raw_pwrite_stream &OutFile, StringRef Swift5ReflectionSegmentName, DIEBuilder &DIEBldr, - DWARFRewriter &Rewriter) { + GDBIndex &GDBIndexSection) { std::unique_ptr Streamer = std::make_unique( - &DIEBldr, Rewriter, DWARFLinkerBase::OutputFileType::Object, OutFile, + &DIEBldr, GDBIndexSection, DWARFLinkerBase::OutputFileType::Object, + OutFile, [&](const Twine &Warning, StringRef Context, const DWARFDie *) {}); Error Err = Streamer->init(TheTriple, Swift5ReflectionSegmentName); if (Err) @@ -484,13 +484,12 @@ emitUnit(DIEBuilder &DIEBldr, DIEStreamer &Streamer, DWARFUnit &Unit) { return {U.UnitOffset, U.UnitLength, TypeHash}; } -static void emitDWOBuilder(const std::string &DWOName, - DIEBuilder &DWODIEBuilder, DWARFRewriter &Rewriter, - DWARFUnit &SplitCU, DWARFUnit &CU, - DWARFRewriter::DWPState &State, - DebugLocWriter &LocWriter, - DebugStrOffsetsWriter &StrOffstsWriter, - DebugStrWriter &StrWriter) { +static void +emitDWOBuilder(const std::string &DWOName, DIEBuilder &DWODIEBuilder, + DWARFRewriter &Rewriter, DWARFUnit &SplitCU, DWARFUnit &CU, + DWARFRewriter::DWPState &State, DebugLocWriter &LocWriter, + DebugStrOffsetsWriter &StrOffstsWriter, + DebugStrWriter &StrWriter, GDBIndex &GDBIndexSection) { // Populate debug_info and debug_abbrev for current dwo into StringRef. DWODIEBuilder.generateAbbrevs(); DWODIEBuilder.finish(); @@ -500,8 +499,9 @@ static void emitDWOBuilder(const std::string &DWOName, std::make_shared(OutBuffer); const object::ObjectFile *File = SplitCU.getContext().getDWARFObj().getFile(); auto TheTriple = std::make_unique(File->makeTriple()); - std::unique_ptr Streamer = createDIEStreamer( - *TheTriple, *ObjOS, "DwoStreamerInitAug2", DWODIEBuilder, Rewriter); + std::unique_ptr Streamer = + createDIEStreamer(*TheTriple, *ObjOS, "DwoStreamerInitAug2", + DWODIEBuilder, GDBIndexSection); DWARFRewriter::UnitMetaVectorType TUMetaVector; DWARFRewriter::UnitMeta CUMI = {0, 0, 0}; if (SplitCU.getContext().getMaxDWOVersion() >= 5) { @@ -652,6 +652,7 @@ void DWARFRewriter::updateDebugInfo() { DWARF5AcceleratorTable DebugNamesTable(opts::CreateDebugNames, BC, *StrWriter); + GDBIndex GDBIndexSection(BC); DWPState State; if (opts::WriteDWP) initDWPState(State); @@ -704,7 +705,8 @@ void DWARFRewriter::updateDebugInfo() { TempRangesSectionWriter->finalizeSection(); emitDWOBuilder(DWOName, DWODIEBuilder, *this, **SplitCU, *Unit, State, - DebugLocDWoWriter, DWOStrOffstsWriter, DWOStrWriter); + DebugLocDWoWriter, DWOStrOffstsWriter, DWOStrWriter, + GDBIndexSection); } if (Unit->getVersion() >= 5) { @@ -729,9 +731,10 @@ void DWARFRewriter::updateDebugInfo() { std::make_unique(OutBuffer); const object::ObjectFile *File = BC.DwCtx->getDWARFObj().getFile(); auto TheTriple = std::make_unique(File->makeTriple()); - std::unique_ptr Streamer = - createDIEStreamer(*TheTriple, *ObjOS, "TypeStreamer", DIEBlder, *this); - CUOffsetMap OffsetMap = finalizeTypeSections(DIEBlder, *Streamer); + std::unique_ptr Streamer = createDIEStreamer( + *TheTriple, *ObjOS, "TypeStreamer", DIEBlder, GDBIndexSection); + CUOffsetMap OffsetMap = + finalizeTypeSections(DIEBlder, *Streamer, GDBIndexSection); const bool SingleThreadedMode = opts::NoThreads || opts::DeterministicDebugInfo; @@ -761,7 +764,8 @@ void DWARFRewriter::updateDebugInfo() { finalizeDebugSections(DIEBlder, DebugNamesTable, *Streamer, *ObjOS, OffsetMap); - updateGdbIndexSection(OffsetMap, CUIndex); + GDBIndexSection.updateGdbIndexSection(OffsetMap, CUIndex, + *ARangesSectionWriter); } void DWARFRewriter::updateUnitDebugInfo( @@ -1429,7 +1433,8 @@ void DWARFRewriter::updateLineTableOffsets(const MCAsmLayout &Layout) { } CUOffsetMap DWARFRewriter::finalizeTypeSections(DIEBuilder &DIEBlder, - DIEStreamer &Streamer) { + DIEStreamer &Streamer, + GDBIndex &GDBIndexSection) { // update TypeUnit DW_AT_stmt_list with new .debug_line information. auto updateLineTable = [&](const DWARFUnit &Unit) -> void { DIE *UnitDIE = DIEBlder.getUnitDIEbyUnit(Unit); @@ -1449,8 +1454,8 @@ CUOffsetMap DWARFRewriter::finalizeTypeSections(DIEBuilder &DIEBlder, std::make_shared(OutBuffer); const object::ObjectFile *File = BC.DwCtx->getDWARFObj().getFile(); auto TheTriple = std::make_unique(File->makeTriple()); - std::unique_ptr TypeStreamer = - createDIEStreamer(*TheTriple, *ObjOS, "TypeStreamer", DIEBlder, *this); + std::unique_ptr TypeStreamer = createDIEStreamer( + *TheTriple, *ObjOS, "TypeStreamer", DIEBlder, GDBIndexSection); // generate debug_info and CUMap CUOffsetMap CUMap; diff --git a/bolt/lib/Target/AArch64/AArch64MCPlusBuilder.cpp b/bolt/lib/Target/AArch64/AArch64MCPlusBuilder.cpp index 0ae9d3668b93bb87290a54b763e775a5234cfd6d..a74eda8e4a566eb2d3e1353f2f945f61eb8732a6 100644 --- a/bolt/lib/Target/AArch64/AArch64MCPlusBuilder.cpp +++ b/bolt/lib/Target/AArch64/AArch64MCPlusBuilder.cpp @@ -616,7 +616,7 @@ public: return getTargetAddend(Op.getExpr()); } - bool replaceBranchTarget(MCInst &Inst, const MCSymbol *TBB, + void replaceBranchTarget(MCInst &Inst, const MCSymbol *TBB, MCContext *Ctx) const override { assert((isCall(Inst) || isBranch(Inst)) && !isIndirectBranch(Inst) && "Invalid instruction"); @@ -638,7 +638,6 @@ public: *OI = MCOperand::createExpr( MCSymbolRefExpr::create(TBB, MCSymbolRefExpr::VK_None, *Ctx)); - return true; } /// Matches indirect branch patterns in AArch64 related to a jump table (JT), @@ -969,7 +968,7 @@ public: } } - bool reverseBranchCondition(MCInst &Inst, const MCSymbol *TBB, + void reverseBranchCondition(MCInst &Inst, const MCSymbol *TBB, MCContext *Ctx) const override { if (isTB(Inst) || isCB(Inst)) { Inst.setOpcode(getInvertedBranchOpcode(Inst.getOpcode())); @@ -984,7 +983,7 @@ public: LLVM_DEBUG(Inst.dump()); llvm_unreachable("Unrecognized branch instruction"); } - return replaceBranchTarget(Inst, TBB, Ctx); + replaceBranchTarget(Inst, TBB, Ctx); } int getPCRelEncodingSize(const MCInst &Inst) const override { diff --git a/bolt/lib/Target/RISCV/RISCVMCPlusBuilder.cpp b/bolt/lib/Target/RISCV/RISCVMCPlusBuilder.cpp index 74f2f0aae91e667d12d6edff81f371c1e1044bfe..eb3f38a0b8f4a0d3301ba88cc8f597fd79f43939 100644 --- a/bolt/lib/Target/RISCV/RISCVMCPlusBuilder.cpp +++ b/bolt/lib/Target/RISCV/RISCVMCPlusBuilder.cpp @@ -151,14 +151,14 @@ public: } } - bool reverseBranchCondition(MCInst &Inst, const MCSymbol *TBB, + void reverseBranchCondition(MCInst &Inst, const MCSymbol *TBB, MCContext *Ctx) const override { auto Opcode = getInvertedBranchOpcode(Inst.getOpcode()); Inst.setOpcode(Opcode); - return replaceBranchTarget(Inst, TBB, Ctx); + replaceBranchTarget(Inst, TBB, Ctx); } - bool replaceBranchTarget(MCInst &Inst, const MCSymbol *TBB, + void replaceBranchTarget(MCInst &Inst, const MCSymbol *TBB, MCContext *Ctx) const override { assert((isCall(Inst) || isBranch(Inst)) && !isIndirectBranch(Inst) && "Invalid instruction"); @@ -170,7 +170,6 @@ public: Inst.getOperand(SymOpIndex) = MCOperand::createExpr( MCSymbolRefExpr::create(TBB, MCSymbolRefExpr::VK_None, *Ctx)); - return true; } IndirectBranchType analyzeIndirectBranch( diff --git a/bolt/lib/Target/X86/X86MCPlusBuilder.cpp b/bolt/lib/Target/X86/X86MCPlusBuilder.cpp index a33a9dc8c013ce0b4c07591e64421b275f449b33..e350e701c7b7bae4bda206a3baa61976688b7c1b 100644 --- a/bolt/lib/Target/X86/X86MCPlusBuilder.cpp +++ b/bolt/lib/Target/X86/X86MCPlusBuilder.cpp @@ -2794,14 +2794,13 @@ public: Inst.addOperand(MCOperand::createImm(CC)); } - bool reverseBranchCondition(MCInst &Inst, const MCSymbol *TBB, + void reverseBranchCondition(MCInst &Inst, const MCSymbol *TBB, MCContext *Ctx) const override { unsigned InvCC = getInvertedCondCode(getCondCode(Inst)); assert(InvCC != X86::COND_INVALID && "invalid branch instruction"); Inst.getOperand(Info->get(Inst.getOpcode()).NumOperands - 1).setImm(InvCC); Inst.getOperand(0) = MCOperand::createExpr( MCSymbolRefExpr::create(TBB, MCSymbolRefExpr::VK_None, *Ctx)); - return true; } bool replaceBranchCondition(MCInst &Inst, const MCSymbol *TBB, MCContext *Ctx, @@ -2844,13 +2843,12 @@ public: } } - bool replaceBranchTarget(MCInst &Inst, const MCSymbol *TBB, + void replaceBranchTarget(MCInst &Inst, const MCSymbol *TBB, MCContext *Ctx) const override { assert((isCall(Inst) || isBranch(Inst)) && !isIndirectBranch(Inst) && "Invalid instruction"); Inst.getOperand(0) = MCOperand::createExpr( MCSymbolRefExpr::create(TBB, MCSymbolRefExpr::VK_None, *Ctx)); - return true; } MCPhysReg getX86R11() const override { return X86::R11; } diff --git a/bolt/test/X86/dwarf5-debug-names-skip-forward-decl.s b/bolt/test/X86/dwarf5-debug-names-skip-forward-decl.s new file mode 100644 index 0000000000000000000000000000000000000000..cae27f3cbd3f45d2c072d37ec33ca8d9080227b8 --- /dev/null +++ b/bolt/test/X86/dwarf5-debug-names-skip-forward-decl.s @@ -0,0 +1,708 @@ +# REQUIRES: system-linux + +# RUN: llvm-mc -dwarf-version=5 -filetype=obj -triple x86_64-unknown-linux %s -o %t1.o +# RUN: %clang %cflags -dwarf-5 %t1.o -o %t.exe -Wl,-q +# RUN: llvm-bolt %t.exe -o %t.bolt --update-debug-sections +# RUN: llvm-dwarfdump --debug-names %t.bolt FileCheck --check-prefix=POSTCHECK %s + +## This test checks that BOLT doesn't set DW_IDX_parent an entry, InnerState, when it's parent is a forward declaration. + +# POSTCHECK: debug_names +# POSTCHECK: Bucket 0 [ +# POSTCHECK-NEXT: Name 1 { +# POSTCHECK-NEXT: Hash: 0xB888030 +# POSTCHECK-NEXT: String: 0x00000047 "int" +# POSTCHECK-NEXT: Entry @ 0xfb { +# POSTCHECK-NEXT: Abbrev: 0x1 +# POSTCHECK-NEXT: Tag: DW_TAG_base_type +# POSTCHECK-NEXT: DW_IDX_die_offset: 0x0000005c +# POSTCHECK-NEXT: DW_IDX_parent: +# POSTCHECK-NEXT: } +# POSTCHECK-NEXT: } +# POSTCHECK-NEXT: ] +# POSTCHECK-NEXT: Bucket 1 [ +# POSTCHECK-NEXT: EMPTY +# POSTCHECK-NEXT: ] +# POSTCHECK-NEXT: Bucket 2 [ +# POSTCHECK-NEXT: Name 2 { +# POSTCHECK-NEXT: Hash: 0x7C9A7F6A +# POSTCHECK-NEXT: String: {{.+}} "main" +# POSTCHECK-NEXT: Entry @ {{.+}} { +# POSTCHECK-NEXT: Abbrev: 0x2 +# POSTCHECK-NEXT: Tag: DW_TAG_subprogram +# POSTCHECK-NEXT: DW_IDX_die_offset: 0x00000034 +# POSTCHECK-NEXT: DW_IDX_parent: +# POSTCHECK-NEXT: } +# POSTCHECK-NEXT: } +# POSTCHECK-NEXT: Name 3 { +# POSTCHECK-NEXT: Hash: 0xE0CDC6A2 +# POSTCHECK-NEXT: String: {{.+}} "InnerState" +# POSTCHECK-NEXT: Entry @ {{.+}} { +# POSTCHECK-NEXT: Abbrev: 0x3 +# POSTCHECK-NEXT: Tag: DW_TAG_class_type +# POSTCHECK-NEXT: DW_IDX_type_unit: 0x01 +# POSTCHECK-NEXT: DW_IDX_die_offset: 0x00000030 +# POSTCHECK-NEXT: } +# POSTCHECK-NEXT: } +# POSTCHECK-NEXT: ] +# POSTCHECK-NEXT: Bucket 3 [ +# POSTCHECK-NEXT: EMPTY +# POSTCHECK-NEXT: ] +# POSTCHECK-NEXT: Bucket 4 [ +# POSTCHECK-NEXT: EMPTY +# POSTCHECK-NEXT: ] +# POSTCHECK-NEXT: Bucket 5 [ +# POSTCHECK-NEXT: Name 4 { +# POSTCHECK-NEXT: Hash: 0x2F94396D +# POSTCHECK-NEXT: String: {{.+}} "_Z9get_statev" +# POSTCHECK-NEXT: Entry @ {{.+}} { +# POSTCHECK-NEXT: Abbrev: 0x2 +# POSTCHECK-NEXT: Tag: DW_TAG_subprogram +# POSTCHECK-NEXT: DW_IDX_die_offset: 0x00000024 +# POSTCHECK-NEXT: DW_IDX_parent: +# POSTCHECK-NEXT: } +# POSTCHECK-NEXT: } +# POSTCHECK-NEXT: Name 5 { +# POSTCHECK-NEXT: Hash: 0xCD86E3E5 +# POSTCHECK-NEXT: String: {{.+}} "get_state" +# POSTCHECK-NEXT: Entry @ {{.+}} { +# POSTCHECK-NEXT: Abbrev: 0x2 +# POSTCHECK-NEXT: Tag: DW_TAG_subprogram +# POSTCHECK-NEXT: DW_IDX_die_offset: 0x00000024 +# POSTCHECK-NEXT: DW_IDX_parent: +# POSTCHECK-NEXT: } +# POSTCHECK-NEXT: } +# POSTCHECK-NEXT: ] +# POSTCHECK-NEXT: Bucket 6 [ +# POSTCHECK-NEXT: Name 6 { +# POSTCHECK-NEXT: Hash: 0x2B606 +# POSTCHECK-NEXT: String: {{.+}} "A" +# POSTCHECK-NEXT: Entry @ 0x11a { +# POSTCHECK-NEXT: Abbrev: 0x4 +# POSTCHECK-NEXT: Tag: DW_TAG_namespace +# POSTCHECK-NEXT: DW_IDX_type_unit: 0x00 +# POSTCHECK-NEXT: DW_IDX_die_offset: 0x00000023 +# POSTCHECK-NEXT: DW_IDX_parent: +# POSTCHECK-NEXT: } +# POSTCHECK-NEXT: Entry @ 0x120 { +# POSTCHECK-NEXT: Abbrev: 0x4 +# POSTCHECK-NEXT: Tag: DW_TAG_namespace +# POSTCHECK-NEXT: DW_IDX_type_unit: 0x01 +# POSTCHECK-NEXT: DW_IDX_die_offset: 0x00000023 +# POSTCHECK-NEXT: DW_IDX_parent: +# POSTCHECK-NEXT: } +# POSTCHECK-NEXT: Entry @ 0x126 { +# POSTCHECK-NEXT: Abbrev: 0x5 +# POSTCHECK-NEXT: Tag: DW_TAG_namespace +# POSTCHECK-NEXT: DW_IDX_die_offset: 0x00000043 +# POSTCHECK-NEXT: DW_IDX_parent: +# POSTCHECK-NEXT: } +# POSTCHECK-NEXT: } +# POSTCHECK-NEXT: Name 7 { +# POSTCHECK-NEXT: Hash: 0x10614A06 +# POSTCHECK-NEXT: String: {{.+}} "State" +# POSTCHECK-NEXT: Entry @ {{.+}} { +# POSTCHECK-NEXT: Abbrev: 0x6 +# POSTCHECK-NEXT: Tag: DW_TAG_structure_type +# POSTCHECK-NEXT: DW_IDX_type_unit: 0x00 +# POSTCHECK-NEXT: DW_IDX_die_offset: 0x00000027 +# POSTCHECK-NEXT: DW_IDX_parent: Entry @ 0x137 +# POSTCHECK-NEXT: } +# POSTCHECK-NEXT: } +# POSTCHECK-NEXT: ] +# POSTCHECK-NEXT: Bucket 7 [ +# POSTCHECK-NEXT: Name 8 { +# POSTCHECK-NEXT: Hash: 0x2B607 +# POSTCHECK-NEXT: String: {{.+}} "B" +# POSTCHECK-NEXT: Entry @ 0x137 { +# POSTCHECK-NEXT: Abbrev: 0x7 +# POSTCHECK-NEXT: Tag: DW_TAG_namespace +# POSTCHECK-NEXT: DW_IDX_type_unit: 0x00 +# POSTCHECK-NEXT: DW_IDX_die_offset: 0x00000025 +# POSTCHECK-NEXT: DW_IDX_parent: Entry @ 0x11a +# POSTCHECK-NEXT: } +# POSTCHECK-NEXT: Entry @ {{.+}} { +# POSTCHECK-NEXT: Abbrev: 0x7 +# POSTCHECK-NEXT: Tag: DW_TAG_namespace +# POSTCHECK-NEXT: DW_IDX_type_unit: 0x01 +# POSTCHECK-NEXT: DW_IDX_die_offset: 0x00000025 +# POSTCHECK-NEXT: DW_IDX_parent: Entry @ 0x120 +# POSTCHECK-NEXT: } +# POSTCHECK-NEXT: Entry @ {{.+}} { +# POSTCHECK-NEXT: Abbrev: 0x8 +# POSTCHECK-NEXT: Tag: DW_TAG_namespace +# POSTCHECK-NEXT: DW_IDX_die_offset: 0x00000045 +# POSTCHECK-NEXT: DW_IDX_parent: Entry @ 0x126 +# POSTCHECK-NEXT: } +# POSTCHECK-NEXT: } +# POSTCHECK-NEXT: ] +# POSTCHECK-NEXT: } + +## clang++ -g2 -O0 -fdebug-types-section -gpubnames -S +## A::B::State::InnerState get_state() { return A::B::State::InnerState(); } +## int main() { +## return 0; +## } + +## Manually modified to fix bug in clang where for TU0 "B" was pointing to CU DIE instead of parent in TU + .text + .file "main.cpp" + .globl _Z9get_statev # -- Begin function _Z9get_statev + .p2align 4, 0x90 + .type _Z9get_statev,@function +_Z9get_statev: # @_Z9get_statev +.Lfunc_begin0: + .file 0 "/skipDecl" "main.cpp" md5 0xd417b4a09217d7c3ec58d64286de7ba4 + .loc 0 2 0 # main.cpp:2: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 +.Ltmp0: + .loc 0 2 39 prologue_end epilogue_begin # main.cpp:2:39 + popq %rbp + .cfi_def_cfa %rsp, 8 + retq +.Ltmp1: +.Lfunc_end0: + .size _Z9get_statev, .Lfunc_end0-_Z9get_statev + .cfi_endproc + # -- End function + .globl main # -- Begin function main + .p2align 4, 0x90 + .type main,@function +main: # @main +.Lfunc_begin1: + .loc 0 4 0 # main.cpp:4: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) +.Ltmp2: + .loc 0 5 3 prologue_end # main.cpp:5:3 + xorl %eax, %eax + .loc 0 5 3 epilogue_begin is_stmt 0 # main.cpp:5:3 + popq %rbp + .cfi_def_cfa %rsp, 8 + retq +.Ltmp3: +.Lfunc_end1: + .size main, .Lfunc_end1-main + .cfi_endproc + # -- End function + .section .debug_info,"G",@progbits,16664150534606561860,comdat +.Ltu_begin0: + .long .Ldebug_info_end0-.Ldebug_info_start0 # Length of Unit +.Ldebug_info_start0: + .short 5 # DWARF version number + .byte 2 # DWARF Unit Type + .byte 8 # Address Size (in bytes) + .long .debug_abbrev # Offset Into Abbrev. Section + .quad -1782593539102989756 # Type Signature + .long 39 # Type DIE Offset + .byte 1 # Abbrev [1] 0x18:0x18 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:0xc DW_TAG_namespace + .byte 5 # DW_AT_name + .byte 2 # Abbrev [2] 0x25:0x9 DW_TAG_namespace + .byte 6 # DW_AT_name + .byte 3 # Abbrev [3] 0x27:0x6 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 0 # End Of Children Mark + .byte 0 # End Of Children Mark + .byte 0 # End Of Children Mark +.Ldebug_info_end0: + .section .debug_info,"G",@progbits,1766745463811827694,comdat +.Ltu_begin1: + .long .Ldebug_info_end1-.Ldebug_info_start1 # Length of Unit +.Ldebug_info_start1: + .short 5 # DWARF version number + .byte 2 # DWARF Unit Type + .byte 8 # Address Size (in bytes) + .long .debug_abbrev # Offset Into Abbrev. Section + .quad 1766745463811827694 # Type Signature + .long 48 # Type DIE Offset + .byte 1 # Abbrev [1] 0x18:0x22 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:0x16 DW_TAG_namespace + .byte 5 # DW_AT_name + .byte 2 # Abbrev [2] 0x25:0x13 DW_TAG_namespace + .byte 6 # DW_AT_name + .byte 4 # Abbrev [4] 0x27:0x10 DW_TAG_structure_type + # DW_AT_declaration + .quad -1782593539102989756 # DW_AT_signature + .byte 5 # Abbrev [5] 0x30:0x6 DW_TAG_class_type + .byte 5 # DW_AT_calling_convention + .byte 8 # DW_AT_name + .byte 1 # DW_AT_byte_size + .byte 0 # DW_AT_decl_file + .byte 1 # DW_AT_decl_line + .byte 0 # End Of Children Mark + .byte 0 # End Of Children Mark + .byte 0 # End Of Children Mark + .byte 0 # End Of Children Mark +.Ldebug_info_end1: + .section .debug_abbrev,"",@progbits + .byte 1 # Abbreviation Code + .byte 65 # DW_TAG_type_unit + .byte 1 # DW_CHILDREN_yes + .byte 19 # DW_AT_language + .byte 5 # DW_FORM_data2 + .byte 16 # DW_AT_stmt_list + .byte 23 # DW_FORM_sec_offset + .byte 114 # DW_AT_str_offsets_base + .byte 23 # DW_FORM_sec_offset + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 2 # Abbreviation Code + .byte 57 # DW_TAG_namespace + .byte 1 # DW_CHILDREN_yes + .byte 3 # DW_AT_name + .byte 37 # DW_FORM_strx1 + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 3 # Abbreviation Code + .byte 19 # DW_TAG_structure_type + .byte 0 # DW_CHILDREN_no + .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 19 # DW_TAG_structure_type + .byte 1 # DW_CHILDREN_yes + .byte 60 # DW_AT_declaration + .byte 25 # DW_FORM_flag_present + .byte 105 # DW_AT_signature + .byte 32 # DW_FORM_ref_sig8 + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 5 # Abbreviation Code + .byte 2 # DW_TAG_class_type + .byte 0 # DW_CHILDREN_no + .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 6 # 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 7 # 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 110 # DW_AT_linkage_name + .byte 37 # DW_FORM_strx1 + .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 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 9 # Abbreviation Code + .byte 2 # DW_TAG_class_type + .byte 0 # DW_CHILDREN_no + .byte 60 # DW_AT_declaration + .byte 25 # DW_FORM_flag_present + .byte 105 # DW_AT_signature + .byte 32 # DW_FORM_ref_sig8 + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 10 # Abbreviation Code + .byte 36 # DW_TAG_base_type + .byte 0 # DW_CHILDREN_no + .byte 3 # DW_AT_name + .byte 37 # DW_FORM_strx1 + .byte 62 # DW_AT_encoding + .byte 11 # DW_FORM_data1 + .byte 11 # DW_AT_byte_size + .byte 11 # DW_FORM_data1 + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 0 # EOM(3) + .section .debug_info,"",@progbits +.Lcu_begin0: + .long .Ldebug_info_end2-.Ldebug_info_start2 # Length of Unit +.Ldebug_info_start2: + .short 5 # DWARF version number + .byte 1 # DWARF Unit Type + .byte 8 # Address Size (in bytes) + .long .debug_abbrev # Offset Into Abbrev. Section + .byte 6 # Abbrev [6] 0xc:0x54 DW_TAG_compile_unit + .byte 0 # DW_AT_producer + .short 33 # DW_AT_language + .byte 1 # DW_AT_name + .long .Lstr_offsets_base0 # DW_AT_str_offsets_base + .long .Lline_table_start0 # DW_AT_stmt_list + .byte 2 # DW_AT_comp_dir + .byte 0 # DW_AT_low_pc + .long .Lfunc_end1-.Lfunc_begin0 # DW_AT_high_pc + .long .Laddr_table_base0 # DW_AT_addr_base + .byte 7 # Abbrev [7] 0x23:0x10 DW_TAG_subprogram + .byte 0 # DW_AT_low_pc + .long .Lfunc_end0-.Lfunc_begin0 # DW_AT_high_pc + .byte 1 # DW_AT_frame_base + .byte 86 + .byte 3 # DW_AT_linkage_name + .byte 4 # DW_AT_name + .byte 0 # DW_AT_decl_file + .byte 2 # DW_AT_decl_line + .long 79 # DW_AT_type + # DW_AT_external + .byte 8 # Abbrev [8] 0x33:0xf DW_TAG_subprogram + .byte 1 # DW_AT_low_pc + .long .Lfunc_end1-.Lfunc_begin1 # DW_AT_high_pc + .byte 1 # DW_AT_frame_base + .byte 86 + .byte 9 # DW_AT_name + .byte 0 # DW_AT_decl_file + .byte 4 # DW_AT_decl_line + .long 91 # DW_AT_type + # DW_AT_external + .byte 2 # Abbrev [2] 0x42:0x19 DW_TAG_namespace + .byte 5 # DW_AT_name + .byte 2 # Abbrev [2] 0x44:0x16 DW_TAG_namespace + .byte 6 # DW_AT_name + .byte 4 # Abbrev [4] 0x46:0x13 DW_TAG_structure_type + # DW_AT_declaration + .quad -1782593539102989756 # DW_AT_signature + .byte 9 # Abbrev [9] 0x4f:0x9 DW_TAG_class_type + # DW_AT_declaration + .quad 1766745463811827694 # DW_AT_signature + .byte 0 # End Of Children Mark + .byte 0 # End Of Children Mark + .byte 0 # End Of Children Mark + .byte 10 # Abbrev [10] 0x5b:0x4 DW_TAG_base_type + .byte 10 # DW_AT_name + .byte 5 # DW_AT_encoding + .byte 4 # DW_AT_byte_size + .byte 0 # End Of Children Mark +.Ldebug_info_end2: + .section .debug_str_offsets,"",@progbits + .long 48 # Length of String Offsets Set + .short 5 + .short 0 +.Lstr_offsets_base0: + .section .debug_str,"MS",@progbits,1 +.Linfo_string0: + .asciz "clang version 19.0.0git" # string offset=0 +.Linfo_string1: + .asciz "main.cpp" # string offset=24 +.Linfo_string2: + .asciz "/skipDecl" # string offset=33 +.Linfo_string3: + .asciz "get_state" # string offset=80 +.Linfo_string4: + .asciz "_Z9get_statev" # string offset=90 +.Linfo_string5: + .asciz "main" # string offset=104 +.Linfo_string6: + .asciz "A" # string offset=109 +.Linfo_string7: + .asciz "B" # string offset=111 +.Linfo_string8: + .asciz "State" # string offset=113 +.Linfo_string9: + .asciz "InnerState" # string offset=119 +.Linfo_string10: + .asciz "int" # string offset=130 + .section .debug_str_offsets,"",@progbits + .long .Linfo_string0 + .long .Linfo_string1 + .long .Linfo_string2 + .long .Linfo_string4 + .long .Linfo_string3 + .long .Linfo_string6 + .long .Linfo_string7 + .long .Linfo_string8 + .long .Linfo_string9 + .long .Linfo_string5 + .long .Linfo_string10 + .section .debug_addr,"",@progbits + .long .Ldebug_addr_end0-.Ldebug_addr_start0 # Length of contribution +.Ldebug_addr_start0: + .short 5 # DWARF version number + .byte 8 # Address size + .byte 0 # Segment selector size +.Laddr_table_base0: + .quad .Lfunc_begin0 + .quad .Lfunc_begin1 +.Ldebug_addr_end0: + .section .debug_names,"",@progbits + .long .Lnames_end0-.Lnames_start0 # Header: unit length +.Lnames_start0: + .short 5 # Header: version + .short 0 # Header: padding + .long 1 # Header: compilation unit count + .long 2 # Header: local type unit count + .long 0 # Header: foreign type unit count + .long 8 # Header: bucket count + .long 8 # 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 .Ltu_begin1 # Type unit 1 + .long 1 # Bucket 0 + .long 0 # Bucket 1 + .long 2 # Bucket 2 + .long 0 # Bucket 3 + .long 0 # Bucket 4 + .long 4 # Bucket 5 + .long 6 # Bucket 6 + .long 8 # Bucket 7 + .long 193495088 # Hash in Bucket 0 + .long 2090499946 # Hash in Bucket 2 + .long -523385182 # Hash in Bucket 2 + .long 798243181 # Hash in Bucket 5 + .long -846797851 # Hash in Bucket 5 + .long 177670 # Hash in Bucket 6 + .long 274811398 # Hash in Bucket 6 + .long 177671 # Hash in Bucket 7 + .long .Linfo_string10 # String in Bucket 0: int + .long .Linfo_string5 # String in Bucket 2: main + .long .Linfo_string9 # String in Bucket 2: InnerState + .long .Linfo_string4 # String in Bucket 5: _Z9get_statev + .long .Linfo_string3 # String in Bucket 5: get_state + .long .Linfo_string6 # String in Bucket 6: A + .long .Linfo_string8 # String in Bucket 6: State + .long .Linfo_string7 # String in Bucket 7: B + .long .Lnames7-.Lnames_entries0 # Offset in Bucket 0 + .long .Lnames2-.Lnames_entries0 # Offset in Bucket 2 + .long .Lnames6-.Lnames_entries0 # Offset in Bucket 2 + .long .Lnames1-.Lnames_entries0 # Offset in Bucket 5 + .long .Lnames0-.Lnames_entries0 # Offset in Bucket 5 + .long .Lnames3-.Lnames_entries0 # Offset in Bucket 6 + .long .Lnames5-.Lnames_entries0 # Offset in Bucket 6 + .long .Lnames4-.Lnames_entries0 # Offset in Bucket 7 +.Lnames_abbrev_start0: + .byte 1 # Abbrev code + .byte 36 # DW_TAG_base_type + .byte 3 # DW_IDX_die_offset + .byte 19 # DW_FORM_ref4 + .byte 4 # DW_IDX_parent + .byte 25 # DW_FORM_flag_present + .byte 0 # End of abbrev + .byte 0 # End of abbrev + .byte 2 # Abbrev code + .byte 46 # DW_TAG_subprogram + .byte 3 # DW_IDX_die_offset + .byte 19 # DW_FORM_ref4 + .byte 4 # DW_IDX_parent + .byte 25 # DW_FORM_flag_present + .byte 0 # End of abbrev + .byte 0 # End of abbrev + .byte 3 # Abbrev code + .byte 2 # DW_TAG_class_type + .byte 2 # DW_IDX_type_unit + .byte 11 # DW_FORM_data1 + .byte 3 # DW_IDX_die_offset + .byte 19 # DW_FORM_ref4 + .byte 0 # End of abbrev + .byte 0 # End of abbrev + .byte 4 # Abbrev code + .byte 57 # DW_TAG_namespace + .byte 2 # DW_IDX_type_unit + .byte 11 # DW_FORM_data1 + .byte 3 # DW_IDX_die_offset + .byte 19 # DW_FORM_ref4 + .byte 4 # DW_IDX_parent + .byte 25 # DW_FORM_flag_present + .byte 0 # End of abbrev + .byte 0 # End of abbrev + .byte 5 # Abbrev code + .byte 57 # DW_TAG_namespace + .byte 3 # DW_IDX_die_offset + .byte 19 # DW_FORM_ref4 + .byte 4 # DW_IDX_parent + .byte 25 # DW_FORM_flag_present + .byte 0 # End of abbrev + .byte 0 # End of abbrev + .byte 6 # Abbrev code + .byte 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 19 # DW_FORM_ref4 + .byte 0 # End of abbrev + .byte 0 # End of abbrev + .byte 7 # Abbrev code + .byte 57 # DW_TAG_namespace + .byte 2 # DW_IDX_type_unit + .byte 11 # DW_FORM_data1 + .byte 3 # DW_IDX_die_offset + .byte 19 # DW_FORM_ref4 + .byte 4 # DW_IDX_parent + .byte 19 # DW_FORM_ref4 + .byte 0 # End of abbrev + .byte 0 # End of abbrev + .byte 8 # Abbrev code + .byte 57 # DW_TAG_namespace + .byte 3 # DW_IDX_die_offset + .byte 19 # DW_FORM_ref4 + .byte 4 # DW_IDX_parent + .byte 19 # DW_FORM_ref4 + .byte 0 # End of abbrev + .byte 0 # End of abbrev + .byte 0 # End of abbrev list +.Lnames_abbrev_end0: +.Lnames_entries0: +.Lnames7: +.L6: + .byte 1 # Abbreviation code + .long 91 # DW_IDX_die_offset + .byte 0 # DW_IDX_parent + # End of list: int +.Lnames2: +.L1: + .byte 2 # Abbreviation code + .long 51 # DW_IDX_die_offset + .byte 0 # DW_IDX_parent + # End of list: main +.Lnames6: +.L8: + .byte 3 # Abbreviation code + .byte 1 # DW_IDX_type_unit + .long 48 # DW_IDX_die_offset + .byte 0 # End of list: InnerState +.Lnames1: +.L4: + .byte 2 # Abbreviation code + .long 35 # DW_IDX_die_offset + .byte 0 # DW_IDX_parent + # End of list: _Z9get_statev +.Lnames0: + .byte 2 # Abbreviation code + .long 35 # DW_IDX_die_offset + .byte 0 # DW_IDX_parent + # End of list: get_state +.Lnames3: +.LmanualLabel: + .byte 4 # Abbreviation code + .byte 0 # DW_IDX_type_unit + .long 35 # DW_IDX_die_offset +.L3: # DW_IDX_parent + .byte 4 # Abbreviation code + .byte 1 # DW_IDX_type_unit + .long 35 # DW_IDX_die_offset +.L2: # DW_IDX_parent + .byte 5 # Abbreviation code + .long 66 # DW_IDX_die_offset + .byte 0 # DW_IDX_parent + # End of list: A +.Lnames5: +.L0: + .byte 6 # Abbreviation code + .byte 0 # DW_IDX_type_unit + .long 39 # DW_IDX_die_offset + .long .L5-.Lnames_entries0 # DW_IDX_parent + .byte 0 # End of list: State +.Lnames4: +.L5: + .byte 7 # Abbreviation code + .byte 0 # DW_IDX_type_unit + .long 37 # DW_IDX_die_offset + .long .LmanualLabel-.Lnames_entries0 # DW_IDX_parent +.L7: + .byte 7 # Abbreviation code + .byte 1 # DW_IDX_type_unit + .long 37 # DW_IDX_die_offset + .long .L3-.Lnames_entries0 # DW_IDX_parent +.L9: + .byte 8 # Abbreviation code + .long 68 # DW_IDX_die_offset + .long .L2-.Lnames_entries0 # DW_IDX_parent + .byte 0 # End of list: B + .p2align 2, 0x0 +.Lnames_end0: + .ident "clang version 19.0.0git" + .section ".note.GNU-stack","",@progbits + .addrsig + .section .debug_line,"",@progbits +.Lline_table_start0: diff --git a/clang-tools-extra/clang-query/QueryParser.cpp b/clang-tools-extra/clang-query/QueryParser.cpp index 1d0b7d9bc6fc84350f0497da542603661a4da3c8..97cb264a611af35f0dd833d6d34bbb016ef885a6 100644 --- a/clang-tools-extra/clang-query/QueryParser.cpp +++ b/clang-tools-extra/clang-query/QueryParser.cpp @@ -144,13 +144,11 @@ QueryRef QueryParser::endQuery(QueryRef Q) { StringRef Extra = Line; StringRef ExtraTrimmed = Extra.ltrim(" \t\v\f\r"); - if ((!ExtraTrimmed.empty() && ExtraTrimmed[0] == '\n') || - (ExtraTrimmed.size() >= 2 && ExtraTrimmed[0] == '\r' && - ExtraTrimmed[1] == '\n')) + if (ExtraTrimmed.starts_with('\n') || ExtraTrimmed.starts_with("\r\n")) Q->RemainingContent = Extra; else { StringRef TrailingWord = lexWord(); - if (!TrailingWord.empty() && TrailingWord.front() == '#') { + if (TrailingWord.starts_with('#')) { Line = Line.drop_until([](char c) { return c == '\n'; }); Line = Line.drop_while([](char c) { return c == '\n'; }); return endQuery(Q); diff --git a/clang-tools-extra/clang-tidy/bugprone/MultiLevelImplicitPointerConversionCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/MultiLevelImplicitPointerConversionCheck.cpp index 4dd3cb57e6dd12d83faef394caad692420cb4842..7a989b07119aad82e14a4e277c67f11502b3e078 100644 --- a/clang-tools-extra/clang-tidy/bugprone/MultiLevelImplicitPointerConversionCheck.cpp +++ b/clang-tools-extra/clang-tidy/bugprone/MultiLevelImplicitPointerConversionCheck.cpp @@ -48,12 +48,21 @@ AST_MATCHER(ImplicitCastExpr, isMultiLevelPointerConversion) { return SourcePtrLevel != TargetPtrLevel; } +AST_MATCHER(QualType, isPointerType) { + const QualType Type = + Node.getCanonicalType().getNonReferenceType().getUnqualifiedType(); + + return !Type.isNull() && Type->isPointerType(); +} + } // namespace void MultiLevelImplicitPointerConversionCheck::registerMatchers( MatchFinder *Finder) { Finder->addMatcher( - implicitCastExpr(hasCastKind(CK_BitCast), isMultiLevelPointerConversion()) + implicitCastExpr(hasCastKind(CK_BitCast), isMultiLevelPointerConversion(), + unless(hasParent(explicitCastExpr( + hasDestinationType(isPointerType()))))) .bind("expr"), this); } diff --git a/clang-tools-extra/clang-tidy/bugprone/SizeofExpressionCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/SizeofExpressionCheck.cpp index 5e64d23874ec17728f5401bbb4b7642099940efd..c25ee42d0899aeb0b7e83c9d8c756f69f4afacfe 100644 --- a/clang-tools-extra/clang-tidy/bugprone/SizeofExpressionCheck.cpp +++ b/clang-tools-extra/clang-tidy/bugprone/SizeofExpressionCheck.cpp @@ -67,7 +67,8 @@ SizeofExpressionCheck::SizeofExpressionCheck(StringRef Name, WarnOnSizeOfCompareToConstant( Options.get("WarnOnSizeOfCompareToConstant", true)), WarnOnSizeOfPointerToAggregate( - Options.get("WarnOnSizeOfPointerToAggregate", true)) {} + Options.get("WarnOnSizeOfPointerToAggregate", true)), + WarnOnSizeOfPointer(Options.get("WarnOnSizeOfPointer", false)) {} void SizeofExpressionCheck::storeOptions(ClangTidyOptions::OptionMap &Opts) { Options.store(Opts, "WarnOnSizeOfConstant", WarnOnSizeOfConstant); @@ -78,6 +79,7 @@ void SizeofExpressionCheck::storeOptions(ClangTidyOptions::OptionMap &Opts) { WarnOnSizeOfCompareToConstant); Options.store(Opts, "WarnOnSizeOfPointerToAggregate", WarnOnSizeOfPointerToAggregate); + Options.store(Opts, "WarnOnSizeOfPointer", WarnOnSizeOfPointer); } void SizeofExpressionCheck::registerMatchers(MatchFinder *Finder) { @@ -127,17 +129,30 @@ void SizeofExpressionCheck::registerMatchers(MatchFinder *Finder) { const auto ConstStrLiteralDecl = varDecl(isDefinition(), hasType(hasCanonicalType(CharPtrType)), hasInitializer(ignoringParenImpCasts(stringLiteral()))); + const auto VarWithConstStrLiteralDecl = expr( + hasType(hasCanonicalType(CharPtrType)), + ignoringParenImpCasts(declRefExpr(hasDeclaration(ConstStrLiteralDecl)))); Finder->addMatcher( - sizeOfExpr(has(ignoringParenImpCasts( - expr(hasType(hasCanonicalType(CharPtrType)), - ignoringParenImpCasts(declRefExpr( - hasDeclaration(ConstStrLiteralDecl))))))) + sizeOfExpr(has(ignoringParenImpCasts(VarWithConstStrLiteralDecl))) .bind("sizeof-charp"), this); - // Detect sizeof(ptr) where ptr points to an aggregate (i.e. sizeof(&S)). - // Do not find it if RHS of a 'sizeof(arr) / sizeof(arr[0])' expression. - if (WarnOnSizeOfPointerToAggregate) { + // Detect sizeof(ptr) where ptr is a pointer (CWE-467). + // + // In WarnOnSizeOfPointerToAggregate mode only report cases when ptr points + // to an aggregate type or ptr is an expression that (implicitly or + // explicitly) casts an array to a pointer type. (These are more suspicious + // than other sizeof(ptr) expressions because they can appear as distorted + // forms of the common sizeof(aggregate) expressions.) + // + // To avoid false positives, the check doesn't report expressions like + // 'sizeof(pp[0])' and 'sizeof(*pp)' where `pp` is a pointer-to-pointer or + // array of pointers. (This filters out both `sizeof(arr) / sizeof(arr[0])` + // expressions and other cases like `p = realloc(p, newsize * sizeof(*p));`.) + // + // Moreover this generic message is suppressed in cases that are also matched + // by the more concrete matchers 'sizeof-this' and 'sizeof-charp'. + if (WarnOnSizeOfPointerToAggregate || WarnOnSizeOfPointer) { const auto ArrayExpr = ignoringParenImpCasts(hasType(hasCanonicalType(arrayType()))); const auto ArrayCastExpr = expr(anyOf( @@ -149,32 +164,31 @@ void SizeofExpressionCheck::registerMatchers(MatchFinder *Finder) { const auto PointerToStructType = hasUnqualifiedDesugaredType(pointerType(pointee(recordType()))); - const auto PointerToStructExpr = expr( - hasType(hasCanonicalType(PointerToStructType)), unless(cxxThisExpr())); - - const auto ArrayOfPointersExpr = ignoringParenImpCasts( - hasType(hasCanonicalType(arrayType(hasElementType(pointerType())) - .bind("type-of-array-of-pointers")))); - const auto ArrayOfSamePointersExpr = - ignoringParenImpCasts(hasType(hasCanonicalType( - arrayType(equalsBoundNode("type-of-array-of-pointers"))))); + const auto PointerToStructTypeWithBinding = + type(PointerToStructType).bind("struct-type"); + const auto PointerToStructExpr = + expr(hasType(hasCanonicalType(PointerToStructType))); + + const auto PointerToDetectedExpr = + WarnOnSizeOfPointer + ? expr(hasType(hasUnqualifiedDesugaredType(pointerType()))) + : expr(anyOf(ArrayCastExpr, PointerToArrayExpr, + PointerToStructExpr)); + const auto ZeroLiteral = ignoringParenImpCasts(integerLiteral(equals(0))); - const auto ArrayOfSamePointersZeroSubscriptExpr = - ignoringParenImpCasts(arraySubscriptExpr( - hasBase(ArrayOfSamePointersExpr), hasIndex(ZeroLiteral))); - const auto ArrayLengthExprDenom = - expr(hasParent(binaryOperator(hasOperatorName("/"), - hasLHS(ignoringParenImpCasts(sizeOfExpr( - has(ArrayOfPointersExpr)))))), - sizeOfExpr(has(ArrayOfSamePointersZeroSubscriptExpr))); + const auto SubscriptExprWithZeroIndex = + arraySubscriptExpr(hasIndex(ZeroLiteral)); + const auto DerefExpr = + ignoringParenImpCasts(unaryOperator(hasOperatorName("*"))); Finder->addMatcher( - expr(sizeOfExpr(anyOf( - has(ignoringParenImpCasts(anyOf( - ArrayCastExpr, PointerToArrayExpr, PointerToStructExpr))), - has(PointerToStructType))), - unless(ArrayLengthExprDenom)) - .bind("sizeof-pointer-to-aggregate"), + expr(sizeOfExpr(anyOf(has(ignoringParenImpCasts( + expr(PointerToDetectedExpr, unless(DerefExpr), + unless(SubscriptExprWithZeroIndex), + unless(VarWithConstStrLiteralDecl), + unless(cxxThisExpr())))), + has(PointerToStructTypeWithBinding)))) + .bind("sizeof-pointer"), this); } @@ -292,11 +306,17 @@ void SizeofExpressionCheck::check(const MatchFinder::MatchResult &Result) { diag(E->getBeginLoc(), "suspicious usage of 'sizeof(char*)'; do you mean 'strlen'?") << E->getSourceRange(); - } else if (const auto *E = - Result.Nodes.getNodeAs("sizeof-pointer-to-aggregate")) { - diag(E->getBeginLoc(), - "suspicious usage of 'sizeof(A*)'; pointer to aggregate") - << E->getSourceRange(); + } else if (const auto *E = Result.Nodes.getNodeAs("sizeof-pointer")) { + if (Result.Nodes.getNodeAs("struct-type")) { + diag(E->getBeginLoc(), + "suspicious usage of 'sizeof(A*)' on pointer-to-aggregate type; did " + "you mean 'sizeof(A)'?") + << E->getSourceRange(); + } else { + diag(E->getBeginLoc(), "suspicious usage of 'sizeof()' on an expression " + "that results in a pointer") + << E->getSourceRange(); + } } else if (const auto *E = Result.Nodes.getNodeAs( "sizeof-compare-constant")) { diag(E->getOperatorLoc(), @@ -332,18 +352,23 @@ void SizeofExpressionCheck::check(const MatchFinder::MatchResult &Result) { " numerator is not a multiple of denominator") << E->getLHS()->getSourceRange() << E->getRHS()->getSourceRange(); } else if (NumTy && DenomTy && NumTy == DenomTy) { + // FIXME: This message is wrong, it should not refer to sizeof "pointer" + // usage (and by the way, it would be to clarify all the messages). diag(E->getOperatorLoc(), "suspicious usage of sizeof pointer 'sizeof(T)/sizeof(T)'") << E->getLHS()->getSourceRange() << E->getRHS()->getSourceRange(); - } else if (PointedTy && DenomTy && PointedTy == DenomTy) { - diag(E->getOperatorLoc(), - "suspicious usage of sizeof pointer 'sizeof(T*)/sizeof(T)'") - << E->getLHS()->getSourceRange() << E->getRHS()->getSourceRange(); - } else if (NumTy && DenomTy && NumTy->isPointerType() && - DenomTy->isPointerType()) { - diag(E->getOperatorLoc(), - "suspicious usage of sizeof pointer 'sizeof(P*)/sizeof(Q*)'") - << E->getLHS()->getSourceRange() << E->getRHS()->getSourceRange(); + } else if (!WarnOnSizeOfPointer) { + // When 'WarnOnSizeOfPointer' is enabled, these messages become redundant: + if (PointedTy && DenomTy && PointedTy == DenomTy) { + diag(E->getOperatorLoc(), + "suspicious usage of sizeof pointer 'sizeof(T*)/sizeof(T)'") + << E->getLHS()->getSourceRange() << E->getRHS()->getSourceRange(); + } else if (NumTy && DenomTy && NumTy->isPointerType() && + DenomTy->isPointerType()) { + diag(E->getOperatorLoc(), + "suspicious usage of sizeof pointer 'sizeof(P*)/sizeof(Q*)'") + << E->getLHS()->getSourceRange() << E->getRHS()->getSourceRange(); + } } } else if (const auto *E = Result.Nodes.getNodeAs("sizeof-sizeof-expr")) { diff --git a/clang-tools-extra/clang-tidy/bugprone/SizeofExpressionCheck.h b/clang-tools-extra/clang-tidy/bugprone/SizeofExpressionCheck.h index 55becdd4ecdba11f48a7f184da093a6351c2bedf..9ca17bc9e6f124def1bbb64d69c573dfbfcdacde 100644 --- a/clang-tools-extra/clang-tidy/bugprone/SizeofExpressionCheck.h +++ b/clang-tools-extra/clang-tidy/bugprone/SizeofExpressionCheck.h @@ -30,6 +30,7 @@ private: const bool WarnOnSizeOfThis; const bool WarnOnSizeOfCompareToConstant; const bool WarnOnSizeOfPointerToAggregate; + const bool WarnOnSizeOfPointer; }; } // namespace clang::tidy::bugprone diff --git a/clang-tools-extra/clang-tidy/misc/CMakeLists.txt b/clang-tools-extra/clang-tidy/misc/CMakeLists.txt index 35e29b9a7d13670f2feb130aef1ef5cdef8d1119..1c1d3b836ea1b8cc96683ad9e9e47aeb280dbfef 100644 --- a/clang-tools-extra/clang-tidy/misc/CMakeLists.txt +++ b/clang-tools-extra/clang-tidy/misc/CMakeLists.txt @@ -41,9 +41,9 @@ add_clang_library(clangTidyMiscModule UnusedParametersCheck.cpp UnusedUsingDeclsCheck.cpp UseAnonymousNamespaceCheck.cpp + UseInternalLinkageCheck.cpp LINK_LIBS - clangAnalysis clangTidy clangTidyUtils diff --git a/clang-tools-extra/clang-tidy/misc/HeaderIncludeCycleCheck.cpp b/clang-tools-extra/clang-tidy/misc/HeaderIncludeCycleCheck.cpp index fadfdc869d37b05403aa190b2577e1d4411e089d..cdb5e6b16069b7fe6b3e4fe56fbf09e8061d975c 100644 --- a/clang-tools-extra/clang-tidy/misc/HeaderIncludeCycleCheck.cpp +++ b/clang-tools-extra/clang-tidy/misc/HeaderIncludeCycleCheck.cpp @@ -130,18 +130,15 @@ public: << FileName; const bool IsIncludePathValid = - std::all_of(Files.rbegin(), It, [](const Include &Elem) { + std::all_of(Files.rbegin(), It + 1, [](const Include &Elem) { return !Elem.Name.empty() && Elem.Loc.isValid(); }); - if (!IsIncludePathValid) return; - auto CurrentIt = Files.rbegin(); - do { - Check.diag(CurrentIt->Loc, "'%0' included from here", DiagnosticIDs::Note) - << CurrentIt->Name; - } while (CurrentIt++ != It); + for (const Include &I : llvm::make_range(Files.rbegin(), It + 1)) + Check.diag(I.Loc, "'%0' included from here", DiagnosticIDs::Note) + << I.Name; } bool isFileIgnored(StringRef FileName) const { diff --git a/clang-tools-extra/clang-tidy/misc/MiscTidyModule.cpp b/clang-tools-extra/clang-tidy/misc/MiscTidyModule.cpp index d8a88324ee63e08b66bd84c3d71ecd9892283450..54bcebca7e186689bf0a0be910785f7250b4f059 100644 --- a/clang-tools-extra/clang-tidy/misc/MiscTidyModule.cpp +++ b/clang-tools-extra/clang-tidy/misc/MiscTidyModule.cpp @@ -31,6 +31,7 @@ #include "UnusedParametersCheck.h" #include "UnusedUsingDeclsCheck.h" #include "UseAnonymousNamespaceCheck.h" +#include "UseInternalLinkageCheck.h" namespace clang::tidy { namespace misc { @@ -78,6 +79,8 @@ public: "misc-unused-using-decls"); CheckFactories.registerCheck( "misc-use-anonymous-namespace"); + CheckFactories.registerCheck( + "misc-use-internal-linkage"); } }; diff --git a/clang-tools-extra/clang-tidy/misc/UseInternalLinkageCheck.cpp b/clang-tools-extra/clang-tidy/misc/UseInternalLinkageCheck.cpp new file mode 100644 index 0000000000000000000000000000000000000000..70d0281df28fad816c7ec08205004f7a7e83d592 --- /dev/null +++ b/clang-tools-extra/clang-tidy/misc/UseInternalLinkageCheck.cpp @@ -0,0 +1,95 @@ +//===--- UseInternalLinkageCheck.cpp - clang-tidy--------------------------===// +// +// 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 "UseInternalLinkageCheck.h" +#include "../utils/FileExtensionsUtils.h" +#include "clang/AST/Decl.h" +#include "clang/ASTMatchers/ASTMatchFinder.h" +#include "clang/ASTMatchers/ASTMatchers.h" +#include "clang/ASTMatchers/ASTMatchersMacros.h" +#include "clang/Basic/SourceLocation.h" +#include "clang/Basic/Specifiers.h" +#include "llvm/ADT/STLExtras.h" + +using namespace clang::ast_matchers; + +namespace clang::tidy::misc { + +namespace { + +AST_MATCHER(Decl, isFirstDecl) { return Node.isFirstDecl(); } + +static bool isInMainFile(SourceLocation L, SourceManager &SM, + const FileExtensionsSet &HeaderFileExtensions) { + for (;;) { + if (utils::isSpellingLocInHeaderFile(L, SM, HeaderFileExtensions)) + return false; + if (SM.isInMainFile(L)) + return true; + // not in header file but not in main file + L = SM.getIncludeLoc(SM.getFileID(L)); + if (L.isValid()) + continue; + // Conservative about the unknown + return false; + } +} + +AST_MATCHER_P(Decl, isAllRedeclsInMainFile, FileExtensionsSet, + HeaderFileExtensions) { + return llvm::all_of(Node.redecls(), [&](const Decl *D) { + return isInMainFile(D->getLocation(), + Finder->getASTContext().getSourceManager(), + HeaderFileExtensions); + }); +} + +AST_POLYMORPHIC_MATCHER(isExternStorageClass, + AST_POLYMORPHIC_SUPPORTED_TYPES(FunctionDecl, + VarDecl)) { + return Node.getStorageClass() == SC_Extern; +} + +} // namespace + +void UseInternalLinkageCheck::registerMatchers(MatchFinder *Finder) { + auto Common = + allOf(isFirstDecl(), isAllRedeclsInMainFile(HeaderFileExtensions), + unless(anyOf( + // 1. internal linkage + isStaticStorageClass(), isInAnonymousNamespace(), + // 2. explicit external linkage + isExternStorageClass(), isExternC(), + // 3. template + isExplicitTemplateSpecialization(), + // 4. friend + hasAncestor(friendDecl())))); + Finder->addMatcher( + functionDecl(Common, unless(cxxMethodDecl()), unless(isMain())) + .bind("fn"), + this); + Finder->addMatcher(varDecl(Common, hasGlobalStorage()).bind("var"), this); +} + +static constexpr StringRef Message = + "%0 %1 can be made static or moved into an anonymous namespace " + "to enforce internal linkage"; + +void UseInternalLinkageCheck::check(const MatchFinder::MatchResult &Result) { + if (const auto *FD = Result.Nodes.getNodeAs("fn")) { + diag(FD->getLocation(), Message) << "function" << FD; + return; + } + if (const auto *VD = Result.Nodes.getNodeAs("var")) { + diag(VD->getLocation(), Message) << "variable" << VD; + return; + } + llvm_unreachable(""); +} + +} // namespace clang::tidy::misc diff --git a/clang-tools-extra/clang-tidy/misc/UseInternalLinkageCheck.h b/clang-tools-extra/clang-tidy/misc/UseInternalLinkageCheck.h new file mode 100644 index 0000000000000000000000000000000000000000..a3c1c33965903611bbb293ac1fa485a3dfbdd079 --- /dev/null +++ b/clang-tools-extra/clang-tidy/misc/UseInternalLinkageCheck.h @@ -0,0 +1,38 @@ +//===--- UseInternalLinkageCheck.h - clang-tidy -----------------*- 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_TOOLS_EXTRA_CLANG_TIDY_MISC_USEINTERNALLINKAGECHECK_H +#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MISC_USEINTERNALLINKAGECHECK_H + +#include "../ClangTidyCheck.h" + +namespace clang::tidy::misc { + +/// Detects variables and functions that can be marked as static or moved into +/// an anonymous namespace to enforce internal linkage. +/// +/// For the user-facing documentation see: +/// http://clang.llvm.org/extra/clang-tidy/checks/misc/use-internal-linkage.html +class UseInternalLinkageCheck : public ClangTidyCheck { +public: + UseInternalLinkageCheck(StringRef Name, ClangTidyContext *Context) + : ClangTidyCheck(Name, Context), + HeaderFileExtensions(Context->getHeaderFileExtensions()) {} + void registerMatchers(ast_matchers::MatchFinder *Finder) override; + void check(const ast_matchers::MatchFinder::MatchResult &Result) override; + std::optional getCheckTraversalKind() const override { + return TK_IgnoreUnlessSpelledInSource; + } + +private: + FileExtensionsSet HeaderFileExtensions; +}; + +} // namespace clang::tidy::misc + +#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MISC_USEINTERNALLINKAGECHECK_H diff --git a/clang-tools-extra/clang-tidy/modernize/UseDesignatedInitializersCheck.cpp b/clang-tools-extra/clang-tidy/modernize/UseDesignatedInitializersCheck.cpp index ebc5338d0a7bfac8d03f4867adebbfc4e29f8d63..2a0cc403b726e8d4050ff63dfab3a00e15839fb5 100644 --- a/clang-tools-extra/clang-tidy/modernize/UseDesignatedInitializersCheck.cpp +++ b/clang-tools-extra/clang-tidy/modernize/UseDesignatedInitializersCheck.cpp @@ -32,6 +32,14 @@ static constexpr bool RestrictToPODTypesDefault = false; static constexpr char IgnoreMacrosName[] = "IgnoreMacros"; static constexpr bool IgnoreMacrosDefault = true; +static constexpr char StrictCStandardComplianceName[] = + "StrictCStandardCompliance"; +static constexpr bool StrictCStandardComplianceDefault = true; + +static constexpr char StrictCppStandardComplianceName[] = + "StrictCppStandardCompliance"; +static constexpr bool StrictCppStandardComplianceDefault = true; + namespace { struct Designators { @@ -97,7 +105,12 @@ UseDesignatedInitializersCheck::UseDesignatedInitializersCheck( RestrictToPODTypes( Options.get(RestrictToPODTypesName, RestrictToPODTypesDefault)), IgnoreMacros( - Options.getLocalOrGlobal(IgnoreMacrosName, IgnoreMacrosDefault)) {} + Options.getLocalOrGlobal(IgnoreMacrosName, IgnoreMacrosDefault)), + StrictCStandardCompliance(Options.get(StrictCStandardComplianceName, + StrictCStandardComplianceDefault)), + StrictCppStandardCompliance( + Options.get(StrictCppStandardComplianceName, + StrictCppStandardComplianceDefault)) {} void UseDesignatedInitializersCheck::registerMatchers(MatchFinder *Finder) { const auto HasBaseWithFields = @@ -179,6 +192,9 @@ void UseDesignatedInitializersCheck::storeOptions( IgnoreSingleElementAggregates); Options.store(Opts, RestrictToPODTypesName, RestrictToPODTypes); Options.store(Opts, IgnoreMacrosName, IgnoreMacros); + Options.store(Opts, StrictCStandardComplianceName, StrictCStandardCompliance); + Options.store(Opts, StrictCppStandardComplianceName, + StrictCppStandardCompliance); } } // namespace clang::tidy::modernize diff --git a/clang-tools-extra/clang-tidy/modernize/UseDesignatedInitializersCheck.h b/clang-tools-extra/clang-tidy/modernize/UseDesignatedInitializersCheck.h index 0a496f51b95762037634c764393c85f3d5841bbd..79095ade5037173e2810acf2559f4e5f641bdf8c 100644 --- a/clang-tools-extra/clang-tidy/modernize/UseDesignatedInitializersCheck.h +++ b/clang-tools-extra/clang-tidy/modernize/UseDesignatedInitializersCheck.h @@ -29,10 +29,19 @@ public: return TK_IgnoreUnlessSpelledInSource; } + bool isLanguageVersionSupported(const LangOptions &LangOpts) const override { + return LangOpts.CPlusPlus20 || LangOpts.C99 || + (LangOpts.CPlusPlus && !StrictCppStandardCompliance) || + (!LangOpts.CPlusPlus && !LangOpts.ObjC && + !StrictCStandardCompliance); + } + private: bool IgnoreSingleElementAggregates; bool RestrictToPODTypes; bool IgnoreMacros; + bool StrictCStandardCompliance; + bool StrictCppStandardCompliance; }; } // namespace clang::tidy::modernize diff --git a/clang-tools-extra/clang-tidy/performance/UnnecessaryCopyInitialization.cpp b/clang-tools-extra/clang-tidy/performance/UnnecessaryCopyInitialization.cpp index 9beb185cba929decf438eb430f7f773f6fdb9c32..61240fa4b0eb8e32aba4170793439b41ca0c3291 100644 --- a/clang-tools-extra/clang-tidy/performance/UnnecessaryCopyInitialization.cpp +++ b/clang-tools-extra/clang-tidy/performance/UnnecessaryCopyInitialization.cpp @@ -75,16 +75,16 @@ void recordRemoval(const DeclStmt &Stmt, ASTContext &Context, } } -AST_MATCHER_FUNCTION_P(StatementMatcher, isConstRefReturningMethodCall, +AST_MATCHER_FUNCTION_P(StatementMatcher, + isRefReturningMethodCallWithConstOverloads, std::vector, ExcludedContainerTypes) { // Match method call expressions where the `this` argument is only used as - // const, this will be checked in `check()` part. This returned const - // reference is highly likely to outlive the local const reference of the - // variable being declared. The assumption is that the const reference being - // returned either points to a global static variable or to a member of the - // called object. + // const, this will be checked in `check()` part. This returned reference is + // highly likely to outlive the local const reference of the variable being + // declared. The assumption is that the reference being returned either points + // to a global static variable or to a member of the called object. const auto MethodDecl = - cxxMethodDecl(returns(hasCanonicalType(matchers::isReferenceToConst()))) + cxxMethodDecl(returns(hasCanonicalType(referenceType()))) .bind(MethodDeclId); const auto ReceiverExpr = ignoringParenImpCasts(declRefExpr(to(varDecl().bind(ObjectArgId)))); @@ -121,7 +121,7 @@ AST_MATCHER_FUNCTION_P(StatementMatcher, initializerReturnsReferenceToConst, declRefExpr(to(varDecl(hasLocalStorage()).bind(OldVarDeclId))); return expr( anyOf(isConstRefReturningFunctionCall(), - isConstRefReturningMethodCall(ExcludedContainerTypes), + isRefReturningMethodCallWithConstOverloads(ExcludedContainerTypes), ignoringImpCasts(OldVarDeclRef), ignoringImpCasts(unaryOperator(hasOperatorName("&"), hasUnaryOperand(OldVarDeclRef))))); @@ -259,10 +259,11 @@ void UnnecessaryCopyInitialization::registerMatchers(MatchFinder *Finder) { .bind("blockStmt"); }; - Finder->addMatcher(LocalVarCopiedFrom(anyOf(isConstRefReturningFunctionCall(), - isConstRefReturningMethodCall( - ExcludedContainerTypes))), - this); + Finder->addMatcher( + LocalVarCopiedFrom(anyOf( + isConstRefReturningFunctionCall(), + isRefReturningMethodCallWithConstOverloads(ExcludedContainerTypes))), + this); Finder->addMatcher(LocalVarCopiedFrom(declRefExpr( to(varDecl(hasLocalStorage()).bind(OldVarDeclId)))), diff --git a/clang-tools-extra/clang-tidy/readability/ContainerSizeEmptyCheck.cpp b/clang-tools-extra/clang-tidy/readability/ContainerSizeEmptyCheck.cpp index bbc1b47b97ae6143c01cf5bd9afce7a18e3fc008..bf7a847dff103cd97679039d3121a07a14560b72 100644 --- a/clang-tools-extra/clang-tidy/readability/ContainerSizeEmptyCheck.cpp +++ b/clang-tools-extra/clang-tidy/readability/ContainerSizeEmptyCheck.cpp @@ -96,9 +96,14 @@ AST_MATCHER(QualType, isIntegralType) { AST_MATCHER_P(UserDefinedLiteral, hasLiteral, clang::ast_matchers::internal::Matcher, InnerMatcher) { - if (const Expr *CookedLiteral = Node.getCookedLiteral()) { + const UserDefinedLiteral::LiteralOperatorKind LOK = + Node.getLiteralOperatorKind(); + if (LOK == UserDefinedLiteral::LOK_Template || + LOK == UserDefinedLiteral::LOK_Raw) + return false; + + if (const Expr *CookedLiteral = Node.getCookedLiteral()) return InnerMatcher.matches(*CookedLiteral, Finder, Builder); - } return false; } diff --git a/clang-tools-extra/clang-tidy/readability/ImplicitBoolConversionCheck.cpp b/clang-tools-extra/clang-tidy/readability/ImplicitBoolConversionCheck.cpp index 28f5eada6d825af19876a096d90f6ee95181d6aa..aa115cd450c4f619f1035e601e83a2910d295c67 100644 --- a/clang-tools-extra/clang-tidy/readability/ImplicitBoolConversionCheck.cpp +++ b/clang-tools-extra/clang-tidy/readability/ImplicitBoolConversionCheck.cpp @@ -279,6 +279,9 @@ void ImplicitBoolConversionCheck::registerMatchers(MatchFinder *Finder) { hasParent(callExpr()), hasSourceExpression(binaryOperator(hasAnyOperatorName("==", "!=")))); + auto IsInCompilerGeneratedFunction = hasAncestor(namedDecl(anyOf( + isImplicit(), functionDecl(isDefaulted()), functionTemplateDecl()))); + Finder->addMatcher( traverse(TK_AsIs, implicitCastExpr( @@ -299,7 +302,7 @@ void ImplicitBoolConversionCheck::registerMatchers(MatchFinder *Finder) { // additional parens in replacement. optionally(hasParent(stmt().bind("parentStmt"))), unless(isInTemplateInstantiation()), - unless(hasAncestor(functionTemplateDecl()))) + unless(IsInCompilerGeneratedFunction)) .bind("implicitCastToBool")), this); @@ -331,7 +334,7 @@ void ImplicitBoolConversionCheck::registerMatchers(MatchFinder *Finder) { anyOf(hasParent(implicitCastExpr().bind("furtherImplicitCast")), anything()), unless(isInTemplateInstantiation()), - unless(hasAncestor(functionTemplateDecl())))), + unless(IsInCompilerGeneratedFunction))), this); } diff --git a/clang-tools-extra/clang-tidy/readability/MathMissingParenthesesCheck.cpp b/clang-tools-extra/clang-tidy/readability/MathMissingParenthesesCheck.cpp index 65fd296094915bbddf4e114e3ee96f8d5efb5f50..64ce94e3fc1db60f4f13fdab79ec41ecd2acd9fe 100644 --- a/clang-tools-extra/clang-tidy/readability/MathMissingParenthesesCheck.cpp +++ b/clang-tools-extra/clang-tidy/readability/MathMissingParenthesesCheck.cpp @@ -57,7 +57,8 @@ static void addParantheses(const BinaryOperator *BinOp, int Precedence1 = getPrecedence(BinOp); int Precedence2 = getPrecedence(ParentBinOp); - if (ParentBinOp != nullptr && Precedence1 != Precedence2) { + if (ParentBinOp != nullptr && Precedence1 != Precedence2 && Precedence1 > 0 && + Precedence2 > 0) { const clang::SourceLocation StartLoc = BinOp->getBeginLoc(); const clang::SourceLocation EndLoc = clang::Lexer::getLocForEndOfToken(BinOp->getEndLoc(), 0, SM, LangOpts); diff --git a/clang-tools-extra/clang-tidy/readability/RedundantMemberInitCheck.cpp b/clang-tools-extra/clang-tidy/readability/RedundantMemberInitCheck.cpp index 015347ee9294ce50751bcaf2bccd247529904bb7..601ff44cdd10a52e94ab31830024d0e772259c62 100644 --- a/clang-tools-extra/clang-tidy/readability/RedundantMemberInitCheck.cpp +++ b/clang-tools-extra/clang-tidy/readability/RedundantMemberInitCheck.cpp @@ -41,25 +41,35 @@ void RedundantMemberInitCheck::storeOptions(ClangTidyOptions::OptionMap &Opts) { void RedundantMemberInitCheck::registerMatchers(MatchFinder *Finder) { auto ConstructorMatcher = - cxxConstructExpr(argumentCountIs(0), - hasDeclaration(cxxConstructorDecl(ofClass(cxxRecordDecl( - unless(isTriviallyDefaultConstructible())))))) + cxxConstructExpr( + argumentCountIs(0), + hasDeclaration(cxxConstructorDecl( + ofClass(cxxRecordDecl(unless(isTriviallyDefaultConstructible())) + .bind("class"))))) .bind("construct"); + auto HasUnionAsParent = hasParent(recordDecl(isUnion())); + + auto HasTypeEqualToConstructorClass = hasType(qualType( + hasCanonicalType(qualType(hasDeclaration(equalsBoundNode("class")))))); + Finder->addMatcher( cxxConstructorDecl( unless(isDelegatingConstructor()), ofClass(unless(isUnion())), forEachConstructorInitializer( - cxxCtorInitializer(withInitializer(ConstructorMatcher), - unless(forField(fieldDecl( - anyOf(hasType(isConstQualified()), - hasParent(recordDecl(isUnion()))))))) + cxxCtorInitializer( + withInitializer(ConstructorMatcher), + anyOf(isBaseInitializer(), + forField(fieldDecl(unless(hasType(isConstQualified())), + unless(HasUnionAsParent), + HasTypeEqualToConstructorClass)))) .bind("init"))) .bind("constructor"), this); Finder->addMatcher(fieldDecl(hasInClassInitializer(ConstructorMatcher), - unless(hasParent(recordDecl(isUnion())))) + HasTypeEqualToConstructorClass, + unless(HasUnionAsParent)) .bind("field"), this); } diff --git a/clang-tools-extra/clang-tidy/tool/clang-tidy-diff.py b/clang-tools-extra/clang-tidy/tool/clang-tidy-diff.py index d96b3450fdbe810db853dea0da09eac18682c4c0..b048460abf2fca814ae4983394adceafc26394a6 100755 --- a/clang-tools-extra/clang-tidy/tool/clang-tidy-diff.py +++ b/clang-tools-extra/clang-tidy/tool/clang-tidy-diff.py @@ -242,7 +242,7 @@ def main(): filename = None lines_by_file = {} for line in sys.stdin: - match = re.search('^\+\+\+\ "?(.*?/){%s}([^ \t\n"]*)' % args.p, line) + match = re.search('^\\+\\+\\+\\ "?(.*?/){%s}([^ \t\n"]*)' % args.p, line) if match: filename = match.group(2) if filename is None: @@ -255,7 +255,7 @@ def main(): if not re.match("^%s$" % args.iregex, filename, re.IGNORECASE): continue - match = re.search("^@@.*\+(\d+)(,(\d+))?", line) + match = re.search(r"^@@.*\+(\d+)(,(\d+))?", line) if match: start_line = int(match.group(1)) line_count = 1 diff --git a/clang-tools-extra/clang-tidy/utils/DeclRefExprUtils.cpp b/clang-tools-extra/clang-tidy/utils/DeclRefExprUtils.cpp index a48e45e13568134d44a5a080757c5838407823a6..a6062ccf42230bf304c19621249b95448248a63f 100644 --- a/clang-tools-extra/clang-tidy/utils/DeclRefExprUtils.cpp +++ b/clang-tools-extra/clang-tidy/utils/DeclRefExprUtils.cpp @@ -36,6 +36,116 @@ void extractNodesByIdTo(ArrayRef Matches, StringRef ID, Nodes.insert(Match.getNodeAs(ID)); } +// Returns true if both types refer to the same type, +// ignoring the const-qualifier. +bool isSameTypeIgnoringConst(QualType A, QualType B) { + A = A.getCanonicalType(); + B = B.getCanonicalType(); + A.addConst(); + B.addConst(); + return A == B; +} + +// Returns true if `D` and `O` have the same parameter types. +bool hasSameParameterTypes(const CXXMethodDecl &D, const CXXMethodDecl &O) { + if (D.getNumParams() != O.getNumParams()) + return false; + for (int I = 0, E = D.getNumParams(); I < E; ++I) { + if (!isSameTypeIgnoringConst(D.getParamDecl(I)->getType(), + O.getParamDecl(I)->getType())) + return false; + } + return true; +} + +// If `D` has a const-qualified overload with otherwise identical +// ref-qualifiers and parameter types, returns that overload. +const CXXMethodDecl *findConstOverload(const CXXMethodDecl &D) { + assert(!D.isConst()); + + DeclContext::lookup_result LookupResult = + D.getParent()->lookup(D.getNameInfo().getName()); + if (LookupResult.isSingleResult()) { + // No overload. + return nullptr; + } + for (const Decl *Overload : LookupResult) { + const auto *O = dyn_cast(Overload); + if (O && !O->isDeleted() && O->isConst() && + O->getRefQualifier() == D.getRefQualifier() && + hasSameParameterTypes(D, *O)) + return O; + } + return nullptr; +} + +// Returns true if both types are pointers or reference to the same type, +// ignoring the const-qualifier. +bool pointsToSameTypeIgnoringConst(QualType A, QualType B) { + assert(A->isPointerType() || A->isReferenceType()); + assert(B->isPointerType() || B->isReferenceType()); + return isSameTypeIgnoringConst(A->getPointeeType(), B->getPointeeType()); +} + +// Return true if non-const member function `M` likely does not mutate `*this`. +// +// Note that if the member call selects a method/operator `f` that +// is not const-qualified, then we also consider that the object is +// not mutated if: +// - (A) there is a const-qualified overload `cf` of `f` that has +// the +// same ref-qualifiers; +// - (B) * `f` returns a value, or +// * if `f` returns a `T&`, `cf` returns a `const T&` (up to +// possible aliases such as `reference` and +// `const_reference`), or +// * if `f` returns a `T*`, `cf` returns a `const T*` (up to +// possible aliases). +// - (C) the result of the call is not mutated. +// +// The assumption that `cf` has the same semantics as `f`. +// For example: +// - In `std::vector v; const T t = v[...];`, we consider that +// expression `v[...]` does not mutate `v` as +// `T& std::vector::operator[]` has a const overload +// `const T& std::vector::operator[] const`, and the +// result expression of type `T&` is only used as a `const T&`; +// - In `std::map m; V v = m.at(...);`, we consider +// `m.at(...)` to be an immutable access for the same reason. +// However: +// - In `std::map m; const V v = m[...];`, We consider that +// `m[...]` mutates `m` as `V& std::map::operator[]` does +// not have a const overload. +// - In `std::vector v; T& t = v[...];`, we consider that +// expression `v[...]` mutates `v` as the result is kept as a +// mutable reference. +// +// This function checks (A) ad (B), but the caller should make sure that the +// object is not mutated through the return value. +bool isLikelyShallowConst(const CXXMethodDecl &M) { + assert(!M.isConst()); + // The method can mutate our variable. + + // (A) + const CXXMethodDecl *ConstOverload = findConstOverload(M); + if (ConstOverload == nullptr) { + return false; + } + + // (B) + const QualType CallTy = M.getReturnType().getCanonicalType(); + const QualType OverloadTy = ConstOverload->getReturnType().getCanonicalType(); + if (CallTy->isReferenceType()) { + return OverloadTy->isReferenceType() && + pointsToSameTypeIgnoringConst(CallTy, OverloadTy); + } + if (CallTy->isPointerType()) { + return OverloadTy->isPointerType() && + pointsToSameTypeIgnoringConst(CallTy, OverloadTy); + } + return isSameTypeIgnoringConst(CallTy, OverloadTy); +} + // A matcher that matches DeclRefExprs that are used in ways such that the // underlying declaration is not modified. // If the declaration is of pointer type, `Indirections` specifies the level @@ -54,16 +164,15 @@ void extractNodesByIdTo(ArrayRef Matches, StringRef ID, // matches (A). // AST_MATCHER_P(DeclRefExpr, doesNotMutateObject, int, Indirections) { - // We walk up the parents of the DeclRefExpr recursively until we end up on a - // parent that cannot modify the underlying object. There are a few kinds of - // expressions: - // - Those that cannot be used to mutate the underlying object. We can stop + // We walk up the parents of the DeclRefExpr recursively. There are a few + // kinds of expressions: + // - Those that cannot be used to mutate the underlying variable. We can stop // recursion there. - // - Those that can be used to mutate the underlying object in analyzable + // - Those that can be used to mutate the underlying variable in analyzable // ways (such as taking the address or accessing a subobject). We have to // examine the parents. // - Those that we don't know how to analyze. In that case we stop there and - // we assume that they can mutate the underlying expression. + // we assume that they can modify the expression. struct StackEntry { StackEntry(const Expr *E, int Indirections) @@ -90,7 +199,7 @@ AST_MATCHER_P(DeclRefExpr, doesNotMutateObject, int, Indirections) { assert(Ty->isPointerType()); Ty = Ty->getPointeeType().getCanonicalType(); } - if (Ty.isConstQualified()) + if (Ty->isVoidType() || Ty.isConstQualified()) continue; // Otherwise we have to look at the parents to see how the expression is @@ -159,11 +268,56 @@ AST_MATCHER_P(DeclRefExpr, doesNotMutateObject, int, Indirections) { // The method call cannot mutate our variable. continue; } + if (isLikelyShallowConst(*Method)) { + // We still have to check that the object is not modified through + // the method's return value (C). + const auto MemberParents = Ctx.getParents(*Member); + assert(MemberParents.size() == 1); + const auto *Call = MemberParents[0].get(); + // If `o` is an object of class type and `f` is a member function, + // then `o.f` has to be used as part of a call expression. + assert(Call != nullptr && "member function has to be called"); + Stack.emplace_back( + Call, + Method->getReturnType().getCanonicalType()->isPointerType() + ? 1 + : 0); + continue; + } return false; } Stack.emplace_back(Member, 0); continue; } + if (const auto *const OpCall = dyn_cast(P)) { + // Operator calls have function call syntax. The `*this` parameter + // is the first parameter. + if (OpCall->getNumArgs() == 0 || OpCall->getArg(0) != Entry.E) { + return false; + } + const auto *const Method = + dyn_cast(OpCall->getDirectCallee()); + + if (Method == nullptr) { + // This is not a member operator. Typically, a friend operator. These + // are handled like function calls. + return false; + } + + if (Method->isConst() || Method->isStatic()) { + continue; + } + if (isLikelyShallowConst(*Method)) { + // We still have to check that the object is not modified through + // the operator's return value (C). + Stack.emplace_back( + OpCall, + Method->getReturnType().getCanonicalType()->isPointerType() ? 1 + : 0); + continue; + } + return false; + } if (const auto *const Op = dyn_cast(P)) { switch (Op->getOpcode()) { diff --git a/clang-tools-extra/clangd/FindSymbols.cpp b/clang-tools-extra/clangd/FindSymbols.cpp index 5244a4e893769ed373e310ff1795ecf4419df7e1..55f16b7085a6fec6508ea23bcb6c6220c14f0b61 100644 --- a/clang-tools-extra/clangd/FindSymbols.cpp +++ b/clang-tools-extra/clangd/FindSymbols.cpp @@ -454,7 +454,7 @@ private: if (!MacroName.isValid() || !MacroName.isFileID()) continue; // All conditions satisfied, add the macro. - if (auto *Tok = AST.getTokens().spelledTokenAt(MacroName)) + if (auto *Tok = AST.getTokens().spelledTokenContaining(MacroName)) CurParent = &CurParent->inMacro( *Tok, SM, AST.getTokens().expansionStartingAt(Tok)); } diff --git a/clang-tools-extra/clangd/IncludeCleaner.cpp b/clang-tools-extra/clangd/IncludeCleaner.cpp index 01b47679790f1d52633b8bb8b49aeca13147a060..dc5b7ec95db5ff1617bf1d4502df5563b060e637 100644 --- a/clang-tools-extra/clangd/IncludeCleaner.cpp +++ b/clang-tools-extra/clangd/IncludeCleaner.cpp @@ -303,7 +303,7 @@ collectMacroReferences(ParsedAST &AST) { for (const auto &[_, Refs] : AST.getMacros().MacroRefs) { for (const auto &Ref : Refs) { auto Loc = SM.getComposedLoc(SM.getMainFileID(), Ref.StartOffset); - const auto *Tok = AST.getTokens().spelledTokenAt(Loc); + const auto *Tok = AST.getTokens().spelledTokenContaining(Loc); if (!Tok) continue; auto Macro = locateMacroAt(*Tok, PP); diff --git a/clang-tools-extra/clangd/SemanticHighlighting.cpp b/clang-tools-extra/clangd/SemanticHighlighting.cpp index eb025f21f3616126ee7e0a22d0019f95bdae0073..a366f1331c2d3d999982eb38b0bf7a9e3dffccb8 100644 --- a/clang-tools-extra/clangd/SemanticHighlighting.cpp +++ b/clang-tools-extra/clangd/SemanticHighlighting.cpp @@ -447,11 +447,10 @@ public: if (!RLoc.isValid()) return; - const auto *RTok = TB.spelledTokenAt(RLoc); - // Handle `>>`. RLoc is always pointing at the right location, just change - // the end to be offset by 1. - // We'll either point at the beginning of `>>`, hence get a proper spelled - // or point in the middle of `>>` hence get no spelled tok. + const auto *RTok = TB.spelledTokenContaining(RLoc); + // Handle `>>`. RLoc is either part of `>>` or a spelled token on its own + // `>`. If it's the former, slice to have length of 1, if latter use the + // token as-is. if (!RTok || RTok->kind() == tok::greatergreater) { Position Begin = sourceLocToPosition(SourceMgr, RLoc); Position End = sourceLocToPosition(SourceMgr, RLoc.getLocWithOffset(1)); @@ -577,7 +576,7 @@ private: return std::nullopt; // We might have offsets in the main file that don't correspond to any // spelled tokens. - const auto *Tok = TB.spelledTokenAt(Loc); + const auto *Tok = TB.spelledTokenContaining(Loc); if (!Tok) return std::nullopt; return halfOpenToRange(SourceMgr, diff --git a/clang-tools-extra/clangd/XRefs.cpp b/clang-tools-extra/clangd/XRefs.cpp index cd909266489a850b54322ca21edd191a3519c3a5..f94cadeffaa298ab4bd5d6a583d604913dc34116 100644 --- a/clang-tools-extra/clangd/XRefs.cpp +++ b/clang-tools-extra/clangd/XRefs.cpp @@ -844,7 +844,7 @@ std::vector getDocumentLinks(ParsedAST &AST) { if (Inc.Resolved.empty()) continue; auto HashLoc = SM.getComposedLoc(SM.getMainFileID(), Inc.HashOffset); - const auto *HashTok = AST.getTokens().spelledTokenAt(HashLoc); + const auto *HashTok = AST.getTokens().spelledTokenContaining(HashLoc); assert(HashTok && "got inclusion at wrong offset"); const auto *IncludeTok = std::next(HashTok); const auto *FileTok = std::next(IncludeTok); @@ -938,7 +938,7 @@ public: CollectorOpts.CollectMainFileSymbols = true; for (SourceLocation L : Locs) { L = SM.getFileLoc(L); - if (const auto *Tok = TB.spelledTokenAt(L)) + if (const auto *Tok = TB.spelledTokenContaining(L)) References.push_back( {*Tok, Roles, SymbolCollector::getRefContainer(ASTNode.Parent, CollectorOpts)}); @@ -1216,7 +1216,7 @@ DocumentHighlight toHighlight(const ReferenceFinder::Reference &Ref, std::optional toHighlight(SourceLocation Loc, const syntax::TokenBuffer &TB) { Loc = TB.sourceManager().getFileLoc(Loc); - if (const auto *Tok = TB.spelledTokenAt(Loc)) { + if (const auto *Tok = TB.spelledTokenContaining(Loc)) { DocumentHighlight Result; Result.range = halfOpenToRange( TB.sourceManager(), @@ -1353,7 +1353,8 @@ maybeFindIncludeReferences(ParsedAST &AST, Position Pos, Loc = SM.getIncludeLoc(SM.getFileID(Loc)); ReferencesResult::Reference Result; - const auto *Token = AST.getTokens().spelledTokenAt(Loc); + const auto *Token = AST.getTokens().spelledTokenContaining(Loc); + assert(Token && "references expected token here"); Result.Loc.range = Range{sourceLocToPosition(SM, Token->location()), sourceLocToPosition(SM, Token->endLocation())}; Result.Loc.uri = URIMainFile; diff --git a/clang-tools-extra/clangd/index/remote/CMakeLists.txt b/clang-tools-extra/clangd/index/remote/CMakeLists.txt index ed6269d2ccaa986d4bf98272468fe3fb3786239e..106bbeff84ccf35e7533e13cf2dbf998eed2124e 100644 --- a/clang-tools-extra/clangd/index/remote/CMakeLists.txt +++ b/clang-tools-extra/clangd/index/remote/CMakeLists.txt @@ -26,7 +26,6 @@ if (CLANGD_ENABLE_REMOTE) clangdRemoteIndexProto clangdRemoteIndexServiceProto clangdRemoteMarshalling - clangBasic clangDaemon clangdSupport @@ -35,6 +34,11 @@ if (CLANGD_ENABLE_REMOTE) clangdRemoteIndexServiceProto ) + clang_target_link_libraries(clangdRemoteIndex + PRIVATE + clangBasic + ) + add_subdirectory(marshalling) add_subdirectory(server) add_subdirectory(monitor) diff --git a/clang-tools-extra/clangd/refactor/Rename.cpp b/clang-tools-extra/clangd/refactor/Rename.cpp index c0fc4453a3fccc61bb8abe75c7abf139b98e10ca..c85e13dbdfe97f00bb8474e7504ebb3faa2c7acc 100644 --- a/clang-tools-extra/clangd/refactor/Rename.cpp +++ b/clang-tools-extra/clangd/refactor/Rename.cpp @@ -748,7 +748,7 @@ std::vector collectRenameIdentifierRanges( clangd::Range tokenRangeForLoc(ParsedAST &AST, SourceLocation TokLoc, const SourceManager &SM, const LangOptions &LangOpts) { - const auto *Token = AST.getTokens().spelledTokenAt(TokLoc); + const auto *Token = AST.getTokens().spelledTokenContaining(TokLoc); assert(Token && "rename expects spelled tokens"); clangd::Range Result; Result.start = sourceLocToPosition(SM, Token->location()); diff --git a/clang-tools-extra/clangd/unittests/PreambleTests.cpp b/clang-tools-extra/clangd/unittests/PreambleTests.cpp index 6420516e78557672aae2301d3b0c06fca62ff7e0..16a2f9448b1ecf4d48548d87ea415394955f8cc5 100644 --- a/clang-tools-extra/clangd/unittests/PreambleTests.cpp +++ b/clang-tools-extra/clangd/unittests/PreambleTests.cpp @@ -417,7 +417,7 @@ TEST(PreamblePatchTest, LocateMacroAtWorks) { ASSERT_TRUE(AST); const auto &SM = AST->getSourceManager(); - auto *MacroTok = AST->getTokens().spelledTokenAt( + auto *MacroTok = AST->getTokens().spelledTokenContaining( SM.getComposedLoc(SM.getMainFileID(), Modified.point("use"))); ASSERT_TRUE(MacroTok); @@ -441,7 +441,7 @@ TEST(PreamblePatchTest, LocateMacroAtDeletion) { ASSERT_TRUE(AST); const auto &SM = AST->getSourceManager(); - auto *MacroTok = AST->getTokens().spelledTokenAt( + auto *MacroTok = AST->getTokens().spelledTokenContaining( SM.getComposedLoc(SM.getMainFileID(), Modified.point())); ASSERT_TRUE(MacroTok); @@ -512,9 +512,10 @@ TEST(PreamblePatchTest, RefsToMacros) { ExpectedLocations.push_back(referenceRangeIs(R)); for (const auto &P : Modified.points()) { - auto *MacroTok = AST->getTokens().spelledTokenAt(SM.getComposedLoc( - SM.getMainFileID(), - llvm::cantFail(positionToOffset(Modified.code(), P)))); + auto *MacroTok = + AST->getTokens().spelledTokenContaining(SM.getComposedLoc( + SM.getMainFileID(), + llvm::cantFail(positionToOffset(Modified.code(), P)))); ASSERT_TRUE(MacroTok); EXPECT_THAT(findReferences(*AST, P, 0).References, testing::ElementsAreArray(ExpectedLocations)); diff --git a/clang-tools-extra/clangd/unittests/XRefsTests.cpp b/clang-tools-extra/clangd/unittests/XRefsTests.cpp index f53cbf01b7992c8d59daa3cd09492ddfe2324157..cbceb9a343f87ca2d4a502cb5f987986dfc8a4b6 100644 --- a/clang-tools-extra/clangd/unittests/XRefsTests.cpp +++ b/clang-tools-extra/clangd/unittests/XRefsTests.cpp @@ -2173,6 +2173,11 @@ TEST(FindReferences, WithinAST) { using $def[[MyTypeD^ef]] = int; enum MyEnum : $(MyEnum)[[MyTy^peDef]] { }; )cpp", + // UDL + R"cpp( + bool $decl[[operator]]"" _u^dl(unsigned long long value); + bool x = $(x)[[1_udl]]; + )cpp", }; for (const char *Test : Tests) checkFindRefs(Test); @@ -2358,7 +2363,13 @@ TEST(FindReferences, UsedSymbolsFromInclude) { R"cpp([[#in^clude ]] std::[[vector]] vec; - )cpp"}; + )cpp", + + R"cpp( + [[#include ^"udl_header.h"]] + auto x = [[1_b]]; + )cpp", + }; for (const char *Test : Tests) { Annotations T(Test); auto TU = TestTU::withCode(T.code()); @@ -2375,6 +2386,9 @@ TEST(FindReferences, UsedSymbolsFromInclude) { class vector{}; } )cpp"); + TU.AdditionalFiles["udl_header.h"] = guard(R"cpp( + bool operator"" _b(unsigned long long value); + )cpp"); TU.ExtraArgs.push_back("-isystem" + testPath("system")); auto AST = TU.build(); diff --git a/clang-tools-extra/docs/ReleaseNotes.rst b/clang-tools-extra/docs/ReleaseNotes.rst index 33b65caf2b02cedfd179fe005c3bd4ab487b27ed..2dc39d0ad74af8cc0a80074d887fdb062e6b9fc1 100644 --- a/clang-tools-extra/docs/ReleaseNotes.rst +++ b/clang-tools-extra/docs/ReleaseNotes.rst @@ -148,6 +148,12 @@ New checks to reading out-of-bounds data due to inadequate or incorrect string null termination. +- New :doc:`misc-use-internal-linkage + ` check. + + Detects variables and functions that can be marked as static or moved into + an anonymous namespace to enforce internal linkage. + - New :doc:`modernize-min-max-use-initializer-list ` check. @@ -218,6 +224,10 @@ Changes in existing checks check by ignoring ``__func__`` macro in lambda captures, initializers of default parameters and nested function declarations. +- Improved :doc:`bugprone-multi-level-implicit-pointer-conversion + ` check + by ignoring implicit pointer conversions that are part of a cast expression. + - Improved :doc:`bugprone-non-zero-enum-to-bool-conversion ` check by eliminating false positives resulting from direct usage of bitwise operators @@ -227,6 +237,12 @@ Changes in existing checks ` check by eliminating false positives resulting from use of optionals in unevaluated context. +- Improved :doc:`bugprone-sizeof-expression + ` check by eliminating some + false positives and adding a new (off-by-default) option + `WarnOnSizeOfPointer` that reports all ``sizeof(pointer)`` expressions + (except for a few that are idiomatic). + - Improved :doc:`bugprone-suspicious-include ` check by replacing the local options `HeaderFileExtensions` and `ImplementationFileExtensions` by the @@ -317,6 +333,10 @@ Changes in existing checks Additionally, the option `UseHeaderFileExtensions` is removed, so that the check uses the `HeaderFileExtensions` option unconditionally. +- Improved :doc:`misc-header-include-cycle + ` check by avoiding crash for self + include cycles. + - Improved :doc:`misc-unused-using-decls ` check by replacing the local option `HeaderFileExtensions` by the global option of the same name. @@ -362,8 +382,10 @@ Changes in existing checks - Improved :doc:`performance-unnecessary-copy-initialization ` check by detecting more cases of constant access. In particular, pointers can be - analyzed, se the check now handles the common patterns + analyzed, so the check now handles the common patterns `const auto e = (*vector_ptr)[i]` and `const auto e = vector_ptr->at(i);`. + Calls to mutable function where there exists a `const` overload are also + handled. - Improved :doc:`readability-avoid-return-with-void-value ` check by adding @@ -376,6 +398,7 @@ Changes in existing checks - Improved :doc:`readability-container-size-empty ` check to prevent false positives when utilizing ``size`` or ``length`` methods that accept parameter. + Fixed crash when facing template user defined literals. - Improved :doc:`readability-duplicate-include ` check by excluding include @@ -397,12 +420,18 @@ Changes in existing checks valid fix suggestions for ``static_cast`` without a preceding space and fixed problem with duplicate parentheses in double implicit casts. Corrected the fix suggestions for C23 and later by using C-style casts instead of - ``static_cast``. + ``static_cast``. Fixed false positives in C++20 spaceship operator by ignoring + casts in implicit and defaulted functions. - Improved :doc:`readability-redundant-inline-specifier ` check to properly emit warnings for static data member with an in-class initializer. +- Improved :doc:`readability-redundant-member-init + ` check to avoid + false-positives when type of the member does not match the type of the + initializer. + - Improved :doc:`readability-static-accessed-through-instance ` check to support calls to overloaded operators as base expression and provide fixes to diff --git a/clang-tools-extra/docs/clang-tidy/checks/bugprone/sizeof-expression.rst b/clang-tools-extra/docs/clang-tidy/checks/bugprone/sizeof-expression.rst index c37df1706eb4e19e0a310b91a259ea241403067f..ed5bb4fbb89baf18c8792eef7e54091651af9102 100644 --- a/clang-tools-extra/docs/clang-tidy/checks/bugprone/sizeof-expression.rst +++ b/clang-tools-extra/docs/clang-tidy/checks/bugprone/sizeof-expression.rst @@ -190,6 +190,15 @@ Options .. option:: WarnOnSizeOfPointerToAggregate - When `true`, the check will warn on an expression like - ``sizeof(expr)`` where the expression is a pointer - to aggregate. Default is `true`. + When `true`, the check will warn when the argument of ``sizeof`` is either a + pointer-to-aggregate type, an expression returning a pointer-to-aggregate + value or an expression that returns a pointer from an array-to-pointer + conversion (that may be implicit or explicit, for example ``array + 2`` or + ``(int *)array``). Default is `true`. + +.. option:: WarnOnSizeOfPointer + + When `true`, the check will report all expressions where the argument of + ``sizeof`` is an expression that produces a pointer (except for a few + idiomatic expressions that are probably intentional and correct). + This detects occurrences of CWE 467. Default is `false`. diff --git a/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/cplusplus.ArrayDelete.rst b/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/cplusplus.ArrayDelete.rst new file mode 100644 index 0000000000000000000000000000000000000000..98147aaaa6883e4818745c6f6e6708eaf97e3c81 --- /dev/null +++ b/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/cplusplus.ArrayDelete.rst @@ -0,0 +1,14 @@ +.. title:: clang-tidy - clang-analyzer-cplusplus.ArrayDelete +.. meta:: + :http-equiv=refresh: 5;URL=https://clang.llvm.org/docs/analyzer/checkers.html#cplusplus-arraydelete + +clang-analyzer-cplusplus.ArrayDelete +==================================== + +Reports destructions of arrays of polymorphic objects that are destructed as +their base class. + +The `clang-analyzer-cplusplus.ArrayDelete` check is an alias, please see +`Clang Static Analyzer Available Checkers +`_ +for more information. diff --git a/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/security.SetgidSetuidOrder.rst b/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/security.SetgidSetuidOrder.rst new file mode 100644 index 0000000000000000000000000000000000000000..82f22b11f77fb42f4949de7fb23a05a6aa3778fe --- /dev/null +++ b/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/security.SetgidSetuidOrder.rst @@ -0,0 +1,10 @@ +.. title:: clang-tidy - clang-analyzer-security.SetgidSetuidOrder + +clang-analyzer-security.SetgidSetuidOrder +========================================= + +Warn on possible reversed order of 'setgid(getgid()))' and 'setuid(getuid())' +(CERT: POS36-C). + +The clang-analyzer-security.SetgidSetuidOrder check is an alias of +Clang Static Analyzer security.SetgidSetuidOrder. diff --git a/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/unix.Stream.rst b/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/unix.Stream.rst new file mode 100644 index 0000000000000000000000000000000000000000..82a8bdcaefce797d4bf4b64acc435b97de0d4f0d --- /dev/null +++ b/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/unix.Stream.rst @@ -0,0 +1,13 @@ +.. title:: clang-tidy - clang-analyzer-unix.Stream +.. meta:: + :http-equiv=refresh: 5;URL=https://clang.llvm.org/docs/analyzer/checkers.html#unix-stream + +clang-analyzer-unix.Stream +========================== + +Check stream handling functions. + +The `clang-analyzer-unix.Stream` check is an alias, please see +`Clang Static Analyzer Available Checkers +`_ +for more information. diff --git a/clang-tools-extra/docs/clang-tidy/checks/gen-static-analyzer-docs.py b/clang-tools-extra/docs/clang-tidy/checks/gen-static-analyzer-docs.py index 6545a3906fa50e54da8e36b0a13f05cb0d002605..fba1592c7c1c756043ceba5a4b64448b446c562c 100644 --- a/clang-tools-extra/docs/clang-tidy/checks/gen-static-analyzer-docs.py +++ b/clang-tools-extra/docs/clang-tidy/checks/gen-static-analyzer-docs.py @@ -47,7 +47,7 @@ def get_checkers(checkers_td, checkers_rst): parent_package_ = package["ParentPackage"] hidden = (checker["Hidden"] != 0) or (package["Hidden"] != 0) - while parent_package_ != None: + while parent_package_ is not None: parent_package = table_entries[parent_package_["def"]] checker_package_prefix = ( parent_package["PackageName"] + "." + checker_package_prefix @@ -59,7 +59,7 @@ def get_checkers(checkers_td, checkers_rst): "clang-analyzer-" + checker_package_prefix + "." + checker_name ) anchor_url = re.sub( - "\.", "-", checker_package_prefix + "." + checker_name + r"\.", "-", checker_package_prefix + "." + checker_name ).lower() if not hidden and "alpha" not in full_package_name.lower(): @@ -130,7 +130,7 @@ Args: def update_documentation_list(checkers): with open(os.path.join(__location__, "list.rst"), "r+") as f: f_text = f.read() - check_text = f_text.split(".. csv-table:: Aliases..\n")[1] + check_text = f_text.split(':header: "Name", "Redirect", "Offers fixes"\n')[1] checks = [x for x in check_text.split("\n") if ":header:" not in x and x] old_check_text = "\n".join(checks) checks = [x for x in checks if "clang-analyzer-" not in x] diff --git a/clang-tools-extra/docs/clang-tidy/checks/list.rst b/clang-tools-extra/docs/clang-tidy/checks/list.rst index 85e4f0352ac22b2b4e23cc36eb6b14814b48a08b..a698cecc0825c6ef202458b7cd987959478c1a4d 100644 --- a/clang-tools-extra/docs/clang-tidy/checks/list.rst +++ b/clang-tools-extra/docs/clang-tidy/checks/list.rst @@ -267,6 +267,7 @@ Clang-Tidy Checks :doc:`misc-unused-parameters `, "Yes" :doc:`misc-unused-using-decls `, "Yes" :doc:`misc-use-anonymous-namespace `, + :doc:`misc-use-internal-linkage `, :doc:`modernize-avoid-bind `, "Yes" :doc:`modernize-avoid-c-arrays `, :doc:`modernize-concat-nested-namespaces `, "Yes" @@ -442,6 +443,7 @@ Check aliases :doc:`clang-analyzer-core.uninitialized.CapturedBlockVariable `, `Clang Static Analyzer core.uninitialized.CapturedBlockVariable `_, :doc:`clang-analyzer-core.uninitialized.NewArraySize `, `Clang Static Analyzer core.uninitialized.NewArraySize `_, :doc:`clang-analyzer-core.uninitialized.UndefReturn `, `Clang Static Analyzer core.uninitialized.UndefReturn `_, + :doc:`clang-analyzer-cplusplus.ArrayDelete `, `Clang Static Analyzer cplusplus.ArrayDelete `_, :doc:`clang-analyzer-cplusplus.InnerPointer `, `Clang Static Analyzer cplusplus.InnerPointer `_, :doc:`clang-analyzer-cplusplus.Move `, Clang Static Analyzer cplusplus.Move, :doc:`clang-analyzer-cplusplus.NewDelete `, `Clang Static Analyzer cplusplus.NewDelete `_, @@ -496,6 +498,7 @@ Check aliases :doc:`clang-analyzer-osx.coreFoundation.containers.OutOfBounds `, `Clang Static Analyzer osx.coreFoundation.containers.OutOfBounds `_, :doc:`clang-analyzer-osx.coreFoundation.containers.PointerSizedValues `, `Clang Static Analyzer osx.coreFoundation.containers.PointerSizedValues `_, :doc:`clang-analyzer-security.FloatLoopCounter `, `Clang Static Analyzer security.FloatLoopCounter `_, + :doc:`clang-analyzer-security.SetgidSetuidOrder `, Clang Static Analyzer security.SetgidSetuidOrder, :doc:`clang-analyzer-security.cert.env.InvalidPtr `, `Clang Static Analyzer security.cert.env.InvalidPtr `_, :doc:`clang-analyzer-security.insecureAPI.DeprecatedOrUnsafeBufferHandling `, `Clang Static Analyzer security.insecureAPI.DeprecatedOrUnsafeBufferHandling `_, :doc:`clang-analyzer-security.insecureAPI.UncheckedReturn `, `Clang Static Analyzer security.insecureAPI.UncheckedReturn `_, @@ -516,6 +519,7 @@ Check aliases :doc:`clang-analyzer-unix.MallocSizeof `, `Clang Static Analyzer unix.MallocSizeof `_, :doc:`clang-analyzer-unix.MismatchedDeallocator `, `Clang Static Analyzer unix.MismatchedDeallocator `_, :doc:`clang-analyzer-unix.StdCLibraryFunctions `, `Clang Static Analyzer unix.StdCLibraryFunctions `_, + :doc:`clang-analyzer-unix.Stream `, `Clang Static Analyzer unix.Stream `_, :doc:`clang-analyzer-unix.Vfork `, `Clang Static Analyzer unix.Vfork `_, :doc:`clang-analyzer-unix.cstring.BadSizeArg `, `Clang Static Analyzer unix.cstring.BadSizeArg `_, :doc:`clang-analyzer-unix.cstring.NullArg `, `Clang Static Analyzer unix.cstring.NullArg `_, diff --git a/clang-tools-extra/docs/clang-tidy/checks/misc/use-internal-linkage.rst b/clang-tools-extra/docs/clang-tidy/checks/misc/use-internal-linkage.rst new file mode 100644 index 0000000000000000000000000000000000000000..e8e43a1fb3d63249bcfa84b88fd1fd7f34717bf2 --- /dev/null +++ b/clang-tools-extra/docs/clang-tidy/checks/misc/use-internal-linkage.rst @@ -0,0 +1,27 @@ +.. title:: clang-tidy - misc-use-internal-linkage + +misc-use-internal-linkage +========================= + +Detects variables and functions that can be marked as static or moved into +an anonymous namespace to enforce internal linkage. + +Static functions and variables are scoped to a single file. Marking functions +and variables as static helps to better remove dead code. In addition, it gives +the compiler more information and allows for more aggressive optimizations. + +Example: + +.. code-block:: c++ + + int v1; // can be marked as static + + void fn1(); // can be marked as static + + namespace { + // already in anonymous namespace + int v2; + void fn2(); + } + // already declared as extern + extern int v2; diff --git a/clang-tools-extra/docs/clang-tidy/checks/modernize/use-designated-initializers.rst b/clang-tools-extra/docs/clang-tidy/checks/modernize/use-designated-initializers.rst index 22f50980baade6a4b4a7fa80aed5ce819fbe869b..f101cfc6f3a2b3954d2d0a73230ae176c9a86bcc 100644 --- a/clang-tools-extra/docs/clang-tidy/checks/modernize/use-designated-initializers.rst +++ b/clang-tools-extra/docs/clang-tidy/checks/modernize/use-designated-initializers.rst @@ -37,7 +37,7 @@ declaration of ``S``. Even when compiling in a language version older than C++20, depending on your compiler, designated initializers are potentially supported. Therefore, the -check is not restricted to C++20 and newer versions. Check out the options +check is by default restricted to C99/C++20 and above. Check out the options ``-Wc99-designator`` to get support for mixed designators in initializer list in C and ``-Wc++20-designator`` for support of designated initializers in older C++ language modes. @@ -60,3 +60,13 @@ Options The value `true` specifies that only Plain Old Data (POD) types shall be checked. This makes the check applicable to even older C++ standards. The default value is `false`. + +.. option:: StrictCStandardCompliance + + When set to `false`, the check will not restrict itself to C99 and above. + The default value is `true`. + +.. option:: StrictCppStandardCompliance + + When set to `false`, the check will not restrict itself to C++20 and above. + The default value is `true`. diff --git a/clang-tools-extra/pseudo/lib/CMakeLists.txt b/clang-tools-extra/pseudo/lib/CMakeLists.txt index f92f79be121508475bb522131db8a01883289b7c..a13b5d20cf7c3b5fc5a181e639a5084e044a2e18 100644 --- a/clang-tools-extra/pseudo/lib/CMakeLists.txt +++ b/clang-tools-extra/pseudo/lib/CMakeLists.txt @@ -14,8 +14,6 @@ add_clang_library(clangPseudo Token.cpp LINK_LIBS - clangBasic - clangLex clangPseudoGrammar DEPENDS @@ -25,3 +23,9 @@ add_clang_library(clangPseudo target_include_directories(clangPseudo INTERFACE $ ) + +clang_target_link_libraries(clangPseudo + PRIVATE + clangBasic + clangLex + ) diff --git a/clang-tools-extra/pseudo/lib/cxx/CMakeLists.txt b/clang-tools-extra/pseudo/lib/cxx/CMakeLists.txt index d56d16c893c3d422eb9affc2281c7a14fdfa95be..2fecdce6a10f9cc6e2e74140a78398b05743be88 100644 --- a/clang-tools-extra/pseudo/lib/cxx/CMakeLists.txt +++ b/clang-tools-extra/pseudo/lib/cxx/CMakeLists.txt @@ -9,7 +9,11 @@ add_clang_library(clangPseudoCXX cxx_gen LINK_LIBS - clangBasic clangPseudo clangPseudoGrammar ) + +clang_target_link_libraries(clangPseudoCXX + PRIVATE + clangBasic + ) diff --git a/clang-tools-extra/test/clang-tidy/checkers/bugprone/multi-level-implicit-pointer-conversion.cpp b/clang-tools-extra/test/clang-tidy/checkers/bugprone/multi-level-implicit-pointer-conversion.cpp index 7a56242e4202d61d9a2f3b0f52c336fb77b6dda7..6868f9e5909088c68fb929619b0b5f686b794ca3 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/bugprone/multi-level-implicit-pointer-conversion.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/bugprone/multi-level-implicit-pointer-conversion.cpp @@ -63,3 +63,15 @@ void test() takeSecondLevelVoidPtr(getSecondLevelVoidPtr()); } + +namespace PR93959 { + void free(void*); + + void test() { + char **p = nullptr; + free(p); + // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: multilevel pointer conversion from 'char **' to 'void *', please use explicit cast [bugprone-multi-level-implicit-pointer-conversion] + free((void *)p); + free(static_cast(p)); + } +} diff --git a/clang-tools-extra/test/clang-tidy/checkers/bugprone/sizeof-expression-2.c b/clang-tools-extra/test/clang-tidy/checkers/bugprone/sizeof-expression-2.c index 8c4feb8f86169bffcbf20df99c9f060764a9cfda..aef930f2c8fda743678b7c6766560f38c47ecc2a 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/bugprone/sizeof-expression-2.c +++ b/clang-tools-extra/test/clang-tidy/checkers/bugprone/sizeof-expression-2.c @@ -34,24 +34,24 @@ int Test5() { int sum = 0; sum += sizeof(&S); - // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof(A*)'; pointer to aggregate + // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof()' on an expression that results in a pointer sum += sizeof(__typeof(&S)); sum += sizeof(&TS); - // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof(A*)'; pointer to aggregate + // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof()' on an expression that results in a pointer sum += sizeof(__typeof(&TS)); sum += sizeof(STRKWD MyStruct*); sum += sizeof(__typeof(STRKWD MyStruct*)); sum += sizeof(TypedefStruct*); sum += sizeof(__typeof(TypedefStruct*)); sum += sizeof(PTTS); - // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof(A*)'; pointer to aggregate + // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof()' on an expression that results in a pointer sum += sizeof(PMyStruct); sum += sizeof(PS); - // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof(A*)'; pointer to aggregate + // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof()' on an expression that results in a pointer sum += sizeof(PS2); - // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof(A*)'; pointer to aggregate + // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof()' on an expression that results in a pointer sum += sizeof(&A10); - // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof(A*)'; pointer to aggregate + // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof()' on an expression that results in a pointer #ifdef __cplusplus MyStruct &rS = S; diff --git a/clang-tools-extra/test/clang-tidy/checkers/bugprone/sizeof-expression-any-pointer.cpp b/clang-tools-extra/test/clang-tidy/checkers/bugprone/sizeof-expression-any-pointer.cpp new file mode 100644 index 0000000000000000000000000000000000000000..bfb2ec3a9eb02c00a4f99d38112f9b4c5a3a9543 --- /dev/null +++ b/clang-tools-extra/test/clang-tidy/checkers/bugprone/sizeof-expression-any-pointer.cpp @@ -0,0 +1,241 @@ +// RUN: %check_clang_tidy %s bugprone-sizeof-expression %t -- -config="{CheckOptions: {bugprone-sizeof-expression.WarnOnSizeOfIntegerExpression: true, bugprone-sizeof-expression.WarnOnSizeOfPointer: true}}" -- + +class C { + int size() { return sizeof(this); } + // CHECK-MESSAGES: :[[@LINE-1]]:23: warning: suspicious usage of 'sizeof(this)' +}; + +#define LEN 8 + +int X; +extern int A[10]; +extern short B[10]; + +#pragma pack(1) +struct S { char a, b, c; }; + +enum E { E_VALUE = 0 }; +enum class EC { VALUE = 0 }; + +bool AsBool() { return false; } +int AsInt() { return 0; } +E AsEnum() { return E_VALUE; } +EC AsEnumClass() { return EC::VALUE; } +S AsStruct() { return {}; } + +struct M { + int AsInt() { return 0; } + E AsEnum() { return E_VALUE; } + S AsStruct() { return {}; } +}; + +int Test1(const char* ptr) { + int sum = 0; + sum += sizeof(LEN); + // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof(K)' + sum += sizeof(LEN + 1); + // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof(K)' + sum += sizeof(sum, LEN); + // CHECK-MESSAGES: :[[@LINE-1]]:20: warning: suspicious usage of 'sizeof(..., ...)' + sum += sizeof(AsBool()); + // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof()' on an expression that results in an integer + sum += sizeof(AsInt()); + // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof()' on an expression that results in an integer + sum += sizeof(AsEnum()); + // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof()' on an expression that results in an integer + sum += sizeof(AsEnumClass()); + // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof()' on an expression that results in an integer + sum += sizeof(M{}.AsInt()); + // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof()' on an expression that results in an integer + sum += sizeof(M{}.AsEnum()); + // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof()' on an expression that results in an integer + sum += sizeof(sizeof(X)); + // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof(sizeof(...))' + sum += sizeof(LEN + sizeof(X)); + // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof(sizeof(...))' + sum += sizeof(LEN + LEN + sizeof(X)); + // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof(sizeof(...))' + sum += sizeof(LEN + (LEN + sizeof(X))); + // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof(sizeof(...))' + sum += sizeof(LEN + -sizeof(X)); + // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof(sizeof(...))' + sum += sizeof(LEN + - + -sizeof(X)); + // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof(sizeof(...))' + sum += sizeof(char) / sizeof(char); + // CHECK-MESSAGES: :[[@LINE-1]]:23: warning: suspicious usage of sizeof pointer 'sizeof(T)/sizeof(T)' + sum += sizeof(A) / sizeof(S); + // CHECK-MESSAGES: :[[@LINE-1]]:20: warning: suspicious usage of 'sizeof(...)/sizeof(...)'; numerator is not a multiple of denominator + sum += sizeof(char) / sizeof(int); + // CHECK-MESSAGES: :[[@LINE-1]]:23: warning: suspicious usage of 'sizeof(...)/sizeof(...)'; numerator is not a multiple of denominator + sum += sizeof(char) / sizeof(A); + // CHECK-MESSAGES: :[[@LINE-1]]:23: warning: suspicious usage of 'sizeof(...)/sizeof(...)'; numerator is not a multiple of denominator + sum += sizeof(B[0]) / sizeof(A); + // CHECK-MESSAGES: :[[@LINE-1]]:23: warning: suspicious usage of 'sizeof(...)/sizeof(...)'; numerator is not a multiple of denominator + sum += sizeof(ptr) / sizeof(char); + // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof()' on an expression that results in a pointer + sum += sizeof(ptr) / sizeof(ptr[0]); + // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof()' on an expression that results in a pointer + sum += sizeof(ptr) / sizeof(char*); + // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof()' on an expression that results in a pointer + sum += sizeof(ptr) / sizeof(void*); + // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof()' on an expression that results in a pointer + sum += sizeof(ptr) / sizeof(const void volatile*); + // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof()' on an expression that results in a pointer + sum += sizeof(ptr) / sizeof(char); + // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof()' on an expression that results in a pointer + sum += sizeof(int) * sizeof(char); + // CHECK-MESSAGES: :[[@LINE-1]]:22: warning: suspicious 'sizeof' by 'sizeof' multiplication + sum += sizeof(ptr) * sizeof(ptr[0]); + // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof()' on an expression that results in a pointer + // CHECK-MESSAGES: :[[@LINE-2]]:22: warning: suspicious 'sizeof' by 'sizeof' multiplication + sum += sizeof(int) * (2 * sizeof(char)); + // CHECK-MESSAGES: :[[@LINE-1]]:22: warning: suspicious 'sizeof' by 'sizeof' multiplication + sum += (2 * sizeof(char)) * sizeof(int); + // CHECK-MESSAGES: :[[@LINE-1]]:29: warning: suspicious 'sizeof' by 'sizeof' multiplication + if (sizeof(A) < 0x100000) sum += 42; + // CHECK-MESSAGES: :[[@LINE-1]]:17: warning: suspicious comparison of 'sizeof(expr)' to a constant + if (sizeof(A) <= 0xFFFFFFFEU) sum += 42; + // CHECK-MESSAGES: :[[@LINE-1]]:17: warning: suspicious comparison of 'sizeof(expr)' to a constant + return sum; +} + +int Test5() { + typedef int Array10[10]; + typedef C ArrayC[10]; + + struct MyStruct { + Array10 arr; + Array10* ptr; + }; + typedef const MyStruct TMyStruct; + typedef const MyStruct *PMyStruct; + typedef TMyStruct *PMyStruct2; + + static TMyStruct kGlocalMyStruct = {}; + static TMyStruct volatile * kGlocalMyStructPtr = &kGlocalMyStruct; + + MyStruct S; + PMyStruct PS; + PMyStruct2 PS2; + Array10 A10; + C *PtrArray[10]; + C *PC; + + char *PChar; + int *PInt, **PPInt; + MyStruct **PPMyStruct; + + int sum = 0; + sum += sizeof(&S.arr); + // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof()' on an expression that results in a pointer + sum += sizeof(&kGlocalMyStruct.arr); + // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof()' on an expression that results in a pointer + sum += sizeof(&kGlocalMyStructPtr->arr); + // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof()' on an expression that results in a pointer + sum += sizeof(S.arr + 0); + // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof()' on an expression that results in a pointer + sum += sizeof(+ S.arr); + // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof()' on an expression that results in a pointer + sum += sizeof((int*)S.arr); + // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof()' on an expression that results in a pointer + + sum += sizeof(S.ptr); + // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof()' on an expression that results in a pointer + sum += sizeof(kGlocalMyStruct.ptr); + // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof()' on an expression that results in a pointer + sum += sizeof(kGlocalMyStructPtr->ptr); + // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof()' on an expression that results in a pointer + + sum += sizeof(&kGlocalMyStruct); + // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof()' on an expression that results in a pointer + sum += sizeof(&S); + // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof()' on an expression that results in a pointer + sum += sizeof(MyStruct*); + sum += sizeof(PMyStruct); + sum += sizeof(PS); + // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof()' on an expression that results in a pointer + sum += sizeof(PS2); + // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof()' on an expression that results in a pointer + sum += sizeof(&A10); + // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof()' on an expression that results in a pointer + sum += sizeof(PtrArray) / sizeof(PtrArray[1]); + // CHECK-MESSAGES: :[[@LINE-1]]:29: warning: suspicious usage of 'sizeof()' on an expression that results in a pointer + sum += sizeof(A10) / sizeof(PtrArray[0]); + sum += sizeof(PC) / sizeof(PtrArray[0]); + // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof()' on an expression that results in a pointer + // CHECK-MESSAGES: :[[@LINE-2]]:21: warning: suspicious usage of sizeof pointer 'sizeof(T)/sizeof(T)' + sum += sizeof(ArrayC) / sizeof(PtrArray[0]); + // CHECK-MESSAGES: :[[@LINE-1]]:25: warning: suspicious usage of 'sizeof(...)/sizeof(...)'; numerator is not a multiple of denominator + + sum += sizeof(PChar); + // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof()' on an expression that results in a pointer + sum += sizeof(PInt); + // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof()' on an expression that results in a pointer + sum += sizeof(PPInt); + // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof()' on an expression that results in a pointer + sum += sizeof(PPMyStruct); + // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof()' on an expression that results in a pointer + + return sum; +} + +void some_generic_function(const void *arg, int argsize); +int *IntP, **IntPP; +C *ClassP, **ClassPP; + +void GenericFunctionTest() { + // The `sizeof(pointer)` checks ignore situations where the pointer is + // produced by dereferencing a pointer-to-pointer, because this is unlikely + // to be an accident and can appear in legitimate code that tries to call + // a generic function which emulates dynamic typing within C. + some_generic_function(IntPP, sizeof(*IntPP)); + some_generic_function(ClassPP, sizeof(*ClassPP)); + // Using `...[0]` instead of the dereference operator is another common + // variant, which is also widespread in the idiomatic array-size calculation: + // `sizeof(array) / sizeof(array[0])`. + some_generic_function(IntPP, sizeof(IntPP[0])); + some_generic_function(ClassPP, sizeof(ClassPP[0])); + // FIXME: There is a third common pattern where the generic function is + // called with `&Variable` and `sizeof(Variable)`. Right now these are + // reported by the `sizeof(pointer)` checks, but this causes some false + // positives, so it would be good to create an exception for them. + some_generic_function(&IntPP, sizeof(IntP)); + // CHECK-MESSAGES: :[[@LINE-1]]:33: warning: suspicious usage of 'sizeof()' on an expression that results in a pointer + some_generic_function(&ClassPP, sizeof(ClassP)); + // CHECK-MESSAGES: :[[@LINE-1]]:35: warning: suspicious usage of 'sizeof()' on an expression that results in a pointer +} + +int ValidExpressions() { + int A[] = {1, 2, 3, 4}; + static const char str[] = "hello"; + static const char* ptr[] { "aaa", "bbb", "ccc" }; + typedef C *CA10[10]; + C *PtrArray[10]; + CA10 PtrArray1; + + int sum = 0; + if (sizeof(A) < 10) + sum += sizeof(A); + sum += sizeof(int); + sum += sizeof(AsStruct()); + sum += sizeof(M{}.AsStruct()); + sum += sizeof(A[sizeof(A) / sizeof(int)]); + // Here the outer sizeof is reported, but the inner ones are accepted: + sum += sizeof(&A[sizeof(A) / sizeof(int)]); + // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof()' on an expression that results in a pointer + sum += sizeof(sizeof(0)); // Special case: sizeof size_t. + sum += sizeof(void*); + sum += sizeof(void const *); + sum += sizeof(void const *) / 4; + sum += sizeof(str); + sum += sizeof(str) / sizeof(char); + sum += sizeof(str) / sizeof(str[0]); + sum += sizeof(ptr) / sizeof(ptr[0]); + sum += sizeof(ptr) / sizeof(*(ptr)); + sum += sizeof(PtrArray) / sizeof(PtrArray[0]); + // Canonical type of PtrArray1 is same as PtrArray. + sum = sizeof(PtrArray) / sizeof(PtrArray1[0]); + // There is no warning for 'sizeof(T*)/sizeof(Q)' case. + sum += sizeof(PtrArray) / sizeof(A[0]); + return sum; +} diff --git a/clang-tools-extra/test/clang-tidy/checkers/bugprone/sizeof-expression.cpp b/clang-tools-extra/test/clang-tidy/checkers/bugprone/sizeof-expression.cpp index 003a02209c3d2deee8cc0592b229c601d528b401..064f31cb08c6b34f6a33379a61da29ef03b80409 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/bugprone/sizeof-expression.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/bugprone/sizeof-expression.cpp @@ -124,8 +124,6 @@ int Test1(const char* ptr) { // CHECK-MESSAGES: :[[@LINE-1]]:22: warning: suspicious usage of sizeof pointer 'sizeof(P*)/sizeof(Q*)' sum += sizeof(ptr) / sizeof(char); // CHECK-MESSAGES: :[[@LINE-1]]:22: warning: suspicious usage of sizeof pointer 'sizeof(T*)/sizeof(T)' - sum += sizeof(ptr) / sizeof(ptr[0]); - // CHECK-MESSAGES: :[[@LINE-1]]:22: warning: suspicious usage of sizeof pointer 'sizeof(T*)/sizeof(T)' sum += sizeof(int) * sizeof(char); // CHECK-MESSAGES: :[[@LINE-1]]:22: warning: suspicious 'sizeof' by 'sizeof' multiplication sum += sizeof(ptr) * sizeof(ptr[0]); @@ -207,50 +205,57 @@ int Test5() { C *PtrArray[10]; C *PC; + char *PChar; + int *PInt, **PPInt; + MyStruct **PPMyStruct; + int sum = 0; sum += sizeof(&S.arr); - // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof(A*)'; pointer to aggregate + // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof()' on an expression that results in a pointer sum += sizeof(&kGlocalMyStruct.arr); - // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof(A*)'; pointer to aggregate + // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof()' on an expression that results in a pointer sum += sizeof(&kGlocalMyStructPtr->arr); - // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof(A*)'; pointer to aggregate + // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof()' on an expression that results in a pointer sum += sizeof(S.arr + 0); - // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof(A*)'; pointer to aggregate + // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof()' on an expression that results in a pointer sum += sizeof(+ S.arr); - // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof(A*)'; pointer to aggregate + // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof()' on an expression that results in a pointer sum += sizeof((int*)S.arr); - // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof(A*)'; pointer to aggregate + // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof()' on an expression that results in a pointer sum += sizeof(S.ptr); - // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof(A*)'; pointer to aggregate + // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof()' on an expression that results in a pointer sum += sizeof(kGlocalMyStruct.ptr); - // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof(A*)'; pointer to aggregate + // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof()' on an expression that results in a pointer sum += sizeof(kGlocalMyStructPtr->ptr); - // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof(A*)'; pointer to aggregate + // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof()' on an expression that results in a pointer sum += sizeof(&kGlocalMyStruct); - // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof(A*)'; pointer to aggregate + // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof()' on an expression that results in a pointer sum += sizeof(&S); - // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof(A*)'; pointer to aggregate + // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof()' on an expression that results in a pointer sum += sizeof(MyStruct*); sum += sizeof(PMyStruct); sum += sizeof(PS); - // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof(A*)'; pointer to aggregate + // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof()' on an expression that results in a pointer sum += sizeof(PS2); - // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof(A*)'; pointer to aggregate + // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof()' on an expression that results in a pointer sum += sizeof(&A10); - // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof(A*)'; pointer to aggregate + // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof()' on an expression that results in a pointer sum += sizeof(PtrArray) / sizeof(PtrArray[1]); - // CHECK-MESSAGES: :[[@LINE-1]]:29: warning: suspicious usage of 'sizeof(A*)'; pointer to aggregate + // CHECK-MESSAGES: :[[@LINE-1]]:29: warning: suspicious usage of 'sizeof()' on an expression that results in a pointer sum += sizeof(A10) / sizeof(PtrArray[0]); - // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: suspicious usage of 'sizeof(A*)'; pointer to aggregate sum += sizeof(PC) / sizeof(PtrArray[0]); - // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof(A*)'; pointer to aggregate + // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof()' on an expression that results in a pointer // CHECK-MESSAGES: :[[@LINE-2]]:21: warning: suspicious usage of sizeof pointer 'sizeof(T)/sizeof(T)' - // CHECK-MESSAGES: :[[@LINE-3]]:23: warning: suspicious usage of 'sizeof(A*)'; pointer to aggregate sum += sizeof(ArrayC) / sizeof(PtrArray[0]); // CHECK-MESSAGES: :[[@LINE-1]]:25: warning: suspicious usage of 'sizeof(...)/sizeof(...)'; numerator is not a multiple of denominator - // CHECK-MESSAGES: :[[@LINE-2]]:27: warning: suspicious usage of 'sizeof(A*)'; pointer to aggregate + + // These pointers do not point to aggregate types, so they are not reported in this mode: + sum += sizeof(PChar); + sum += sizeof(PInt); + sum += sizeof(PPInt); + sum += sizeof(PPMyStruct); return sum; } @@ -293,6 +298,32 @@ bool Baz() { return sizeof(A) < N; } // CHECK-MESSAGES: :[[@LINE-1]]:31: warning: suspicious comparison of 'sizeof(expr)' to a constant bool Test7() { return Baz<-1>(); } +void some_generic_function(const void *arg, int argsize); +int *IntP, **IntPP; +C *ClassP, **ClassPP; + +void GenericFunctionTest() { + // The `sizeof(pointer)` checks ignore situations where the pointer is + // produced by dereferencing a pointer-to-pointer, because this is unlikely + // to be an accident and can appear in legitimate code that tries to call + // a generic function which emulates dynamic typing within C. + some_generic_function(IntPP, sizeof(*IntPP)); + some_generic_function(ClassPP, sizeof(*ClassPP)); + // Using `...[0]` instead of the dereference operator is another common + // variant, which is also widespread in the idiomatic array-size calculation: + // `sizeof(array) / sizeof(array[0])`. + some_generic_function(IntPP, sizeof(IntPP[0])); + some_generic_function(ClassPP, sizeof(ClassPP[0])); + // FIXME: There is a third common pattern where the generic function is + // called with `&Variable` and `sizeof(Variable)`. Right now these are + // reported by the `sizeof(pointer)` checks, but this causes some false + // positives, so it would be good to create an exception for them. + // NOTE: `sizeof(IntP)` is only reported with `WarnOnSizeOfPointer=true`. + some_generic_function(&IntPP, sizeof(IntP)); + some_generic_function(&ClassPP, sizeof(ClassP)); + // CHECK-MESSAGES: :[[@LINE-1]]:35: warning: suspicious usage of 'sizeof()' on an expression that results in a pointer +} + int ValidExpressions() { int A[] = {1, 2, 3, 4}; static const char str[] = "hello"; diff --git a/clang-tools-extra/test/clang-tidy/checkers/misc/Inputs/use-internal-linkage/func.h b/clang-tools-extra/test/clang-tidy/checkers/misc/Inputs/use-internal-linkage/func.h new file mode 100644 index 0000000000000000000000000000000000000000..0f2b576a126c4a422657c7063a81d3362e8f38d4 --- /dev/null +++ b/clang-tools-extra/test/clang-tidy/checkers/misc/Inputs/use-internal-linkage/func.h @@ -0,0 +1,5 @@ +#pragma once + +void func_header(); + +#include "func_h.inc" diff --git a/clang-tools-extra/test/clang-tidy/checkers/misc/Inputs/use-internal-linkage/func_cpp.inc b/clang-tools-extra/test/clang-tidy/checkers/misc/Inputs/use-internal-linkage/func_cpp.inc new file mode 100644 index 0000000000000000000000000000000000000000..97e026f0116e99542d83e9fccda74bf4262469ef --- /dev/null +++ b/clang-tools-extra/test/clang-tidy/checkers/misc/Inputs/use-internal-linkage/func_cpp.inc @@ -0,0 +1 @@ +void func_cpp_inc(); diff --git a/clang-tools-extra/test/clang-tidy/checkers/misc/Inputs/use-internal-linkage/func_h.inc b/clang-tools-extra/test/clang-tidy/checkers/misc/Inputs/use-internal-linkage/func_h.inc new file mode 100644 index 0000000000000000000000000000000000000000..1130f710edd7c3d5090daed8e148fc3e7a6e290d --- /dev/null +++ b/clang-tools-extra/test/clang-tidy/checkers/misc/Inputs/use-internal-linkage/func_h.inc @@ -0,0 +1 @@ +void func_h_inc(); diff --git a/clang-tools-extra/test/clang-tidy/checkers/misc/Inputs/use-internal-linkage/var.h b/clang-tools-extra/test/clang-tidy/checkers/misc/Inputs/use-internal-linkage/var.h new file mode 100644 index 0000000000000000000000000000000000000000..37e4cfbafff1460fd214cebc89357193f4e9ade7 --- /dev/null +++ b/clang-tools-extra/test/clang-tidy/checkers/misc/Inputs/use-internal-linkage/var.h @@ -0,0 +1,3 @@ +#pragma once + +extern int gloabl_header; diff --git a/clang-tools-extra/test/clang-tidy/checkers/misc/header-include-cycle.self.cpp b/clang-tools-extra/test/clang-tidy/checkers/misc/header-include-cycle.self.cpp new file mode 100644 index 0000000000000000000000000000000000000000..245dd0a65a8b42bf696e20586783de572a865bac --- /dev/null +++ b/clang-tools-extra/test/clang-tidy/checkers/misc/header-include-cycle.self.cpp @@ -0,0 +1,3 @@ +// RUN: not clang-tidy %s -checks='-*,misc-header-include-cycle' + +#include "header-include-cycle.self.cpp" diff --git a/clang-tools-extra/test/clang-tidy/checkers/misc/use-internal-linkage-func.cpp b/clang-tools-extra/test/clang-tidy/checkers/misc/use-internal-linkage-func.cpp new file mode 100644 index 0000000000000000000000000000000000000000..c6c513fe0b0c06329029499bd0d3729d18ffb1db --- /dev/null +++ b/clang-tools-extra/test/clang-tidy/checkers/misc/use-internal-linkage-func.cpp @@ -0,0 +1,37 @@ +// RUN: %check_clang_tidy %s misc-use-internal-linkage %t -- -- -I%S/Inputs/use-internal-linkage + +#include "func.h" + +void func() {} +// CHECK-MESSAGES: :[[@LINE-1]]:6: warning: function 'func' + +template +void func_template() {} +// CHECK-MESSAGES: :[[@LINE-1]]:6: warning: function 'func_template' + +void func_cpp_inc(); +// CHECK-MESSAGES: :[[@LINE-1]]:6: warning: function 'func_cpp_inc' + +#include "func_cpp.inc" + +void func_h_inc(); + +struct S { + void method(); +}; +void S::method() {} + +void func_header(); +extern void func_extern(); +static void func_static(); +namespace { +void func_anonymous_ns(); +} // namespace + +int main(int argc, const char*argv[]) {} + +extern "C" { +void func_extern_c_1() {} +} + +extern "C" void func_extern_c_2() {} diff --git a/clang-tools-extra/test/clang-tidy/checkers/misc/use-internal-linkage-var.cpp b/clang-tools-extra/test/clang-tidy/checkers/misc/use-internal-linkage-var.cpp new file mode 100644 index 0000000000000000000000000000000000000000..bd5ef5431de6ccdd23bb9851f37b8f1af20c1bea --- /dev/null +++ b/clang-tools-extra/test/clang-tidy/checkers/misc/use-internal-linkage-var.cpp @@ -0,0 +1,40 @@ +// RUN: %check_clang_tidy %s misc-use-internal-linkage %t -- -- -I%S/Inputs/use-internal-linkage + +#include "var.h" + +int global; +// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: variable 'global' + +template +T global_template; +// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: variable 'global_template' + +int gloabl_header; + +extern int global_extern; + +static int global_static; + +namespace { +static int global_anonymous_ns; +namespace NS { +static int global_anonymous_ns; +} +} + +static void f(int para) { + int local; + static int local_static; +} + +struct S { + int m1; + static int m2; +}; +int S::m2; + +extern "C" { +int global_in_extern_c_1; +} + +extern "C" int global_in_extern_c_2; diff --git a/clang-tools-extra/test/clang-tidy/checkers/modernize/use-designated-initializers.cpp b/clang-tools-extra/test/clang-tidy/checkers/modernize/use-designated-initializers.cpp index 7e5c26e3f4404a1759c225a9a50501718d7c19bc..9b769ad0be23cab8e399bea24797f95b45973a46 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/modernize/use-designated-initializers.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/modernize/use-designated-initializers.cpp @@ -1,13 +1,13 @@ -// RUN: %check_clang_tidy -std=c++17 %s modernize-use-designated-initializers %t \ +// RUN: %check_clang_tidy -std=c++20 %s modernize-use-designated-initializers %t \ // RUN: -- \ // RUN: -- -fno-delayed-template-parsing -// RUN: %check_clang_tidy -check-suffixes=,SINGLE-ELEMENT -std=c++17 %s modernize-use-designated-initializers %t \ +// RUN: %check_clang_tidy -check-suffixes=,SINGLE-ELEMENT -std=c++20 %s modernize-use-designated-initializers %t \ // RUN: -- -config="{CheckOptions: {modernize-use-designated-initializers.IgnoreSingleElementAggregates: false}}" \ // RUN: -- -fno-delayed-template-parsing -// RUN: %check_clang_tidy -check-suffixes=POD -std=c++17 %s modernize-use-designated-initializers %t \ +// RUN: %check_clang_tidy -check-suffixes=POD -std=c++20 %s modernize-use-designated-initializers %t \ // RUN: -- -config="{CheckOptions: {modernize-use-designated-initializers.RestrictToPODTypes: true}}" \ // RUN: -- -fno-delayed-template-parsing -// RUN: %check_clang_tidy -check-suffixes=,MACROS -std=c++17 %s modernize-use-designated-initializers %t \ +// RUN: %check_clang_tidy -check-suffixes=,MACROS -std=c++20 %s modernize-use-designated-initializers %t \ // RUN: -- -config="{CheckOptions: {modernize-use-designated-initializers.IgnoreMacros: false}}" \ // RUN: -- -fno-delayed-template-parsing diff --git a/clang-tools-extra/test/clang-tidy/checkers/performance/unnecessary-copy-initialization.cpp b/clang-tools-extra/test/clang-tidy/checkers/performance/unnecessary-copy-initialization.cpp index 92625cc1332e286296075f4ef2e2b7654cb308ed..f259552dc8f1d89fd1d36eb9e17876fb08d3c68b 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/performance/unnecessary-copy-initialization.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/performance/unnecessary-copy-initialization.cpp @@ -32,6 +32,9 @@ struct ExpensiveToCopyType { template struct Container { + using reference = T&; + using const_reference = const T&; + bool empty() const; const T& operator[](int) const; const T& operator[](int); @@ -42,8 +45,8 @@ struct Container { void nonConstMethod(); bool constMethod() const; - const T& at(int) const; - T& at(int); + reference at(int) const; + const_reference at(int); }; @@ -207,6 +210,28 @@ void PositiveOperatorCallConstValueParam(const Container C) VarCopyConstructed.constMethod(); } +void PositiveOperatorValueParam(Container C) { + const auto AutoAssigned = C[42]; + // CHECK-MESSAGES: [[@LINE-1]]:14: warning: the const qualified variable 'AutoAssigned' + // CHECK-FIXES: const auto& AutoAssigned = C[42]; + AutoAssigned.constMethod(); + + const auto AutoCopyConstructed(C[42]); + // CHECK-MESSAGES: [[@LINE-1]]:14: warning: the const qualified variable 'AutoCopyConstructed' + // CHECK-FIXES: const auto& AutoCopyConstructed(C[42]); + AutoCopyConstructed.constMethod(); + + const ExpensiveToCopyType VarAssigned = C.at(42); + // CHECK-MESSAGES: [[@LINE-1]]:29: warning: the const qualified variable 'VarAssigned' + // CHECK-FIXES: const ExpensiveToCopyType& VarAssigned = C.at(42); + VarAssigned.constMethod(); + + const ExpensiveToCopyType VarCopyConstructed(C.at(42)); + // CHECK-MESSAGES: [[@LINE-1]]:29: warning: the const qualified variable 'VarCopyConstructed' + // CHECK-FIXES: const ExpensiveToCopyType& VarCopyConstructed(C.at(42)); + VarCopyConstructed.constMethod(); +} + void PositiveOperatorCallConstValueParamAlias(const ExpensiveToCopyContainerAlias C) { const auto AutoAssigned = C[42]; // CHECK-MESSAGES: [[@LINE-1]]:14: warning: the const qualified variable 'AutoAssigned' diff --git a/clang-tools-extra/test/clang-tidy/checkers/readability/container-size-empty.cpp b/clang-tools-extra/test/clang-tidy/checkers/readability/container-size-empty.cpp index ecaf97fa348cc1a4134659b0d39564fe9a2bc6c2..46755270b48ead3d093dbac3e574df6b7c781aa0 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/readability/container-size-empty.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/readability/container-size-empty.cpp @@ -889,3 +889,9 @@ namespace PR88203 { // CHECK-FIXES: {{^ }}if (s.empty()) {}{{$}} } } + +namespace PR94454 { + template + int operator""_ci() { return 0; } + auto eq = 0_ci == 0; +} diff --git a/clang-tools-extra/test/clang-tidy/checkers/readability/implicit-bool-conversion-cxx20.cpp b/clang-tools-extra/test/clang-tidy/checkers/readability/implicit-bool-conversion-cxx20.cpp new file mode 100644 index 0000000000000000000000000000000000000000..13aa5c5774b472e1416eabb1cbb2faa8079e829b --- /dev/null +++ b/clang-tools-extra/test/clang-tidy/checkers/readability/implicit-bool-conversion-cxx20.cpp @@ -0,0 +1,31 @@ +// RUN: %check_clang_tidy -std=c++20 %s readability-implicit-bool-conversion %t + +namespace std { +struct strong_ordering { + int n; + constexpr operator int() const { return n; } + static const strong_ordering equal, greater, less; +}; +constexpr strong_ordering strong_ordering::equal = {0}; +constexpr strong_ordering strong_ordering::greater = {1}; +constexpr strong_ordering strong_ordering::less = {-1}; +} // namespace std + +namespace PR93409 { + struct X + { + auto operator<=>(const X&) const = default; + bool m_b; + }; + + struct Y + { + auto operator<=>(const Y&) const = default; + X m_x; + }; + + bool compare(const Y& y1, const Y& y2) + { + return y1 == y2 || y1 < y2 || y1 > y2; + } +} diff --git a/clang-tools-extra/test/clang-tidy/checkers/readability/math-missing-parentheses.cpp b/clang-tools-extra/test/clang-tidy/checkers/readability/math-missing-parentheses.cpp index a6045c079a4823bb0852e64e15a0d8853bd13bc7..4face0bb3fe6805e1407c38cecd3b0e9b031b298 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/readability/math-missing-parentheses.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/readability/math-missing-parentheses.cpp @@ -140,3 +140,20 @@ void f(){ //CHECK-MESSAGES: :[[@LINE+1]]:13: warning: '*' has higher precedence than '+'; add parentheses to explicitly specify the order of operations [readability-math-missing-parentheses] int v = FUN5(0 + 1); } + +namespace PR92516 { + void f(int i) { + int j, k; + for (j = i + 1, k = 0; j < 1; ++j) {} + } + + void f2(int i) { + int j; + for (j = i + 1; j < 1; ++j) {} + } + + void f3(int i) { + int j; + for (j = i + 1, 2; j < 1; ++j) {} + } +} diff --git a/clang-tools-extra/test/clang-tidy/checkers/readability/redundant-member-init.cpp b/clang-tools-extra/test/clang-tidy/checkers/readability/redundant-member-init.cpp index 17b2714abca07b64b5545c580381d6b70d58a711..6f18a6043be93e95ed9f16167a822408d1729839 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/readability/redundant-member-init.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/readability/redundant-member-init.cpp @@ -302,3 +302,19 @@ struct D7 { D7 d7i; D7 d7s; + +struct SS { + SS() = default; + SS(S s) : s(s) {} + + S s; +}; + +struct D8 { + SS ss = S(); +}; + +struct D9 { + D9() : ss(S()) {} + SS ss; +}; diff --git a/clang-tools-extra/unittests/clang-tidy/DeclRefExprUtilsTest.cpp b/clang-tools-extra/unittests/clang-tidy/DeclRefExprUtilsTest.cpp index 3d9f51e2e17b0945bec574145a46a3437f9402df..064e04c932de83e212a035be7da8bf7c88a4f493 100644 --- a/clang-tools-extra/unittests/clang-tidy/DeclRefExprUtilsTest.cpp +++ b/clang-tools-extra/unittests/clang-tidy/DeclRefExprUtilsTest.cpp @@ -46,6 +46,7 @@ template void RunTest(StringRef Snippet) { StringRef CommonCode = R"( struct ConstTag{}; struct NonConstTag{}; + struct Tag1{}; struct S { void constMethod() const; @@ -59,6 +60,13 @@ template void RunTest(StringRef Snippet) { void operator[](int); void operator[](int) const; + int& at(int); + const int& at(int) const; + const int& at(Tag1); + + int& weird_overload(); + const double& weird_overload() const; + bool operator==(const S&) const; int int_member; @@ -161,9 +169,11 @@ TEST(ConstReferenceDeclRefExprsTest, ConstRefVar) { useIntConstRef(/*const*/target.int_member); useIntPtr(/*const*/target.ptr_member); useIntConstPtr(&/*const*/target.int_member); + (void)/*const*/target.at(3); const S& const_target_ref = /*const*/target; const S* const_target_ptr = &/*const*/target; + (void)/*const*/target.at(3); } )"); } @@ -187,7 +197,7 @@ TEST(ConstReferenceDeclRefExprsTest, ValueVar) { /*const*/target.staticMethod(); target.nonConstMethod(); /*const*/target(ConstTag{}); - target[42]; + /*const*/target[42]; /*const*/target(ConstTag{}); target(NonConstTag{}); useRef(target); @@ -211,6 +221,14 @@ TEST(ConstReferenceDeclRefExprsTest, ValueVar) { const S& const_target_ref = /*const*/target; const S* const_target_ptr = &/*const*/target; S* target_ptr = ⌖ + + (void)/*const*/target.at(3); + ++target.at(3); + const int civ = /*const*/target.at(3); + const int& cir = /*const*/target.at(3); + int& ir = target.at(3); + target.at(Tag1{}); + target.weird_overload(); } )"); } @@ -227,7 +245,7 @@ TEST(ConstReferenceDeclRefExprsTest, RefVar) { /*const*/target.staticMethod(); target.nonConstMethod(); /*const*/target(ConstTag{}); - target[42]; + /*const*/target[42]; useConstRef((/*const*/target)); (/*const*/target).constMethod(); (void)(/*const*/target == /*const*/target); @@ -249,6 +267,14 @@ TEST(ConstReferenceDeclRefExprsTest, RefVar) { const S& const_target_ref = /*const*/target; const S* const_target_ptr = &/*const*/target; S* target_ptr = ⌖ + + (void)/*const*/target.at(3); + ++target.at(3); + const int civ = /*const*/target.at(3); + const int& cir = /*const*/target.at(3); + int& ir = target.at(3); + target.at(Tag1{}); + target.weird_overload(); } )"); } @@ -266,8 +292,8 @@ TEST(ConstReferenceDeclRefExprsTest, PtrVar) { /*const*/target->staticMethod(); target->nonConstMethod(); (*/*const*/target)(ConstTag{}); - (*target)[42]; - target->operator[](42); + (*/*const*/target)[42]; + /*const*/target->operator[](42); useConstRef((*/*const*/target)); (/*const*/target)->constMethod(); (void)(*/*const*/target == */*const*/target); @@ -284,7 +310,15 @@ TEST(ConstReferenceDeclRefExprsTest, PtrVar) { const S& const_target_ref = */*const*/target; const S* const_target_ptr = /*const*/target; - S* target_ptr = target; // FIXME: we could chect const usage of `target_ptr`. + S* target_ptr = target; // FIXME: we could chect const usage of `target_ptr` + + (void)/*const*/target->at(3); + ++target->at(3); + const int civ = /*const*/target->at(3); + const int& cir = /*const*/target->at(3); + int& ir = target->at(3); + target->at(Tag1{}); + target->weird_overload(); } )"); } @@ -319,6 +353,10 @@ TEST(ConstReferenceDeclRefExprsTest, ConstPtrVar) { const S& const_target_ref = */*const*/target; const S* const_target_ptr = /*const*/target; + + (void)/*const*/target->at(3); + const int civ = /*const*/target->at(3); + const int& cir = /*const*/target->at(3); } )"); } diff --git a/clang/CMakeLists.txt b/clang/CMakeLists.txt index 2ac0bccb42f50d1a2fbf5527ce02831dff7cfd55..c6496167d3828b9089c2419cd4725090a3f4d94e 100644 --- a/clang/CMakeLists.txt +++ b/clang/CMakeLists.txt @@ -350,7 +350,9 @@ if (LLVM_COMPILER_IS_GCC_COMPATIBLE) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pedantic -Wno-long-long") endif () - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-nested-anon-types" ) + if (CMAKE_CXX_COMPILER_ID MATCHES "Clang") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-nested-anon-types" ) + endif () endif () # Determine HOST_LINK_VERSION on Darwin. @@ -848,23 +850,17 @@ if (CLANG_ENABLE_BOOTSTRAP) set(CLANG_BOOTSTRAP_TARGETS check-llvm check-clang check-all) endif() foreach(target ${CLANG_BOOTSTRAP_TARGETS}) - # Install targets have side effects, so we always want to execute them. - # "install" is reserved by CMake and can't be used as a step name for - # ExternalProject_Add_Step, so we can match against "^install-" instead of - # "^install" to get a tighter match. CMake's installation scripts already - # skip up-to-date files, so there's no behavior change if you install to the - # same destination multiple times. - if(target MATCHES "^install-") - set(step_always ON) - else() - set(step_always OFF) - endif() ExternalProject_Add_Step(${NEXT_CLANG_STAGE} ${target} COMMAND ${CMAKE_COMMAND} --build --target ${target} COMMENT "Performing ${target} for '${NEXT_CLANG_STAGE}'" DEPENDEES configure - ALWAYS ${step_always} + # We need to set ALWAYS to ON here, otherwise these targets won't be + # built on a second invocation of ninja. The targets have their own + # logic to determine if they should build or not so setting ALWAYS ON + # here does not mean the targets will always rebuild it just means that + # they will check their dependenices and see if they need to be built. + ALWAYS ON EXCLUDE_FROM_MAIN ON USES_TERMINAL 1 ) diff --git a/clang/cmake/caches/CrossWinToARMLinux.cmake b/clang/cmake/caches/CrossWinToARMLinux.cmake index 6826d01f8b2a7381fb9c9c4bc245d2f6c7816bee..e4d0a0c2d14cb9a1d3589fd440969761cd34c0a3 100644 --- a/clang/cmake/caches/CrossWinToARMLinux.cmake +++ b/clang/cmake/caches/CrossWinToARMLinux.cmake @@ -6,21 +6,23 @@ # on Windows platform. # # NOTE: the build requires a development ARM Linux root filesystem to use -# proper target platform depended library and header files: -# - create directory and put the clang configuration -# file named .cfg into it. -# - add the `--sysroot=` argument into -# this configuration file. -# - add other necessary target depended clang arguments there, -# such as '-mcpu=cortex-a78' & etc. +# proper target platform depended library and header files. +# +# The build generates a proper clang configuration file with stored +# --sysroot argument for specified target triple. Also it is possible +# to specify configuration path via CMake arguments, such as +# -DCLANG_CONFIG_FILE_USER_DIR= +# and/or +# -DCLANG_CONFIG_FILE_SYSTEM_DIR= # # See more details here: https://clang.llvm.org/docs/UsersManual.html#configuration-files # # Configure: # cmake -G Ninja ^ # -DTOOLCHAIN_TARGET_TRIPLE=aarch64-unknown-linux-gnu ^ +# -DTOOLCHAIN_TARGET_SYSROOTFS= ^ +# -DTOOLCHAIN_SHARED_LIBS=OFF ^ # -DCMAKE_INSTALL_PREFIX=../install ^ -# -DCLANG_CONFIG_FILE_USER_DIR= ^ # -DCMAKE_CXX_FLAGS="-D__OPTIMIZE__" ^ # -DREMOTE_TEST_HOST="" ^ # -DREMOTE_TEST_USER="" ^ @@ -81,6 +83,20 @@ endif() message(STATUS "Toolchain target triple: ${TOOLCHAIN_TARGET_TRIPLE}") +if (DEFINED TOOLCHAIN_TARGET_SYSROOTFS) + message(STATUS "Toolchain target sysroot: ${TOOLCHAIN_TARGET_SYSROOTFS}") + # Store the --sysroot argument for the compiler-rt test flags. + set(sysroot_flags --sysroot='${TOOLCHAIN_TARGET_SYSROOTFS}') + # Generate the clang configuration file for the specified target triple + # and store --sysroot in this file. + file(WRITE "${CMAKE_BINARY_DIR}/bin/${TOOLCHAIN_TARGET_TRIPLE}.cfg" ${sysroot_flags}) +endif() + +# Build the shared libraries for libc++/libc++abi/libunwind. +if (NOT DEFINED TOOLCHAIN_SHARED_LIBS) + set(TOOLCHAIN_SHARED_LIBS OFF) +endif() + if (NOT DEFINED LLVM_TARGETS_TO_BUILD) if ("${TOOLCHAIN_TARGET_TRIPLE}" MATCHES "^(armv|arm32)+") set(LLVM_TARGETS_TO_BUILD "ARM" CACHE STRING "") @@ -183,20 +199,21 @@ set(RUNTIMES_${TOOLCHAIN_TARGET_TRIPLE}_COMPILER_RT_CAN_EXECUTE_TESTS set(RUNTIMES_${TOOLCHAIN_TARGET_TRIPLE}_COMPILER_RT_USE_BUILTINS_LIBRARY ON CACHE BOOL "") set(RUNTIMES_${TOOLCHAIN_TARGET_TRIPLE}_COMPILER_RT_CXX_LIBRARY libcxx CACHE STRING "") -# Tell Clang to seach C++ headers alongside with the just-built binaries for the C++ compiler-rt tests. -set(RUNTIMES_${TOOLCHAIN_TARGET_TRIPLE}_COMPILER_RT_TEST_COMPILER_CFLAGS "--stdlib=libc++" CACHE STRING "") - +# The compiler-rt tests disable the clang configuration files during the execution by setting CLANG_NO_DEFAULT_CONFIG=1 +# and drops out the --sysroot from there. Provide it explicity via the test flags here if target sysroot has been specified. +set(RUNTIMES_${TOOLCHAIN_TARGET_TRIPLE}_COMPILER_RT_TEST_COMPILER_CFLAGS "--stdlib=libc++ ${sysroot_flags}" CACHE STRING "") + set(RUNTIMES_${TOOLCHAIN_TARGET_TRIPLE}_LIBUNWIND_USE_COMPILER_RT ON CACHE BOOL "") -set(RUNTIMES_${TOOLCHAIN_TARGET_TRIPLE}_LIBUNWIND_ENABLE_SHARED OFF CACHE BOOL "") +set(RUNTIMES_${TOOLCHAIN_TARGET_TRIPLE}_LIBUNWIND_ENABLE_SHARED ${TOOLCHAIN_SHARED_LIBS} CACHE BOOL "") set(RUNTIMES_${TOOLCHAIN_TARGET_TRIPLE}_LIBCXXABI_USE_LLVM_UNWINDER ON CACHE BOOL "") set(RUNTIMES_${TOOLCHAIN_TARGET_TRIPLE}_LIBCXXABI_ENABLE_STATIC_UNWINDER ON CACHE BOOL "") set(RUNTIMES_${TOOLCHAIN_TARGET_TRIPLE}_LIBCXXABI_USE_COMPILER_RT ON CACHE BOOL "") set(RUNTIMES_${TOOLCHAIN_TARGET_TRIPLE}_LIBCXXABI_ENABLE_NEW_DELETE_DEFINITIONS OFF CACHE BOOL "") -set(RUNTIMES_${TOOLCHAIN_TARGET_TRIPLE}_LIBCXXABI_ENABLE_SHARED OFF CACHE BOOL "") +set(RUNTIMES_${TOOLCHAIN_TARGET_TRIPLE}_LIBCXXABI_ENABLE_SHARED ${TOOLCHAIN_SHARED_LIBS} CACHE BOOL "") set(RUNTIMES_${TOOLCHAIN_TARGET_TRIPLE}_LIBCXX_USE_COMPILER_RT ON CACHE BOOL "") -set(RUNTIMES_${TOOLCHAIN_TARGET_TRIPLE}_LIBCXX_ENABLE_SHARED OFF CACHE BOOL "") +set(RUNTIMES_${TOOLCHAIN_TARGET_TRIPLE}_LIBCXX_ENABLE_SHARED ${TOOLCHAIN_SHARED_LIBS} CACHE BOOL "") set(RUNTIMES_${TOOLCHAIN_TARGET_TRIPLE}_LIBCXX_ABI_VERSION ${LIBCXX_ABI_VERSION} CACHE STRING "") set(RUNTIMES_${TOOLCHAIN_TARGET_TRIPLE}_LIBCXX_CXX_ABI "libcxxabi" CACHE STRING "") #!!! set(RUNTIMES_${TOOLCHAIN_TARGET_TRIPLE}_LIBCXX_ENABLE_NEW_DELETE_DEFINITIONS ON CACHE BOOL "") diff --git a/clang/cmake/caches/Release.cmake b/clang/cmake/caches/Release.cmake index c0bfcbdfc1c2ae6cb32edfcb26e376baa1dd2641..9e6feb479d45fc81d21614e9beee7037dca14e42 100644 --- a/clang/cmake/caches/Release.cmake +++ b/clang/cmake/caches/Release.cmake @@ -30,7 +30,7 @@ endfunction() # # cmake -D LLVM_RELEASE_ENABLE_PGO=ON -C Release.cmake set(LLVM_RELEASE_ENABLE_LTO THIN CACHE STRING "") -set(LLVM_RELEASE_ENABLE_PGO OFF CACHE BOOL "") +set(LLVM_RELEASE_ENABLE_PGO ON CACHE BOOL "") set(LLVM_RELEASE_ENABLE_RUNTIMES "compiler-rt;libcxx;libcxxabi;libunwind" CACHE STRING "") set(LLVM_RELEASE_ENABLE_PROJECTS "clang;lld;lldb;clang-tools-extra;bolt;polly;mlir;flang" CACHE STRING "") # Note we don't need to add install here, since it is one of the pre-defined @@ -91,4 +91,6 @@ endif() # Final Stage Config (stage2) set_final_stage_var(LLVM_ENABLE_RUNTIMES "${LLVM_RELEASE_ENABLE_RUNTIMES}" STRING) set_final_stage_var(LLVM_ENABLE_PROJECTS "${LLVM_RELEASE_ENABLE_PROJECTS}" STRING) +set_final_stage_var(CPACK_GENERATOR "TXZ" STRING) +set_final_stage_var(CPACK_ARCHIVE_THREADS "0" STRING) diff --git a/clang/docs/LanguageExtensions.rst b/clang/docs/LanguageExtensions.rst index 46f99d0bbdd066932de0adbb7cb83ff5322ae36e..a49e4122ffc100801a2d40c34a13e3938e2ee79e 100644 --- a/clang/docs/LanguageExtensions.rst +++ b/clang/docs/LanguageExtensions.rst @@ -4016,6 +4016,30 @@ Note that the `size` argument must be a compile time constant. Note that this intrinsic cannot yet be called in a ``constexpr`` context. +``__is_bitwise_cloneable`` +-------------------------- + +A type trait is used to check whether a type can be safely copied by memcpy. + +**Syntax**: + +.. code-block:: c++ + + bool __is_bitwise_cloneable(Type) + +**Description**: + +Objects of bitwise cloneable types can be bitwise copied by memcpy/memmove. The +Clang compiler warrants that this behavior is well defined, and won't be +broken by compiler optimizations and sanitizers. + +For implicit-lifetime types, the lifetime of the new object is implicitly +started after the copy. For other types (e.g., classes with virtual methods), +the lifetime isn't started, and using the object results in undefined behavior +according to the C++ Standard. + +This builtin can be used in constant expressions. + Atomic Min/Max builtins with memory ordering -------------------------------------------- diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index deb1560b781eef28afa293e4943897f89a91baa7..cf1ba02cbc4b2f59534acf4c43a7153f65b32134 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -214,6 +214,9 @@ C++23 Feature Support - Added a ``__reference_converts_from_temporary`` builtin, completing the necessary compiler support for `P2255R2: Type trait to determine if a reference binds to a temporary `_. +- Implemented `P2797R0: Static and explicit object member functions with the same parameter-type-lists `_. + This completes the support for "deducing this". + C++2c Feature Support ^^^^^^^^^^^^^^^^^^^^^ @@ -337,6 +340,9 @@ Non-comprehensive list of changes in this release ``-Winvalid-constexpr`` is not enabled for the function definition, which should result in mild compile-time performance improvements. +- Added ``__is_bitwise_cloneable`` which is used to check whether a type + can be safely copied by memcpy/memmove. + New Compiler Flags ------------------ - ``-fsanitize=implicit-bitfield-conversion`` checks implicit truncation and @@ -901,6 +907,7 @@ Arm and AArch64 Support * Arm Cortex-A520AE (cortex-a520ae). * Arm Cortex-A720AE (cortex-a720ae). * Arm Cortex-R82AE (cortex-r82ae). + * Arm Cortex-R52+ (cortex-r52plus). * Arm Neoverse-N3 (neoverse-n3). * Arm Neoverse-V3 (neoverse-v3). * Arm Neoverse-V3AE (neoverse-v3ae). @@ -951,7 +958,7 @@ CUDA/HIP Language Changes CUDA Support ^^^^^^^^^^^^ -- Clang now supports CUDA SDK up to 12.4 +- Clang now supports CUDA SDK up to 12.5 AIX Support ^^^^^^^^^^^ diff --git a/clang/docs/analyzer/checkers.rst b/clang/docs/analyzer/checkers.rst index 1ae6e9c000420869772e51df45678962e6861e8f..f53dd545df5a9ecb4dbb73bfed2b6663d04e9b99 100644 --- a/clang/docs/analyzer/checkers.rst +++ b/clang/docs/analyzer/checkers.rst @@ -599,7 +599,7 @@ Warns when a nullable pointer is returned from a function that has _Nonnull retu optin ^^^^^ -Checkers for portability, performance or coding style specific rules. +Checkers for portability, performance, optional security and coding style specific rules. .. _optin-core-EnumCastOutOfRange: @@ -938,6 +938,53 @@ optin.portability.UnixAPI """"""""""""""""""""""""" Finds implementation-defined behavior in UNIX/Posix functions. +.. _optin-taint-TaintedAlloc: + +optin.taint.TaintedAlloc (C, C++) +""""""""""""""""""""""""""""""""" + +This checker warns for cases when the ``size`` parameter of the ``malloc`` , +``calloc``, ``realloc``, ``alloca`` or the size parameter of the +array new C++ operator is tainted (potentially attacker controlled). +If an attacker can inject a large value as the size parameter, memory exhaustion +denial of service attack can be carried out. + +The ``alpha.security.taint.TaintPropagation`` checker also needs to be enabled for +this checker to give warnings. + +The analyzer emits warning only if it cannot prove that the size parameter is +within reasonable bounds (``<= SIZE_MAX/4``). This functionality partially +covers the SEI Cert coding standard rule `INT04-C +`_. + +You can silence this warning either by bound checking the ``size`` parameter, or +by explicitly marking the ``size`` parameter as sanitized. See the +:ref:`alpha-security-taint-TaintPropagation` checker for more details. + +.. code-block:: c + + void vulnerable(void) { + size_t size = 0; + scanf("%zu", &size); + int *p = malloc(size); // warn: malloc is called with a tainted (potentially attacker controlled) value + free(p); + } + + void not_vulnerable(void) { + size_t size = 0; + scanf("%zu", &size); + if (1024 < size) + return; + int *p = malloc(size); // No warning expected as the the user input is bound + free(p); + } + + void vulnerable_cpp(void) { + size_t size = 0; + scanf("%zu", &size); + int *ptr = new int[size];// warn: Memory allocation function is called with a tainted (potentially attacker controlled) value + delete[] ptr; + } .. _security-checkers: diff --git a/clang/docs/tools/clang-formatted-files.txt b/clang/docs/tools/clang-formatted-files.txt index dee51e402b687fa36f598a6ba22262cdb871e173..4866bd4aee634fc18bd808fdb429dc9c7fcd0f13 100644 --- a/clang/docs/tools/clang-formatted-files.txt +++ b/clang/docs/tools/clang-formatted-files.txt @@ -622,6 +622,7 @@ clang/tools/libclang/CXCursor.h clang/tools/scan-build-py/tests/functional/src/include/clean-one.h clang/unittests/Analysis/CFGBuildResult.h clang/unittests/Analysis/MacroExpansionContextTest.cpp +clang/unittests/Analysis/FlowSensitive/ASTOpsTest.cpp clang/unittests/Analysis/FlowSensitive/CNFFormula.cpp clang/unittests/Analysis/FlowSensitive/DataflowAnalysisContextTest.cpp clang/unittests/Analysis/FlowSensitive/DataflowEnvironmentTest.cpp diff --git a/clang/examples/PrintFunctionNames/PrintFunctionNames.cpp b/clang/examples/PrintFunctionNames/PrintFunctionNames.cpp index 6509a6440e12d5d7e67943a2c86396ea7a4cb1e7..b2b785b87c25cf0975eb84350f6d7cd5b32c45cb 100644 --- a/clang/examples/PrintFunctionNames/PrintFunctionNames.cpp +++ b/clang/examples/PrintFunctionNames/PrintFunctionNames.cpp @@ -72,7 +72,7 @@ public: *sema.LateParsedTemplateMap.find(FD)->second; sema.LateTemplateParser(sema.OpaqueParser, LPT); llvm::errs() << "late-parsed-decl: \"" << FD->getNameAsString() << "\"\n"; - } + } } }; diff --git a/clang/include/clang-c/Index.h b/clang/include/clang-c/Index.h index 365b607c741179e94146e57d3909e164857a9960..ce2282937f86cbc3144fc84ad226f64eea833a3a 100644 --- a/clang/include/clang-c/Index.h +++ b/clang/include/clang-c/Index.h @@ -2150,7 +2150,11 @@ enum CXCursorKind { */ CXCursor_OpenACCComputeConstruct = 320, - CXCursor_LastStmt = CXCursor_OpenACCComputeConstruct, + /** OpenACC Loop Construct. + */ + CXCursor_OpenACCLoopConstruct = 321, + + CXCursor_LastStmt = CXCursor_OpenACCLoopConstruct, /** * Cursor that represents the translation unit itself. diff --git a/clang/include/clang/AST/ASTUnresolvedSet.h b/clang/include/clang/AST/ASTUnresolvedSet.h index 398ffb188c95b04abe266b104f9fe722926ede2f..dcce3bc63df2521f5f79cc9ea70b0b9d9e3918a1 100644 --- a/clang/include/clang/AST/ASTUnresolvedSet.h +++ b/clang/include/clang/AST/ASTUnresolvedSet.h @@ -16,6 +16,7 @@ #include "clang/AST/ASTVector.h" #include "clang/AST/DeclAccessPair.h" +#include "clang/AST/DeclID.h" #include "clang/AST/UnresolvedSet.h" #include "clang/Basic/Specifiers.h" #include @@ -56,6 +57,10 @@ public: Decls.push_back(DeclAccessPair::make(D, AS), C); } + void addLazyDecl(ASTContext &C, GlobalDeclID ID, AccessSpecifier AS) { + Decls.push_back(DeclAccessPair::makeLazy(ID.get(), AS), C); + } + /// Replaces the given declaration with the new one, once. /// /// \return true if the set changed @@ -109,10 +114,10 @@ public: void reserve(ASTContext &C, unsigned N) { Impl.reserve(C, N); } - void addLazyDecl(ASTContext &C, uintptr_t ID, AccessSpecifier AS) { + void addLazyDecl(ASTContext &C, GlobalDeclID ID, AccessSpecifier AS) { assert(Impl.empty() || Impl.Decls.isLazy()); Impl.Decls.setLazy(true); - Impl.addDecl(C, reinterpret_cast(ID << 2), AS); + Impl.addLazyDecl(C, ID, AS); } }; diff --git a/clang/include/clang/AST/CommentCommands.td b/clang/include/clang/AST/CommentCommands.td index e839031752cdd8e41debe9df32af6f83fb784bdc..06b2fa9b5531c6b3957c3ba16e10ba0705dcf6cf 100644 --- a/clang/include/clang/AST/CommentCommands.td +++ b/clang/include/clang/AST/CommentCommands.td @@ -132,9 +132,9 @@ def Tparam : BlockCommand<"tparam"> { let IsTParamCommand = 1; } // HeaderDoc command for template parameter documentation. def Templatefield : BlockCommand<"templatefield"> { let IsTParamCommand = 1; } -def Throws : BlockCommand<"throws"> { let IsThrowsCommand = 1; } -def Throw : BlockCommand<"throw"> { let IsThrowsCommand = 1; } -def Exception : BlockCommand<"exception"> { let IsThrowsCommand = 1; } +def Throws : BlockCommand<"throws"> { let IsThrowsCommand = 1; let NumArgs = 1; } +def Throw : BlockCommand<"throw"> { let IsThrowsCommand = 1; let NumArgs = 1; } +def Exception : BlockCommand<"exception"> { let IsThrowsCommand = 1; let NumArgs = 1;} def Deprecated : BlockCommand<"deprecated"> { let IsEmptyParagraphAllowed = 1; diff --git a/clang/include/clang/AST/CommentParser.h b/clang/include/clang/AST/CommentParser.h index e11e818b1af0a17aaab8b2cf724ae3f3df6f4540..a2d0e30835e2c451eba16c77fe3842e71fcf3326 100644 --- a/clang/include/clang/AST/CommentParser.h +++ b/clang/include/clang/AST/CommentParser.h @@ -100,6 +100,11 @@ public: ArrayRef parseCommandArgs(TextTokenRetokenizer &Retokenizer, unsigned NumArgs); + /// Parse arguments for \throws command supported args are in form of class + /// or template. + ArrayRef + parseThrowCommandArgs(TextTokenRetokenizer &Retokenizer, unsigned NumArgs); + BlockCommandComment *parseBlockCommand(); InlineCommandComment *parseInlineCommand(); diff --git a/clang/include/clang/AST/DeclAccessPair.h b/clang/include/clang/AST/DeclAccessPair.h index 805342c2910a7177a9f1403d8472a837c35b1b8f..4becfde963057247f8a5d56fe76a6fc548aa8a33 100644 --- a/clang/include/clang/AST/DeclAccessPair.h +++ b/clang/include/clang/AST/DeclAccessPair.h @@ -19,6 +19,7 @@ #include "clang/Basic/Specifiers.h" #include "llvm/Support/DataTypes.h" +#include "llvm/Support/Endian.h" namespace clang { @@ -27,9 +28,17 @@ class NamedDecl; /// A POD class for pairing a NamedDecl* with an access specifier. /// Can be put into unions. class DeclAccessPair { - uintptr_t Ptr; // we'd use llvm::PointerUnion, but it isn't trivial + /// Use the lower 2 bit to store AccessSpecifier. Use the higher + /// 61 bit to store the pointer to a NamedDecl or the DeclID to + /// a NamedDecl. If the 3rd bit is set, storing the DeclID, otherwise + /// storing the pointer. + llvm::support::detail::packed_endian_specific_integral< + uint64_t, llvm::endianness::native, alignof(void *)> + Ptr; - enum { Mask = 0x3 }; + enum { ASMask = 0x3, Mask = 0x7 }; + + bool isDeclID() const { return (Ptr >> 2) & 0x1; } public: static DeclAccessPair make(NamedDecl *D, AccessSpecifier AS) { @@ -38,12 +47,22 @@ public: return p; } + static DeclAccessPair makeLazy(uint64_t ID, AccessSpecifier AS) { + DeclAccessPair p; + p.Ptr = (ID << 3) | (0x1 << 2) | uint64_t(AS); + return p; + } + + uint64_t getDeclID() const { + assert(isDeclID()); + return (~Mask & Ptr) >> 3; + } + NamedDecl *getDecl() const { + assert(!isDeclID()); return reinterpret_cast(~Mask & Ptr); } - AccessSpecifier getAccess() const { - return AccessSpecifier(Mask & Ptr); - } + AccessSpecifier getAccess() const { return AccessSpecifier(ASMask & Ptr); } void setDecl(NamedDecl *D) { set(D, getAccess()); @@ -52,12 +71,18 @@ public: set(getDecl(), AS); } void set(NamedDecl *D, AccessSpecifier AS) { - Ptr = uintptr_t(AS) | reinterpret_cast(D); + Ptr = uint64_t(AS) | reinterpret_cast(D); } operator NamedDecl*() const { return getDecl(); } NamedDecl *operator->() const { return getDecl(); } }; + +// Make sure DeclAccessPair is pointer-aligned types. +static_assert(alignof(DeclAccessPair) == alignof(void *)); +// Make sure DeclAccessPair is still POD. +static_assert(std::is_standard_layout_v && + std::is_trivial_v); } #endif diff --git a/clang/include/clang/AST/DeclBase.h b/clang/include/clang/AST/DeclBase.h index 600ce73c7f01995adcfaa0a1bd05997289e02aef..5f19af1891b74284358dd8195cb3572cee53ba21 100644 --- a/clang/include/clang/AST/DeclBase.h +++ b/clang/include/clang/AST/DeclBase.h @@ -708,10 +708,7 @@ public: /// Set the owning module ID. This may only be called for /// deserialized Decls. - void setOwningModuleID(unsigned ID) { - assert(isFromASTFile() && "Only works on a deserialized declaration"); - *((unsigned*)this - 2) = ID; - } + void setOwningModuleID(unsigned ID); public: /// Determine the availability of the given declaration. @@ -784,19 +781,11 @@ public: /// Retrieve the global declaration ID associated with this /// declaration, which specifies where this Decl was loaded from. - GlobalDeclID getGlobalID() const { - if (isFromASTFile()) - return (*((const GlobalDeclID *)this - 1)); - return GlobalDeclID(); - } + GlobalDeclID getGlobalID() const; /// Retrieve the global ID of the module that owns this particular /// declaration. - unsigned getOwningModuleID() const { - if (isFromASTFile()) - return *((const unsigned*)this - 2); - return 0; - } + unsigned getOwningModuleID() const; private: Module *getOwningModuleSlow() const; diff --git a/clang/include/clang/AST/DeclID.h b/clang/include/clang/AST/DeclID.h index 614ba06b63860cdd13f7c1f2761c40231ca39275..32d2ed41a374a096636a204c4bc06e02f64ed6c7 100644 --- a/clang/include/clang/AST/DeclID.h +++ b/clang/include/clang/AST/DeclID.h @@ -19,6 +19,8 @@ #include "llvm/ADT/DenseMapInfo.h" #include "llvm/ADT/iterator.h" +#include + namespace clang { /// Predefined declaration IDs. @@ -107,12 +109,16 @@ public: /// /// DeclID should only be used directly in serialization. All other users /// should use LocalDeclID or GlobalDeclID. - using DeclID = uint32_t; + using DeclID = uint64_t; protected: DeclIDBase() : ID(PREDEF_DECL_NULL_ID) {} explicit DeclIDBase(DeclID ID) : ID(ID) {} + explicit DeclIDBase(unsigned LocalID, unsigned ModuleFileIndex) { + ID = (DeclID)LocalID | ((DeclID)ModuleFileIndex << 32); + } + public: DeclID get() const { return ID; } @@ -124,6 +130,10 @@ public: bool isInvalid() const { return ID == PREDEF_DECL_NULL_ID; } + unsigned getModuleFileIndex() const { return ID >> 32; } + + unsigned getLocalDeclIndex() const; + friend bool operator==(const DeclIDBase &LHS, const DeclIDBase &RHS) { return LHS.ID == RHS.ID; } @@ -156,6 +166,9 @@ public: LocalDeclID(PredefinedDeclIDs ID) : Base(ID) {} explicit LocalDeclID(DeclID ID) : Base(ID) {} + explicit LocalDeclID(unsigned LocalID, unsigned ModuleFileIndex) + : Base(LocalID, ModuleFileIndex) {} + LocalDeclID &operator++() { ++ID; return *this; @@ -175,6 +188,9 @@ public: GlobalDeclID() : Base() {} explicit GlobalDeclID(DeclID ID) : Base(ID) {} + explicit GlobalDeclID(unsigned LocalID, unsigned ModuleFileIndex) + : Base(LocalID, ModuleFileIndex) {} + // For DeclIDIterator to be able to convert a GlobalDeclID // to a LocalDeclID. explicit operator LocalDeclID() const { return LocalDeclID(this->ID); } diff --git a/clang/include/clang/AST/ExprCXX.h b/clang/include/clang/AST/ExprCXX.h index dbf693611a7fa56edf7a9345d0613a3a1af71f59..d2e8d936563595a0794e26be565e960fbc86c14f 100644 --- a/clang/include/clang/AST/ExprCXX.h +++ b/clang/include/clang/AST/ExprCXX.h @@ -3025,9 +3025,10 @@ protected: public: struct FindResult { - OverloadExpr *Expression; - bool IsAddressOfOperand; - bool HasFormOfMemberPointer; + OverloadExpr *Expression = nullptr; + bool IsAddressOfOperand = false; + bool IsAddressOfOperandWithParen = false; + bool HasFormOfMemberPointer = false; }; /// Finds the overloaded expression in the given expression \p E of @@ -3039,6 +3040,7 @@ public: assert(E->getType()->isSpecificBuiltinType(BuiltinType::Overload)); FindResult Result; + bool HasParen = isa(E); E = E->IgnoreParens(); if (isa(E)) { @@ -3048,10 +3050,9 @@ public: Result.HasFormOfMemberPointer = (E == Ovl && Ovl->getQualifier()); Result.IsAddressOfOperand = true; + Result.IsAddressOfOperandWithParen = HasParen; Result.Expression = Ovl; } else { - Result.HasFormOfMemberPointer = false; - Result.IsAddressOfOperand = false; Result.Expression = cast(E); } diff --git a/clang/include/clang/AST/OpenACCClause.h b/clang/include/clang/AST/OpenACCClause.h index 28ff8c44bd25698564251cb69d67e165f95bbd36..ea1ffbc7fd08b463ffa9aff0b32fa9ee44e6dc10 100644 --- a/clang/include/clang/AST/OpenACCClause.h +++ b/clang/include/clang/AST/OpenACCClause.h @@ -54,6 +54,149 @@ public: virtual ~OpenACCClause() = default; }; +// Represents the 'auto' clause. +class OpenACCAutoClause : public OpenACCClause { +protected: + OpenACCAutoClause(SourceLocation BeginLoc, SourceLocation EndLoc) + : OpenACCClause(OpenACCClauseKind::Auto, BeginLoc, EndLoc) {} + +public: + static bool classof(const OpenACCClause *C) { + return C->getClauseKind() == OpenACCClauseKind::Auto; + } + + static OpenACCAutoClause * + Create(const ASTContext &Ctx, SourceLocation BeginLoc, SourceLocation EndLoc); + + child_range children() { + return child_range(child_iterator(), child_iterator()); + } + const_child_range children() const { + return const_child_range(const_child_iterator(), const_child_iterator()); + } +}; + +// Represents the 'independent' clause. +class OpenACCIndependentClause : public OpenACCClause { +protected: + OpenACCIndependentClause(SourceLocation BeginLoc, SourceLocation EndLoc) + : OpenACCClause(OpenACCClauseKind::Independent, BeginLoc, EndLoc) {} + +public: + static bool classof(const OpenACCClause *C) { + return C->getClauseKind() == OpenACCClauseKind::Independent; + } + + static OpenACCIndependentClause * + Create(const ASTContext &Ctx, SourceLocation BeginLoc, SourceLocation EndLoc); + + child_range children() { + return child_range(child_iterator(), child_iterator()); + } + const_child_range children() const { + return const_child_range(const_child_iterator(), const_child_iterator()); + } +}; +// Represents the 'seq' clause. +class OpenACCSeqClause : public OpenACCClause { +protected: + OpenACCSeqClause(SourceLocation BeginLoc, SourceLocation EndLoc) + : OpenACCClause(OpenACCClauseKind::Seq, BeginLoc, EndLoc) {} + +public: + static bool classof(const OpenACCClause *C) { + return C->getClauseKind() == OpenACCClauseKind::Seq; + } + + static OpenACCSeqClause * + Create(const ASTContext &Ctx, SourceLocation BeginLoc, SourceLocation EndLoc); + + child_range children() { + return child_range(child_iterator(), child_iterator()); + } + const_child_range children() const { + return const_child_range(const_child_iterator(), const_child_iterator()); + } +}; + +// Not yet implemented, but the type name is necessary for 'seq' diagnostics, so +// this provides a basic, do-nothing implementation. We still need to add this +// type to the visitors/etc, as well as get it to take its proper arguments. +class OpenACCGangClause : public OpenACCClause { +protected: + OpenACCGangClause(SourceLocation BeginLoc, SourceLocation EndLoc) + : OpenACCClause(OpenACCClauseKind::Gang, BeginLoc, EndLoc) { + llvm_unreachable("Not yet implemented"); + } + +public: + static bool classof(const OpenACCClause *C) { + return C->getClauseKind() == OpenACCClauseKind::Gang; + } + + static OpenACCGangClause * + Create(const ASTContext &Ctx, SourceLocation BeginLoc, SourceLocation EndLoc); + + child_range children() { + return child_range(child_iterator(), child_iterator()); + } + const_child_range children() const { + return const_child_range(const_child_iterator(), const_child_iterator()); + } +}; + +// Not yet implemented, but the type name is necessary for 'seq' diagnostics, so +// this provides a basic, do-nothing implementation. We still need to add this +// type to the visitors/etc, as well as get it to take its proper arguments. +class OpenACCVectorClause : public OpenACCClause { +protected: + OpenACCVectorClause(SourceLocation BeginLoc, SourceLocation EndLoc) + : OpenACCClause(OpenACCClauseKind::Vector, BeginLoc, EndLoc) { + llvm_unreachable("Not yet implemented"); + } + +public: + static bool classof(const OpenACCClause *C) { + return C->getClauseKind() == OpenACCClauseKind::Gang; + } + + static OpenACCVectorClause * + Create(const ASTContext &Ctx, SourceLocation BeginLoc, SourceLocation EndLoc); + + child_range children() { + return child_range(child_iterator(), child_iterator()); + } + const_child_range children() const { + return const_child_range(const_child_iterator(), const_child_iterator()); + } +}; + +// Not yet implemented, but the type name is necessary for 'seq' diagnostics, so +// this provides a basic, do-nothing implementation. We still need to add this +// type to the visitors/etc, as well as get it to take its proper arguments. +class OpenACCWorkerClause : public OpenACCClause { +protected: + OpenACCWorkerClause(SourceLocation BeginLoc, SourceLocation EndLoc) + : OpenACCClause(OpenACCClauseKind::Gang, BeginLoc, EndLoc) { + llvm_unreachable("Not yet implemented"); + } + +public: + static bool classof(const OpenACCClause *C) { + return C->getClauseKind() == OpenACCClauseKind::Gang; + } + + static OpenACCWorkerClause * + Create(const ASTContext &Ctx, SourceLocation BeginLoc, SourceLocation EndLoc); + + child_range children() { + return child_range(child_iterator(), child_iterator()); + } + const_child_range children() const { + return const_child_range(const_child_iterator(), const_child_iterator()); + } +}; + /// Represents a clause that has a list of parameters. class OpenACCClauseWithParams : public OpenACCClause { /// Location of the '('. @@ -724,7 +867,7 @@ public: case OpenACCClauseKind::CLAUSE_NAME: \ Visit##CLAUSE_NAME##Clause(*cast(C)); \ return; -#define CLAUSE_ALIAS(ALIAS_NAME, CLAUSE_NAME) \ +#define CLAUSE_ALIAS(ALIAS_NAME, CLAUSE_NAME, DEPRECATED) \ case OpenACCClauseKind::ALIAS_NAME: \ Visit##CLAUSE_NAME##Clause(*cast(C)); \ return; diff --git a/clang/include/clang/AST/RecursiveASTVisitor.h b/clang/include/clang/AST/RecursiveASTVisitor.h index 99093aa17972c416d3b557d3d2011e9125cefbe1..aa55e2e7e87188d7d5fe41b3c7452202417c0dd7 100644 --- a/clang/include/clang/AST/RecursiveASTVisitor.h +++ b/clang/include/clang/AST/RecursiveASTVisitor.h @@ -4000,6 +4000,8 @@ bool RecursiveASTVisitor::VisitOpenACCClauseList( DEF_TRAVERSE_STMT(OpenACCComputeConstruct, { TRY_TO(TraverseOpenACCAssociatedStmtConstruct(S)); }) +DEF_TRAVERSE_STMT(OpenACCLoopConstruct, + { TRY_TO(TraverseOpenACCAssociatedStmtConstruct(S)); }) // FIXME: look at the following tricky-seeming exprs to see if we // need to recurse on anything. These are ones that have methods diff --git a/clang/include/clang/AST/StmtOpenACC.h b/clang/include/clang/AST/StmtOpenACC.h index 04daf511f58713ce0b2be283ad3605f334c56352..b3aea09be03ddf1789008c7ec96bd26465c72b9c 100644 --- a/clang/include/clang/AST/StmtOpenACC.h +++ b/clang/include/clang/AST/StmtOpenACC.h @@ -113,6 +113,8 @@ public: return const_cast(this)->children(); } }; + +class OpenACCLoopConstruct; /// This class represents a compute construct, representing a 'Kind' of /// `parallel', 'serial', or 'kernel'. These constructs are associated with a /// 'structured block', defined as: @@ -165,6 +167,11 @@ class OpenACCComputeConstruct final } void setStructuredBlock(Stmt *S) { setAssociatedStmt(S); } + // Serialization helper function that searches the structured block for 'loop' + // constructs that should be associated with this, and sets their parent + // compute construct to this one. This isn't necessary normally, since we have + // the ability to record the state during parsing. + void findAndSetChildLoops(); public: static bool classof(const Stmt *T) { @@ -176,12 +183,74 @@ public: static OpenACCComputeConstruct * Create(const ASTContext &C, OpenACCDirectiveKind K, SourceLocation BeginLoc, SourceLocation DirectiveLoc, SourceLocation EndLoc, - ArrayRef Clauses, Stmt *StructuredBlock); + ArrayRef Clauses, Stmt *StructuredBlock, + ArrayRef AssociatedLoopConstructs); Stmt *getStructuredBlock() { return getAssociatedStmt(); } const Stmt *getStructuredBlock() const { return const_cast(this)->getStructuredBlock(); } }; +/// This class represents a 'loop' construct. The 'loop' construct applies to a +/// 'for' loop (or range-for loop), and is optionally associated with a Compute +/// Construct. +class OpenACCLoopConstruct final + : public OpenACCAssociatedStmtConstruct, + public llvm::TrailingObjects { + // The compute construct this loop is associated with, or nullptr if this is + // an orphaned loop construct, or if it hasn't been set yet. Because we + // construct the directives at the end of their statement, the 'parent' + // construct is not yet available at the time of construction, so this needs + // to be set 'later'. + const OpenACCComputeConstruct *ParentComputeConstruct = nullptr; + + friend class ASTStmtWriter; + friend class ASTStmtReader; + friend class ASTContext; + friend class OpenACCComputeConstruct; + + OpenACCLoopConstruct(unsigned NumClauses); + + OpenACCLoopConstruct(SourceLocation Start, SourceLocation DirLoc, + SourceLocation End, + ArrayRef Clauses, Stmt *Loop); + void setLoop(Stmt *Loop); + + void setParentComputeConstruct(OpenACCComputeConstruct *CC) { + assert(!ParentComputeConstruct && "Parent already set?"); + ParentComputeConstruct = CC; + } + +public: + static bool classof(const Stmt *T) { + return T->getStmtClass() == OpenACCLoopConstructClass; + } + + static OpenACCLoopConstruct *CreateEmpty(const ASTContext &C, + unsigned NumClauses); + + static OpenACCLoopConstruct * + Create(const ASTContext &C, SourceLocation BeginLoc, SourceLocation DirLoc, + SourceLocation EndLoc, ArrayRef Clauses, + Stmt *Loop); + + Stmt *getLoop() { return getAssociatedStmt(); } + const Stmt *getLoop() const { + return const_cast(this)->getLoop(); + } + + /// OpenACC 3.3 2.9: + /// An orphaned loop construct is a loop construct that is not lexically + /// enclosed within a compute construct. The parent compute construct of a + /// loop construct is the nearest compute construct that lexically contains + /// the loop construct. + bool isOrphanedLoopConstruct() const { + return ParentComputeConstruct == nullptr; + } + const OpenACCComputeConstruct *getParentComputeConstruct() const { + return ParentComputeConstruct; + } +}; } // namespace clang #endif // LLVM_CLANG_AST_STMTOPENACC_H diff --git a/clang/include/clang/AST/TemplateBase.h b/clang/include/clang/AST/TemplateBase.h index fea2c8ccfee675eec1d1aa3efe500dd57299953f..0eaa4b0eedb35f7f293be48f1af9cc1b752c4796 100644 --- a/clang/include/clang/AST/TemplateBase.h +++ b/clang/include/clang/AST/TemplateBase.h @@ -459,7 +459,7 @@ public: bool IncludeType) const; /// Debugging aid that dumps the template argument. - void dump(raw_ostream &Out) const; + void dump(raw_ostream &Out, const ASTContext &Context) const; /// Debugging aid that dumps the template argument to standard error. void dump() const; diff --git a/clang/include/clang/AST/TemplateName.h b/clang/include/clang/AST/TemplateName.h index 489fccb2ef74d6beb43614cc5c6127ed549e5983..988a55acd22525ebb32dad6c44fa9c26b9242a29 100644 --- a/clang/include/clang/AST/TemplateName.h +++ b/clang/include/clang/AST/TemplateName.h @@ -340,7 +340,7 @@ public: Qualified Qual = Qualified::AsWritten) const; /// Debugging aid that dumps the template name. - void dump(raw_ostream &OS) const; + void dump(raw_ostream &OS, const ASTContext &Context) const; /// Debugging aid that dumps the template name to standard /// error. diff --git a/clang/include/clang/AST/TextNodeDumper.h b/clang/include/clang/AST/TextNodeDumper.h index caa33abd99e47d598fc630140385fbf4c8343c30..abfafcaef271b6cbb989846e288eb558d53db5e5 100644 --- a/clang/include/clang/AST/TextNodeDumper.h +++ b/clang/include/clang/AST/TextNodeDumper.h @@ -408,6 +408,7 @@ public: VisitLifetimeExtendedTemporaryDecl(const LifetimeExtendedTemporaryDecl *D); void VisitHLSLBufferDecl(const HLSLBufferDecl *D); void VisitOpenACCConstructStmt(const OpenACCConstructStmt *S); + void VisitOpenACCLoopConstruct(const OpenACCLoopConstruct *S); }; } // namespace clang diff --git a/clang/include/clang/AST/Type.h b/clang/include/clang/AST/Type.h index 263b632df23ce42d00e9d04c6b7acbdf0b3d6df6..9eb3f6c09e3d3b188d3e316f320283e61a8498a9 100644 --- a/clang/include/clang/AST/Type.h +++ b/clang/include/clang/AST/Type.h @@ -1120,6 +1120,20 @@ public: /// Return true if this is a trivially copyable type (C++0x [basic.types]p9) bool isTriviallyCopyableType(const ASTContext &Context) const; + /// Return true if the type is safe to bitwise copy using memcpy/memmove. + /// + /// This is an extension in clang: bitwise cloneable types act as trivially + /// copyable types, meaning their underlying bytes can be safely copied by + /// memcpy or memmove. After the copy, the destination object has the same + /// object representation. + /// + /// However, there are cases where it is not safe to copy: + /// - When sanitizers, such as AddressSanitizer, add padding with poison, + /// which can cause issues if those poisoned padding bits are accessed. + /// - Types with Objective-C lifetimes, where specific runtime + /// semantics may not be preserved during a bitwise copy. + bool isBitwiseCloneableType(const ASTContext &Context) const; + /// Return true if this is a trivially copyable type bool isTriviallyCopyConstructibleType(const ASTContext &Context) const; diff --git a/clang/include/clang/AST/UnresolvedSet.h b/clang/include/clang/AST/UnresolvedSet.h index ee31be969b6e3585dcfbe9cc290003ae744f356a..1369725ab4e96adfb17d6b8b4cbba3b4c47e3786 100644 --- a/clang/include/clang/AST/UnresolvedSet.h +++ b/clang/include/clang/AST/UnresolvedSet.h @@ -47,6 +47,7 @@ public: // temporaries with defaulted ctors are not zero initialized. UnresolvedSetIterator() : iterator_adaptor_base(nullptr) {} + uint64_t getDeclID() const { return I->getDeclID(); } NamedDecl *getDecl() const { return I->getDecl(); } void setDecl(NamedDecl *ND) const { return I->setDecl(ND); } AccessSpecifier getAccess() const { return I->getAccess(); } diff --git a/clang/include/clang/Analysis/Analyses/ThreadSafetyCommon.h b/clang/include/clang/Analysis/Analyses/ThreadSafetyCommon.h index 7bdb9052e57e745f76ebf39d90ed39320a172906..e99c5b2466334ab2382869d5ec0ba87c1b09748a 100644 --- a/clang/include/clang/Analysis/Analyses/ThreadSafetyCommon.h +++ b/clang/include/clang/Analysis/Analyses/ThreadSafetyCommon.h @@ -330,9 +330,9 @@ public: bool shouldIgnore() const { return sexpr() == nullptr; } - bool isInvalid() const { return sexpr() && isa(sexpr()); } + bool isInvalid() const { return isa_and_nonnull(sexpr()); } - bool isUniversal() const { return sexpr() && isa(sexpr()); } + bool isUniversal() const { return isa_and_nonnull(sexpr()); } }; // Translate clang::Expr to til::SExpr. diff --git a/clang/include/clang/Basic/Attr.td b/clang/include/clang/Basic/Attr.td index 17d9a710d948b24d9e8781b1611bdf8f920b5cbc..b70b0c8b836a547547979f90a9af684089256503 100644 --- a/clang/include/clang/Basic/Attr.td +++ b/clang/include/clang/Basic/Attr.td @@ -4470,37 +4470,20 @@ def HLSLShader : InheritableAttr { let Subjects = SubjectList<[HLSLEntry]>; let LangOpts = [HLSL]; let Args = [ - EnumArgument<"Type", "ShaderType", /*is_string=*/true, + EnumArgument<"Type", "llvm::Triple::EnvironmentType", /*is_string=*/true, ["pixel", "vertex", "geometry", "hull", "domain", "compute", "raygeneration", "intersection", "anyhit", "closesthit", "miss", "callable", "mesh", "amplification"], ["Pixel", "Vertex", "Geometry", "Hull", "Domain", "Compute", "RayGeneration", "Intersection", "AnyHit", "ClosestHit", - "Miss", "Callable", "Mesh", "Amplification"]> + "Miss", "Callable", "Mesh", "Amplification"], + /*opt=*/0, /*fake=*/0, /*isExternalType=*/1> ]; let Documentation = [HLSLSV_ShaderTypeAttrDocs]; let AdditionalMembers = [{ - static const unsigned ShaderTypeMaxValue = (unsigned)HLSLShaderAttr::Amplification; - - static llvm::Triple::EnvironmentType getTypeAsEnvironment(HLSLShaderAttr::ShaderType ShaderType) { - switch (ShaderType) { - case HLSLShaderAttr::Pixel: return llvm::Triple::Pixel; - case HLSLShaderAttr::Vertex: return llvm::Triple::Vertex; - case HLSLShaderAttr::Geometry: return llvm::Triple::Geometry; - case HLSLShaderAttr::Hull: return llvm::Triple::Hull; - case HLSLShaderAttr::Domain: return llvm::Triple::Domain; - case HLSLShaderAttr::Compute: return llvm::Triple::Compute; - case HLSLShaderAttr::RayGeneration: return llvm::Triple::RayGeneration; - case HLSLShaderAttr::Intersection: return llvm::Triple::Intersection; - case HLSLShaderAttr::AnyHit: return llvm::Triple::AnyHit; - case HLSLShaderAttr::ClosestHit: return llvm::Triple::ClosestHit; - case HLSLShaderAttr::Miss: return llvm::Triple::Miss; - case HLSLShaderAttr::Callable: return llvm::Triple::Callable; - case HLSLShaderAttr::Mesh: return llvm::Triple::Mesh; - case HLSLShaderAttr::Amplification: return llvm::Triple::Amplification; - } - llvm_unreachable("unknown enumeration value"); + static bool isValidShaderType(llvm::Triple::EnvironmentType ShaderType) { + return ShaderType >= llvm::Triple::Pixel && ShaderType <= llvm::Triple::Amplification; } }]; } diff --git a/clang/include/clang/Basic/Builtins.td b/clang/include/clang/Basic/Builtins.td index 11982af3fa609bea617811b4b550954da698258e..7bef5fd7ad40f28c98685e7fb6cfad76ce76effc 100644 --- a/clang/include/clang/Basic/Builtins.td +++ b/clang/include/clang/Basic/Builtins.td @@ -482,11 +482,11 @@ def SqrtF16F128 : Builtin, F16F128MathTemplate { let Prototype = "T(T)"; } -def TanF128 : Builtin { - let Spellings = ["__builtin_tanf128"]; +def TanF16F128 : Builtin, F16F128MathTemplate { + let Spellings = ["__builtin_tan"]; let Attributes = [FunctionWithBuiltinPrefix, NoThrow, ConstIgnoringErrnoAndExceptions]; - let Prototype = "__float128(__float128)"; + let Prototype = "T(T)"; } def TanhF128 : Builtin { diff --git a/clang/include/clang/Basic/BuiltinsAMDGPU.def b/clang/include/clang/Basic/BuiltinsAMDGPU.def index 433c7795325f0c75c7418be4b9df8273bed172f3..9e6800ea814a0aff9c95c24cb304ea3e185bcf1e 100644 --- a/clang/include/clang/Basic/BuiltinsAMDGPU.def +++ b/clang/include/clang/Basic/BuiltinsAMDGPU.def @@ -240,7 +240,7 @@ TARGET_BUILTIN(__builtin_amdgcn_flat_atomic_fadd_v2bf16, "V2sV2s*0V2s", "t", "at TARGET_BUILTIN(__builtin_amdgcn_global_atomic_fadd_v2bf16, "V2sV2s*1V2s", "t", "atomic-global-pk-add-bf16-inst") TARGET_BUILTIN(__builtin_amdgcn_ds_atomic_fadd_v2bf16, "V2sV2s*3V2s", "t", "atomic-ds-pk-add-16-insts") TARGET_BUILTIN(__builtin_amdgcn_ds_atomic_fadd_v2f16, "V2hV2h*3V2h", "t", "atomic-ds-pk-add-16-insts") -TARGET_BUILTIN(__builtin_amdgcn_global_load_lds, "vv*1v*3UiiUi", "t", "gfx940-insts") +TARGET_BUILTIN(__builtin_amdgcn_global_load_lds, "vv*1v*3IUiIiIUi", "t", "gfx940-insts") //===----------------------------------------------------------------------===// // Deep learning builtins. diff --git a/clang/include/clang/Basic/BuiltinsNVPTX.def b/clang/include/clang/Basic/BuiltinsNVPTX.def index 9e243d740ed7aec7e7b8b94f305478e6eba9011d..504314d8d96e91e72a8accf6bba8a6ac4c171aef 100644 --- a/clang/include/clang/Basic/BuiltinsNVPTX.def +++ b/clang/include/clang/Basic/BuiltinsNVPTX.def @@ -62,7 +62,9 @@ #pragma push_macro("PTX82") #pragma push_macro("PTX83") #pragma push_macro("PTX84") -#define PTX84 "ptx84" +#pragma push_macro("PTX85") +#define PTX85 "ptx85" +#define PTX84 "ptx84|" PTX85 #define PTX83 "ptx83|" PTX84 #define PTX82 "ptx82|" PTX83 #define PTX81 "ptx81|" PTX82 @@ -1094,3 +1096,4 @@ TARGET_BUILTIN(__nvvm_getctarank_shared_cluster, "iv*3", "", AND(SM_90,PTX78)) #pragma pop_macro("PTX82") #pragma pop_macro("PTX83") #pragma pop_macro("PTX84") +#pragma pop_macro("PTX85") diff --git a/clang/include/clang/Basic/CodeGenOptions.def b/clang/include/clang/Basic/CodeGenOptions.def index 07b0ca1691a679a2148a72734e2a658bb5286d58..7ffc40a00504fb9fb9058dd73880cd2608a8d6a3 100644 --- a/clang/include/clang/Basic/CodeGenOptions.def +++ b/clang/include/clang/Basic/CodeGenOptions.def @@ -61,7 +61,7 @@ CODEGENOPT(SeparateNamedSections, 1, 0) ///< Set for -fseparate-named-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 +ENUM_CODEGENOPT(FramePointer, FramePointerKind, 2, FramePointerKind::None) /// frame-pointer: all,non-leaf,reserved,none CODEGENOPT(ClearASTBeforeBackend , 1, 0) ///< Free the AST before running backend code generation. Only works with -disable-free. CODEGENOPT(DisableFree , 1, 0) ///< Don't free memory. diff --git a/clang/include/clang/Basic/CodeGenOptions.h b/clang/include/clang/Basic/CodeGenOptions.h index 9469a424045bb0472a6cd725ebf55bfa1e0e08d8..00523a84d3895f14279c1180a25de5800b2ae8bd 100644 --- a/clang/include/clang/Basic/CodeGenOptions.h +++ b/clang/include/clang/Basic/CodeGenOptions.h @@ -127,15 +127,18 @@ public: std::string BinutilsVersion; enum class FramePointerKind { - None, // Omit all frame pointers. - NonLeaf, // Keep non-leaf frame pointers. - All, // Keep all frame pointers. + None, // Omit all frame pointers. + Reserved, // Maintain valid frame pointer chain. + NonLeaf, // Keep non-leaf frame pointers. + All, // Keep all frame pointers. }; static StringRef getFramePointerKindName(FramePointerKind Kind) { switch (Kind) { case FramePointerKind::None: return "none"; + case FramePointerKind::Reserved: + return "reserved"; case FramePointerKind::NonLeaf: return "non-leaf"; case FramePointerKind::All: diff --git a/clang/include/clang/Basic/Cuda.h b/clang/include/clang/Basic/Cuda.h index 2d67c4181d12957e0e1df2429e3c6a3f6935c40c..0d5e38e825aa78e44f0560d1fb8c3f0a33c70ced 100644 --- a/clang/include/clang/Basic/Cuda.h +++ b/clang/include/clang/Basic/Cuda.h @@ -42,9 +42,10 @@ enum class CudaVersion { CUDA_122, CUDA_123, CUDA_124, + CUDA_125, FULLY_SUPPORTED = CUDA_123, PARTIALLY_SUPPORTED = - CUDA_124, // Partially supported. Proceed with a warning. + CUDA_125, // Partially supported. Proceed with a warning. NEW = 10000, // Too new. Issue a warning, but allow using it. }; const char *CudaVersionToString(CudaVersion V); @@ -91,6 +92,7 @@ enum class CudaArch { GFX803, GFX805, GFX810, + GFX9_GENERIC, GFX900, GFX902, GFX904, @@ -102,10 +104,12 @@ enum class CudaArch { GFX940, GFX941, GFX942, + GFX10_1_GENERIC, GFX1010, GFX1011, GFX1012, GFX1013, + GFX10_3_GENERIC, GFX1030, GFX1031, GFX1032, @@ -113,12 +117,15 @@ enum class CudaArch { GFX1034, GFX1035, GFX1036, + GFX11_GENERIC, GFX1100, GFX1101, GFX1102, GFX1103, GFX1150, GFX1151, + GFX1152, + GFX12_GENERIC, GFX1200, GFX1201, Generic, // A processor model named 'generic' if the target backend defines a diff --git a/clang/include/clang/Basic/DiagnosticOptions.h b/clang/include/clang/Basic/DiagnosticOptions.h index 099982c3bdd5a00a5b4b2cd7787d01f51b11ed4e..30141c2b8f447548fbd6f74217d59c3d74eb1464 100644 --- a/clang/include/clang/Basic/DiagnosticOptions.h +++ b/clang/include/clang/Basic/DiagnosticOptions.h @@ -124,7 +124,7 @@ public: /// default). std::vector VerifyPrefixes; - /// The list of -Wsystem-header-in-module=... options used to override + /// The list of -Wsystem-headers-in-module=... options used to override /// whether -Wsystem-headers is enabled on a per-module basis. std::vector SystemHeaderWarningsModules; diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index e34eb692941b4fc51fa6a61e0ba6043f4316de4e..193eae3bc41d61d12f89c13b420f8ded7f6a051a 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -607,6 +607,8 @@ def note_using_decl_class_member_workaround : Note< "a const variable|a constexpr variable}0 instead">; def err_using_decl_can_not_refer_to_namespace : Error< "using declaration cannot refer to a namespace">; +def note_namespace_using_decl : Note< + "did you mean 'using namespace'?">; def warn_cxx17_compat_using_decl_scoped_enumerator: Warning< "using declaration naming a scoped enumerator is incompatible with " "C++ standards before C++20">, InGroup, DefaultIgnore; @@ -6088,9 +6090,9 @@ def err_redefinition_different_concept : Error< "redefinition of concept %0 with different template parameters or requirements">; def err_tag_reference_non_tag : Error< "%select{non-struct type|non-class type|non-union type|non-enum " - "type|typedef|type alias|template|type alias template|template " - "template argument}1 %0 cannot be referenced with a " - "%select{struct|interface|union|class|enum}2 specifier">; + "type|typedef|type alias|template|alias template|template " + "template argument}1 %0 cannot be referenced with the '" + "%select{struct|interface|union|class|enum}2' specifier">; def err_tag_reference_conflict : Error< "implicit declaration introduced by elaborated type conflicts with a " "%select{non-struct type|non-class type|non-union type|non-enum " @@ -9013,6 +9015,11 @@ def err_cuda_ovl_target : Error< "cannot overload %select{__device__|__global__|__host__|__host__ __device__}2 function %3">; def note_cuda_ovl_candidate_target_mismatch : Note< "candidate template ignored: target attributes do not match">; +def warn_offload_incompatible_redeclare : Warning< + "target-attribute based function overloads are not supported by NVCC and will be treated as a function redeclaration:" + "new declaration is %select{__device__|__global__|__host__|__host__ __device__}0 function, " + "old declaration is %select{__device__|__global__|__host__|__host__ __device__}1 function">, + InGroup>, DefaultIgnore; def err_cuda_device_builtin_surftex_cls_template : Error< "illegal device builtin %select{surface|texture}0 reference " @@ -10082,6 +10089,12 @@ def warn_new_dangling_initializer_list : Warning< "the allocated initializer list}0 " "will be destroyed at the end of the full-expression">, InGroup; +def warn_unsupported_lifetime_extension : Warning< + "lifetime extension of " + "%select{temporary|backing array of initializer list}0 created " + "by aggregate initialization using a default member initializer " + "is not yet supported; lifetime of %select{temporary|backing array}0 " + "will end at the end of the full-expression">, InGroup; // For non-floating point, expressions of the form x == x or x != x // should result in a warning, since these always evaluate to a constant. @@ -12398,7 +12411,10 @@ def err_acc_var_not_pointer_type def note_acc_expected_pointer_var : Note<"expected variable of pointer type">; def err_acc_clause_after_device_type : Error<"OpenACC clause '%0' may not follow a '%1' clause in a " - "compute construct">; + "%select{'%3'|compute}2 construct">; +def err_acc_clause_cannot_combine + : Error<"OpenACC clause '%0' may not appear on the same construct as a " + "'%1' clause on a 'loop' construct">; def err_acc_reduction_num_gangs_conflict : Error< "OpenACC 'reduction' clause may not appear on a 'parallel' construct " @@ -12413,6 +12429,12 @@ def err_acc_reduction_composite_type def err_acc_reduction_composite_member_type :Error< "OpenACC 'reduction' composite variable must not have non-scalar field">; def note_acc_reduction_composite_member_loc : Note<"invalid field is here">; +def err_acc_loop_not_for_loop + : Error<"OpenACC 'loop' construct can only be applied to a 'for' loop">; +def note_acc_construct_here : Note<"'%0' construct is here">; +def err_acc_loop_spec_conflict + : Error<"OpenACC clause '%0' on '%1' construct conflicts with previous " + "data dependence clause">; // AMDGCN builtins diagnostics def err_amdgcn_global_load_lds_size_invalid_value : Error<"invalid size value">; diff --git a/clang/include/clang/Basic/Features.def b/clang/include/clang/Basic/Features.def index b762e44e755ec44914161b6b4ac1364140e3a9eb..53f410d3cb4bde7ada4339834664eee0536d4be0 100644 --- a/clang/include/clang/Basic/Features.def +++ b/clang/include/clang/Basic/Features.def @@ -96,6 +96,7 @@ FEATURE(nullability, true) FEATURE(nullability_on_arrays, true) FEATURE(nullability_on_classes, true) FEATURE(nullability_nullable_result, true) +FEATURE(numerical_stability_sanitizer, LangOpts.Sanitize.has(SanitizerKind::NumericalStability)) FEATURE(memory_sanitizer, LangOpts.Sanitize.hasOneOf(SanitizerKind::Memory | SanitizerKind::KernelMemory)) diff --git a/clang/include/clang/Basic/OpenACCClauses.def b/clang/include/clang/Basic/OpenACCClauses.def index 3e464abaafd928a183acde5bc2ee677d35269899..85f4859925f0bc6982a1854ec3567ae94482e915 100644 --- a/clang/include/clang/Basic/OpenACCClauses.def +++ b/clang/include/clang/Basic/OpenACCClauses.def @@ -15,32 +15,34 @@ // // VISIT_CLAUSE(CLAUSE_NAME) // -// CLAUSE_ALIAS(ALIAS_NAME, CLAUSE_NAME) +// CLAUSE_ALIAS(ALIAS_NAME, CLAUSE_NAME, DEPRECATED) #ifndef CLAUSE_ALIAS -#define CLAUSE_ALIAS(ALIAS_NAME, CLAUSE_NAME) +#define CLAUSE_ALIAS(ALIAS_NAME, CLAUSE_NAME, false) #endif +VISIT_CLAUSE(Auto) VISIT_CLAUSE(Async) VISIT_CLAUSE(Attach) VISIT_CLAUSE(Copy) -CLAUSE_ALIAS(PCopy, Copy) -CLAUSE_ALIAS(PresentOrCopy, Copy) +CLAUSE_ALIAS(PCopy, Copy, true) +CLAUSE_ALIAS(PresentOrCopy, Copy, true) VISIT_CLAUSE(CopyIn) -CLAUSE_ALIAS(PCopyIn, CopyIn) -CLAUSE_ALIAS(PresentOrCopyIn, CopyIn) +CLAUSE_ALIAS(PCopyIn, CopyIn, true) +CLAUSE_ALIAS(PresentOrCopyIn, CopyIn, true) VISIT_CLAUSE(CopyOut) -CLAUSE_ALIAS(PCopyOut, CopyOut) -CLAUSE_ALIAS(PresentOrCopyOut, CopyOut) +CLAUSE_ALIAS(PCopyOut, CopyOut, true) +CLAUSE_ALIAS(PresentOrCopyOut, CopyOut, true) VISIT_CLAUSE(Create) -CLAUSE_ALIAS(PCreate, Create) -CLAUSE_ALIAS(PresentOrCreate, Create) +CLAUSE_ALIAS(PCreate, Create, true) +CLAUSE_ALIAS(PresentOrCreate, Create, true) VISIT_CLAUSE(Default) VISIT_CLAUSE(DevicePtr) VISIT_CLAUSE(DeviceType) -CLAUSE_ALIAS(DType, DeviceType) +CLAUSE_ALIAS(DType, DeviceType, false) VISIT_CLAUSE(FirstPrivate) VISIT_CLAUSE(If) +VISIT_CLAUSE(Independent) VISIT_CLAUSE(NoCreate) VISIT_CLAUSE(NumGangs) VISIT_CLAUSE(NumWorkers) @@ -48,6 +50,7 @@ VISIT_CLAUSE(Present) VISIT_CLAUSE(Private) VISIT_CLAUSE(Reduction) VISIT_CLAUSE(Self) +VISIT_CLAUSE(Seq) VISIT_CLAUSE(VectorLength) VISIT_CLAUSE(Wait) diff --git a/clang/include/clang/Basic/Sanitizers.def b/clang/include/clang/Basic/Sanitizers.def index b228ffd07ee7454dafab9255bbda0d3e3f43484f..bee35e9dca7c39cb7fae26f93cad36b9f7c51931 100644 --- a/clang/include/clang/Basic/Sanitizers.def +++ b/clang/include/clang/Basic/Sanitizers.def @@ -76,6 +76,9 @@ SANITIZER("fuzzer-no-link", FuzzerNoLink) // ThreadSanitizer SANITIZER("thread", Thread) +// Numerical stability sanitizer. +SANITIZER("numerical", NumericalStability) + // LeakSanitizer SANITIZER("leak", Leak) diff --git a/clang/include/clang/Basic/StmtNodes.td b/clang/include/clang/Basic/StmtNodes.td index 305f19daa4a9238fff2d9a755fb163da2ff06dfc..6ca08abdb14f072d8f1d5a060737156e4c77bcd1 100644 --- a/clang/include/clang/Basic/StmtNodes.td +++ b/clang/include/clang/Basic/StmtNodes.td @@ -302,3 +302,4 @@ def OpenACCConstructStmt : StmtNode; def OpenACCAssociatedStmtConstruct : StmtNode; def OpenACCComputeConstruct : StmtNode; +def OpenACCLoopConstruct : StmtNode; diff --git a/clang/include/clang/Basic/TokenKinds.def b/clang/include/clang/Basic/TokenKinds.def index b5a0e9df9f7aeea1301250f5308a11d8799e0708..9c4b17465e18a178ba56cb472d651da3eed5888b 100644 --- a/clang/include/clang/Basic/TokenKinds.def +++ b/clang/include/clang/Basic/TokenKinds.def @@ -542,6 +542,8 @@ TYPE_TRAIT_2(__reference_converts_from_temporary, ReferenceConvertsFromTemporary // is not exposed to users. TYPE_TRAIT_2(/*EmptySpellingName*/, IsDeducible, KEYCXX) +TYPE_TRAIT_1(__is_bitwise_cloneable, IsBitwiseCloneable, KEYALL) + // Embarcadero Expression Traits EXPRESSION_TRAIT(__is_lvalue_expr, IsLValueExpr, KEYCXX) EXPRESSION_TRAIT(__is_rvalue_expr, IsRValueExpr, KEYCXX) diff --git a/clang/include/clang/Basic/riscv_vector.td b/clang/include/clang/Basic/riscv_vector.td index cca4367751b92b0812c6e16bc084d64aceea641e..a0820e2093bc2071a6f1f9207f2927a094702aee 100644 --- a/clang/include/clang/Basic/riscv_vector.td +++ b/clang/include/clang/Basic/riscv_vector.td @@ -2637,7 +2637,8 @@ let UnMaskedPolicyScheme = HasPassthruOperand in { defm vbrev : RVVOutBuiltinSetZvbb; defm vclz : RVVOutBuiltinSetZvbb; defm vctz : RVVOutBuiltinSetZvbb; - defm vcpopv : RVVOutBuiltinSetZvbb; + let IRName = "vcpopv", MaskedIRName = "vcpopv_mask" in + defm vcpop : RVVOutBuiltinSetZvbb; let OverloadedName = "vwsll" in defm vwsll : RVVSignedWidenBinBuiltinSetVwsll; } diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td index 5ab2d49c7a497d73b9dbbc5a4f168e72ce7b057b..d44faa55c456f24cb449f211f12f8263c0e9efec 100644 --- a/clang/include/clang/Driver/Options.td +++ b/clang/include/clang/Driver/Options.td @@ -3592,7 +3592,7 @@ def fopenmp_offload_mandatory : Flag<["-"], "fopenmp-offload-mandatory">, Group< HelpText<"Do not create a host fallback if offloading to the device fails.">, MarshallingInfoFlag>; def fopenmp_force_usm : Flag<["-"], "fopenmp-force-usm">, Group, - Flags<[NoArgumentUnused]>, Visibility<[ClangOption, CC1Option]>, + Flags<[NoArgumentUnused]>, Visibility<[ClangOption, CC1Option, FlangOption, FC1Option]>, HelpText<"Force behvaior as if the user specified pragma omp requires unified_shared_memory.">, MarshallingInfoFlag>; def fopenmp_target_jit : Flag<["-"], "fopenmp-target-jit">, Group, @@ -7724,8 +7724,8 @@ def pic_is_pie : Flag<["-"], "pic-is-pie">, MarshallingInfoFlag>; def mframe_pointer_EQ : Joined<["-"], "mframe-pointer=">, - HelpText<"Specify which frame pointers to retain.">, Values<"all,non-leaf,none">, - NormalizedValuesScope<"CodeGenOptions::FramePointerKind">, NormalizedValues<["All", "NonLeaf", "None"]>, + HelpText<"Specify which frame pointers to retain.">, Values<"all,non-leaf,reserved,none">, + NormalizedValuesScope<"CodeGenOptions::FramePointerKind">, NormalizedValues<["All", "NonLeaf", "Reserved", "None"]>, MarshallingInfoEnum, "None">; diff --git a/clang/include/clang/Driver/SanitizerArgs.h b/clang/include/clang/Driver/SanitizerArgs.h index 07070ec4fc065300aeb5ea653a1495b2a0aab85e..47ef175302679f868bd6a1137910317b533837c5 100644 --- a/clang/include/clang/Driver/SanitizerArgs.h +++ b/clang/include/clang/Driver/SanitizerArgs.h @@ -103,6 +103,9 @@ public: bool needsCfiDiagRt() const; bool needsStatsRt() const { return Stats; } bool needsScudoRt() const { return Sanitizers.has(SanitizerKind::Scudo); } + bool needsNsanRt() const { + return Sanitizers.has(SanitizerKind::NumericalStability); + } bool hasMemTag() const { return hasMemtagHeap() || hasMemtagStack() || hasMemtagGlobals(); diff --git a/clang/include/clang/Driver/ToolChain.h b/clang/include/clang/Driver/ToolChain.h index a4f9cad98aa8b1e40d609d001d483e29f2b00077..9789cfacafd780d45b8e04b26fa56b05a83eb5d4 100644 --- a/clang/include/clang/Driver/ToolChain.h +++ b/clang/include/clang/Driver/ToolChain.h @@ -205,7 +205,8 @@ protected: /// Executes the given \p Executable and returns the stdout. llvm::Expected> - executeToolChainProgram(StringRef Executable) const; + executeToolChainProgram(StringRef Executable, + unsigned SecondsToWait = 0) const; void setTripleEnvironment(llvm::Triple::EnvironmentType Env); diff --git a/clang/include/clang/Lex/DependencyDirectivesScanner.h b/clang/include/clang/Lex/DependencyDirectivesScanner.h index 2f8354dec939f7cd0ae66e4210dd683b01cd567e..0e115906fbfe51924d8028c7cc024de86a507e6d 100644 --- a/clang/include/clang/Lex/DependencyDirectivesScanner.h +++ b/clang/include/clang/Lex/DependencyDirectivesScanner.h @@ -17,7 +17,6 @@ #ifndef LLVM_CLANG_LEX_DEPENDENCYDIRECTIVESSCANNER_H #define LLVM_CLANG_LEX_DEPENDENCYDIRECTIVESSCANNER_H -#include "clang/Basic/LangOptions.h" #include "clang/Basic/SourceLocation.h" #include "llvm/ADT/ArrayRef.h" @@ -118,7 +117,7 @@ struct Directive { bool scanSourceForDependencyDirectives( StringRef Input, SmallVectorImpl &Tokens, SmallVectorImpl &Directives, - const LangOptions &LangOpts, DiagnosticsEngine *Diags = nullptr, + DiagnosticsEngine *Diags = nullptr, SourceLocation InputSourceLoc = SourceLocation()); /// Print the previously scanned dependency directives as minimized source text. diff --git a/clang/include/clang/Lex/Preprocessor.h b/clang/include/clang/Lex/Preprocessor.h index c0850a8fa9f7f8eeb6d468a92a481b7d9cc0bdcd..9b1628d2d86f9ea832fad1b3c6bc88ff3dbfa996 100644 --- a/clang/include/clang/Lex/Preprocessor.h +++ b/clang/include/clang/Lex/Preprocessor.h @@ -1360,7 +1360,7 @@ public: MacroState &S = CurSubmoduleState->Macros[II]; auto *MD = S.getLatest(); - while (MD && isa(MD)) + while (isa_and_nonnull(MD)) MD = MD->getPrevious(); return MacroDefinition(dyn_cast_or_null(MD), S.getActiveModuleMacros(*this, II), diff --git a/clang/include/clang/Sema/Initialization.h b/clang/include/clang/Sema/Initialization.h index 2072cd8d1c3ef8671e4e4a810b9d3ba36a10b8c3..f443e327eaf32985e20393cb53cd18538e6d3525 100644 --- a/clang/include/clang/Sema/Initialization.h +++ b/clang/include/clang/Sema/Initialization.h @@ -212,7 +212,7 @@ private: struct C Capture; }; - InitializedEntity() {}; + InitializedEntity() {} /// Create the initialization entity for a variable. InitializedEntity(VarDecl *Var, EntityKind EK = EK_Variable) diff --git a/clang/include/clang/Sema/Overload.h b/clang/include/clang/Sema/Overload.h index 76311b00d2fc586fc249b1a3e0456412ddc4b05e..4a5c9e8ca1229522ad57ede2486976fbae649e2b 100644 --- a/clang/include/clang/Sema/Overload.h +++ b/clang/include/clang/Sema/Overload.h @@ -899,6 +899,8 @@ class Sema; /// object argument. bool IgnoreObjectArgument : 1; + bool TookAddressOfOverload : 1; + /// True if the candidate was found using ADL. CallExpr::ADLCallKind IsADLCandidate : 1; @@ -999,6 +1001,10 @@ class Sema; /// Initialization of an object of class type by constructor, /// using either a parenthesized or braced list of arguments. CSK_InitByConstructor, + + /// C++ [over.match.call.general] + /// Resolve a call through the address of an overload set. + CSK_AddressOfOverloadSet, }; /// Information about operator rewrites to consider when adding operator diff --git a/clang/include/clang/Sema/SemaHLSL.h b/clang/include/clang/Sema/SemaHLSL.h index e145f5e7f43f85da1b65193126f92f433697bb02..0e41a72e444ef45f9a62470b1ce317f2b5aaf717 100644 --- a/clang/include/clang/Sema/SemaHLSL.h +++ b/clang/include/clang/Sema/SemaHLSL.h @@ -39,7 +39,7 @@ public: const AttributeCommonInfo &AL, int X, int Y, int Z); HLSLShaderAttr *mergeShaderAttr(Decl *D, const AttributeCommonInfo &AL, - HLSLShaderAttr::ShaderType ShaderType); + llvm::Triple::EnvironmentType ShaderType); HLSLParamModifierAttr * mergeParamModifierAttr(Decl *D, const AttributeCommonInfo &AL, HLSLParamModifierAttr::Spelling Spelling); @@ -48,8 +48,8 @@ public: void CheckSemanticAnnotation(FunctionDecl *EntryPoint, const Decl *Param, const HLSLAnnotationAttr *AnnotationAttr); void DiagnoseAttrStageMismatch( - const Attr *A, HLSLShaderAttr::ShaderType Stage, - std::initializer_list AllowedStages); + const Attr *A, llvm::Triple::EnvironmentType Stage, + std::initializer_list AllowedStages); void DiagnoseAvailabilityViolations(TranslationUnitDecl *TU); void handleNumThreadsAttr(Decl *D, const ParsedAttr &AL); diff --git a/clang/include/clang/Sema/SemaObjC.h b/clang/include/clang/Sema/SemaObjC.h index 91430797e5ed82517de07e28b4bc333432204b14..bb8887691ce5d3108a1be0a22236bd92a1bf9957 100644 --- a/clang/include/clang/Sema/SemaObjC.h +++ b/clang/include/clang/Sema/SemaObjC.h @@ -383,7 +383,7 @@ public: void AddAnyMethodToGlobalPool(Decl *D); void ActOnStartOfObjCMethodDef(Scope *S, Decl *D); - bool isObjCMethodDecl(Decl *D) { return D && isa(D); } + bool isObjCMethodDecl(Decl *D) { return isa_and_nonnull(D); } /// CheckImplementationIvars - This routine checks if the instance variables /// listed in the implelementation match those listed in the interface. diff --git a/clang/include/clang/Sema/SemaOpenACC.h b/clang/include/clang/Sema/SemaOpenACC.h index 66144de4340a8a3827c011ffe315cce190c37711..a5f2a8bf74657770e057a2747cd5dc3a69754e02 100644 --- a/clang/include/clang/Sema/SemaOpenACC.h +++ b/clang/include/clang/Sema/SemaOpenACC.h @@ -15,6 +15,7 @@ #define LLVM_CLANG_SEMA_SEMAOPENACC_H #include "clang/AST/DeclGroup.h" +#include "clang/AST/StmtOpenACC.h" #include "clang/Basic/OpenACCKinds.h" #include "clang/Basic/SourceLocation.h" #include "clang/Sema/Ownership.h" @@ -25,6 +26,15 @@ namespace clang { class OpenACCClause; class SemaOpenACC : public SemaBase { +private: + /// A collection of loop constructs in the compute construct scope that + /// haven't had their 'parent' compute construct set yet. Entires will only be + /// made to this list in the case where we know the loop isn't an orphan. + llvm::SmallVector ParentlessLoopConstructs; + /// Whether we are inside of a compute construct, and should add loops to the + /// above collection. + bool InsideComputeConstruct = false; + public: // Redeclaration of the version in OpenACCClause.h. using DeviceTypeArgument = std::pair; @@ -394,7 +404,8 @@ public: bool ActOnStartDeclDirective(OpenACCDirectiveKind K, SourceLocation StartLoc); /// Called when we encounter an associated statement for our construct, this /// should check legality of the statement as it appertains to this Construct. - StmtResult ActOnAssociatedStmt(OpenACCDirectiveKind K, StmtResult AssocStmt); + StmtResult ActOnAssociatedStmt(SourceLocation DirectiveLoc, + OpenACCDirectiveKind K, StmtResult AssocStmt); /// Called after the directive has been completely parsed, including the /// declaration group or associated statement. @@ -431,6 +442,20 @@ public: Expr *LowerBound, SourceLocation ColonLocFirst, Expr *Length, SourceLocation RBLoc); + + /// Helper type for the registration/assignment of constructs that need to + /// 'know' about their parent constructs and hold a reference to them, such as + /// Loop needing its parent construct. + class AssociatedStmtRAII { + SemaOpenACC &SemaRef; + bool WasInsideComputeConstruct; + OpenACCDirectiveKind DirKind; + llvm::SmallVector ParentlessLoopConstructs; + + public: + AssociatedStmtRAII(SemaOpenACC &, OpenACCDirectiveKind); + ~AssociatedStmtRAII(); + }; }; } // namespace clang diff --git a/clang/include/clang/Serialization/ASTBitCodes.h b/clang/include/clang/Serialization/ASTBitCodes.h index fe1bd47348be1e77b1e3742cdf14a47bab8dead5..52a6c5e10f802592d14a17b65bd5954546b83107 100644 --- a/clang/include/clang/Serialization/ASTBitCodes.h +++ b/clang/include/clang/Serialization/ASTBitCodes.h @@ -255,6 +255,12 @@ public: } }; +// The unaligned decl ID used in the Blobs of bistreams. +using unaligned_decl_id_t = + llvm::support::detail::packed_endian_specific_integral< + serialization::DeclID, llvm::endianness::native, + llvm::support::unaligned>; + /// The number of predefined preprocessed entity IDs. const unsigned int NUM_PREDEF_PP_ENTITY_IDS = 1; @@ -1946,6 +1952,7 @@ enum StmtCode { // OpenACC Constructs STMT_OPENACC_COMPUTE_CONSTRUCT, + STMT_OPENACC_LOOP_CONSTRUCT, }; /// The kinds of designators that can occur in a @@ -1979,33 +1986,44 @@ enum CleanupObjectKind { COK_Block, COK_CompoundLiteral }; /// Describes the categories of an Objective-C class. struct ObjCCategoriesInfo { - // The ID of the definition - LocalDeclID DefinitionID; + // The ID of the definition. Use unaligned_decl_id_t to keep + // ObjCCategoriesInfo 32-bit aligned. + unaligned_decl_id_t DefinitionID; // Offset into the array of category lists. unsigned Offset; + ObjCCategoriesInfo() = default; + ObjCCategoriesInfo(LocalDeclID ID, unsigned Offset) + : DefinitionID(ID.get()), Offset(Offset) {} + + LocalDeclID getDefinitionID() const { return LocalDeclID(DefinitionID); } + friend bool operator<(const ObjCCategoriesInfo &X, const ObjCCategoriesInfo &Y) { - return X.DefinitionID < Y.DefinitionID; + return X.getDefinitionID() < Y.getDefinitionID(); } friend bool operator>(const ObjCCategoriesInfo &X, const ObjCCategoriesInfo &Y) { - return X.DefinitionID > Y.DefinitionID; + return X.getDefinitionID() > Y.getDefinitionID(); } friend bool operator<=(const ObjCCategoriesInfo &X, const ObjCCategoriesInfo &Y) { - return X.DefinitionID <= Y.DefinitionID; + return X.getDefinitionID() <= Y.getDefinitionID(); } friend bool operator>=(const ObjCCategoriesInfo &X, const ObjCCategoriesInfo &Y) { - return X.DefinitionID >= Y.DefinitionID; + return X.getDefinitionID() >= Y.getDefinitionID(); } }; +static_assert(alignof(ObjCCategoriesInfo) <= 4); +static_assert(std::is_standard_layout_v && + std::is_trivial_v); + /// A key used when looking up entities by \ref DeclarationName. /// /// Different \ref DeclarationNames are mapped to different keys, but the diff --git a/clang/include/clang/Serialization/ASTReader.h b/clang/include/clang/Serialization/ASTReader.h index bea58d60d36c41c02ed926141b9bad313b239724..0a9006223dcbd589fbc75623be30d2dadbcbc5b4 100644 --- a/clang/include/clang/Serialization/ASTReader.h +++ b/clang/include/clang/Serialization/ASTReader.h @@ -504,12 +504,6 @@ private: /// = I + 1 has already been loaded. llvm::PagedVector DeclsLoaded; - using GlobalDeclMapType = ContinuousRangeMap; - - /// Mapping from global declaration IDs to the module in which the - /// declaration resides. - GlobalDeclMapType GlobalDeclMap; - using FileOffset = std::pair; using FileOffsetsTy = SmallVector; using DeclUpdateOffsetsMap = llvm::DenseMap; @@ -592,10 +586,11 @@ private: struct FileDeclsInfo { ModuleFile *Mod = nullptr; - ArrayRef Decls; + ArrayRef Decls; FileDeclsInfo() = default; - FileDeclsInfo(ModuleFile *Mod, ArrayRef Decls) + FileDeclsInfo(ModuleFile *Mod, + ArrayRef Decls) : Mod(Mod), Decls(Decls) {} }; @@ -604,11 +599,7 @@ private: /// An array of lexical contents of a declaration context, as a sequence of /// Decl::Kind, DeclID pairs. - using unaligned_decl_id_t = - llvm::support::detail::packed_endian_specific_integral< - serialization::DeclID, llvm::endianness::native, - llvm::support::unaligned>; - using LexicalContents = ArrayRef; + using LexicalContents = ArrayRef; /// Map from a DeclContext to its lexical contents. llvm::DenseMap> @@ -1489,10 +1480,11 @@ private: unsigned ClientLoadCapabilities); public: - class ModuleDeclIterator : public llvm::iterator_adaptor_base< - ModuleDeclIterator, const LocalDeclID *, - std::random_access_iterator_tag, const Decl *, - ptrdiff_t, const Decl *, const Decl *> { + class ModuleDeclIterator + : public llvm::iterator_adaptor_base< + ModuleDeclIterator, const serialization::unaligned_decl_id_t *, + std::random_access_iterator_tag, const Decl *, ptrdiff_t, + const Decl *, const Decl *> { ASTReader *Reader = nullptr; ModuleFile *Mod = nullptr; @@ -1500,11 +1492,11 @@ public: ModuleDeclIterator() : iterator_adaptor_base(nullptr) {} ModuleDeclIterator(ASTReader *Reader, ModuleFile *Mod, - const LocalDeclID *Pos) + const serialization::unaligned_decl_id_t *Pos) : iterator_adaptor_base(Pos), Reader(Reader), Mod(Mod) {} value_type operator*() const { - return Reader->GetDecl(Reader->getGlobalDeclID(*Mod, *I)); + return Reader->GetDecl(Reader->getGlobalDeclID(*Mod, (LocalDeclID)*I)); } value_type operator->() const { return **this; } @@ -1544,6 +1536,9 @@ private: StringRef Arg2 = StringRef(), StringRef Arg3 = StringRef()) const; void Error(llvm::Error &&Err) const; + /// Translate a \param GlobalDeclID to the index of DeclsLoaded array. + unsigned translateGlobalDeclIDToIndex(GlobalDeclID ID) const; + public: /// Load the AST file and validate its contents against the given /// Preprocessor. @@ -1915,7 +1910,8 @@ public: /// Retrieve the module file that owns the given declaration, or NULL /// if the declaration is not from a module file. - ModuleFile *getOwningModuleFile(const Decl *D); + ModuleFile *getOwningModuleFile(const Decl *D) const; + ModuleFile *getOwningModuleFile(GlobalDeclID ID) const; /// Returns the source location for the decl \p ID. SourceLocation getSourceLocationForDeclID(GlobalDeclID ID); diff --git a/clang/include/clang/Serialization/ModuleFile.h b/clang/include/clang/Serialization/ModuleFile.h index 992d26a8b88c12d4dabb666b8de65ce97ce884ba..56193d44dd6f33bb04718f79ec93307d9ab83d14 100644 --- a/clang/include/clang/Serialization/ModuleFile.h +++ b/clang/include/clang/Serialization/ModuleFile.h @@ -454,23 +454,11 @@ public: /// by the declaration ID (-1). const DeclOffset *DeclOffsets = nullptr; - /// Base declaration ID for declarations local to this module. - serialization::DeclID BaseDeclID = 0; - - /// Remapping table for declaration IDs in this module. - ContinuousRangeMap DeclRemap; - - /// Mapping from the module files that this module file depends on - /// to the base declaration ID for that module as it is understood within this - /// module. - /// - /// This is effectively a reverse global-to-local mapping for declaration - /// IDs, so that we can interpret a true global ID (for this translation unit) - /// as a local ID (for this module file). - llvm::DenseMap GlobalToLocalDeclIDs; + /// Base declaration index in ASTReader for declarations local to this module. + unsigned BaseDeclIndex = 0; /// Array of file-level DeclIDs sorted by file. - const LocalDeclID *FileSortedDecls = nullptr; + const serialization::unaligned_decl_id_t *FileSortedDecls = nullptr; unsigned NumFileSortedDecls = 0; /// Array of category list location information within this diff --git a/clang/include/clang/Serialization/ModuleManager.h b/clang/include/clang/Serialization/ModuleManager.h index d770bc52eaf4f734fcfc817d08176af497e7c1cc..f898dab39f06d3527c901a231ed0fe67ddc66b77 100644 --- a/clang/include/clang/Serialization/ModuleManager.h +++ b/clang/include/clang/Serialization/ModuleManager.h @@ -45,7 +45,7 @@ namespace serialization { /// Manages the set of modules loaded by an AST reader. class ModuleManager { /// The chain of AST files, in the order in which we started to load - /// them (this order isn't really useful for anything). + /// them. SmallVector, 2> Chain; /// The chain of non-module PCH files. The first entry is the one named diff --git a/clang/include/clang/StaticAnalyzer/Checkers/Checkers.td b/clang/include/clang/StaticAnalyzer/Checkers/Checkers.td index 636eeb45f9980a8f2ed1d49882209b5f9fa4c64b..a7f62ef7f2d074ef9deca70c0e57d8595b354105 100644 --- a/clang/include/clang/StaticAnalyzer/Checkers/Checkers.td +++ b/clang/include/clang/StaticAnalyzer/Checkers/Checkers.td @@ -36,6 +36,7 @@ def CoreAlpha : Package<"core">, ParentPackage; // Note: OptIn is *not* intended for checkers that are too noisy to be on by // default. Such checkers belong in the alpha package. def OptIn : Package<"optin">; + def CoreOptIn : Package<"core">, ParentPackage; // In the Portability package reside checkers for finding code that relies on @@ -43,6 +44,9 @@ def CoreOptIn : Package<"core">, ParentPackage; // development, but unwanted for developers who target only a single platform. def PortabilityOptIn : Package<"portability">, ParentPackage; +// Optional checkers related to taint security analysis. +def TaintOptIn : Package<"taint">, ParentPackage; + def Nullability : Package<"nullability">, PackageOptions<[ CmdLineOption, } // end optin.portability + +//===----------------------------------------------------------------------===// +// Taint checkers. +//===----------------------------------------------------------------------===// + +let ParentPackage = TaintOptIn in { + +def TaintedAllocChecker: Checker<"TaintedAlloc">, + HelpText<"Check for memory allocations, where the size parameter " + "might be a tainted (attacker controlled) value.">, + Dependencies<[DynamicMemoryModeling]>, + //FIXME: GenericTaintChecker should be a dependency, but only after it + //is transformed into a modeling checker + Documentation; + +} // end "optin.taint" + //===----------------------------------------------------------------------===// // NonDeterminism checkers. //===----------------------------------------------------------------------===// diff --git a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h index 151d3e57c1cb8157b56ef81505e41e8ff098e888..59805d01be5db7b1a81c00f2b5b115e36a60b38c 100644 --- a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h +++ b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h @@ -781,7 +781,7 @@ class SymbolicRegion : public SubRegion { : SubRegion(sreg, SymbolicRegionKind), sym(s) { // Because pointer arithmetic is represented by ElementRegion layers, // the base symbol here should not contain any arithmetic. - assert(s && isa(s)); + assert(isa_and_nonnull(s)); assert(s->getType()->isAnyPointerType() || s->getType()->isReferenceType() || s->getType()->isBlockPointerType()); diff --git a/clang/include/clang/Tooling/DependencyScanning/DependencyScanningFilesystem.h b/clang/include/clang/Tooling/DependencyScanning/DependencyScanningFilesystem.h index 9dc20065a09a3318d9e5f3b372c07399ade108a0..f7b4510d7f7beb4b6e300180453385e1a84e6af4 100644 --- a/clang/include/clang/Tooling/DependencyScanning/DependencyScanningFilesystem.h +++ b/clang/include/clang/Tooling/DependencyScanning/DependencyScanningFilesystem.h @@ -363,8 +363,7 @@ public: /// /// Returns true if the directive tokens are populated for this file entry, /// false if not (i.e. this entry is not a file or its scan fails). - bool ensureDirectiveTokensArePopulated(EntryRef Entry, - const LangOptions &LangOpts); + bool ensureDirectiveTokensArePopulated(EntryRef Entry); /// Check whether \p Path exists. By default checks cached result of \c /// status(), and falls back on FS if unable to do so. diff --git a/clang/include/clang/Tooling/Syntax/Tokens.h b/clang/include/clang/Tooling/Syntax/Tokens.h index b1bdefed7c97f1163adbe1bbed8eaabc28dca429..f71b8d67bfea4f8626933770c36a8a841bc3c8d5 100644 --- a/clang/include/clang/Tooling/Syntax/Tokens.h +++ b/clang/include/clang/Tooling/Syntax/Tokens.h @@ -292,9 +292,9 @@ public: /// "DECL", "(", "a", ")", ";"} llvm::ArrayRef spelledTokens(FileID FID) const; - /// Returns the spelled Token starting at Loc, if there are no such tokens + /// Returns the spelled Token containing the Loc, if there are no such tokens /// returns nullptr. - const syntax::Token *spelledTokenAt(SourceLocation Loc) const; + const syntax::Token *spelledTokenContaining(SourceLocation Loc) const; /// Get all tokens that expand a macro in \p FID. For the following input /// #define FOO B diff --git a/clang/lib/ARCMigrate/TransUnbridgedCasts.cpp b/clang/lib/ARCMigrate/TransUnbridgedCasts.cpp index 1e6354f71e294a90cb7164255f67786bcbafd3c8..7390ea17c8a4b6ed7779fa17e3e8e7f7b582d702 100644 --- a/clang/lib/ARCMigrate/TransUnbridgedCasts.cpp +++ b/clang/lib/ARCMigrate/TransUnbridgedCasts.cpp @@ -371,7 +371,7 @@ private: Stmt *parent = E; do { parent = StmtMap->getParentIgnoreParenImpCasts(parent); - } while (parent && isa(parent)); + } while (isa_and_nonnull(parent)); if (ReturnStmt *retS = dyn_cast_or_null(parent)) { std::string note = "remove the cast and change return type of function " diff --git a/clang/lib/AST/ASTDumper.cpp b/clang/lib/AST/ASTDumper.cpp index c8973fdeda352de04253a8e02629e0f0eda670aa..f0603880c32dde1e2a647f62dd9c516dce5d36ea 100644 --- a/clang/lib/AST/ASTDumper.cpp +++ b/clang/lib/AST/ASTDumper.cpp @@ -360,3 +360,37 @@ LLVM_DUMP_METHOD void ConceptReference::dump(raw_ostream &OS) const { ASTDumper P(OS, Ctx, Ctx.getDiagnostics().getShowColors()); P.Visit(this); } + +//===----------------------------------------------------------------------===// +// TemplateName method implementations +//===----------------------------------------------------------------------===// + +// FIXME: These are actually using the TemplateArgument dumper, through +// an implicit conversion. The dump will claim this is a template argument, +// which is misleading. + +LLVM_DUMP_METHOD void TemplateName::dump() const { + ASTDumper Dumper(llvm::errs(), /*ShowColors=*/false); + Dumper.Visit(*this); +} + +LLVM_DUMP_METHOD void TemplateName::dump(llvm::raw_ostream &OS, + const ASTContext &Context) const { + ASTDumper Dumper(OS, Context, Context.getDiagnostics().getShowColors()); + Dumper.Visit(*this); +} + +//===----------------------------------------------------------------------===// +// TemplateArgument method implementations +//===----------------------------------------------------------------------===// + +LLVM_DUMP_METHOD void TemplateArgument::dump() const { + ASTDumper Dumper(llvm::errs(), /*ShowColors=*/false); + Dumper.Visit(*this); +} + +LLVM_DUMP_METHOD void TemplateArgument::dump(llvm::raw_ostream &OS, + const ASTContext &Context) const { + ASTDumper Dumper(OS, Context, Context.getDiagnostics().getShowColors()); + Dumper.Visit(*this); +} diff --git a/clang/lib/AST/ASTImporter.cpp b/clang/lib/AST/ASTImporter.cpp index 3b9080e09b33139cc8c44a0078f6d7eda7a43025..02cd4ed9a6cace84a5c1ea5cc866feebed8e8ccf 100644 --- a/clang/lib/AST/ASTImporter.cpp +++ b/clang/lib/AST/ASTImporter.cpp @@ -1505,7 +1505,7 @@ ExpectedType ASTNodeImporter::VisitInjectedClassNameType( // The InjectedClassNameType is created in VisitRecordDecl when the // T->getDecl() is imported. Here we can return the existing type. const Type *Ty = (*ToDeclOrErr)->getTypeForDecl(); - assert(Ty && isa(Ty)); + assert(isa_and_nonnull(Ty)); return QualType(Ty, 0); } diff --git a/clang/lib/AST/CMakeLists.txt b/clang/lib/AST/CMakeLists.txt index 3faefb54f599fb6b311607983810dc448cd5c4a9..a5d3dacfc1a84e1abfbebfb62d403b32189778fb 100644 --- a/clang/lib/AST/CMakeLists.txt +++ b/clang/lib/AST/CMakeLists.txt @@ -87,6 +87,7 @@ add_clang_library(clangAST Interp/Record.cpp Interp/Source.cpp Interp/State.cpp + Interp/MemberPointer.cpp Interp/InterpShared.cpp ItaniumCXXABI.cpp ItaniumMangle.cpp diff --git a/clang/lib/AST/CommentParser.cpp b/clang/lib/AST/CommentParser.cpp index 8adfd85d0160c3bbb26193d47b4acab6b57512c6..5baf81a509fb606a61cff856d9705cb7ce13fa40 100644 --- a/clang/lib/AST/CommentParser.cpp +++ b/clang/lib/AST/CommentParser.cpp @@ -89,6 +89,31 @@ class TextTokenRetokenizer { } } + /// Extract a template type + bool lexTemplate(SmallString<32> &WordText) { + unsigned BracketCount = 0; + while (!isEnd()) { + const char C = peek(); + WordText.push_back(C); + consumeChar(); + switch (C) { + case '<': { + BracketCount++; + break; + } + case '>': { + BracketCount--; + if (!BracketCount) + return true; + break; + } + default: + break; + } + } + return false; + } + /// Add a token. /// Returns true on success, false if there are no interesting tokens to /// fetch from lexer. @@ -149,6 +174,54 @@ public: addToken(); } + /// Extract a type argument + bool lexType(Token &Tok) { + if (isEnd()) + return false; + + // Save current position in case we need to rollback because the type is + // empty. + Position SavedPos = Pos; + + // Consume any leading whitespace. + consumeWhitespace(); + SmallString<32> WordText; + const char *WordBegin = Pos.BufferPtr; + SourceLocation Loc = getSourceLocation(); + + while (!isEnd()) { + const char C = peek(); + // For non-whitespace characters we check if it's a template or otherwise + // continue reading the text into a word. + if (!isWhitespace(C)) { + if (C == '<') { + if (!lexTemplate(WordText)) + return false; + } else { + WordText.push_back(C); + consumeChar(); + } + } else { + consumeChar(); + break; + } + } + + const unsigned Length = WordText.size(); + if (Length == 0) { + Pos = SavedPos; + return false; + } + + char *TextPtr = Allocator.Allocate(Length + 1); + + memcpy(TextPtr, WordText.c_str(), Length + 1); + StringRef Text = StringRef(TextPtr, Length); + + formTokenWithChars(Tok, Loc, WordBegin, Length, Text); + return true; + } + /// Extract a word -- sequence of non-whitespace characters. bool lexWord(Token &Tok) { if (isEnd()) @@ -304,6 +377,23 @@ Parser::parseCommandArgs(TextTokenRetokenizer &Retokenizer, unsigned NumArgs) { return llvm::ArrayRef(Args, ParsedArgs); } +ArrayRef +Parser::parseThrowCommandArgs(TextTokenRetokenizer &Retokenizer, + unsigned NumArgs) { + auto *Args = new (Allocator.Allocate(NumArgs)) + Comment::Argument[NumArgs]; + unsigned ParsedArgs = 0; + Token Arg; + + while (ParsedArgs < NumArgs && Retokenizer.lexType(Arg)) { + Args[ParsedArgs] = Comment::Argument{ + SourceRange(Arg.getLocation(), Arg.getEndLocation()), Arg.getText()}; + ParsedArgs++; + } + + return llvm::ArrayRef(Args, ParsedArgs); +} + BlockCommandComment *Parser::parseBlockCommand() { assert(Tok.is(tok::backslash_command) || Tok.is(tok::at_command)); @@ -356,6 +446,9 @@ BlockCommandComment *Parser::parseBlockCommand() { parseParamCommandArgs(PC, Retokenizer); else if (TPC) parseTParamCommandArgs(TPC, Retokenizer); + else if (Info->IsThrowsCommand) + S.actOnBlockCommandArgs( + BC, parseThrowCommandArgs(Retokenizer, Info->NumArgs)); else S.actOnBlockCommandArgs(BC, parseCommandArgs(Retokenizer, Info->NumArgs)); diff --git a/clang/lib/AST/DeclBase.cpp b/clang/lib/AST/DeclBase.cpp index 1e9c879e371bc176a442d8ec0b3933c8eb9eddb0..e64a8326e8d5dd8fc2c4bb618688820c7339bcbc 100644 --- a/clang/lib/AST/DeclBase.cpp +++ b/clang/lib/AST/DeclBase.cpp @@ -74,18 +74,17 @@ void *Decl::operator new(std::size_t Size, const ASTContext &Context, GlobalDeclID ID, std::size_t Extra) { // Allocate an extra 8 bytes worth of storage, which ensures that the // resulting pointer will still be 8-byte aligned. - static_assert(sizeof(unsigned) * 2 >= alignof(Decl), - "Decl won't be misaligned"); + static_assert(sizeof(uint64_t) >= alignof(Decl), "Decl won't be misaligned"); void *Start = Context.Allocate(Size + Extra + 8); void *Result = (char*)Start + 8; - unsigned *PrefixPtr = (unsigned *)Result - 2; + uint64_t *PrefixPtr = (uint64_t *)Result - 1; - // Zero out the first 4 bytes; this is used to store the owning module ID. - PrefixPtr[0] = 0; + *PrefixPtr = ID.get(); - // Store the global declaration ID in the second 4 bytes. - PrefixPtr[1] = ID.get(); + // We leave the upper 16 bits to store the module IDs. 48 bits should be + // sufficient to store a declaration ID. + assert(*PrefixPtr < llvm::maskTrailingOnes(48)); return Result; } @@ -111,6 +110,29 @@ void *Decl::operator new(std::size_t Size, const ASTContext &Ctx, return ::operator new(Size + Extra, Ctx); } +GlobalDeclID Decl::getGlobalID() const { + if (!isFromASTFile()) + return GlobalDeclID(); + // See the comments in `Decl::operator new` for details. + uint64_t ID = *((const uint64_t *)this - 1); + return GlobalDeclID(ID & llvm::maskTrailingOnes(48)); +} + +unsigned Decl::getOwningModuleID() const { + if (!isFromASTFile()) + return 0; + + uint64_t ID = *((const uint64_t *)this - 1); + return ID >> 48; +} + +void Decl::setOwningModuleID(unsigned ID) { + assert(isFromASTFile() && "Only works on a deserialized declaration"); + uint64_t *IDAddress = (uint64_t *)this - 1; + *IDAddress &= llvm::maskTrailingOnes(48); + *IDAddress |= (uint64_t)ID << 48; +} + Module *Decl::getOwningModuleSlow() const { assert(isFromASTFile() && "Not from AST file?"); return getASTContext().getExternalSource()->getModule(getOwningModuleID()); @@ -1094,7 +1116,7 @@ bool Decl::isInExportDeclContext() const { while (DC && !isa(DC)) DC = DC->getLexicalParent(); - return DC && isa(DC); + return isa_and_nonnull(DC); } bool Decl::isInAnotherModuleUnit() const { @@ -2163,3 +2185,7 @@ DependentDiagnostic *DependentDiagnostic::Create(ASTContext &C, return DD; } + +unsigned DeclIDBase::getLocalDeclIndex() const { + return ID & llvm::maskTrailingOnes(32); +} diff --git a/clang/lib/AST/DeclCXX.cpp b/clang/lib/AST/DeclCXX.cpp index 75c441293d62e2038743e7b2f218c70082a5b665..7f2c786547b9b6eaa2b9cecfd778ed51d96f356c 100644 --- a/clang/lib/AST/DeclCXX.cpp +++ b/clang/lib/AST/DeclCXX.cpp @@ -68,8 +68,8 @@ void LazyASTUnresolvedSet::getFromExternalSource(ASTContext &C) const { assert(Source && "getFromExternalSource with no external source"); for (ASTUnresolvedSet::iterator I = Impl.begin(); I != Impl.end(); ++I) - I.setDecl(cast(Source->GetExternalDecl( - GlobalDeclID(reinterpret_cast(I.getDecl()) >> 2)))); + I.setDecl( + cast(Source->GetExternalDecl(GlobalDeclID(I.getDeclID())))); Impl.Decls.setLazy(false); } diff --git a/clang/lib/AST/Expr.cpp b/clang/lib/AST/Expr.cpp index f9d634550dc06100a39221fe23bd31657411d838..7e555689b64c487574653debce428458e4e8db0a 100644 --- a/clang/lib/AST/Expr.cpp +++ b/clang/lib/AST/Expr.cpp @@ -837,7 +837,7 @@ std::string PredefinedExpr::ComputeName(PredefinedIdentKind IK, typedef SmallVector SpecsTy; SpecsTy Specs; const DeclContext *Ctx = FD->getDeclContext(); - while (Ctx && isa(Ctx)) { + while (isa_and_nonnull(Ctx)) { const ClassTemplateSpecializationDecl *Spec = dyn_cast(Ctx); if (Spec && !Spec->isExplicitSpecialization()) @@ -3067,7 +3067,7 @@ Expr *Expr::IgnoreParenCasts() { Expr *Expr::IgnoreConversionOperatorSingleStep() { if (auto *MCE = dyn_cast(this)) { - if (MCE->getMethodDecl() && isa(MCE->getMethodDecl())) + if (isa_and_nonnull(MCE->getMethodDecl())) return MCE->getImplicitObjectArgument(); } return this; diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp index f1aa19e4409e159c2a008901306876e615b2f6e3..d5057452cec9c5a2899402910478aada10ad48cc 100644 --- a/clang/lib/AST/ExprConstant.cpp +++ b/clang/lib/AST/ExprConstant.cpp @@ -2130,7 +2130,7 @@ static bool IsWeakLValue(const LValue &Value) { static bool isZeroSized(const LValue &Value) { const ValueDecl *Decl = GetLValueBaseDecl(Value); - if (Decl && isa(Decl)) { + if (isa_and_nonnull(Decl)) { QualType Ty = Decl->getType(); if (Ty->isArrayType()) return Ty->isIncompleteType() || @@ -15209,11 +15209,21 @@ bool ComplexExprEvaluator::VisitBinaryOperator(const BinaryOperator *E) { APFloat &ResI = Result.getComplexFloatImag(); if (LHSReal) { assert(!RHSReal && "Cannot have two real operands for a complex op!"); - ResR = A * C; - ResI = A * D; + ResR = A; + ResI = A; + // ResR = A * C; + // ResI = A * D; + if (!handleFloatFloatBinOp(Info, E, ResR, BO_Mul, C) || + !handleFloatFloatBinOp(Info, E, ResI, BO_Mul, D)) + return false; } else if (RHSReal) { - ResR = C * A; - ResI = C * B; + // ResR = C * A; + // ResI = C * B; + ResR = C; + ResI = C; + if (!handleFloatFloatBinOp(Info, E, ResR, BO_Mul, A) || + !handleFloatFloatBinOp(Info, E, ResI, BO_Mul, B)) + return false; } else { // In the fully general case, we need to handle NaNs and infinities // robustly. @@ -15289,8 +15299,13 @@ bool ComplexExprEvaluator::VisitBinaryOperator(const BinaryOperator *E) { APFloat &ResR = Result.getComplexFloatReal(); APFloat &ResI = Result.getComplexFloatImag(); if (RHSReal) { - ResR = A / C; - ResI = B / C; + ResR = A; + ResI = B; + // ResR = A / C; + // ResI = B / C; + if (!handleFloatFloatBinOp(Info, E, ResR, BO_Div, C) || + !handleFloatFloatBinOp(Info, E, ResI, BO_Div, C)) + return false; } else { if (LHSReal) { // No real optimizations we can do here, stub out with zero. diff --git a/clang/lib/AST/Interp/ByteCodeExprGen.cpp b/clang/lib/AST/Interp/ByteCodeExprGen.cpp index 3eb7e7544df71393dfefe97e5ee07e228d7dc48f..0899a98b3b95a6358f28abcddd0246ac21005f2a 100644 --- a/clang/lib/AST/Interp/ByteCodeExprGen.cpp +++ b/clang/lib/AST/Interp/ByteCodeExprGen.cpp @@ -100,6 +100,35 @@ bool ByteCodeExprGen::VisitCastExpr(const CastExpr *CE) { return this->emitMemcpy(CE); } + case CK_DerivedToBaseMemberPointer: { + assert(classifyPrim(CE->getType()) == PT_MemberPtr); + assert(classifyPrim(SubExpr->getType()) == PT_MemberPtr); + const auto *FromMP = SubExpr->getType()->getAs(); + const auto *ToMP = CE->getType()->getAs(); + + unsigned DerivedOffset = collectBaseOffset(QualType(ToMP->getClass(), 0), + QualType(FromMP->getClass(), 0)); + + if (!this->visit(SubExpr)) + return false; + + return this->emitGetMemberPtrBasePop(DerivedOffset, CE); + } + + case CK_BaseToDerivedMemberPointer: { + assert(classifyPrim(CE) == PT_MemberPtr); + assert(classifyPrim(SubExpr) == PT_MemberPtr); + const auto *FromMP = SubExpr->getType()->getAs(); + const auto *ToMP = CE->getType()->getAs(); + + unsigned DerivedOffset = collectBaseOffset(QualType(FromMP->getClass(), 0), + QualType(ToMP->getClass(), 0)); + + if (!this->visit(SubExpr)) + return false; + return this->emitGetMemberPtrBasePop(-DerivedOffset, CE); + } + case CK_UncheckedDerivedToBase: case CK_DerivedToBase: { if (!this->visit(SubExpr)) @@ -187,7 +216,8 @@ bool ByteCodeExprGen::VisitCastExpr(const CastExpr *CE) { return this->emitCastFloatingIntegral(*ToT, CE); } - case CK_NullToPointer: { + case CK_NullToPointer: + case CK_NullToMemberPointer: { if (DiscardResult) return true; @@ -288,15 +318,24 @@ bool ByteCodeExprGen::VisitCastExpr(const CastExpr *CE) { if (DiscardResult) return this->discard(SubExpr); - std::optional FromT = classify(SubExpr->getType()); + QualType SubExprTy = SubExpr->getType(); + std::optional FromT = classify(SubExprTy); std::optional ToT = classify(CE->getType()); if (!FromT || !ToT) return false; assert(isPtrType(*FromT)); assert(isPtrType(*ToT)); - if (FromT == ToT) - return this->delegate(SubExpr); + if (FromT == ToT) { + if (CE->getType()->isVoidPointerType()) + return this->delegate(SubExpr); + + if (!this->visit(SubExpr)) + return false; + if (FromT == PT_Ptr) + return this->emitPtrPtrCast(SubExprTy->isVoidPointerType(), CE); + return true; + } if (!this->visit(SubExpr)) return false; @@ -326,7 +365,8 @@ bool ByteCodeExprGen::VisitCastExpr(const CastExpr *CE) { return this->emitCast(*FromT, *ToT, CE); } - case CK_PointerToBoolean: { + case CK_PointerToBoolean: + case CK_MemberPointerToBoolean: { PrimType PtrT = classifyPrim(SubExpr->getType()); // Just emit p != nullptr for this. @@ -534,8 +574,23 @@ bool ByteCodeExprGen::VisitBinaryOperator(const BinaryOperator *BO) { BO->isComparisonOp()) return this->emitComplexComparison(LHS, RHS, BO); - if (BO->isPtrMemOp()) - return this->visit(RHS); + if (BO->isPtrMemOp()) { + if (!this->visit(LHS)) + return false; + + if (!this->visit(RHS)) + return false; + + if (!this->emitToMemberPtr(BO)) + return false; + + if (classifyPrim(BO) == PT_MemberPtr) + return true; + + if (!this->emitCastMemberPtrPtr(BO)) + return false; + return DiscardResult ? this->emitPopPtr(BO) : true; + } // Typecheck the args. std::optional LT = classify(LHS->getType()); @@ -1058,14 +1113,9 @@ bool ByteCodeExprGen::visitInitList(ArrayRef Inits, if (!this->visit(Init)) return false; - if (FieldToInit->isBitField()) { - if (!this->emitInitBitField(T, FieldToInit, E)) - return false; - } else { - if (!this->emitInitField(T, FieldToInit->Offset, E)) - return false; - } - return this->emitPopPtr(E); + if (FieldToInit->isBitField()) + return this->emitInitBitField(T, FieldToInit, E); + return this->emitInitField(T, FieldToInit->Offset, E); }; auto initCompositeField = [=](const Record::Field *FieldToInit, @@ -1101,9 +1151,6 @@ bool ByteCodeExprGen::visitInitList(ArrayRef Inits, else FToInit = cast(E)->getInitializedFieldInUnion(); - if (!this->emitDupPtr(E)) - return false; - const Record::Field *FieldToInit = R->getField(FToInit); if (std::optional T = classify(Init)) { if (!initPrimitiveField(FieldToInit, Init, *T)) @@ -1123,8 +1170,6 @@ bool ByteCodeExprGen::visitInitList(ArrayRef Inits, while (InitIndex < R->getNumFields() && R->getField(InitIndex)->Decl->isUnnamedBitField()) ++InitIndex; - if (!this->emitDupPtr(E)) - return false; if (std::optional T = classify(Init)) { const Record::Field *FieldToInit = R->getField(InitIndex); @@ -1134,7 +1179,7 @@ bool ByteCodeExprGen::visitInitList(ArrayRef Inits, } else { // Initializer for a direct base class. if (const Record::Base *B = R->getBase(Init->getType())) { - if (!this->emitGetPtrBasePop(B->Offset, Init)) + if (!this->emitGetPtrBase(B->Offset, Init)) return false; if (!this->visitInitializer(Init)) @@ -1467,7 +1512,7 @@ bool ByteCodeExprGen::VisitMemberExpr(const MemberExpr *E) { // Leave a pointer to the field on the stack. if (F->Decl->getType()->isReferenceType()) return this->emitGetFieldPop(PT_Ptr, F->Offset, E) && maybeLoadValue(); - return this->emitGetPtrField(F->Offset, E) && maybeLoadValue(); + return this->emitGetPtrFieldPop(F->Offset, E) && maybeLoadValue(); } return false; @@ -1798,6 +1843,9 @@ bool ByteCodeExprGen::VisitCompoundAssignOperator( std::optional RT = classify(RHS->getType()); std::optional ResultT = classify(E->getType()); + if (!Ctx.getLangOpts().CPlusPlus14) + return this->visit(RHS) && this->visit(LHS) && this->emitError(E); + if (!LT || !RT || !ResultT || !LHSComputationT) return false; @@ -2101,9 +2149,6 @@ bool ByteCodeExprGen::VisitLambdaExpr(const LambdaExpr *E) { if (!this->emitInitField(*T, F.Offset, E)) return false; } else { - if (!this->emitDupPtr(E)) - return false; - if (!this->emitGetPtrField(F.Offset, E)) return false; @@ -2773,6 +2818,8 @@ bool ByteCodeExprGen::visitZeroInitializer(PrimType T, QualType QT, return this->emitNullPtr(nullptr, E); case PT_FnPtr: return this->emitNullFnPtr(nullptr, E); + case PT_MemberPtr: + return this->emitNullMemberPtr(nullptr, E); case PT_Float: { return this->emitConstFloat(APFloat::getZero(Ctx.getFloatSemantics(QT)), E); } @@ -2798,9 +2845,6 @@ bool ByteCodeExprGen::visitZeroRecordInitializer(const Record *R, continue; } - // TODO: Add GetPtrFieldPop and get rid of this dup. - if (!this->emitDupPtr(E)) - return false; if (!this->emitGetPtrField(Field.Offset, E)) return false; @@ -2875,6 +2919,7 @@ bool ByteCodeExprGen::emitConst(T Value, PrimType Ty, const Expr *E) { return this->emitConstBool(Value, E); case PT_Ptr: case PT_FnPtr: + case PT_MemberPtr: case PT_Float: case PT_IntAP: case PT_IntAPS: @@ -3080,12 +3125,22 @@ bool ByteCodeExprGen::visitDecl(const VarDecl *VD) { } } - // Return the value - if (VarT) - return this->emitRet(*VarT, VD); - - // Return non-primitive values as pointers here. - return this->emitRet(PT_Ptr, VD); + // Return the value. + if (!this->emitRet(VarT.value_or(PT_Ptr), VD)) { + // If the Ret above failed and this is a global variable, mark it as + // uninitialized, even everything else succeeded. + if (Context::shouldBeGloballyIndexed(VD)) { + auto GlobalIndex = P.getGlobal(VD); + assert(GlobalIndex); + Block *GlobalBlock = P.getGlobal(*GlobalIndex); + InlineDescriptor &ID = + *reinterpret_cast(GlobalBlock->rawData()); + ID.IsInitialized = false; + GlobalBlock->invokeDtor(); + } + return false; + } + return true; } template @@ -3159,9 +3214,18 @@ bool ByteCodeExprGen::visitAPValue(const APValue &Val, return this->emitConst(Val.getInt(), ValType, E); if (Val.isLValue()) { + if (Val.isNullPointer()) + return this->emitNull(ValType, nullptr, E); APValue::LValueBase Base = Val.getLValueBase(); if (const Expr *BaseExpr = Base.dyn_cast()) return this->visit(BaseExpr); + else if (const auto *VD = Base.dyn_cast()) { + return this->visitDeclRef(VD, E); + } + } else if (Val.isMemberPointer()) { + if (const ValueDecl *MemberDecl = Val.getMemberPointerDecl()) + return this->emitGetMemberPtr(MemberDecl, E); + return this->emitNullMemberPtr(nullptr, E); } return false; @@ -3170,15 +3234,15 @@ bool ByteCodeExprGen::visitAPValue(const APValue &Val, template bool ByteCodeExprGen::visitAPValueInitializer(const APValue &Val, const Expr *E) { + if (Val.isStruct()) { const Record *R = this->getRecord(E->getType()); assert(R); - for (unsigned I = 0, N = Val.getStructNumFields(); I != N; ++I) { const APValue &F = Val.getStructField(I); const Record::Field *RF = R->getField(I); - if (F.isInt()) { + if (F.isInt() || F.isLValue() || F.isMemberPointer()) { PrimType T = classifyPrim(RF->Decl->getType()); if (!this->visitAPValue(F, T, E)) return false; @@ -3190,8 +3254,6 @@ bool ByteCodeExprGen::visitAPValueInitializer(const APValue &Val, PrimType ElemT = classifyPrim(ArrType->getElementType()); assert(ArrType); - if (!this->emitDupPtr(E)) - return false; if (!this->emitGetPtrField(RF->Offset, E)) return false; @@ -3204,11 +3266,28 @@ bool ByteCodeExprGen::visitAPValueInitializer(const APValue &Val, if (!this->emitPopPtr(E)) return false; + } else if (F.isStruct() || F.isUnion()) { + if (!this->emitGetPtrField(RF->Offset, E)) + return false; + if (!this->visitAPValueInitializer(F, E)) + return false; + if (!this->emitPopPtr(E)) + return false; } else { assert(false && "I don't think this should be possible"); } } return true; + } else if (Val.isUnion()) { + const FieldDecl *UnionField = Val.getUnionField(); + const Record *R = this->getRecord(UnionField->getParent()); + assert(R); + const APValue &F = Val.getUnionValue(); + const Record::Field *RF = R->getField(UnionField); + PrimType T = classifyPrim(RF->Decl->getType()); + if (!this->visitAPValue(F, T, E)) + return false; + return this->emitInitElem(T, 0, E); } // TODO: Other types. @@ -3298,10 +3377,27 @@ bool ByteCodeExprGen::VisitCallExpr(const CallExpr *E) { } } + std::optional CalleeOffset; // Add the (optional, implicit) This pointer. if (const auto *MC = dyn_cast(E)) { - if (!this->visit(MC->getImplicitObjectArgument())) + if (!FuncDecl && classifyPrim(E->getCallee()) == PT_MemberPtr) { + // If we end up creating a CallPtr op for this, we need the base of the + // member pointer as the instance pointer, and later extract the function + // decl as the function pointer. + const Expr *Callee = E->getCallee(); + CalleeOffset = + this->allocateLocalPrimitive(Callee, PT_MemberPtr, true, false); + if (!this->visit(Callee)) + return false; + if (!this->emitSetLocal(PT_MemberPtr, *CalleeOffset, E)) + return false; + if (!this->emitGetLocal(PT_MemberPtr, *CalleeOffset, E)) + return false; + if (!this->emitGetMemberPtrBase(E)) + return false; + } else if (!this->visit(MC->getImplicitObjectArgument())) { return false; + } } llvm::BitVector NonNullArgs = collectNonNullArgs(FuncDecl, Args); @@ -3370,11 +3466,22 @@ bool ByteCodeExprGen::VisitCallExpr(const CallExpr *E) { for (unsigned I = 0, N = E->getNumArgs(); I != N; ++I) ArgSize += align(primSize(classify(E->getArg(I)).value_or(PT_Ptr))); - if (!this->visit(E->getCallee())) - return false; + // Get the callee, either from a member pointer saved in CalleeOffset, + // or by just visiting the Callee expr. + if (CalleeOffset) { + if (!this->emitGetLocal(PT_MemberPtr, *CalleeOffset, E)) + return false; + if (!this->emitGetMemberPtrDecl(E)) + return false; + if (!this->emitCallPtr(ArgSize, E, E)) + return false; + } else { + if (!this->visit(E->getCallee())) + return false; - if (!this->emitCallPtr(ArgSize, E, E)) - return false; + if (!this->emitCallPtr(ArgSize, E, E)) + return false; + } } // Cleanup for discarded return values. @@ -3613,6 +3720,11 @@ bool ByteCodeExprGen::VisitUnaryOperator(const UnaryOperator *E) { return false; return DiscardResult ? this->emitPop(*T, E) : true; case UO_AddrOf: // &x + if (E->getType()->isMemberPointerType()) { + // C++11 [expr.unary.op]p3 has very strict rules on how the address of a + // member can be formed. + return this->emitGetMemberPtr(cast(SubExpr)->getDecl(), E); + } // We should already have a pointer when we get here. return this->delegate(SubExpr); case UO_Deref: // *x @@ -3727,6 +3839,21 @@ bool ByteCodeExprGen::VisitComplexUnaryOperator( // we sometimes have to do the lvalue-to-rvalue conversion here manually. return this->emitArrayElemPop(classifyPrim(E->getType()), 1, E); + case UO_Not: // ~x + if (!this->visit(SubExpr)) + return false; + // Negate the imaginary component. + if (!this->emitArrayElem(ElemT, 1, E)) + return false; + if (!this->emitNeg(ElemT, E)) + return false; + if (!this->emitInitElem(ElemT, 1, E)) + return false; + return DiscardResult ? this->emitPopPtr(E) : true; + + case UO_Extension: + return this->delegate(SubExpr); + default: return this->emitInvalid(E); } @@ -3735,12 +3862,10 @@ bool ByteCodeExprGen::VisitComplexUnaryOperator( } template -bool ByteCodeExprGen::VisitDeclRefExpr(const DeclRefExpr *E) { +bool ByteCodeExprGen::visitDeclRef(const ValueDecl *D, const Expr *E) { if (DiscardResult) return true; - const auto *D = E->getDecl(); - if (const auto *ECD = dyn_cast(D)) { return this->emitConst(ECD->getInitVal(), E); } else if (const auto *BD = dyn_cast(D)) { @@ -3796,6 +3921,14 @@ bool ByteCodeExprGen::VisitDeclRefExpr(const DeclRefExpr *E) { if (IsPtr) return this->emitGetThisFieldPtr(Offset, E); return this->emitGetPtrThisField(Offset, E); + } else if (const auto *DRE = dyn_cast(E); + DRE && DRE->refersToEnclosingVariableOrCapture()) { + if (const auto *VD = dyn_cast(D); VD && VD->isInitCapture()) { + if (!this->visitVarDecl(cast(D))) + return false; + // Retry. + return this->visitDeclRef(D, E); + } } // Try to lazily visit (or emit dummy pointers for) declarations @@ -3808,7 +3941,7 @@ bool ByteCodeExprGen::VisitDeclRefExpr(const DeclRefExpr *E) { if (!this->visitVarDecl(VD)) return false; // Retry. - return this->VisitDeclRefExpr(E); + return this->visitDeclRef(VD, E); } } } else { @@ -3818,7 +3951,7 @@ bool ByteCodeExprGen::VisitDeclRefExpr(const DeclRefExpr *E) { if (!this->visitVarDecl(VD)) return false; // Retry. - return this->VisitDeclRefExpr(E); + return this->visitDeclRef(VD, E); } } @@ -3835,7 +3968,15 @@ bool ByteCodeExprGen::VisitDeclRefExpr(const DeclRefExpr *E) { return true; } - return this->emitInvalidDeclRef(E, E); + if (const auto *DRE = dyn_cast(E)) + return this->emitInvalidDeclRef(DRE, E); + return false; +} + +template +bool ByteCodeExprGen::VisitDeclRefExpr(const DeclRefExpr *E) { + const auto *D = E->getDecl(); + return this->visitDeclRef(D, E); } template @@ -4075,8 +4216,6 @@ bool ByteCodeExprGen::emitRecordDestruction(const Record *R) { for (const Record::Field &Field : llvm::reverse(R->fields())) { const Descriptor *D = Field.Desc; if (!D->isPrimitive() && !D->isPrimitiveArray()) { - if (!this->emitDupPtr(SourceInfo{})) - return false; if (!this->emitGetPtrField(Field.Offset, SourceInfo{})) return false; if (!this->emitDestruction(D)) diff --git a/clang/lib/AST/Interp/ByteCodeExprGen.h b/clang/lib/AST/Interp/ByteCodeExprGen.h index 44c495240289f8b7251c776120762c2670aaceea..7ab14b6ab383e84d03fa88903b4c473debff0c91 100644 --- a/clang/lib/AST/Interp/ByteCodeExprGen.h +++ b/clang/lib/AST/Interp/ByteCodeExprGen.h @@ -189,6 +189,8 @@ protected: /// Visit an APValue. bool visitAPValue(const APValue &Val, PrimType ValType, const Expr *E); bool visitAPValueInitializer(const APValue &Val, const Expr *E); + /// Visit the given decl as if we have a reference to it. + bool visitDeclRef(const ValueDecl *D, const Expr *E); /// Visits an expression and converts it to a boolean. bool visitBool(const Expr *E); diff --git a/clang/lib/AST/Interp/Context.cpp b/clang/lib/AST/Interp/Context.cpp index 4ecfa0f9bfd75170c9120d9d4a065e1d81931497..98d1837204ebc4eda7cedde5d9794137731e97bd 100644 --- a/clang/lib/AST/Interp/Context.cpp +++ b/clang/lib/AST/Interp/Context.cpp @@ -46,6 +46,7 @@ bool Context::evaluateAsRValue(State &Parent, const Expr *E, APValue &Result) { auto Res = C.interpretExpr(E, /*ConvertResultToRValue=*/E->isGLValue()); if (Res.isInvalid()) { + C.cleanup(); Stk.clear(); return false; } @@ -70,6 +71,7 @@ bool Context::evaluate(State &Parent, const Expr *E, APValue &Result) { auto Res = C.interpretExpr(E); if (Res.isInvalid()) { + C.cleanup(); Stk.clear(); return false; } @@ -97,6 +99,7 @@ bool Context::evaluateAsInitializer(State &Parent, const VarDecl *VD, (VD->getType()->isRecordType() || VD->getType()->isArrayType()); auto Res = C.interpretDecl(VD, CheckGlobalInitialized); if (Res.isInvalid()) { + C.cleanup(); Stk.clear(); return false; } @@ -160,8 +163,12 @@ std::optional Context::classify(QualType T) const { if (T->isFloatingType()) return PT_Float; + if (T->isSpecificBuiltinType(BuiltinType::BoundMember) || + T->isMemberPointerType()) + return PT_MemberPtr; + if (T->isFunctionPointerType() || T->isFunctionReferenceType() || - T->isFunctionType() || T->isSpecificBuiltinType(BuiltinType::BoundMember)) + T->isFunctionType()) return PT_FnPtr; if (T->isReferenceType() || T->isPointerType() || @@ -174,9 +181,6 @@ std::optional Context::classify(QualType T) const { if (const auto *DT = dyn_cast(T)) return classify(DT->getUnderlyingType()); - if (const auto *DT = dyn_cast(T)) - return classify(DT->getPointeeType()); - return std::nullopt; } @@ -289,10 +293,12 @@ unsigned Context::collectBaseOffset(const RecordDecl *BaseDecl, } if (CurDecl == FinalDecl) break; - - // break; } assert(OffsetSum > 0); return OffsetSum; } + +const Record *Context::getRecord(const RecordDecl *D) const { + return P->getOrCreateRecord(D); +} diff --git a/clang/lib/AST/Interp/Context.h b/clang/lib/AST/Interp/Context.h index 360e9499d0844071e0ffe9b3c857c93a9800ada9..c78dc9a2a471eb7af44371a139d525e2a1df4460 100644 --- a/clang/lib/AST/Interp/Context.h +++ b/clang/lib/AST/Interp/Context.h @@ -107,6 +107,8 @@ public: unsigned collectBaseOffset(const RecordDecl *BaseDecl, const RecordDecl *DerivedDecl) const; + const Record *getRecord(const RecordDecl *D) const; + private: /// Runs a function. bool Run(State &Parent, const Function *Func, APValue &Result); diff --git a/clang/lib/AST/Interp/Descriptor.cpp b/clang/lib/AST/Interp/Descriptor.cpp index 746b765ca421679b33a437b4ba1913c385efad26..d20ab1340c89039736c31a01d8827a37973b0745 100644 --- a/clang/lib/AST/Interp/Descriptor.cpp +++ b/clang/lib/AST/Interp/Descriptor.cpp @@ -11,6 +11,7 @@ #include "Floating.h" #include "FunctionPointer.h" #include "IntegralAP.h" +#include "MemberPointer.h" #include "Pointer.h" #include "PrimType.h" #include "Record.h" diff --git a/clang/lib/AST/Interp/Disasm.cpp b/clang/lib/AST/Interp/Disasm.cpp index ccdc96a79436dad25bcf595c537e7953b64fe042..0ab84d159c58b733c8dcaac4343d12a611e0cf89 100644 --- a/clang/lib/AST/Interp/Disasm.cpp +++ b/clang/lib/AST/Interp/Disasm.cpp @@ -11,12 +11,15 @@ //===----------------------------------------------------------------------===// #include "Boolean.h" +#include "Context.h" +#include "EvaluationResult.h" #include "Floating.h" #include "Function.h" #include "FunctionPointer.h" #include "Integral.h" #include "IntegralAP.h" #include "InterpFrame.h" +#include "MemberPointer.h" #include "Opcode.h" #include "PrimType.h" #include "Program.h" @@ -120,6 +123,8 @@ static const char *primTypeToString(PrimType T) { return "Ptr"; case PT_FnPtr: return "FnPtr"; + case PT_MemberPtr: + return "MemberPtr"; } llvm_unreachable("Unhandled PrimType"); } @@ -150,7 +155,7 @@ LLVM_DUMP_METHOD void Program::dump(llvm::raw_ostream &OS) const { } Desc->dump(OS); OS << "\n"; - if (Desc->isPrimitive() && !Desc->isDummy()) { + if (GP.isInitialized() && Desc->isPrimitive() && !Desc->isDummy()) { OS << " "; { ColorScope SC(OS, true, {llvm::raw_ostream::BRIGHT_CYAN, false}); @@ -305,3 +310,43 @@ LLVM_DUMP_METHOD void Block::dump(llvm::raw_ostream &OS) const { OS << " Extern: " << IsExtern << "\n"; OS << " Initialized: " << IsInitialized << "\n"; } + +LLVM_DUMP_METHOD void EvaluationResult::dump() const { + assert(Ctx); + auto &OS = llvm::errs(); + const ASTContext &ASTCtx = Ctx->getASTContext(); + + switch (Kind) { + case Empty: + OS << "Empty\n"; + break; + case RValue: + OS << "RValue: "; + std::get(Value).dump(OS, ASTCtx); + break; + case LValue: { + assert(Source); + QualType SourceType; + if (const auto *D = Source.dyn_cast()) { + if (const auto *VD = dyn_cast(D)) + SourceType = VD->getType(); + } else if (const auto *E = Source.dyn_cast()) { + SourceType = E->getType(); + } + + OS << "LValue: "; + if (const auto *P = std::get_if(&Value)) + P->toAPValue().printPretty(OS, ASTCtx, SourceType); + else if (const auto *FP = std::get_if(&Value)) // Nope + FP->toAPValue().printPretty(OS, ASTCtx, SourceType); + OS << "\n"; + break; + } + case Invalid: + OS << "Invalid\n"; + break; + case Valid: + OS << "Valid\n"; + break; + } +} diff --git a/clang/lib/AST/Interp/EvalEmitter.cpp b/clang/lib/AST/Interp/EvalEmitter.cpp index 388c3612f292b099d41cf0888ceb1337159fc9bc..025b46b3d7886af4e75d8d80646244685da7fceb 100644 --- a/clang/lib/AST/Interp/EvalEmitter.cpp +++ b/clang/lib/AST/Interp/EvalEmitter.cpp @@ -32,10 +32,16 @@ EvalEmitter::~EvalEmitter() { } } +/// Clean up all our resources. This needs to done in failed evaluations before +/// we call InterpStack::clear(), because there might be a Pointer on the stack +/// pointing into a Block in the EvalEmitter. +void EvalEmitter::cleanup() { S.cleanup(); } + EvaluationResult EvalEmitter::interpretExpr(const Expr *E, bool ConvertResultToRValue) { S.setEvalLocation(E->getExprLoc()); - this->ConvertResultToRValue = ConvertResultToRValue; + this->ConvertResultToRValue = ConvertResultToRValue && !isa(E); + this->CheckFullyInitialized = isa(E); EvalResult.setSource(E); if (!this->visitExpr(E)) { @@ -50,10 +56,14 @@ EvaluationResult EvalEmitter::interpretExpr(const Expr *E, EvaluationResult EvalEmitter::interpretDecl(const VarDecl *VD, bool CheckFullyInitialized) { this->CheckFullyInitialized = CheckFullyInitialized; - this->ConvertResultToRValue = - VD->getAnyInitializer() && - (VD->getAnyInitializer()->getType()->isAnyComplexType() || - VD->getAnyInitializer()->getType()->isVectorType()); + + if (const Expr *Init = VD->getAnyInitializer()) { + QualType T = VD->getType(); + this->ConvertResultToRValue = !Init->isGLValue() && !T->isPointerType() && + !T->isObjCObjectPointerType(); + } else + this->ConvertResultToRValue = false; + EvalResult.setSource(VD); if (!this->visitDecl(VD) && EvalResult.empty()) @@ -132,6 +142,10 @@ template <> bool EvalEmitter::emitRet(const SourceInfo &Info) { return true; const Pointer &Ptr = S.Stk.pop(); + + if (CheckFullyInitialized && !EvalResult.checkFullyInitialized(S, Ptr)) + return false; + // Implicitly convert lvalue to rvalue, if requested. if (ConvertResultToRValue) { if (std::optional V = Ptr.toRValue(Ctx)) { @@ -140,17 +154,7 @@ template <> bool EvalEmitter::emitRet(const SourceInfo &Info) { return false; } } else { - if (CheckFullyInitialized) { - if (!EvalResult.checkFullyInitialized(S, Ptr)) - return false; - - std::optional RValueResult = Ptr.toRValue(Ctx); - if (!RValueResult) - return false; - EvalResult.setValue(*RValueResult); - } else { - EvalResult.setValue(Ptr.toAPValue()); - } + EvalResult.setValue(Ptr.toAPValue()); } return true; @@ -170,6 +174,10 @@ bool EvalEmitter::emitRetVoid(const SourceInfo &Info) { bool EvalEmitter::emitRetValue(const SourceInfo &Info) { const auto &Ptr = S.Stk.pop(); + + if (CheckFullyInitialized && !EvalResult.checkFullyInitialized(S, Ptr)) + return false; + if (std::optional APV = Ptr.toRValue(S.getCtx())) { EvalResult.setValue(*APV); return true; diff --git a/clang/lib/AST/Interp/EvalEmitter.h b/clang/lib/AST/Interp/EvalEmitter.h index 116f1d6fc134a7a0657b9089ef080b7f17bde2d0..98d6026bbcce487f0ac99b491ee55b3e6fe442e8 100644 --- a/clang/lib/AST/Interp/EvalEmitter.h +++ b/clang/lib/AST/Interp/EvalEmitter.h @@ -38,6 +38,9 @@ public: bool ConvertResultToRValue = false); EvaluationResult interpretDecl(const VarDecl *VD, bool CheckFullyInitialized); + /// Clean up all resources. + void cleanup(); + InterpState &getState() { return S; } protected: diff --git a/clang/lib/AST/Interp/EvaluationResult.cpp b/clang/lib/AST/Interp/EvaluationResult.cpp index 150a793da881dbce07a919dffeaff6ccf49347f7..387e3dc88bff26f5d2135871038a7f1311efdd5c 100644 --- a/clang/lib/AST/Interp/EvaluationResult.cpp +++ b/clang/lib/AST/Interp/EvaluationResult.cpp @@ -7,7 +7,6 @@ //===----------------------------------------------------------------------===// #include "EvaluationResult.h" -#include "Context.h" #include "InterpState.h" #include "Record.h" #include "clang/AST/ExprCXX.h" @@ -142,61 +141,22 @@ bool EvaluationResult::checkFullyInitialized(InterpState &S, const Pointer &Ptr) const { assert(Source); assert(empty()); - - // Our Source must be a VarDecl. - const Decl *SourceDecl = Source.dyn_cast(); - assert(SourceDecl); - const auto *VD = cast(SourceDecl); - assert(VD->getType()->isRecordType() || VD->getType()->isArrayType()); - SourceLocation InitLoc = VD->getAnyInitializer()->getExprLoc(); - assert(!Ptr.isZero()); + SourceLocation InitLoc; + if (const auto *D = Source.dyn_cast()) + InitLoc = cast(D)->getAnyInitializer()->getExprLoc(); + else if (const auto *E = Source.dyn_cast()) + InitLoc = E->getExprLoc(); + if (const Record *R = Ptr.getRecord()) return CheckFieldsInitialized(S, InitLoc, Ptr, R); - const auto *CAT = - cast(Ptr.getType()->getAsArrayTypeUnsafe()); - return CheckArrayInitialized(S, InitLoc, Ptr, CAT); -} -void EvaluationResult::dump() const { - assert(Ctx); - auto &OS = llvm::errs(); - const ASTContext &ASTCtx = Ctx->getASTContext(); + if (const auto *CAT = dyn_cast_if_present( + Ptr.getType()->getAsArrayTypeUnsafe())) + return CheckArrayInitialized(S, InitLoc, Ptr, CAT); - switch (Kind) { - case Empty: - OS << "Empty\n"; - break; - case RValue: - OS << "RValue: "; - std::get(Value).dump(OS, ASTCtx); - break; - case LValue: { - assert(Source); - QualType SourceType; - if (const auto *D = Source.dyn_cast()) { - if (const auto *VD = dyn_cast(D)) - SourceType = VD->getType(); - } else if (const auto *E = Source.dyn_cast()) { - SourceType = E->getType(); - } - - OS << "LValue: "; - if (const auto *P = std::get_if(&Value)) - P->toAPValue().printPretty(OS, ASTCtx, SourceType); - else if (const auto *FP = std::get_if(&Value)) // Nope - FP->toAPValue().printPretty(OS, ASTCtx, SourceType); - OS << "\n"; - break; - } - case Invalid: - OS << "Invalid\n"; - break; - case Valid: - OS << "Valid\n"; - break; - } + return true; } } // namespace interp diff --git a/clang/lib/AST/Interp/Function.cpp b/clang/lib/AST/Interp/Function.cpp index 1d04998d5dd158815a51843c43983e46aad9fa73..00f5a1fced531a981996c7caa1842f9ab7f19f67 100644 --- a/clang/lib/AST/Interp/Function.cpp +++ b/clang/lib/AST/Interp/Function.cpp @@ -40,7 +40,8 @@ SourceInfo Function::getSource(CodePtr PC) const { unsigned Offset = PC - getCodeBegin(); using Elem = std::pair; auto It = llvm::lower_bound(SrcMap, Elem{Offset, {}}, llvm::less_first()); - assert(It != SrcMap.end()); + if (It == SrcMap.end()) + return SrcMap.back().second; return It->second; } diff --git a/clang/lib/AST/Interp/Interp.cpp b/clang/lib/AST/Interp/Interp.cpp index 145fa65791da207a2534d04c9ea9085abdadac52..49015b1dd63d33b6d75b912141c3ab6e61f037bb 100644 --- a/clang/lib/AST/Interp/Interp.cpp +++ b/clang/lib/AST/Interp/Interp.cpp @@ -373,6 +373,26 @@ bool CheckSubobject(InterpState &S, CodePtr OpPC, const Pointer &Ptr, return false; } +bool CheckDowncast(InterpState &S, CodePtr OpPC, const Pointer &Ptr, + uint32_t Offset) { + uint32_t MinOffset = Ptr.getDeclDesc()->getMetadataSize(); + uint32_t PtrOffset = Ptr.getByteOffset(); + + // We subtract Offset from PtrOffset. The result must be at least + // MinOffset. + if (Offset < PtrOffset && (PtrOffset - Offset) >= MinOffset) + return true; + + const auto *E = cast(S.Current->getExpr(OpPC)); + QualType TargetQT = E->getType()->getPointeeType(); + QualType MostDerivedQT = Ptr.getDeclPtr().getType(); + + S.CCEDiag(E, diag::note_constexpr_invalid_downcast) + << MostDerivedQT << TargetQT; + + return false; +} + bool CheckConst(InterpState &S, CodePtr OpPC, const Pointer &Ptr) { assert(Ptr.isLive() && "Pointer is not live"); if (!Ptr.isConst()) @@ -493,10 +513,12 @@ bool CheckStore(InterpState &S, CodePtr OpPC, const Pointer &Ptr) { bool CheckInvoke(InterpState &S, CodePtr OpPC, const Pointer &Ptr) { if (!CheckLive(S, OpPC, Ptr, AK_MemberCall)) return false; - if (!CheckExtern(S, OpPC, Ptr)) - return false; - if (!CheckRange(S, OpPC, Ptr, AK_MemberCall)) - return false; + if (!Ptr.isDummy()) { + if (!CheckExtern(S, OpPC, Ptr)) + return false; + if (!CheckRange(S, OpPC, Ptr, AK_MemberCall)) + return false; + } return true; } @@ -516,7 +538,7 @@ bool CheckCallable(InterpState &S, CodePtr OpPC, const Function *F) { return false; } - if (!F->isConstexpr()) { + if (!F->isConstexpr() || !F->hasBody()) { const SourceLocation &Loc = S.Current->getLocation(OpPC); if (S.getLangOpts().CPlusPlus11) { const FunctionDecl *DiagDecl = F->getDecl(); @@ -550,9 +572,10 @@ bool CheckCallable(InterpState &S, CodePtr OpPC, const Function *F) { S.checkingPotentialConstantExpression()) return false; - // If the declaration is defined _and_ declared 'constexpr', the below - // diagnostic doesn't add anything useful. - if (DiagDecl->isDefined() && DiagDecl->isConstexpr()) + // If the declaration is defined, declared 'constexpr' _and_ has a body, + // the below diagnostic doesn't add anything useful. + if (DiagDecl->isDefined() && DiagDecl->isConstexpr() && + DiagDecl->hasBody()) return false; S.FFDiag(Loc, diag::note_constexpr_invalid_function, 1) diff --git a/clang/lib/AST/Interp/Interp.h b/clang/lib/AST/Interp/Interp.h index eca1792e64718e024dfff24a9cd73a176272d049..784e138e1467d47f6f0ea1108e8ca5894dcefeb1 100644 --- a/clang/lib/AST/Interp/Interp.h +++ b/clang/lib/AST/Interp/Interp.h @@ -20,6 +20,7 @@ #include "InterpFrame.h" #include "InterpStack.h" #include "InterpState.h" +#include "MemberPointer.h" #include "Opcode.h" #include "PrimType.h" #include "Program.h" @@ -75,6 +76,11 @@ bool CheckRange(InterpState &S, CodePtr OpPC, const Pointer &Ptr, bool CheckSubobject(InterpState &S, CodePtr OpPC, const Pointer &Ptr, CheckSubobjectKind CSK); +/// Checks if the dowcast using the given offset is possible with the given +/// pointer. +bool CheckDowncast(InterpState &S, CodePtr OpPC, const Pointer &Ptr, + uint32_t Offset); + /// Checks if a pointer points to const storage. bool CheckConst(InterpState &S, CodePtr OpPC, const Pointer &Ptr); @@ -725,6 +731,9 @@ using CompareFn = llvm::function_ref; template bool CmpHelper(InterpState &S, CodePtr OpPC, CompareFn Fn) { + assert((!std::is_same_v) && + "Non-equality comparisons on member pointer types should already be " + "rejected in Sema."); using BoolT = PrimConv::T; const T &RHS = S.Stk.pop(); const T &LHS = S.Stk.pop(); @@ -834,6 +843,47 @@ inline bool CmpHelperEQ(InterpState &S, CodePtr OpPC, CompareFn Fn) { } } +template <> +inline bool CmpHelperEQ(InterpState &S, CodePtr OpPC, + CompareFn Fn) { + const auto &RHS = S.Stk.pop(); + const auto &LHS = S.Stk.pop(); + + // If either operand is a pointer to a weak function, the comparison is not + // constant. + for (const auto &MP : {LHS, RHS}) { + if (const CXXMethodDecl *MD = MP.getMemberFunction(); MD && MD->isWeak()) { + const SourceInfo &Loc = S.Current->getSource(OpPC); + S.FFDiag(Loc, diag::note_constexpr_mem_pointer_weak_comparison) << MD; + return false; + } + } + + // C++11 [expr.eq]p2: + // If both operands are null, they compare equal. Otherwise if only one is + // null, they compare unequal. + if (LHS.isZero() && RHS.isZero()) { + S.Stk.push(Fn(ComparisonCategoryResult::Equal)); + return true; + } + if (LHS.isZero() || RHS.isZero()) { + S.Stk.push(Fn(ComparisonCategoryResult::Unordered)); + return true; + } + + // We cannot compare against virtual declarations at compile time. + for (const auto &MP : {LHS, RHS}) { + if (const CXXMethodDecl *MD = MP.getMemberFunction(); + MD && MD->isVirtual()) { + const SourceInfo &Loc = S.Current->getSource(OpPC); + S.CCEDiag(Loc, diag::note_constexpr_compare_virtual_mem_ptr) << MD; + } + } + + S.Stk.push(Boolean::from(Fn(LHS.compare(RHS)))); + return true; +} + template ::T> bool EQ(InterpState &S, CodePtr OpPC) { return CmpHelperEQ(S, OpPC, [](ComparisonCategoryResult R) { @@ -1233,9 +1283,32 @@ inline bool GetPtrGlobal(InterpState &S, CodePtr OpPC, uint32_t I) { return true; } -/// 1) Pops a Pointer from the stack +/// 1) Peeks a Pointer /// 2) Pushes Pointer.atField(Off) on the stack inline bool GetPtrField(InterpState &S, CodePtr OpPC, uint32_t Off) { + const Pointer &Ptr = S.Stk.peek(); + + if (S.getLangOpts().CPlusPlus && S.inConstantContext() && + !CheckNull(S, OpPC, Ptr, CSK_Field)) + return false; + + if (!CheckExtern(S, OpPC, Ptr)) + return false; + if (!CheckRange(S, OpPC, Ptr, CSK_Field)) + return false; + if (!CheckArray(S, OpPC, Ptr)) + return false; + if (!CheckSubobject(S, OpPC, Ptr, CSK_Field)) + return false; + + if (Ptr.isBlockPointer() && Off > Ptr.block()->getSize()) + return false; + + S.Stk.push(Ptr.atField(Off)); + return true; +} + +inline bool GetPtrFieldPop(InterpState &S, CodePtr OpPC, uint32_t Off) { const Pointer &Ptr = S.Stk.pop(); if (S.getLangOpts().CPlusPlus && S.inConstantContext() && @@ -1300,6 +1373,9 @@ inline bool GetPtrDerivedPop(InterpState &S, CodePtr OpPC, uint32_t Off) { return false; if (!CheckSubobject(S, OpPC, Ptr, CSK_Derived)) return false; + if (!CheckDowncast(S, OpPC, Ptr, Off)) + return false; + S.Stk.push(Ptr.atFieldSub(Off)); return true; } @@ -1324,6 +1400,12 @@ inline bool GetPtrBasePop(InterpState &S, CodePtr OpPC, uint32_t Off) { return true; } +inline bool GetMemberPtrBasePop(InterpState &S, CodePtr OpPC, int32_t Off) { + const auto &Ptr = S.Stk.pop(); + S.Stk.push(Ptr.atInstanceBase(Off)); + return true; +} + inline bool GetPtrThisBase(InterpState &S, CodePtr OpPC, uint32_t Off) { if (S.checkingPotentialConstantExpression()) return false; @@ -1532,6 +1614,24 @@ inline bool Memcpy(InterpState &S, CodePtr OpPC) { return DoMemcpy(S, OpPC, Src, Dest); } +inline bool ToMemberPtr(InterpState &S, CodePtr OpPC) { + const auto &Member = S.Stk.pop(); + const auto &Base = S.Stk.pop(); + + S.Stk.push(Member.takeInstance(Base)); + return true; +} + +inline bool CastMemberPtrPtr(InterpState &S, CodePtr OpPC) { + const auto &MP = S.Stk.pop(); + + if (std::optional Ptr = MP.toPointer(S.Ctx)) { + S.Stk.push(*Ptr); + return true; + } + return false; +} + //===----------------------------------------------------------------------===// // AddOffset, SubOffset //===----------------------------------------------------------------------===// @@ -1696,8 +1796,10 @@ inline bool SubPtr(InterpState &S, CodePtr OpPC) { return true; } - T A = T::from(LHS.getIndex()); - T B = T::from(RHS.getIndex()); + T A = LHS.isElementPastEnd() ? T::from(LHS.getNumElems()) + : T::from(LHS.getIndex()); + T B = RHS.isElementPastEnd() ? T::from(RHS.getNumElems()) + : T::from(RHS.getIndex()); return AddSubMulHelper(S, OpPC, A.bitWidth(), A, B); } @@ -1835,6 +1937,9 @@ template ::T> bool CastPointerIntegral(InterpState &S, CodePtr OpPC) { const Pointer &Ptr = S.Stk.pop(); + if (Ptr.isDummy()) + return false; + const SourceInfo &E = S.Current->getSource(OpPC); S.CCEDiag(E, diag::note_constexpr_invalid_cast) << 2 << S.getLangOpts().CPlusPlus << S.Current->getRange(OpPC); @@ -1847,6 +1952,9 @@ static inline bool CastPointerIntegralAP(InterpState &S, CodePtr OpPC, uint32_t BitWidth) { const Pointer &Ptr = S.Stk.pop(); + if (Ptr.isDummy()) + return false; + const SourceInfo &E = S.Current->getSource(OpPC); S.CCEDiag(E, diag::note_constexpr_invalid_cast) << 2 << S.getLangOpts().CPlusPlus << S.Current->getRange(OpPC); @@ -1860,6 +1968,9 @@ static inline bool CastPointerIntegralAPS(InterpState &S, CodePtr OpPC, uint32_t BitWidth) { const Pointer &Ptr = S.Stk.pop(); + if (Ptr.isDummy()) + return false; + const SourceInfo &E = S.Current->getSource(OpPC); S.CCEDiag(E, diag::note_constexpr_invalid_cast) << 2 << S.getLangOpts().CPlusPlus << S.Current->getRange(OpPC); @@ -1869,6 +1980,28 @@ static inline bool CastPointerIntegralAPS(InterpState &S, CodePtr OpPC, return true; } +static inline bool PtrPtrCast(InterpState &S, CodePtr OpPC, bool SrcIsVoidPtr) { + const auto &Ptr = S.Stk.peek(); + + if (SrcIsVoidPtr && S.getLangOpts().CPlusPlus) { + bool HasValidResult = !Ptr.isZero(); + + if (HasValidResult) { + // FIXME: note_constexpr_invalid_void_star_cast + } else if (!S.getLangOpts().CPlusPlus26) { + const SourceInfo &E = S.Current->getSource(OpPC); + S.CCEDiag(E, diag::note_constexpr_invalid_cast) + << 3 << "'void *'" << S.Current->getRange(OpPC); + } + } else { + const SourceInfo &E = S.Current->getSource(OpPC); + S.CCEDiag(E, diag::note_constexpr_invalid_cast) + << 2 << S.getLangOpts().CPlusPlus << S.Current->getRange(OpPC); + } + + return true; +} + //===----------------------------------------------------------------------===// // Zero, Nullptr //===----------------------------------------------------------------------===// @@ -2115,7 +2248,7 @@ inline bool ArrayDecay(InterpState &S, CodePtr OpPC) { if (!CheckRange(S, OpPC, Ptr, CSK_ArrayToPointer)) return false; - if (!Ptr.isUnknownSizeArray() || Ptr.isDummy()) { + if (Ptr.isRoot() || !Ptr.isUnknownSizeArray() || Ptr.isDummy()) { S.Stk.push(Ptr.atIndex(0)); return true; } @@ -2329,6 +2462,28 @@ inline bool GetIntPtr(InterpState &S, CodePtr OpPC, const Descriptor *Desc) { return true; } +inline bool GetMemberPtr(InterpState &S, CodePtr OpPC, const Decl *D) { + S.Stk.push(D); + return true; +} + +inline bool GetMemberPtrBase(InterpState &S, CodePtr OpPC) { + const auto &MP = S.Stk.pop(); + + S.Stk.push(MP.getBase()); + return true; +} + +inline bool GetMemberPtrDecl(InterpState &S, CodePtr OpPC) { + const auto &MP = S.Stk.pop(); + + const auto *FD = cast(MP.getDecl()); + const auto *Func = S.getContext().getOrCreateFunction(FD); + + S.Stk.push(Func); + return true; +} + /// Just emit a diagnostic. The expression that caused emission of this /// op is not valid in a constant context. inline bool Invalid(InterpState &S, CodePtr OpPC) { diff --git a/clang/lib/AST/Interp/InterpBlock.h b/clang/lib/AST/Interp/InterpBlock.h index 506034e880d0bd72252acc7be4497c4774f06633..2bb195648a9a9125959e06d2bc9fadada0375b2e 100644 --- a/clang/lib/AST/Interp/InterpBlock.h +++ b/clang/lib/AST/Interp/InterpBlock.h @@ -125,13 +125,15 @@ public: void dump() const { dump(llvm::errs()); } void dump(llvm::raw_ostream &OS) const; -protected: +private: friend class Pointer; friend class DeadBlock; friend class InterpState; Block(const Descriptor *Desc, bool IsExtern, bool IsStatic, bool IsDead) - : IsStatic(IsStatic), IsExtern(IsExtern), IsDead(true), Desc(Desc) {} + : IsStatic(IsStatic), IsExtern(IsExtern), IsDead(true), Desc(Desc) { + assert(Desc); + } /// Deletes a dead block at the end of its lifetime. void cleanup(); diff --git a/clang/lib/AST/Interp/InterpFrame.cpp b/clang/lib/AST/Interp/InterpFrame.cpp index 51b0bd5c155159a43fd5c37e2bc1611e6359e9b2..54ccf9034c7a7dd2ff63842c7d6f27b5f35234c9 100644 --- a/clang/lib/AST/Interp/InterpFrame.cpp +++ b/clang/lib/AST/Interp/InterpFrame.cpp @@ -12,6 +12,7 @@ #include "Function.h" #include "InterpStack.h" #include "InterpState.h" +#include "MemberPointer.h" #include "Pointer.h" #include "PrimType.h" #include "Program.h" diff --git a/clang/lib/AST/Interp/InterpStack.cpp b/clang/lib/AST/Interp/InterpStack.cpp index 91fe40feb7671b6b92c3a6be763a6d4d332723f3..c7024740d322ef22d94ffc939f9ac05c9c723e78 100644 --- a/clang/lib/AST/Interp/InterpStack.cpp +++ b/clang/lib/AST/Interp/InterpStack.cpp @@ -10,6 +10,7 @@ #include "Boolean.h" #include "Floating.h" #include "Integral.h" +#include "MemberPointer.h" #include "Pointer.h" #include #include diff --git a/clang/lib/AST/Interp/InterpStack.h b/clang/lib/AST/Interp/InterpStack.h index 3fd0f63c781fc70d8623dce40f2b52d1563ab663..9d85503b851be15a47001980673c6229e2010354 100644 --- a/clang/lib/AST/Interp/InterpStack.h +++ b/clang/lib/AST/Interp/InterpStack.h @@ -15,6 +15,7 @@ #include "FunctionPointer.h" #include "IntegralAP.h" +#include "MemberPointer.h" #include "PrimType.h" #include #include @@ -188,6 +189,8 @@ private: return PT_IntAP; else if constexpr (std::is_same_v>) return PT_IntAP; + else if constexpr (std::is_same_v) + return PT_MemberPtr; llvm_unreachable("unknown type push()'ed into InterpStack"); } diff --git a/clang/lib/AST/Interp/InterpState.cpp b/clang/lib/AST/Interp/InterpState.cpp index 2cb87ef07fe5882c5fcb275d5c68c0e3a2e52f05..550bc9f1a84b975facdbfca3dc4dfd1fbd2bbe1b 100644 --- a/clang/lib/AST/Interp/InterpState.cpp +++ b/clang/lib/AST/Interp/InterpState.cpp @@ -33,6 +33,8 @@ InterpState::~InterpState() { } } +void InterpState::cleanup() {} + Frame *InterpState::getCurrentFrame() { if (Current && Current->Caller) return Current; diff --git a/clang/lib/AST/Interp/InterpState.h b/clang/lib/AST/Interp/InterpState.h index d483c60c58e248c6c45f65b027178b686c6d1b79..0938a723a76d093546ec272e3835b6ec6512bc89 100644 --- a/clang/lib/AST/Interp/InterpState.h +++ b/clang/lib/AST/Interp/InterpState.h @@ -39,6 +39,8 @@ public: ~InterpState(); + void cleanup(); + InterpState(const InterpState &) = delete; InterpState &operator=(const InterpState &) = delete; diff --git a/clang/lib/AST/Interp/MemberPointer.cpp b/clang/lib/AST/Interp/MemberPointer.cpp new file mode 100644 index 0000000000000000000000000000000000000000..96f63643e83c98f808346731dcd9e0d9610db4f5 --- /dev/null +++ b/clang/lib/AST/Interp/MemberPointer.cpp @@ -0,0 +1,76 @@ +//===------------------------- MemberPointer.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 "MemberPointer.h" +#include "Context.h" +#include "FunctionPointer.h" +#include "Program.h" +#include "Record.h" + +namespace clang { +namespace interp { + +std::optional MemberPointer::toPointer(const Context &Ctx) const { + if (!Dcl || isa(Dcl)) + return Base; + const FieldDecl *FD = cast(Dcl); + assert(FD); + + if (!Base.isBlockPointer()) + return std::nullopt; + + Pointer CastedBase = + (PtrOffset < 0 ? Base.atField(-PtrOffset) : Base.atFieldSub(PtrOffset)); + + const Record *BaseRecord = CastedBase.getRecord(); + if (!BaseRecord) + return std::nullopt; + + assert(BaseRecord); + if (FD->getParent() == BaseRecord->getDecl()) + return CastedBase.atField(BaseRecord->getField(FD)->Offset); + + const RecordDecl *FieldParent = FD->getParent(); + const Record *FieldRecord = Ctx.getRecord(FieldParent); + + unsigned Offset = 0; + Offset += FieldRecord->getField(FD)->Offset; + Offset += CastedBase.block()->getDescriptor()->getMetadataSize(); + + if (Offset > CastedBase.block()->getSize()) + return std::nullopt; + + if (const RecordDecl *BaseDecl = Base.getDeclPtr().getRecord()->getDecl(); + BaseDecl != FieldParent) + Offset += Ctx.collectBaseOffset(FieldParent, BaseDecl); + + if (Offset > CastedBase.block()->getSize()) + return std::nullopt; + + assert(Offset <= CastedBase.block()->getSize()); + return Pointer(const_cast(Base.block()), Offset, Offset); +} + +FunctionPointer MemberPointer::toFunctionPointer(const Context &Ctx) const { + return FunctionPointer(Ctx.getProgram().getFunction(cast(Dcl))); +} + +APValue MemberPointer::toAPValue() const { + if (isZero()) + return APValue(static_cast(nullptr), /*IsDerivedMember=*/false, + /*Path=*/{}); + + if (hasBase()) + return Base.toAPValue(); + + return APValue(cast(getDecl()), /*IsDerivedMember=*/false, + /*Path=*/{}); +} + +} // namespace interp +} // namespace clang diff --git a/clang/lib/AST/Interp/MemberPointer.h b/clang/lib/AST/Interp/MemberPointer.h new file mode 100644 index 0000000000000000000000000000000000000000..f56dc530431e46068ce72d2dea9870800da1b8c4 --- /dev/null +++ b/clang/lib/AST/Interp/MemberPointer.h @@ -0,0 +1,112 @@ +//===------------------------- MemberPointer.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_AST_INTERP_MEMBER_POINTER_H +#define LLVM_CLANG_AST_INTERP_MEMBER_POINTER_H + +#include "Pointer.h" +#include + +namespace clang { +class ASTContext; +namespace interp { + +class Context; +class FunctionPointer; + +class MemberPointer final { +private: + Pointer Base; + const Decl *Dcl = nullptr; + int32_t PtrOffset = 0; + + MemberPointer(Pointer Base, const Decl *Dcl, int32_t PtrOffset) + : Base(Base), Dcl(Dcl), PtrOffset(PtrOffset) {} + +public: + MemberPointer() = default; + MemberPointer(Pointer Base, const Decl *Dcl) : Base(Base), Dcl(Dcl) {} + MemberPointer(uint32_t Address, const Descriptor *D) { + // We only reach this for Address == 0, when creating a null member pointer. + assert(Address == 0); + } + + MemberPointer(const Decl *D) : Dcl(D) { + assert((isa(D))); + } + + uint64_t getIntegerRepresentation() const { + assert( + false && + "getIntegerRepresentation() shouldn't be reachable for MemberPointers"); + return 17; + } + + std::optional toPointer(const Context &Ctx) const; + + FunctionPointer toFunctionPointer(const Context &Ctx) const; + + Pointer getBase() const { + if (PtrOffset < 0) + return Base.atField(-PtrOffset); + return Base.atFieldSub(PtrOffset); + } + bool isMemberFunctionPointer() const { + return isa_and_nonnull(Dcl); + } + const CXXMethodDecl *getMemberFunction() const { + return dyn_cast_if_present(Dcl); + } + const FieldDecl *getField() const { + return dyn_cast_if_present(Dcl); + } + + bool hasDecl() const { return Dcl; } + const Decl *getDecl() const { return Dcl; } + + MemberPointer atInstanceBase(unsigned Offset) const { + if (Base.isZero()) + return MemberPointer(Base, Dcl, Offset); + return MemberPointer(this->Base, Dcl, Offset + PtrOffset); + } + + MemberPointer takeInstance(Pointer Instance) const { + assert(this->Base.isZero()); + return MemberPointer(Instance, this->Dcl, this->PtrOffset); + } + + APValue toAPValue() const; + + bool isZero() const { return Base.isZero() && !Dcl; } + bool hasBase() const { return !Base.isZero(); } + + void print(llvm::raw_ostream &OS) const { + OS << "MemberPtr(" << Base << " " << (const void *)Dcl << " + " << PtrOffset + << ")"; + } + + std::string toDiagnosticString(const ASTContext &Ctx) const { + return "FIXME"; + } + + ComparisonCategoryResult compare(const MemberPointer &RHS) const { + if (this->Dcl == RHS.Dcl) + return ComparisonCategoryResult::Equal; + return ComparisonCategoryResult::Unordered; + } +}; + +inline llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, MemberPointer FP) { + FP.print(OS); + return OS; +} + +} // namespace interp +} // namespace clang + +#endif diff --git a/clang/lib/AST/Interp/Opcodes.td b/clang/lib/AST/Interp/Opcodes.td index cfbd7f93c32de83552dc5973d3c9076345ac2cac..df362efd8b58b22c7255adde6d3ecae16e39508e 100644 --- a/clang/lib/AST/Interp/Opcodes.td +++ b/clang/lib/AST/Interp/Opcodes.td @@ -30,6 +30,7 @@ def IntAPS : Type; def Float : Type; def Ptr : Type; def FnPtr : Type; +def MemberPtr : Type; //===----------------------------------------------------------------------===// // Types transferred to the interpreter. @@ -61,6 +62,7 @@ def ArgOffsetOfExpr : ArgType { let Name = "const OffsetOfExpr *"; } def ArgDeclRef : ArgType { let Name = "const DeclRefExpr *"; } def ArgDesc : ArgType { let Name = "const Descriptor *"; } def ArgCCI : ArgType { let Name = "const ComparisonCategoryInfo *"; } +def ArgDecl : ArgType { let Name = "const Decl*"; } //===----------------------------------------------------------------------===// // Classes of types instructions operate on. @@ -93,7 +95,7 @@ def AluTypeClass : TypeClass { } def PtrTypeClass : TypeClass { - let Types = [Ptr, FnPtr]; + let Types = [Ptr, FnPtr, MemberPtr]; } def BoolTypeClass : TypeClass { @@ -137,7 +139,6 @@ class AluOpcode : Opcode { } class FloatOpcode : Opcode { - let Types = []; let Args = [ArgRoundingMode]; } @@ -193,27 +194,22 @@ def NoRet : Opcode {} def Call : Opcode { let Args = [ArgFunction, ArgUint32]; - let Types = []; } def CallVirt : Opcode { let Args = [ArgFunction, ArgUint32]; - let Types = []; } def CallBI : Opcode { let Args = [ArgFunction, ArgCallExpr]; - let Types = []; } def CallPtr : Opcode { let Args = [ArgUint32, ArgCallExpr]; - let Types = []; } def CallVar : Opcode { let Args = [ArgFunction, ArgUint32]; - let Types = []; } def OffsetOf : Opcode { @@ -280,54 +276,37 @@ def Null : Opcode { //===----------------------------------------------------------------------===// // Pointer generation //===----------------------------------------------------------------------===// +class OffsetOpcode : Opcode { + let Args = [ArgUint32]; +} // [] -> [Pointer] -def GetPtrLocal : Opcode { - // Offset of local. - let Args = [ArgUint32]; +def GetPtrLocal : OffsetOpcode { bit HasCustomEval = 1; } // [] -> [Pointer] -def GetPtrParam : Opcode { - // Offset of parameter. - let Args = [ArgUint32]; -} +def GetPtrParam : OffsetOpcode; // [] -> [Pointer] -def GetPtrGlobal : Opcode { - // Index of global. - let Args = [ArgUint32]; -} +def GetPtrGlobal : OffsetOpcode; // [Pointer] -> [Pointer] -def GetPtrField : Opcode { - // Offset of field. - let Args = [ArgUint32]; -} +def GetPtrField : OffsetOpcode; +def GetPtrFieldPop : OffsetOpcode; // [Pointer] -> [Pointer] -def GetPtrActiveField : Opcode { - // Offset of field. - let Args = [ArgUint32]; -} +def GetPtrActiveField : OffsetOpcode; // [] -> [Pointer] -def GetPtrActiveThisField : Opcode { - // Offset of field. - let Args = [ArgUint32]; -} +def GetPtrActiveThisField : OffsetOpcode; // [] -> [Pointer] -def GetPtrThisField : Opcode { - // Offset of field. - let Args = [ArgUint32]; -} +def GetPtrThisField : OffsetOpcode; // [Pointer] -> [Pointer] -def GetPtrBase : Opcode { - // Offset of field, which is a base. - let Args = [ArgUint32]; -} +def GetPtrBase : OffsetOpcode; // [Pointer] -> [Pointer] -def GetPtrBasePop : Opcode { +def GetPtrBasePop : OffsetOpcode; +def GetMemberPtrBasePop : Opcode { // Offset of field, which is a base. - let Args = [ArgUint32]; + let Args = [ArgSint32]; } + def FinishInitPop : Opcode; def FinishInit : Opcode; @@ -415,8 +394,6 @@ def InitGlobalTemp : AccessOpcode { // [Pointer] -> [Pointer] def InitGlobalTempComp : Opcode { let Args = [ArgLETD]; - let Types = []; - let HasGroup = 0; } // [Value] -> [] def SetGlobal : AccessOpcode; @@ -521,13 +498,9 @@ def SubPtr : Opcode { } // [Pointer] -> [Pointer] -def IncPtr : Opcode { - let HasGroup = 0; -} +def IncPtr : Opcode; // [Pointer] -> [Pointer] -def DecPtr : Opcode { - let HasGroup = 0; -} +def DecPtr : Opcode; //===----------------------------------------------------------------------===// // Function pointers. @@ -623,7 +596,6 @@ def Cast: Opcode { } def CastFP : Opcode { - let Types = []; let Args = [ArgFltSemantics, ArgRoundingMode]; } @@ -658,12 +630,10 @@ def CastFloatingIntegral : Opcode { } def CastFloatingIntegralAP : Opcode { - let Types = []; let Args = [ArgUint32]; } def CastFloatingIntegralAPS : Opcode { - let Types = []; let Args = [ArgUint32]; } @@ -672,15 +642,15 @@ def CastPointerIntegral : Opcode { let HasGroup = 1; } def CastPointerIntegralAP : Opcode { - let Types = []; - let HasGroup = 0; let Args = [ArgUint32]; } def CastPointerIntegralAPS : Opcode { - let Types = []; - let HasGroup = 0; let Args = [ArgUint32]; } +def PtrPtrCast : Opcode { + let Args = [ArgBool]; + +} def DecayPtr : Opcode { let Types = [PtrTypeClass, PtrTypeClass]; @@ -751,6 +721,14 @@ def CheckNonNullArg : Opcode { def Memcpy : Opcode; +def ToMemberPtr : Opcode; +def CastMemberPtrPtr : Opcode; +def GetMemberPtr : Opcode { + let Args = [ArgDecl]; +} +def GetMemberPtrBase : Opcode; +def GetMemberPtrDecl : Opcode; + //===----------------------------------------------------------------------===// // Debugging. //===----------------------------------------------------------------------===// diff --git a/clang/lib/AST/Interp/Pointer.cpp b/clang/lib/AST/Interp/Pointer.cpp index 252f7ea46086f9c742fd980c2b4e6a774bb0fcc2..85857d4ee1c8897f9391f7ceb6d9a6e01ddd043a 100644 --- a/clang/lib/AST/Interp/Pointer.cpp +++ b/clang/lib/AST/Interp/Pointer.cpp @@ -13,6 +13,7 @@ #include "Function.h" #include "Integral.h" #include "InterpBlock.h" +#include "MemberPointer.h" #include "PrimType.h" #include "Record.h" @@ -63,26 +64,27 @@ Pointer::~Pointer() { } void Pointer::operator=(const Pointer &P) { - if (!this->isIntegralPointer() || !P.isBlockPointer()) - assert(P.StorageKind == StorageKind || (this->isZero() && P.isZero())); - + // If the current storage type is Block, we need to remove + // this pointer from the block. bool WasBlockPointer = isBlockPointer(); - StorageKind = P.StorageKind; if (StorageKind == Storage::Block) { Block *Old = PointeeStorage.BS.Pointee; - if (WasBlockPointer && PointeeStorage.BS.Pointee) + if (WasBlockPointer && Old) { PointeeStorage.BS.Pointee->removePointer(this); + Old->cleanup(); + } + } - Offset = P.Offset; + StorageKind = P.StorageKind; + Offset = P.Offset; + + if (P.isBlockPointer()) { PointeeStorage.BS = P.PointeeStorage.BS; + PointeeStorage.BS.Pointee = P.PointeeStorage.BS.Pointee; if (PointeeStorage.BS.Pointee) PointeeStorage.BS.Pointee->addPointer(this); - - if (WasBlockPointer && Old) - Old->cleanup(); - - } else if (StorageKind == Storage::Int) { + } else if (P.isIntegralPointer()) { PointeeStorage.Int = P.PointeeStorage.Int; } else { assert(false && "Unhandled storage kind"); @@ -90,26 +92,27 @@ void Pointer::operator=(const Pointer &P) { } void Pointer::operator=(Pointer &&P) { - if (!this->isIntegralPointer() || !P.isBlockPointer()) - assert(P.StorageKind == StorageKind || (this->isZero() && P.isZero())); - + // If the current storage type is Block, we need to remove + // this pointer from the block. bool WasBlockPointer = isBlockPointer(); - StorageKind = P.StorageKind; if (StorageKind == Storage::Block) { Block *Old = PointeeStorage.BS.Pointee; - if (WasBlockPointer && PointeeStorage.BS.Pointee) + if (WasBlockPointer && Old) { PointeeStorage.BS.Pointee->removePointer(this); + Old->cleanup(); + } + } - Offset = P.Offset; + StorageKind = P.StorageKind; + Offset = P.Offset; + + if (P.isBlockPointer()) { PointeeStorage.BS = P.PointeeStorage.BS; + PointeeStorage.BS.Pointee = P.PointeeStorage.BS.Pointee; if (PointeeStorage.BS.Pointee) PointeeStorage.BS.Pointee->addPointer(this); - - if (WasBlockPointer && Old) - Old->cleanup(); - - } else if (StorageKind == Storage::Int) { + } else if (P.isIntegralPointer()) { PointeeStorage.Int = P.PointeeStorage.Int; } else { assert(false && "Unhandled storage kind"); diff --git a/clang/lib/AST/Interp/Pointer.h b/clang/lib/AST/Interp/Pointer.h index 93ca754d04a644a119dc3893296dd668de3240a9..c6e4f4d0b4abd2cc5a006120041f57083d6a5414 100644 --- a/clang/lib/AST/Interp/Pointer.h +++ b/clang/lib/AST/Interp/Pointer.h @@ -620,6 +620,7 @@ public: private: friend class Block; friend class DeadBlock; + friend class MemberPointer; friend struct InitMap; Pointer(Block *Pointee, unsigned Base, uint64_t Offset); diff --git a/clang/lib/AST/Interp/PrimType.cpp b/clang/lib/AST/Interp/PrimType.cpp index 9b96dcfe6a272fc777bb7a2bb8f6c421d775d5bc..3054e67d5c49f36fde89cddce63dc8ff81b4280f 100644 --- a/clang/lib/AST/Interp/PrimType.cpp +++ b/clang/lib/AST/Interp/PrimType.cpp @@ -11,6 +11,7 @@ #include "Floating.h" #include "FunctionPointer.h" #include "IntegralAP.h" +#include "MemberPointer.h" #include "Pointer.h" using namespace clang; diff --git a/clang/lib/AST/Interp/PrimType.h b/clang/lib/AST/Interp/PrimType.h index 604fb5dfde1e416983fb7028bc3d3b7c71e23ca9..20fb5e81774d6ff47234a43e42f39c092d584bfa 100644 --- a/clang/lib/AST/Interp/PrimType.h +++ b/clang/lib/AST/Interp/PrimType.h @@ -25,6 +25,7 @@ class Pointer; class Boolean; class Floating; class FunctionPointer; +class MemberPointer; template class IntegralAP; template class Integral; @@ -44,10 +45,11 @@ enum PrimType : unsigned { PT_Float = 11, PT_Ptr = 12, PT_FnPtr = 13, + PT_MemberPtr = 14, }; inline constexpr bool isPtrType(PrimType T) { - return T == PT_Ptr || T == PT_FnPtr; + return T == PT_Ptr || T == PT_FnPtr || T == PT_MemberPtr; } enum class CastKind : uint8_t { @@ -91,6 +93,9 @@ template <> struct PrimConv { using T = Pointer; }; template <> struct PrimConv { using T = FunctionPointer; }; +template <> struct PrimConv { + using T = MemberPointer; +}; /// Returns the size of a primitive type in bytes. size_t primSize(PrimType Type); @@ -131,6 +136,7 @@ static inline bool aligned(const void *P) { TYPE_SWITCH_CASE(PT_Bool, B) \ TYPE_SWITCH_CASE(PT_Ptr, B) \ TYPE_SWITCH_CASE(PT_FnPtr, B) \ + TYPE_SWITCH_CASE(PT_MemberPtr, B) \ } \ } while (0) diff --git a/clang/lib/AST/Interp/Program.h b/clang/lib/AST/Interp/Program.h index 36b5a1faa513a913e7908a457778ffb204b97eb2..ec7c0744b8856a1801be540b64807ca4c0bab2cb 100644 --- a/clang/lib/AST/Interp/Program.h +++ b/clang/lib/AST/Interp/Program.h @@ -45,7 +45,8 @@ public: // but primitive arrays might have an InitMap* heap allocated and // that needs to be freed. for (Global *G : Globals) - G->block()->invokeDtor(); + if (Block *B = G->block(); B->isInitialized()) + B->invokeDtor(); // Records might actually allocate memory themselves, but they // are allocated using a BumpPtrAllocator. Call their desctructors diff --git a/clang/lib/AST/Mangle.cpp b/clang/lib/AST/Mangle.cpp index 30cff1ba2e6f3791bcd482b17e3f9f02a8558571..4fbf0e3b42dbc80c4ae3d386c88c263c52d01bc6 100644 --- a/clang/lib/AST/Mangle.cpp +++ b/clang/lib/AST/Mangle.cpp @@ -301,9 +301,8 @@ void MangleContext::mangleBlock(const DeclContext *DC, const BlockDecl *BD, } else { assert((isa(DC) || isa(DC)) && "expected a NamedDecl or BlockDecl"); - if (isa(DC)) - for (; DC && isa(DC); DC = DC->getParent()) - (void) getBlockId(cast(DC), true); + for (; isa_and_nonnull(DC); DC = DC->getParent()) + (void)getBlockId(cast(DC), true); assert((isa(DC) || isa(DC)) && "expected a TranslationUnitDecl or a NamedDecl"); if (const auto *CD = dyn_cast(DC)) diff --git a/clang/lib/AST/MicrosoftMangle.cpp b/clang/lib/AST/MicrosoftMangle.cpp index 36d611750ca48cd11b800fc26e495337e8abfc8c..ffc5d2d4cd8fc3c235ba42441d1399fa1c39bdc8 100644 --- a/clang/lib/AST/MicrosoftMangle.cpp +++ b/clang/lib/AST/MicrosoftMangle.cpp @@ -899,6 +899,8 @@ void MicrosoftCXXNameMangler::mangleFloat(llvm::APFloat Number) { case APFloat::S_Float8E4M3FNUZ: case APFloat::S_Float8E4M3B11FNUZ: case APFloat::S_FloatTF32: + case APFloat::S_Float6E3M2FN: + case APFloat::S_Float6E2M3FN: llvm_unreachable("Tried to mangle unexpected APFloat semantics"); } @@ -2748,7 +2750,7 @@ void MicrosoftCXXNameMangler::mangleFunctionType(const FunctionType *T, return; } Out << '@'; - } else if (IsInLambda && D && isa(D)) { + } else if (IsInLambda && isa_and_nonnull(D)) { // The only lambda conversion operators are to function pointers, which // can differ by their calling convention and are typically deduced. So // we make sure that this type gets mangled properly. diff --git a/clang/lib/AST/OpenACCClause.cpp b/clang/lib/AST/OpenACCClause.cpp index cb2c7f98be75cb171a4e88065ecf45af27f59e6d..95089a9b79e2671575bd41471a4814b9e105d6fc 100644 --- a/clang/lib/AST/OpenACCClause.cpp +++ b/clang/lib/AST/OpenACCClause.cpp @@ -104,7 +104,7 @@ OpenACCClause::child_range OpenACCClause::children() { #define VISIT_CLAUSE(CLAUSE_NAME) \ case OpenACCClauseKind::CLAUSE_NAME: \ return cast(this)->children(); -#define CLAUSE_ALIAS(ALIAS_NAME, CLAUSE_NAME) \ +#define CLAUSE_ALIAS(ALIAS_NAME, CLAUSE_NAME, DEPRECATED) \ case OpenACCClauseKind::ALIAS_NAME: \ return cast(this)->children(); @@ -320,6 +320,48 @@ OpenACCReductionClause *OpenACCReductionClause::Create( OpenACCReductionClause(BeginLoc, LParenLoc, Operator, VarList, EndLoc); } +OpenACCAutoClause *OpenACCAutoClause::Create(const ASTContext &C, + SourceLocation BeginLoc, + SourceLocation EndLoc) { + void *Mem = C.Allocate(sizeof(OpenACCAutoClause)); + return new (Mem) OpenACCAutoClause(BeginLoc, EndLoc); +} + +OpenACCIndependentClause * +OpenACCIndependentClause::Create(const ASTContext &C, SourceLocation BeginLoc, + SourceLocation EndLoc) { + void *Mem = C.Allocate(sizeof(OpenACCIndependentClause)); + return new (Mem) OpenACCIndependentClause(BeginLoc, EndLoc); +} + +OpenACCSeqClause *OpenACCSeqClause::Create(const ASTContext &C, + SourceLocation BeginLoc, + SourceLocation EndLoc) { + void *Mem = C.Allocate(sizeof(OpenACCSeqClause)); + return new (Mem) OpenACCSeqClause(BeginLoc, EndLoc); +} + +OpenACCGangClause *OpenACCGangClause::Create(const ASTContext &C, + SourceLocation BeginLoc, + SourceLocation EndLoc) { + void *Mem = C.Allocate(sizeof(OpenACCGangClause)); + return new (Mem) OpenACCGangClause(BeginLoc, EndLoc); +} + +OpenACCWorkerClause *OpenACCWorkerClause::Create(const ASTContext &C, + SourceLocation BeginLoc, + SourceLocation EndLoc) { + void *Mem = C.Allocate(sizeof(OpenACCWorkerClause)); + return new (Mem) OpenACCWorkerClause(BeginLoc, EndLoc); +} + +OpenACCVectorClause *OpenACCVectorClause::Create(const ASTContext &C, + SourceLocation BeginLoc, + SourceLocation EndLoc) { + void *Mem = C.Allocate(sizeof(OpenACCVectorClause)); + return new (Mem) OpenACCVectorClause(BeginLoc, EndLoc); +} + //===----------------------------------------------------------------------===// // OpenACC clauses printing methods //===----------------------------------------------------------------------===// @@ -495,3 +537,16 @@ void OpenACCClausePrinter::VisitDeviceTypeClause( }); OS << ")"; } + +void OpenACCClausePrinter::VisitAutoClause(const OpenACCAutoClause &C) { + OS << "auto"; +} + +void OpenACCClausePrinter::VisitIndependentClause( + const OpenACCIndependentClause &C) { + OS << "independent"; +} + +void OpenACCClausePrinter::VisitSeqClause(const OpenACCSeqClause &C) { + OS << "seq"; +} diff --git a/clang/lib/AST/ParentMap.cpp b/clang/lib/AST/ParentMap.cpp index 534793b837bbb7aa5060a555c6a3d17f58325198..e97cb5e226f5c28ecf841cab05fe8cc3fda73a10 100644 --- a/clang/lib/AST/ParentMap.cpp +++ b/clang/lib/AST/ParentMap.cpp @@ -97,22 +97,6 @@ static void BuildParentMap(MapTy& M, Stmt* S, BuildParentMap(M, SubStmt, OVMode); } break; - case Stmt::CXXDefaultArgExprClass: - if (auto *Arg = dyn_cast(S)) { - if (Arg->hasRewrittenInit()) { - M[Arg->getExpr()] = S; - BuildParentMap(M, Arg->getExpr(), OVMode); - } - } - break; - case Stmt::CXXDefaultInitExprClass: - if (auto *Init = dyn_cast(S)) { - if (Init->hasRewrittenInit()) { - M[Init->getExpr()] = S; - BuildParentMap(M, Init->getExpr(), OVMode); - } - } - break; default: for (Stmt *SubStmt : S->children()) { if (SubStmt) { @@ -155,7 +139,9 @@ Stmt* ParentMap::getParent(Stmt* S) const { } Stmt *ParentMap::getParentIgnoreParens(Stmt *S) const { - do { S = getParent(S); } while (S && isa(S)); + do { + S = getParent(S); + } while (isa_and_nonnull(S)); return S; } @@ -171,7 +157,8 @@ Stmt *ParentMap::getParentIgnoreParenCasts(Stmt *S) const { Stmt *ParentMap::getParentIgnoreParenImpCasts(Stmt *S) const { do { S = getParent(S); - } while (S && isa(S) && cast(S)->IgnoreParenImpCasts() != S); + } while (isa_and_nonnull(S) && + cast(S)->IgnoreParenImpCasts() != S); return S; } diff --git a/clang/lib/AST/StmtOpenACC.cpp b/clang/lib/AST/StmtOpenACC.cpp index 47899b344c97ab206059584af851845ded140671..2d864a28857966970ec5c666baf4cf4faaca4c0f 100644 --- a/clang/lib/AST/StmtOpenACC.cpp +++ b/clang/lib/AST/StmtOpenACC.cpp @@ -12,6 +12,8 @@ #include "clang/AST/StmtOpenACC.h" #include "clang/AST/ASTContext.h" +#include "clang/AST/RecursiveASTVisitor.h" +#include "clang/AST/StmtCXX.h" using namespace clang; OpenACCComputeConstruct * @@ -26,11 +28,98 @@ OpenACCComputeConstruct::CreateEmpty(const ASTContext &C, unsigned NumClauses) { OpenACCComputeConstruct *OpenACCComputeConstruct::Create( const ASTContext &C, OpenACCDirectiveKind K, SourceLocation BeginLoc, SourceLocation DirLoc, SourceLocation EndLoc, - ArrayRef Clauses, Stmt *StructuredBlock) { + ArrayRef Clauses, Stmt *StructuredBlock, + ArrayRef AssociatedLoopConstructs) { void *Mem = C.Allocate( OpenACCComputeConstruct::totalSizeToAlloc( Clauses.size())); auto *Inst = new (Mem) OpenACCComputeConstruct(K, BeginLoc, DirLoc, EndLoc, Clauses, StructuredBlock); + + llvm::for_each(AssociatedLoopConstructs, [&](OpenACCLoopConstruct *C) { + C->setParentComputeConstruct(Inst); + }); + + return Inst; +} + +void OpenACCComputeConstruct::findAndSetChildLoops() { + struct LoopConstructFinder : RecursiveASTVisitor { + OpenACCComputeConstruct *Construct = nullptr; + + LoopConstructFinder(OpenACCComputeConstruct *Construct) + : Construct(Construct) {} + + bool TraverseOpenACCComputeConstruct(OpenACCComputeConstruct *C) { + // Stop searching if we find a compute construct. + return true; + } + bool TraverseOpenACCLoopConstruct(OpenACCLoopConstruct *C) { + // Stop searching if we find a loop construct, after taking ownership of + // it. + C->setParentComputeConstruct(Construct); + return true; + } + }; + + LoopConstructFinder f(this); + f.TraverseStmt(getAssociatedStmt()); +} + +OpenACCLoopConstruct::OpenACCLoopConstruct(unsigned NumClauses) + : OpenACCAssociatedStmtConstruct( + OpenACCLoopConstructClass, OpenACCDirectiveKind::Loop, + SourceLocation{}, SourceLocation{}, SourceLocation{}, + /*AssociatedStmt=*/nullptr) { + std::uninitialized_value_construct( + getTrailingObjects(), + getTrailingObjects() + NumClauses); + setClauseList( + MutableArrayRef(getTrailingObjects(), NumClauses)); +} + +OpenACCLoopConstruct::OpenACCLoopConstruct( + SourceLocation Start, SourceLocation DirLoc, SourceLocation End, + ArrayRef Clauses, Stmt *Loop) + : OpenACCAssociatedStmtConstruct(OpenACCLoopConstructClass, + OpenACCDirectiveKind::Loop, Start, DirLoc, + End, Loop) { + // accept 'nullptr' for the loop. This is diagnosed somewhere, but this gives + // us some level of AST fidelity in the error case. + assert((Loop == nullptr || isa(Loop)) && + "Associated Loop not a for loop?"); + // Initialize the trailing storage. + std::uninitialized_copy(Clauses.begin(), Clauses.end(), + getTrailingObjects()); + + setClauseList(MutableArrayRef(getTrailingObjects(), + Clauses.size())); +} + +void OpenACCLoopConstruct::setLoop(Stmt *Loop) { + assert((isa(Loop)) && + "Associated Loop not a for loop?"); + setAssociatedStmt(Loop); +} + +OpenACCLoopConstruct *OpenACCLoopConstruct::CreateEmpty(const ASTContext &C, + unsigned NumClauses) { + void *Mem = + C.Allocate(OpenACCLoopConstruct::totalSizeToAlloc( + NumClauses)); + auto *Inst = new (Mem) OpenACCLoopConstruct(NumClauses); + return Inst; +} + +OpenACCLoopConstruct * +OpenACCLoopConstruct::Create(const ASTContext &C, SourceLocation BeginLoc, + SourceLocation DirLoc, SourceLocation EndLoc, + ArrayRef Clauses, + Stmt *Loop) { + void *Mem = + C.Allocate(OpenACCLoopConstruct::totalSizeToAlloc( + Clauses.size())); + auto *Inst = + new (Mem) OpenACCLoopConstruct(BeginLoc, DirLoc, EndLoc, Clauses, Loop); return Inst; } diff --git a/clang/lib/AST/StmtPrinter.cpp b/clang/lib/AST/StmtPrinter.cpp index be2d5a2eb6b46d1bf63df77bbdc7dd2cdd085fe5..8f51d16b5db0376a7ed706803f55e9dbabd7b2d5 100644 --- a/clang/lib/AST/StmtPrinter.cpp +++ b/clang/lib/AST/StmtPrinter.cpp @@ -84,7 +84,7 @@ namespace { void PrintStmt(Stmt *S, int SubIndent) { IndentLevel += SubIndent; - if (S && isa(S)) { + if (isa_and_nonnull(S)) { // If this is an expr used in a stmt context, indent and newline it. Indent(); Visit(S); @@ -1156,6 +1156,19 @@ void StmtPrinter::VisitOpenACCComputeConstruct(OpenACCComputeConstruct *S) { PrintStmt(S->getStructuredBlock()); } +void StmtPrinter::VisitOpenACCLoopConstruct(OpenACCLoopConstruct *S) { + Indent() << "#pragma acc loop"; + + if (!S->clauses().empty()) { + OS << ' '; + OpenACCClausePrinter Printer(OS, Policy); + Printer.VisitClauseList(S->clauses()); + } + OS << '\n'; + + PrintStmt(S->getLoop()); +} + //===----------------------------------------------------------------------===// // Expr printing methods. //===----------------------------------------------------------------------===// @@ -1926,7 +1939,7 @@ void StmtPrinter::VisitCXXOperatorCallExpr(CXXOperatorCallExpr *Node) { void StmtPrinter::VisitCXXMemberCallExpr(CXXMemberCallExpr *Node) { // If we have a conversion operator call only print the argument. CXXMethodDecl *MD = Node->getMethodDecl(); - if (MD && isa(MD)) { + if (isa_and_nonnull(MD)) { PrintExpr(Node->getImplicitObjectArgument()); return; } diff --git a/clang/lib/AST/StmtProfile.cpp b/clang/lib/AST/StmtProfile.cpp index 00b8c43af035c74e66cfb13070cad734ba7deaef..d1655905a665662064c40c0b69b4acb585a2844d 100644 --- a/clang/lib/AST/StmtProfile.cpp +++ b/clang/lib/AST/StmtProfile.cpp @@ -2589,6 +2589,13 @@ void OpenACCClauseProfiler::VisitWaitClause(const OpenACCWaitClause &Clause) { void OpenACCClauseProfiler::VisitDeviceTypeClause( const OpenACCDeviceTypeClause &Clause) {} +void OpenACCClauseProfiler::VisitAutoClause(const OpenACCAutoClause &Clause) {} + +void OpenACCClauseProfiler::VisitIndependentClause( + const OpenACCIndependentClause &Clause) {} + +void OpenACCClauseProfiler::VisitSeqClause(const OpenACCSeqClause &Clause) {} + void OpenACCClauseProfiler::VisitReductionClause( const OpenACCReductionClause &Clause) { for (auto *E : Clause.getVarList()) @@ -2605,6 +2612,14 @@ void StmtProfiler::VisitOpenACCComputeConstruct( P.VisitOpenACCClauseList(S->clauses()); } +void StmtProfiler::VisitOpenACCLoopConstruct(const OpenACCLoopConstruct *S) { + // VisitStmt handles children, so the Loop is handled. + VisitStmt(S); + + OpenACCClauseProfiler P{*this}; + P.VisitOpenACCClauseList(S->clauses()); +} + void Stmt::Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context, bool Canonical, bool ProfileLambdaExpr) const { StmtProfilerWithPointers Profiler(ID, Context, Canonical, ProfileLambdaExpr); diff --git a/clang/lib/AST/TemplateBase.cpp b/clang/lib/AST/TemplateBase.cpp index 46f7b79b272ef3f791205df30409a2d750caac9b..2e6839e948d9d3c99d54f16992d0c0895f4e352d 100644 --- a/clang/lib/AST/TemplateBase.cpp +++ b/clang/lib/AST/TemplateBase.cpp @@ -577,15 +577,6 @@ void TemplateArgument::print(const PrintingPolicy &Policy, raw_ostream &Out, } } -void TemplateArgument::dump(raw_ostream &Out) const { - LangOptions LO; // FIXME! see also TemplateName::dump(). - LO.CPlusPlus = true; - LO.Bool = true; - print(PrintingPolicy(LO), Out, /*IncludeType*/ true); -} - -LLVM_DUMP_METHOD void TemplateArgument::dump() const { dump(llvm::errs()); } - //===----------------------------------------------------------------------===// // TemplateArgumentLoc Implementation //===----------------------------------------------------------------------===// diff --git a/clang/lib/AST/TemplateName.cpp b/clang/lib/AST/TemplateName.cpp index 4fc25cb34803e06b9bee607db56e6eaab3159cb3..11544dbb56e31d67c6b1a971f9c0fb6ca9fab17a 100644 --- a/clang/lib/AST/TemplateName.cpp +++ b/clang/lib/AST/TemplateName.cpp @@ -360,14 +360,3 @@ const StreamingDiagnostic &clang::operator<<(const StreamingDiagnostic &DB, OS.flush(); return DB << NameStr; } - -void TemplateName::dump(raw_ostream &OS) const { - LangOptions LO; // FIXME! - LO.CPlusPlus = true; - LO.Bool = true; - print(OS, PrintingPolicy(LO)); -} - -LLVM_DUMP_METHOD void TemplateName::dump() const { - dump(llvm::errs()); -} diff --git a/clang/lib/AST/TextNodeDumper.cpp b/clang/lib/AST/TextNodeDumper.cpp index 0e0e0a86f5cfcb0973a222fc9f62ebeadda57da2..1076dcd40a694a570b9c69879257f051b50f788d 100644 --- a/clang/lib/AST/TextNodeDumper.cpp +++ b/clang/lib/AST/TextNodeDumper.cpp @@ -398,11 +398,13 @@ void TextNodeDumper::Visit(const OpenACCClause *C) { OS << '(' << cast(C)->getDefaultClauseKind() << ')'; break; case OpenACCClauseKind::Async: + case OpenACCClauseKind::Auto: case OpenACCClauseKind::Attach: case OpenACCClauseKind::Copy: case OpenACCClauseKind::PCopy: case OpenACCClauseKind::PresentOrCopy: case OpenACCClauseKind::If: + case OpenACCClauseKind::Independent: case OpenACCClauseKind::DevicePtr: case OpenACCClauseKind::FirstPrivate: case OpenACCClauseKind::NoCreate: @@ -411,6 +413,7 @@ void TextNodeDumper::Visit(const OpenACCClause *C) { case OpenACCClauseKind::Present: case OpenACCClauseKind::Private: case OpenACCClauseKind::Self: + case OpenACCClauseKind::Seq: case OpenACCClauseKind::VectorLength: // The condition expression will be printed as a part of the 'children', // but print 'clause' here so it is clear what is happening from the dump. @@ -955,6 +958,9 @@ void TextNodeDumper::dumpTemplateArgument(const TemplateArgument &TA) { } OS << " '" << Str << "'"; + if (!Context) + return; + if (TemplateArgument CanonTA = Context->getCanonicalTemplateArgument(TA); !CanonTA.structurallyEquals(TA)) { llvm::SmallString<128> CanonStr; @@ -1136,15 +1142,17 @@ void TextNodeDumper::dumpTemplateName(TemplateName TN, StringRef Label) { } OS << " '" << Str << "'"; - if (TemplateName CanonTN = Context->getCanonicalTemplateName(TN); - CanonTN != TN) { - llvm::SmallString<128> CanonStr; - { - llvm::raw_svector_ostream SS(CanonStr); - CanonTN.print(SS, PrintPolicy); + if (Context) { + if (TemplateName CanonTN = Context->getCanonicalTemplateName(TN); + CanonTN != TN) { + llvm::SmallString<128> CanonStr; + { + llvm::raw_svector_ostream SS(CanonStr); + CanonTN.print(SS, PrintPolicy); + } + if (CanonStr != Str) + OS << ":'" << CanonStr << "'"; } - if (CanonStr != Str) - OS << ":'" << CanonStr << "'"; } } dumpBareTemplateName(TN); @@ -2869,3 +2877,10 @@ void TextNodeDumper::VisitHLSLBufferDecl(const HLSLBufferDecl *D) { void TextNodeDumper::VisitOpenACCConstructStmt(const OpenACCConstructStmt *S) { OS << " " << S->getDirectiveKind(); } +void TextNodeDumper::VisitOpenACCLoopConstruct(const OpenACCLoopConstruct *S) { + + if (S->isOrphanedLoopConstruct()) + OS << " "; + else + OS << " parent: " << S->getParentComputeConstruct(); +} diff --git a/clang/lib/AST/Type.cpp b/clang/lib/AST/Type.cpp index 2097b29b7e0b6d972ea562938ddc375c9af2a414..33acae2cbafacf62846613953e86f753eef70512 100644 --- a/clang/lib/AST/Type.cpp +++ b/clang/lib/AST/Type.cpp @@ -2749,6 +2749,43 @@ bool QualType::isTriviallyCopyableType(const ASTContext &Context) const { /*IsCopyConstructible=*/false); } +// FIXME: each call will trigger a full computation, cache the result. +bool QualType::isBitwiseCloneableType(const ASTContext &Context) const { + auto CanonicalType = getCanonicalType(); + if (CanonicalType.hasNonTrivialObjCLifetime()) + return false; + if (CanonicalType->isArrayType()) + return Context.getBaseElementType(CanonicalType) + .isBitwiseCloneableType(Context); + + if (CanonicalType->isIncompleteType()) + return false; + const auto *RD = CanonicalType->getAsRecordDecl(); // struct/union/class + if (!RD) + return true; + + // Never allow memcpy when we're adding poisoned padding bits to the struct. + // Accessing these posioned bits will trigger false alarms on + // SanitizeAddressFieldPadding etc. + if (RD->mayInsertExtraPadding()) + return false; + + for (auto *const Field : RD->fields()) { + if (!Field->getType().isBitwiseCloneableType(Context)) + return false; + } + + if (const auto *CXXRD = dyn_cast(RD)) { + for (auto Base : CXXRD->bases()) + if (!Base.getType().isBitwiseCloneableType(Context)) + return false; + for (auto VBase : CXXRD->vbases()) + if (!VBase.getType().isBitwiseCloneableType(Context)) + return false; + } + return true; +} + bool QualType::isTriviallyCopyConstructibleType( const ASTContext &Context) const { return isTriviallyCopyableTypeImpl(*this, Context, @@ -4444,7 +4481,6 @@ static CachedProperties computeCachedProperties(const Type *T) { #define NON_CANONICAL_UNLESS_DEPENDENT_TYPE(Class,Base) case Type::Class: #include "clang/AST/TypeNodes.inc" // Treat instantiation-dependent types as external. - if (!T->isInstantiationDependentType()) T->dump(); assert(T->isInstantiationDependentType()); return CachedProperties(Linkage::External, false); diff --git a/clang/lib/Analysis/CFG.cpp b/clang/lib/Analysis/CFG.cpp index 02317257c2740523b8a3747464659de9842fe6b5..64e6155de090c5f3e0626968485ca104baa00f9e 100644 --- a/clang/lib/Analysis/CFG.cpp +++ b/clang/lib/Analysis/CFG.cpp @@ -556,10 +556,6 @@ public: private: // Visitors to walk an AST and construct the CFG. - CFGBlock *VisitCXXDefaultArgExpr(CXXDefaultArgExpr *Default, - AddStmtChoice asc); - CFGBlock *VisitCXXDefaultInitExpr(CXXDefaultInitExpr *Default, - AddStmtChoice asc); CFGBlock *VisitInitListExpr(InitListExpr *ILE, AddStmtChoice asc); CFGBlock *VisitAddrLabelExpr(AddrLabelExpr *A, AddStmtChoice asc); CFGBlock *VisitAttributedStmt(AttributedStmt *A, AddStmtChoice asc); @@ -2258,10 +2254,16 @@ CFGBlock *CFGBuilder::Visit(Stmt * S, AddStmtChoice asc, asc, ExternallyDestructed); case Stmt::CXXDefaultArgExprClass: - return VisitCXXDefaultArgExpr(cast(S), asc); - case Stmt::CXXDefaultInitExprClass: - return VisitCXXDefaultInitExpr(cast(S), asc); + // FIXME: The expression inside a CXXDefaultArgExpr is owned by the + // called function's declaration, not by the caller. If we simply add + // this expression to the CFG, we could end up with the same Expr + // appearing multiple times (PR13385). + // + // It's likewise possible for multiple CXXDefaultInitExprs for the same + // expression to be used in the same function (through aggregate + // initialization). + return VisitStmt(S, asc); case Stmt::CXXBindTemporaryExprClass: return VisitCXXBindTemporaryExpr(cast(S), asc); @@ -2431,40 +2433,6 @@ CFGBlock *CFGBuilder::VisitChildren(Stmt *S) { return B; } -CFGBlock *CFGBuilder::VisitCXXDefaultArgExpr(CXXDefaultArgExpr *Arg, - AddStmtChoice asc) { - if (Arg->hasRewrittenInit()) { - if (asc.alwaysAdd(*this, Arg)) { - autoCreateBlock(); - appendStmt(Block, Arg); - } - return VisitStmt(Arg->getExpr(), asc); - } - - // We can't add the default argument if it's not rewritten because the - // expression inside a CXXDefaultArgExpr is owned by the called function's - // declaration, not by the caller, we could end up with the same expression - // appearing multiple times. - return VisitStmt(Arg, asc); -} - -CFGBlock *CFGBuilder::VisitCXXDefaultInitExpr(CXXDefaultInitExpr *Init, - AddStmtChoice asc) { - if (Init->hasRewrittenInit()) { - if (asc.alwaysAdd(*this, Init)) { - autoCreateBlock(); - appendStmt(Block, Init); - } - return VisitStmt(Init->getExpr(), asc); - } - - // We can't add the default initializer if it's not rewritten because multiple - // CXXDefaultInitExprs for the same sub-expression to be used in the same - // function (through aggregate initialization). we could end up with the same - // expression appearing multiple times. - return VisitStmt(Init, asc); -} - CFGBlock *CFGBuilder::VisitInitListExpr(InitListExpr *ILE, AddStmtChoice asc) { if (asc.alwaysAdd(*this, ILE)) { autoCreateBlock(); diff --git a/clang/lib/Analysis/FlowSensitive/ASTOps.cpp b/clang/lib/Analysis/FlowSensitive/ASTOps.cpp index 38b5f51b7b2f0280b5747d28cd508771c7463587..27d42a7b508562ef398441cf8085708a3eb6aee3 100644 --- a/clang/lib/Analysis/FlowSensitive/ASTOps.cpp +++ b/clang/lib/Analysis/FlowSensitive/ASTOps.cpp @@ -100,7 +100,8 @@ getFieldsForInitListExpr(const InitListT *InitList) { std::vector Fields; if (InitList->getType()->isUnionType()) { - Fields.push_back(InitList->getInitializedFieldInUnion()); + if (const FieldDecl *Field = InitList->getInitializedFieldInUnion()) + Fields.push_back(Field); return Fields; } @@ -137,9 +138,11 @@ RecordInitListHelper::RecordInitListHelper( // it doesn't do this -- so we create an `ImplicitValueInitExpr` ourselves. SmallVector InitsForUnion; if (Ty->isUnionType() && Inits.empty()) { - assert(Fields.size() == 1); - ImplicitValueInitForUnion.emplace(Fields.front()->getType()); - InitsForUnion.push_back(&*ImplicitValueInitForUnion); + assert(Fields.size() <= 1); + if (!Fields.empty()) { + ImplicitValueInitForUnion.emplace(Fields.front()->getType()); + InitsForUnion.push_back(&*ImplicitValueInitForUnion); + } Inits = InitsForUnion; } diff --git a/clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp b/clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp index 0d7967c8b934497e032ed7803c19044029482c77..7c88917faf9c65a9d3b682ca0c260736e60efa43 100644 --- a/clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp +++ b/clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp @@ -415,7 +415,7 @@ public: // below them can initialize the same object (or part of it). if (isa(E) || isa(E) || isa(E) || isa(E) || isa(E) || - isa(E) || + isa(E) || isa(E) || // We treat `BuiltinBitCastExpr` as an "original initializer" too as // it may not even be casting from a record type -- and even if it is, // the two objects are in general of unrelated type. diff --git a/clang/lib/Basic/Cuda.cpp b/clang/lib/Basic/Cuda.cpp index e8ce15eb0decb784ab8f508b7c0bef092c33e3d2..1d96a929f95d855cb87141723deb6f55a42c7fce 100644 --- a/clang/lib/Basic/Cuda.cpp +++ b/clang/lib/Basic/Cuda.cpp @@ -42,6 +42,7 @@ static const CudaVersionMapEntry CudaNameVersionMap[] = { CUDA_ENTRY(12, 2), CUDA_ENTRY(12, 3), CUDA_ENTRY(12, 4), + CUDA_ENTRY(12, 5), {"", CudaVersion::NEW, llvm::VersionTuple(std::numeric_limits::max())}, {"unknown", CudaVersion::UNKNOWN, {}} // End of list tombstone. }; @@ -111,6 +112,7 @@ static const CudaArchToStringMap arch_names[] = { GFX(803), // gfx803 GFX(805), // gfx805 GFX(810), // gfx810 + {CudaArch::GFX9_GENERIC, "gfx9-generic", "compute_amdgcn"}, GFX(900), // gfx900 GFX(902), // gfx902 GFX(904), // gfx903 @@ -122,10 +124,12 @@ static const CudaArchToStringMap arch_names[] = { GFX(940), // gfx940 GFX(941), // gfx941 GFX(942), // gfx942 + {CudaArch::GFX10_1_GENERIC, "gfx10-1-generic", "compute_amdgcn"}, GFX(1010), // gfx1010 GFX(1011), // gfx1011 GFX(1012), // gfx1012 GFX(1013), // gfx1013 + {CudaArch::GFX10_3_GENERIC, "gfx10-3-generic", "compute_amdgcn"}, GFX(1030), // gfx1030 GFX(1031), // gfx1031 GFX(1032), // gfx1032 @@ -133,12 +137,15 @@ static const CudaArchToStringMap arch_names[] = { GFX(1034), // gfx1034 GFX(1035), // gfx1035 GFX(1036), // gfx1036 + {CudaArch::GFX11_GENERIC, "gfx11-generic", "compute_amdgcn"}, GFX(1100), // gfx1100 GFX(1101), // gfx1101 GFX(1102), // gfx1102 GFX(1103), // gfx1103 GFX(1150), // gfx1150 GFX(1151), // gfx1151 + GFX(1152), // gfx1152 + {CudaArch::GFX12_GENERIC, "gfx12-generic", "compute_amdgcn"}, GFX(1200), // gfx1200 GFX(1201), // gfx1201 {CudaArch::Generic, "generic", ""}, diff --git a/clang/lib/Basic/Targets.cpp b/clang/lib/Basic/Targets.cpp index dc1792b3471e6c89be0d26644abad127da6150f9..29133f9ee8fcecceacbdf28d184946b061bb6515 100644 --- a/clang/lib/Basic/Targets.cpp +++ b/clang/lib/Basic/Targets.cpp @@ -673,8 +673,11 @@ std::unique_ptr AllocateTarget(const llvm::Triple &Triple, } case llvm::Triple::spirv64: { if (os != llvm::Triple::UnknownOS || - Triple.getEnvironment() != llvm::Triple::UnknownEnvironment) + Triple.getEnvironment() != llvm::Triple::UnknownEnvironment) { + if (os == llvm::Triple::OSType::AMDHSA) + return std::make_unique(Triple, Opts); return nullptr; + } return std::make_unique(Triple, Opts); } case llvm::Triple::wasm32: diff --git a/clang/lib/Basic/Targets/AArch64.cpp b/clang/lib/Basic/Targets/AArch64.cpp index 0db16d4a8971abff969d2ce8770157c1b8c99241..08d13c41a48572e4fe9c51724f0813a15f46f46d 100644 --- a/clang/lib/Basic/Targets/AArch64.cpp +++ b/clang/lib/Basic/Targets/AArch64.cpp @@ -286,7 +286,6 @@ void AArch64TargetInfo::getTargetDefinesARMV84A(const LangOptions &Opts, void AArch64TargetInfo::getTargetDefinesARMV85A(const LangOptions &Opts, MacroBuilder &Builder) const { Builder.defineMacro("__ARM_FEATURE_FRINT", "1"); - Builder.defineMacro("__ARM_FEATURE_BTI", "1"); // Also include the Armv8.4 defines getTargetDefinesARMV84A(Opts, Builder); } @@ -499,6 +498,9 @@ void AArch64TargetInfo::getTargetDefines(const LangOptions &Opts, if (HasPAuthLR) Builder.defineMacro("__ARM_FEATURE_PAUTH_LR", "1"); + if (HasBTI) + Builder.defineMacro("__ARM_FEATURE_BTI", "1"); + if (HasUnalignedAccess) Builder.defineMacro("__ARM_FEATURE_UNALIGNED", "1"); @@ -1085,7 +1087,7 @@ bool AArch64TargetInfo::initFeatureMap( std::string UpdatedFeature = Feature; if (Feature[0] == '+') { std::optional Extension = - llvm::AArch64::parseArchExtension(Feature.substr(1)); + llvm::AArch64::parseArchExtension(Feature.substr(1)); if (Extension) UpdatedFeature = Extension->Feature.str(); } diff --git a/clang/lib/Basic/Targets/LoongArch.h b/clang/lib/Basic/Targets/LoongArch.h index 68572843f2d7486398361271abda589ab075ca69..5fc223483951e92a32f333a84f36e8430acadcb7 100644 --- a/clang/lib/Basic/Targets/LoongArch.h +++ b/clang/lib/Basic/Targets/LoongArch.h @@ -133,7 +133,7 @@ public: LongWidth = LongAlign = PointerWidth = PointerAlign = 64; IntMaxType = Int64Type = SignedLong; HasUnalignedAccess = true; - resetDataLayout("e-m:e-p:64:64-i64:64-i128:128-n64-S128"); + resetDataLayout("e-m:e-p:64:64-i64:64-i128:128-n32:64-S128"); // TODO: select appropriate ABI. setABI("lp64d"); } diff --git a/clang/lib/Basic/Targets/NVPTX.cpp b/clang/lib/Basic/Targets/NVPTX.cpp index 8ad9e6e5f58916c4912af36becba62ca7e0bbc1b..ff7d2f1f92aa41156244694d3c8475308de3a7a0 100644 --- a/clang/lib/Basic/Targets/NVPTX.cpp +++ b/clang/lib/Basic/Targets/NVPTX.cpp @@ -196,6 +196,7 @@ void NVPTXTargetInfo::getTargetDefines(const LangOptions &Opts, case CudaArch::GFX803: case CudaArch::GFX805: case CudaArch::GFX810: + case CudaArch::GFX9_GENERIC: case CudaArch::GFX900: case CudaArch::GFX902: case CudaArch::GFX904: @@ -207,10 +208,12 @@ void NVPTXTargetInfo::getTargetDefines(const LangOptions &Opts, case CudaArch::GFX940: case CudaArch::GFX941: case CudaArch::GFX942: + case CudaArch::GFX10_1_GENERIC: case CudaArch::GFX1010: case CudaArch::GFX1011: case CudaArch::GFX1012: case CudaArch::GFX1013: + case CudaArch::GFX10_3_GENERIC: case CudaArch::GFX1030: case CudaArch::GFX1031: case CudaArch::GFX1032: @@ -218,12 +221,15 @@ void NVPTXTargetInfo::getTargetDefines(const LangOptions &Opts, case CudaArch::GFX1034: case CudaArch::GFX1035: case CudaArch::GFX1036: + case CudaArch::GFX11_GENERIC: case CudaArch::GFX1100: case CudaArch::GFX1101: case CudaArch::GFX1102: case CudaArch::GFX1103: case CudaArch::GFX1150: case CudaArch::GFX1151: + case CudaArch::GFX1152: + case CudaArch::GFX12_GENERIC: case CudaArch::GFX1200: case CudaArch::GFX1201: case CudaArch::Generic: diff --git a/clang/lib/Basic/Targets/SPIR.cpp b/clang/lib/Basic/Targets/SPIR.cpp index dc920177d3a910723bb1a26b4b485686633e1e3f..040303983594f8b3c1d76e376ac4583ebd408b2e 100644 --- a/clang/lib/Basic/Targets/SPIR.cpp +++ b/clang/lib/Basic/Targets/SPIR.cpp @@ -11,7 +11,9 @@ //===----------------------------------------------------------------------===// #include "SPIR.h" +#include "AMDGPU.h" #include "Targets.h" +#include "llvm/TargetParser/TargetParser.h" using namespace clang; using namespace clang::targets; @@ -54,3 +56,76 @@ void SPIRV64TargetInfo::getTargetDefines(const LangOptions &Opts, BaseSPIRVTargetInfo::getTargetDefines(Opts, Builder); DefineStd(Builder, "SPIRV64", Opts); } + +static const AMDGPUTargetInfo AMDGPUTI(llvm::Triple("amdgcn-amd-amdhsa"), {}); + +ArrayRef SPIRV64AMDGCNTargetInfo::getGCCRegNames() const { + return AMDGPUTI.getGCCRegNames(); +} + +bool SPIRV64AMDGCNTargetInfo::initFeatureMap( + llvm::StringMap &Features, DiagnosticsEngine &Diags, StringRef, + const std::vector &FeatureVec) const { + llvm::AMDGPU::fillAMDGPUFeatureMap({}, getTriple(), Features); + + return TargetInfo::initFeatureMap(Features, Diags, {}, FeatureVec); +} + +bool SPIRV64AMDGCNTargetInfo::validateAsmConstraint( + const char *&Name, TargetInfo::ConstraintInfo &Info) const { + return AMDGPUTI.validateAsmConstraint(Name, Info); +} + +std::string +SPIRV64AMDGCNTargetInfo::convertConstraint(const char *&Constraint) const { + return AMDGPUTI.convertConstraint(Constraint); +} + +ArrayRef SPIRV64AMDGCNTargetInfo::getTargetBuiltins() const { + return AMDGPUTI.getTargetBuiltins(); +} + +void SPIRV64AMDGCNTargetInfo::getTargetDefines(const LangOptions &Opts, + MacroBuilder &Builder) const { + BaseSPIRVTargetInfo::getTargetDefines(Opts, Builder); + DefineStd(Builder, "SPIRV64", Opts); + + Builder.defineMacro("__AMD__"); + Builder.defineMacro("__AMDGPU__"); + Builder.defineMacro("__AMDGCN__"); +} + +void SPIRV64AMDGCNTargetInfo::setAuxTarget(const TargetInfo *Aux) { + assert(Aux && "Cannot invoke setAuxTarget without a valid auxiliary target!"); + + // This is a 1:1 copy of AMDGPUTargetInfo::setAuxTarget() + assert(HalfFormat == Aux->HalfFormat); + assert(FloatFormat == Aux->FloatFormat); + assert(DoubleFormat == Aux->DoubleFormat); + + // On x86_64 long double is 80-bit extended precision format, which is + // not supported by AMDGPU. 128-bit floating point format is also not + // supported by AMDGPU. Therefore keep its own format for these two types. + auto SaveLongDoubleFormat = LongDoubleFormat; + auto SaveFloat128Format = Float128Format; + auto SaveLongDoubleWidth = LongDoubleWidth; + auto SaveLongDoubleAlign = LongDoubleAlign; + copyAuxTarget(Aux); + LongDoubleFormat = SaveLongDoubleFormat; + Float128Format = SaveFloat128Format; + LongDoubleWidth = SaveLongDoubleWidth; + LongDoubleAlign = SaveLongDoubleAlign; + // For certain builtin types support on the host target, claim they are + // supported to pass the compilation of the host code during the device-side + // compilation. + // FIXME: As the side effect, we also accept `__float128` uses in the device + // code. To reject these builtin types supported in the host target but not in + // the device target, one approach would support `device_builtin` attribute + // so that we could tell the device builtin types from the host ones. This + // also solves the different representations of the same builtin type, such + // as `size_t` in the MSVC environment. + if (Aux->hasFloat128Type()) { + HasFloat128 = true; + Float128Format = DoubleFormat; + } +} diff --git a/clang/lib/Basic/Targets/SPIR.h b/clang/lib/Basic/Targets/SPIR.h index 44265445ff004b0858266d2c3678636ed5514ac1..37cf9d7921bac52a8177d71ec018977d1cb11ede 100644 --- a/clang/lib/Basic/Targets/SPIR.h +++ b/clang/lib/Basic/Targets/SPIR.h @@ -364,6 +364,57 @@ public: MacroBuilder &Builder) const override; }; +class LLVM_LIBRARY_VISIBILITY SPIRV64AMDGCNTargetInfo final + : public BaseSPIRVTargetInfo { +public: + SPIRV64AMDGCNTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts) + : BaseSPIRVTargetInfo(Triple, Opts) { + assert(Triple.getArch() == llvm::Triple::spirv64 && + "Invalid architecture for 64-bit AMDGCN SPIR-V."); + assert(Triple.getVendor() == llvm::Triple::VendorType::AMD && + "64-bit AMDGCN SPIR-V target must use AMD vendor"); + assert(getTriple().getOS() == llvm::Triple::OSType::AMDHSA && + "64-bit AMDGCN SPIR-V target must use AMDHSA OS"); + assert(getTriple().getEnvironment() == llvm::Triple::UnknownEnvironment && + "64-bit SPIR-V target must use unknown environment type"); + PointerWidth = PointerAlign = 64; + SizeType = TargetInfo::UnsignedLong; + PtrDiffType = IntPtrType = TargetInfo::SignedLong; + + resetDataLayout("e-i64:64-v16:16-v24:32-v32:32-v48:64-" + "v96:128-v192:256-v256:256-v512:512-v1024:1024-G1-P4-A0"); + + BFloat16Width = BFloat16Align = 16; + BFloat16Format = &llvm::APFloat::BFloat(); + + HasLegalHalfType = true; + HasFloat16 = true; + HalfArgsAndReturns = true; + } + + bool hasBFloat16Type() const override { return true; } + + ArrayRef getGCCRegNames() const override; + + bool initFeatureMap(llvm::StringMap &Features, DiagnosticsEngine &Diags, + StringRef, + const std::vector &) const override; + + bool validateAsmConstraint(const char *&Name, + TargetInfo::ConstraintInfo &Info) const override; + + std::string convertConstraint(const char *&Constraint) const override; + + ArrayRef getTargetBuiltins() const override; + + void getTargetDefines(const LangOptions &Opts, + MacroBuilder &Builder) const override; + + void setAuxTarget(const TargetInfo *Aux) override; + + bool hasInt128Type() const override { return TargetInfo::hasInt128Type(); } +}; + } // namespace targets } // namespace clang #endif // LLVM_CLANG_LIB_BASIC_TARGETS_SPIR_H diff --git a/clang/lib/CodeGen/CGBlocks.cpp b/clang/lib/CodeGen/CGBlocks.cpp index bf50f2025de57340af4159c660526c565ef538e7..5dac1cd425bf61e7e8d1fc90d317a0978168f5e4 100644 --- a/clang/lib/CodeGen/CGBlocks.cpp +++ b/clang/lib/CodeGen/CGBlocks.cpp @@ -577,7 +577,7 @@ static void computeBlockInfo(CodeGenModule &CGM, CodeGenFunction *CGF, // First, 'this'. if (block->capturesCXXThis()) { - assert(CGF && CGF->CurFuncDecl && isa(CGF->CurFuncDecl) && + assert(CGF && isa_and_nonnull(CGF->CurFuncDecl) && "Can't capture 'this' outside a method"); QualType thisType = cast(CGF->CurFuncDecl)->getThisType(); diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp index 37d0c478e03308cf1713f5ffef3a9f3b1e08582e..06e201fa71e6ffb543078dfe58048fbb13b93f24 100644 --- a/clang/lib/CodeGen/CGBuiltin.cpp +++ b/clang/lib/CodeGen/CGBuiltin.cpp @@ -2923,6 +2923,18 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID, SetSqrtFPAccuracy(Call); return RValue::get(Call); } + + case Builtin::BItan: + case Builtin::BItanf: + case Builtin::BItanl: + case Builtin::BI__builtin_tan: + case Builtin::BI__builtin_tanf: + case Builtin::BI__builtin_tanf16: + case Builtin::BI__builtin_tanl: + case Builtin::BI__builtin_tanf128: + return RValue::get(emitUnaryMaybeConstrainedFPBuiltin( + *this, E, Intrinsic::tan, Intrinsic::experimental_constrained_tan)); + case Builtin::BItrunc: case Builtin::BItruncf: case Builtin::BItruncl: @@ -6012,6 +6024,9 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID, llvm::Triple::getArchTypePrefix(getTarget().getTriple().getArch()); if (!Prefix.empty()) { IntrinsicID = Intrinsic::getIntrinsicForClangBuiltin(Prefix.data(), Name); + if (IntrinsicID == Intrinsic::not_intrinsic && Prefix == "spv" && + getTarget().getTriple().getOS() == llvm::Triple::OSType::AMDHSA) + IntrinsicID = Intrinsic::getIntrinsicForClangBuiltin("amdgcn", Name); // NOTE we don't need to perform a compatibility flag check here since the // intrinsics are declared in Builtins*.def via LANGBUILTIN which filter the // MS builtins via ALL_MS_LANGUAGES and are filtered earlier. @@ -6182,6 +6197,10 @@ static Value *EmitTargetArchBuiltinExpr(CodeGenFunction *CGF, case llvm::Triple::riscv32: case llvm::Triple::riscv64: return CGF->EmitRISCVBuiltinExpr(BuiltinID, E, ReturnValue); + case llvm::Triple::spirv64: + if (CGF->getTarget().getTriple().getOS() != llvm::Triple::OSType::AMDHSA) + return nullptr; + return CGF->EmitAMDGPUBuiltinExpr(BuiltinID, E); default: return nullptr; } diff --git a/clang/lib/CodeGen/CGCall.cpp b/clang/lib/CodeGen/CGCall.cpp index 97449a5e51e736c80fa085fe0da20900acdabe17..65d82285b907b521a371322153ad5f009864dc0c 100644 --- a/clang/lib/CodeGen/CGCall.cpp +++ b/clang/lib/CodeGen/CGCall.cpp @@ -1917,6 +1917,7 @@ static void getTrivialDefaultFunctionAttributes( case CodeGenOptions::FramePointerKind::None: // This is the default behavior. break; + case CodeGenOptions::FramePointerKind::Reserved: case CodeGenOptions::FramePointerKind::NonLeaf: case CodeGenOptions::FramePointerKind::All: FuncAttrs.addAttribute("frame-pointer", diff --git a/clang/lib/CodeGen/CGClass.cpp b/clang/lib/CodeGen/CGClass.cpp index b8cb78266130c88c14ca51e1ba501dafb50729dd..5a032bdbf93791d9b23458cf0323feacc99c6086 100644 --- a/clang/lib/CodeGen/CGClass.cpp +++ b/clang/lib/CodeGen/CGClass.cpp @@ -859,7 +859,7 @@ void CodeGenFunction::EmitConstructorBody(FunctionArgList &Args) { // Enter the function-try-block before the constructor prologue if // applicable. - bool IsTryBody = (Body && isa(Body)); + bool IsTryBody = isa_and_nonnull(Body); if (IsTryBody) EnterCXXTryStmt(*cast(Body), true); @@ -1475,7 +1475,7 @@ void CodeGenFunction::EmitDestructorBody(FunctionArgList &Args) { // If the body is a function-try-block, enter the try before // anything else. - bool isTryBody = (Body && isa(Body)); + bool isTryBody = isa_and_nonnull(Body); if (isTryBody) EnterCXXTryStmt(*cast(Body), true); EmitAsanPrologueOrEpilogue(false); diff --git a/clang/lib/CodeGen/CGDebugInfo.cpp b/clang/lib/CodeGen/CGDebugInfo.cpp index 5f6f911c7a6d698d44324e94a85c0259f6ed7084..11e2d549d8a4505e9c92d0aeed0bb016284e2483 100644 --- a/clang/lib/CodeGen/CGDebugInfo.cpp +++ b/clang/lib/CodeGen/CGDebugInfo.cpp @@ -58,7 +58,16 @@ using namespace clang::CodeGen; static uint32_t getTypeAlignIfRequired(const Type *Ty, const ASTContext &Ctx) { auto TI = Ctx.getTypeInfo(Ty); - return TI.isAlignRequired() ? TI.Align : 0; + if (TI.isAlignRequired()) + return TI.Align; + + // MaxFieldAlignmentAttr is the attribute added to types + // declared after #pragma pack(n). + if (auto *Decl = Ty->getAsRecordDecl()) + if (Decl->hasAttr()) + return TI.Align; + + return 0; } static uint32_t getTypeAlignIfRequired(QualType Ty, const ASTContext &Ctx) { @@ -5757,28 +5766,16 @@ void CGDebugInfo::EmitPseudoVariable(CGBuilderTy &Builder, // it is loaded upon use, so we identify such pattern here. if (llvm::LoadInst *Load = dyn_cast(Value)) { llvm::Value *Var = Load->getPointerOperand(); - if (llvm::Metadata *MDValue = llvm::ValueAsMetadata::getIfExists(Var)) { - if (llvm::Value *DbgValue = llvm::MetadataAsValue::getIfExists( - CGM.getLLVMContext(), MDValue)) { - for (llvm::User *U : DbgValue->users()) { - if (llvm::CallInst *DbgDeclare = dyn_cast(U)) { - if (DbgDeclare->getCalledFunction()->getIntrinsicID() == - llvm::Intrinsic::dbg_declare && - DbgDeclare->getArgOperand(0) == DbgValue) { - // There can be implicit type cast applied on a variable if it is - // an opaque ptr, in this case its debug info may not match the - // actual type of object being used as in the next instruction, so - // we will need to emit a pseudo variable for type-casted value. - llvm::DILocalVariable *MDNode = cast( - cast(DbgDeclare->getOperand(1)) - ->getMetadata()); - if (MDNode->getType() == Type) - return; - } - } - } - } - } + // There can be implicit type cast applied on a variable if it is an opaque + // ptr, in this case its debug info may not match the actual type of object + // being used as in the next instruction, so we will need to emit a pseudo + // variable for type-casted value. + auto DeclareTypeMatches = [&](auto *DbgDeclare) { + return DbgDeclare->getVariable()->getType() == Type; + }; + if (any_of(llvm::findDbgDeclares(Var), DeclareTypeMatches) || + any_of(llvm::findDVRDeclares(Var), DeclareTypeMatches)) + return; } // Find the correct location to insert a sequence of instructions to diff --git a/clang/lib/CodeGen/CGDeclCXX.cpp b/clang/lib/CodeGen/CGDeclCXX.cpp index b047279912f6b775681909380661d5e39c98dbf0..a88bb2af59fee0ffb9f21824f33b99d1c28736be 100644 --- a/clang/lib/CodeGen/CGDeclCXX.cpp +++ b/clang/lib/CodeGen/CGDeclCXX.cpp @@ -476,6 +476,10 @@ llvm::Function *CodeGenModule::CreateGlobalInitOrCleanUpFunction( !isInNoSanitizeList(SanitizerKind::Thread, Fn, Loc)) Fn->addFnAttr(llvm::Attribute::SanitizeThread); + if (getLangOpts().Sanitize.has(SanitizerKind::NumericalStability) && + !isInNoSanitizeList(SanitizerKind::NumericalStability, Fn, Loc)) + Fn->addFnAttr(llvm::Attribute::SanitizeNumericalStability); + if (getLangOpts().Sanitize.has(SanitizerKind::Memory) && !isInNoSanitizeList(SanitizerKind::Memory, Fn, Loc)) Fn->addFnAttr(llvm::Attribute::SanitizeMemory); diff --git a/clang/lib/CodeGen/CGExpr.cpp b/clang/lib/CodeGen/CGExpr.cpp index d6478cc6835d82dac585180a366b13852af8d2b8..48d8ca3478862139537d59cd39f40fa174d973e7 100644 --- a/clang/lib/CodeGen/CGExpr.cpp +++ b/clang/lib/CodeGen/CGExpr.cpp @@ -3571,9 +3571,8 @@ void CodeGenFunction::EmitCheck( llvm::BasicBlock *Handlers = createBasicBlock("handler." + CheckName); llvm::Instruction *Branch = Builder.CreateCondBr(JointCond, Cont, Handlers); // Give hint that we very much don't expect to execute the handler - // Value chosen to match UR_NONTAKEN_WEIGHT, see BranchProbabilityInfo.cpp llvm::MDBuilder MDHelper(getLLVMContext()); - llvm::MDNode *Node = MDHelper.createBranchWeights((1U << 20) - 1, 1); + llvm::MDNode *Node = MDHelper.createLikelyBranchWeights(); Branch->setMetadata(llvm::LLVMContext::MD_prof, Node); EmitBlock(Handlers); @@ -3641,7 +3640,7 @@ void CodeGenFunction::EmitCfiSlowPathCheck( llvm::BranchInst *BI = Builder.CreateCondBr(Cond, Cont, CheckBB); llvm::MDBuilder MDHelper(getLLVMContext()); - llvm::MDNode *Node = MDHelper.createBranchWeights((1U << 20) - 1, 1); + llvm::MDNode *Node = MDHelper.createLikelyBranchWeights(); BI->setMetadata(llvm::LLVMContext::MD_prof, Node); EmitBlock(CheckBB); diff --git a/clang/lib/CodeGen/CGExprAgg.cpp b/clang/lib/CodeGen/CGExprAgg.cpp index 5b2039af6128bf0de90e324608566b63d3ea8b65..b2a5ceeeae08ba16d88fee4087469a9f394c5b59 100644 --- a/clang/lib/CodeGen/CGExprAgg.cpp +++ b/clang/lib/CodeGen/CGExprAgg.cpp @@ -513,15 +513,6 @@ void AggExprEmitter::EmitArrayInit(Address DestPtr, llvm::ArrayType *AType, QualType elementType = CGF.getContext().getAsArrayType(ArrayQTy)->getElementType(); - - // DestPtr is an array*. Construct an elementType* by drilling - // down a level. - llvm::Value *zero = llvm::ConstantInt::get(CGF.SizeTy, 0); - llvm::Value *indices[] = { zero, zero }; - llvm::Value *begin = Builder.CreateInBoundsGEP(DestPtr.getElementType(), - DestPtr.emitRawPointer(CGF), - indices, "arrayinit.begin"); - CharUnits elementSize = CGF.getContext().getTypeSizeInChars(elementType); CharUnits elementAlign = DestPtr.getAlignment().alignmentOfArrayElement(elementSize); @@ -562,6 +553,7 @@ void AggExprEmitter::EmitArrayInit(Address DestPtr, llvm::ArrayType *AType, Address endOfInit = Address::invalid(); CodeGenFunction::CleanupDeactivationScope deactivation(CGF); + llvm::Value *begin = DestPtr.emitRawPointer(CGF); if (dtorKind) { CodeGenFunction::AllocaTrackerRAII allocaTracker(CGF); // In principle we could tell the cleanup where we are more @@ -585,19 +577,13 @@ void AggExprEmitter::EmitArrayInit(Address DestPtr, llvm::ArrayType *AType, llvm::Value *one = llvm::ConstantInt::get(CGF.SizeTy, 1); - // The 'current element to initialize'. The invariants on this - // variable are complicated. Essentially, after each iteration of - // the loop, it points to the last initialized element, except - // that it points to the beginning of the array before any - // elements have been initialized. - llvm::Value *element = begin; - // Emit the explicit initializers. for (uint64_t i = 0; i != NumInitElements; ++i) { - // Advance to the next element. + llvm::Value *element = begin; if (i > 0) { - element = Builder.CreateInBoundsGEP( - llvmElementType, element, one, "arrayinit.element"); + element = Builder.CreateInBoundsGEP(llvmElementType, begin, + llvm::ConstantInt::get(CGF.SizeTy, i), + "arrayinit.element"); // Tell the cleanup that it needs to destroy up to this // element. TODO: some of these stores can be trivially @@ -624,9 +610,12 @@ void AggExprEmitter::EmitArrayInit(Address DestPtr, llvm::ArrayType *AType, // do { *array++ = filler; } while (array != end); // Advance to the start of the rest of the array. + llvm::Value *element = begin; if (NumInitElements) { element = Builder.CreateInBoundsGEP( - llvmElementType, element, one, "arrayinit.start"); + llvmElementType, element, + llvm::ConstantInt::get(CGF.SizeTy, NumInitElements), + "arrayinit.start"); if (endOfInit.isValid()) Builder.CreateStore(element, endOfInit); } diff --git a/clang/lib/CodeGen/CGExprComplex.cpp b/clang/lib/CodeGen/CGExprComplex.cpp index 9ef73e36f66f359fff4aced01d8aa2f183767c3b..f19334489a0ba5eea594f4273805e943bbb44fea 100644 --- a/clang/lib/CodeGen/CGExprComplex.cpp +++ b/clang/lib/CodeGen/CGExprComplex.cpp @@ -856,8 +856,7 @@ ComplexPairTy ComplexExprEmitter::EmitBinMul(const BinOpInfo &Op) { llvm::BasicBlock *OrigBB = Branch->getParent(); // Give hint that we very much don't expect to see NaNs. - // Value chosen to match UR_NONTAKEN_WEIGHT, see BranchProbabilityInfo.cpp - llvm::MDNode *BrWeight = MDHelper.createBranchWeights(1, (1U << 20) - 1); + llvm::MDNode *BrWeight = MDHelper.createUnlikelyBranchWeights(); Branch->setMetadata(llvm::LLVMContext::MD_prof, BrWeight); // Now test the imaginary part and create its branch. diff --git a/clang/lib/CodeGen/CGExprConstant.cpp b/clang/lib/CodeGen/CGExprConstant.cpp index 4eb65b34a89f56b60984dee3585c9144b25ffe35..0712f40fd8215a06b371974cd79e7840265ada52 100644 --- a/clang/lib/CodeGen/CGExprConstant.cpp +++ b/clang/lib/CodeGen/CGExprConstant.cpp @@ -715,7 +715,7 @@ bool ConstStructBuilder::Build(const InitListExpr *ILE, bool AllowOverwrite) { const Expr *Init = nullptr; if (ElementNo < ILE->getNumInits()) Init = ILE->getInit(ElementNo++); - if (Init && isa(Init)) + if (isa_and_nonnull(Init)) continue; // Zero-sized fields are not emitted, but their initializers may still diff --git a/clang/lib/CodeGen/CGHLSLRuntime.cpp b/clang/lib/CodeGen/CGHLSLRuntime.cpp index 5e6a3dd4878f46550216ed46f9cc94e59d18d522..55ba21ae2ba69ba1c0997cca3e3f03833b894896 100644 --- a/clang/lib/CodeGen/CGHLSLRuntime.cpp +++ b/clang/lib/CodeGen/CGHLSLRuntime.cpp @@ -313,7 +313,7 @@ void clang::CodeGen::CGHLSLRuntime::setHLSLEntryAttributes( assert(ShaderAttr && "All entry functions must have a HLSLShaderAttr"); const StringRef ShaderAttrKindStr = "hlsl.shader"; Fn->addFnAttr(ShaderAttrKindStr, - ShaderAttr->ConvertShaderTypeToStr(ShaderAttr->getType())); + llvm::Triple::getEnvironmentTypeName(ShaderAttr->getType())); if (HLSLNumThreadsAttr *NumThreadsAttr = FD->getAttr()) { const StringRef NumThreadsKindStr = "hlsl.numthreads"; std::string NumThreadsStr = diff --git a/clang/lib/CodeGen/CGObjCGNU.cpp b/clang/lib/CodeGen/CGObjCGNU.cpp index 6540ac69f2d9b08abd16fbc9327ca935f3a3ffcf..948b10954ebbed6c6e7b935020fc5b9660a59ed3 100644 --- a/clang/lib/CodeGen/CGObjCGNU.cpp +++ b/clang/lib/CodeGen/CGObjCGNU.cpp @@ -2069,7 +2069,7 @@ class CGObjCGNUstep2 : public CGObjCGNUstep { Builder.CreateCondBr(Builder.CreateICmpEQ(selfValue, Zero), SelfIsNilBlock, ContBlock, - MDHelper.createBranchWeights(1, 1 << 20)); + MDHelper.createUnlikelyBranchWeights()); CGF.EmitBlock(SelfIsNilBlock); @@ -2104,7 +2104,7 @@ class CGObjCGNUstep2 : public CGObjCGNUstep { CGF.createBasicBlock("objc_direct_method.class_initialized"); Builder.CreateCondBr(Builder.CreateICmpEQ(isInitialized, Zeros[0]), notInitializedBlock, initializedBlock, - MDHelper.createBranchWeights(1, 1 << 20)); + MDHelper.createUnlikelyBranchWeights()); CGF.EmitBlock(notInitializedBlock); Builder.SetInsertPoint(notInitializedBlock); CGF.EmitRuntimeCall(SentInitializeFn, selfValue); diff --git a/clang/lib/CodeGen/CGObjCMac.cpp b/clang/lib/CodeGen/CGObjCMac.cpp index 042cd5d46da4b2eb608a9b5065c7514bde04df2a..30f3911a8b03c2df83aaa1da255925842c39e380 100644 --- a/clang/lib/CodeGen/CGObjCMac.cpp +++ b/clang/lib/CodeGen/CGObjCMac.cpp @@ -4072,7 +4072,7 @@ void CGObjCCommonMac::GenerateDirectMethodPrologue( llvm::MDBuilder MDHelper(CGM.getLLVMContext()); Builder.CreateCondBr(Builder.CreateICmpEQ(selfValue, Zero), SelfIsNilBlock, - ContBlock, MDHelper.createBranchWeights(1, 1 << 20)); + ContBlock, MDHelper.createUnlikelyBranchWeights()); CGF.EmitBlock(SelfIsNilBlock); diff --git a/clang/lib/CodeGen/CGOpenMPRuntimeGPU.cpp b/clang/lib/CodeGen/CGOpenMPRuntimeGPU.cpp index 28da8662f5f6178b37476b646ea46b3c82777638..6e9a1bacd9bf5f4a3f5a840a5c25f9ccd75e0405 100644 --- a/clang/lib/CodeGen/CGOpenMPRuntimeGPU.cpp +++ b/clang/lib/CodeGen/CGOpenMPRuntimeGPU.cpp @@ -3505,6 +3505,7 @@ void CGOpenMPRuntimeGPU::processRequiresDirective( case CudaArch::GFX803: case CudaArch::GFX805: case CudaArch::GFX810: + case CudaArch::GFX9_GENERIC: case CudaArch::GFX900: case CudaArch::GFX902: case CudaArch::GFX904: @@ -3516,10 +3517,12 @@ void CGOpenMPRuntimeGPU::processRequiresDirective( case CudaArch::GFX940: case CudaArch::GFX941: case CudaArch::GFX942: + case CudaArch::GFX10_1_GENERIC: case CudaArch::GFX1010: case CudaArch::GFX1011: case CudaArch::GFX1012: case CudaArch::GFX1013: + case CudaArch::GFX10_3_GENERIC: case CudaArch::GFX1030: case CudaArch::GFX1031: case CudaArch::GFX1032: @@ -3527,12 +3530,15 @@ void CGOpenMPRuntimeGPU::processRequiresDirective( case CudaArch::GFX1034: case CudaArch::GFX1035: case CudaArch::GFX1036: + case CudaArch::GFX11_GENERIC: case CudaArch::GFX1100: case CudaArch::GFX1101: case CudaArch::GFX1102: case CudaArch::GFX1103: case CudaArch::GFX1150: case CudaArch::GFX1151: + case CudaArch::GFX1152: + case CudaArch::GFX12_GENERIC: case CudaArch::GFX1200: case CudaArch::GFX1201: case CudaArch::Generic: diff --git a/clang/lib/CodeGen/CGStmt.cpp b/clang/lib/CodeGen/CGStmt.cpp index 99daaa14cf3fec7a721df5e2c97f9c97ca9f2cbd..39222c0e65353b20b571643a92f0656da64a2291 100644 --- a/clang/lib/CodeGen/CGStmt.cpp +++ b/clang/lib/CodeGen/CGStmt.cpp @@ -414,7 +414,8 @@ void CodeGenFunction::EmitStmt(const Stmt *S, ArrayRef Attrs) { CGM.ErrorUnsupported(S, "OpenMP dispatch directive"); break; case Stmt::OMPScopeDirectiveClass: - llvm_unreachable("scope not supported with FE outlining"); + CGM.ErrorUnsupported(S, "scope with FE outlining"); + break; case Stmt::OMPMaskedDirectiveClass: EmitOMPMaskedDirective(cast(*S)); break; @@ -442,6 +443,9 @@ void CodeGenFunction::EmitStmt(const Stmt *S, ArrayRef Attrs) { case Stmt::OpenACCComputeConstructClass: EmitOpenACCComputeConstruct(cast(*S)); break; + case Stmt::OpenACCLoopConstructClass: + EmitOpenACCLoopConstruct(cast(*S)); + break; } } diff --git a/clang/lib/CodeGen/CGStmtOpenMP.cpp b/clang/lib/CodeGen/CGStmtOpenMP.cpp index 6410f9e102c907ab81f2561feb1ac01a7bf08d44..f73d32de7c48487cd24f87297c67c8168092d3eb 100644 --- a/clang/lib/CodeGen/CGStmtOpenMP.cpp +++ b/clang/lib/CodeGen/CGStmtOpenMP.cpp @@ -72,7 +72,7 @@ class OMPLexicalScope : public CodeGenFunction::LexicalScope { static bool isCapturedVar(CodeGenFunction &CGF, const VarDecl *VD) { return CGF.LambdaCaptureFields.lookup(VD) || (CGF.CapturedStmtInfo && CGF.CapturedStmtInfo->lookup(VD)) || - (CGF.CurCodeDecl && isa(CGF.CurCodeDecl) && + (isa_and_nonnull(CGF.CurCodeDecl) && cast(CGF.CurCodeDecl)->capturesVariable(VD)); } @@ -227,7 +227,7 @@ class OMPSimdLexicalScope : public CodeGenFunction::LexicalScope { static bool isCapturedVar(CodeGenFunction &CGF, const VarDecl *VD) { return CGF.LambdaCaptureFields.lookup(VD) || (CGF.CapturedStmtInfo && CGF.CapturedStmtInfo->lookup(VD)) || - (CGF.CurCodeDecl && isa(CGF.CurCodeDecl) && + (isa_and_nonnull(CGF.CurCodeDecl) && cast(CGF.CurCodeDecl)->capturesVariable(VD)); } @@ -315,7 +315,7 @@ LValue CodeGenFunction::EmitOMPSharedLValue(const Expr *E) { bool IsCaptured = LambdaCaptureFields.lookup(OrigVD) || (CapturedStmtInfo && CapturedStmtInfo->lookup(OrigVD)) || - (CurCodeDecl && isa(CurCodeDecl)); + (isa_and_nonnull(CurCodeDecl)); DeclRefExpr DRE(getContext(), const_cast(OrigVD), IsCaptured, OrigDRE->getType(), VK_LValue, OrigDRE->getExprLoc()); return EmitLValue(&DRE); diff --git a/clang/lib/CodeGen/CodeGenFunction.cpp b/clang/lib/CodeGen/CodeGenFunction.cpp index f0345f3b191b8864b09468fdedeabd1841d6b981..cea0d84c64bc477f9d2de501e6f8d4798584e2ec 100644 --- a/clang/lib/CodeGen/CodeGenFunction.cpp +++ b/clang/lib/CodeGen/CodeGenFunction.cpp @@ -818,6 +818,8 @@ void CodeGenFunction::StartFunction(GlobalDecl GD, QualType RetTy, Fn->addFnAttr(llvm::Attribute::SanitizeMemTag); if (SanOpts.has(SanitizerKind::Thread)) Fn->addFnAttr(llvm::Attribute::SanitizeThread); + if (SanOpts.has(SanitizerKind::NumericalStability)) + Fn->addFnAttr(llvm::Attribute::SanitizeNumericalStability); if (SanOpts.hasOneOf(SanitizerKind::Memory | SanitizerKind::KernelMemory)) Fn->addFnAttr(llvm::Attribute::SanitizeMemory); } @@ -2951,7 +2953,7 @@ void CodeGenFunction::emitAlignmentAssumptionCheck( SourceLocation SecondaryLoc, llvm::Value *Alignment, llvm::Value *OffsetValue, llvm::Value *TheCheck, llvm::Instruction *Assumption) { - assert(Assumption && isa(Assumption) && + assert(isa_and_nonnull(Assumption) && cast(Assumption)->getCalledOperand() == llvm::Intrinsic::getDeclaration( Builder.GetInsertBlock()->getParent()->getParent(), diff --git a/clang/lib/CodeGen/CodeGenFunction.h b/clang/lib/CodeGen/CodeGenFunction.h index 45585361a4fc9960715c23c6f904af6f09b7f2a3..5739fbaaa919400e5c4e9e2d958eba1e81cb3e04 100644 --- a/clang/lib/CodeGen/CodeGenFunction.h +++ b/clang/lib/CodeGen/CodeGenFunction.h @@ -4062,6 +4062,13 @@ public: EmitStmt(S.getStructuredBlock()); } + void EmitOpenACCLoopConstruct(const OpenACCLoopConstruct &S) { + // TODO OpenACC: Implement this. It is currently implemented as a 'no-op', + // simply emitting its loop, but in the future we will implement + // some sort of IR. + EmitStmt(S.getLoop()); + } + //===--------------------------------------------------------------------===// // LValue Expression Emission //===--------------------------------------------------------------------===// diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp index be7bf0b72dc0c1563e8d15acafa11f8281b9b0d3..dd4a665ebc78b7e721f76bfdd1ab9af7a178680c 100644 --- a/clang/lib/CodeGen/CodeGenModule.cpp +++ b/clang/lib/CodeGen/CodeGenModule.cpp @@ -1328,6 +1328,9 @@ void CodeGenModule::Release() { case CodeGenOptions::FramePointerKind::None: // 0 ("none") is the default. break; + case CodeGenOptions::FramePointerKind::Reserved: + getModule().setFramePointer(llvm::FramePointerKind::Reserved); + break; case CodeGenOptions::FramePointerKind::NonLeaf: getModule().setFramePointer(llvm::FramePointerKind::NonLeaf); break; @@ -4509,6 +4512,19 @@ llvm::Constant *CodeGenModule::GetOrCreateMultiVersionResolver(GlobalDecl GD) { return Resolver; } +bool CodeGenModule::shouldDropDLLAttribute(const Decl *D, + const llvm::GlobalValue *GV) const { + auto SC = GV->getDLLStorageClass(); + if (SC == llvm::GlobalValue::DefaultStorageClass) + return false; + const Decl *MRD = D->getMostRecentDecl(); + return (((SC == llvm::GlobalValue::DLLImportStorageClass && + !MRD->hasAttr()) || + (SC == llvm::GlobalValue::DLLExportStorageClass && + !MRD->hasAttr())) && + !shouldMapVisibilityToDLLExport(cast(MRD))); +} + /// GetOrCreateLLVMFunction - If the specified mangled name is not in the /// module, create and return an llvm Function with the specified type. If there /// is something in the module with the specified name, return it potentially @@ -4561,8 +4577,7 @@ llvm::Constant *CodeGenModule::GetOrCreateLLVMFunction( } // Handle dropped DLL attributes. - if (D && !D->hasAttr() && !D->hasAttr() && - !shouldMapVisibilityToDLLExport(cast_or_null(D))) { + if (D && shouldDropDLLAttribute(D, Entry)) { Entry->setDLLStorageClass(llvm::GlobalValue::DefaultStorageClass); setDSOLocal(Entry); } @@ -4856,8 +4871,7 @@ CodeGenModule::GetOrCreateLLVMGlobal(StringRef MangledName, llvm::Type *Ty, } // Handle dropped DLL attributes. - if (D && !D->hasAttr() && !D->hasAttr() && - !shouldMapVisibilityToDLLExport(D)) + if (D && shouldDropDLLAttribute(D, Entry)) Entry->setDLLStorageClass(llvm::GlobalValue::DefaultStorageClass); if (LangOpts.OpenMP && !LangOpts.OpenMPSimd && D) diff --git a/clang/lib/CodeGen/CodeGenModule.h b/clang/lib/CodeGen/CodeGenModule.h index dc24971a3c1862b69311ad7441fc4799b06db295..9b63f47ef42cba4356b35cfc1170d799fc299eb2 100644 --- a/clang/lib/CodeGen/CodeGenModule.h +++ b/clang/lib/CodeGen/CodeGenModule.h @@ -1594,6 +1594,8 @@ public: } private: + bool shouldDropDLLAttribute(const Decl *D, const llvm::GlobalValue *GV) const; + llvm::Constant *GetOrCreateLLVMFunction( StringRef MangledName, llvm::Type *Ty, GlobalDecl D, bool ForVTable, bool DontDefer = false, bool IsThunk = false, diff --git a/clang/lib/CodeGen/Targets/AMDGPU.cpp b/clang/lib/CodeGen/Targets/AMDGPU.cpp index d1ff8b4b62f1570ed545946bf0e198cf1661346a..057f6ef40c5133d5589d09ecb4ed75d64662e3eb 100644 --- a/clang/lib/CodeGen/Targets/AMDGPU.cpp +++ b/clang/lib/CodeGen/Targets/AMDGPU.cpp @@ -120,7 +120,11 @@ void AMDGPUABIInfo::computeInfo(CGFunctionInfo &FI) const { Address AMDGPUABIInfo::EmitVAArg(CodeGenFunction &CGF, Address VAListAddr, QualType Ty) const { - llvm_unreachable("AMDGPU does not support varargs"); + const bool IsIndirect = false; + const bool AllowHigherAlign = false; + return emitVoidPtrVAArg(CGF, VAListAddr, Ty, IsIndirect, + getContext().getTypeInfoInChars(Ty), + CharUnits::fromQuantity(4), AllowHigherAlign); } ABIArgInfo AMDGPUABIInfo::classifyReturnType(QualType RetTy) const { diff --git a/clang/lib/Driver/SanitizerArgs.cpp b/clang/lib/Driver/SanitizerArgs.cpp index 273f215ca94a886c6c5235d5f590b71e45cb7b54..86825a6ccf7a1df26b74adfc571a5468e9f3647d 100644 --- a/clang/lib/Driver/SanitizerArgs.cpp +++ b/clang/lib/Driver/SanitizerArgs.cpp @@ -41,7 +41,8 @@ static const SanitizerMask NotAllowedWithExecuteOnly = SanitizerKind::Function | SanitizerKind::KCFI; static const SanitizerMask NeedsUnwindTables = SanitizerKind::Address | SanitizerKind::HWAddress | SanitizerKind::Thread | - SanitizerKind::Memory | SanitizerKind::DataFlow; + SanitizerKind::Memory | SanitizerKind::DataFlow | + SanitizerKind::NumericalStability; static const SanitizerMask SupportsCoverage = SanitizerKind::Address | SanitizerKind::HWAddress | SanitizerKind::KernelAddress | SanitizerKind::KernelHWAddress | @@ -53,7 +54,8 @@ static const SanitizerMask SupportsCoverage = SanitizerKind::DataFlow | SanitizerKind::Fuzzer | SanitizerKind::FuzzerNoLink | SanitizerKind::FloatDivideByZero | SanitizerKind::SafeStack | SanitizerKind::ShadowCallStack | - SanitizerKind::Thread | SanitizerKind::ObjCCast | SanitizerKind::KCFI; + SanitizerKind::Thread | SanitizerKind::ObjCCast | SanitizerKind::KCFI | + SanitizerKind::NumericalStability; static const SanitizerMask RecoverableByDefault = SanitizerKind::Undefined | SanitizerKind::Integer | SanitizerKind::ImplicitConversion | SanitizerKind::Nullability | @@ -175,6 +177,7 @@ static void addDefaultIgnorelists(const Driver &D, SanitizerMask Kinds, {"hwasan_ignorelist.txt", SanitizerKind::HWAddress}, {"memtag_ignorelist.txt", SanitizerKind::MemTag}, {"msan_ignorelist.txt", SanitizerKind::Memory}, + {"nsan_ignorelist.txt", SanitizerKind::NumericalStability}, {"tsan_ignorelist.txt", SanitizerKind::Thread}, {"dfsan_abilist.txt", SanitizerKind::DataFlow}, {"cfi_ignorelist.txt", SanitizerKind::CFI}, diff --git a/clang/lib/Driver/ToolChain.cpp b/clang/lib/Driver/ToolChain.cpp index 0e86bc07e0ea2c5d5265bc0a1422f535e70d0449..40ab2e91125d1e531254a7d6d0a9d6db9e14afc0 100644 --- a/clang/lib/Driver/ToolChain.cpp +++ b/clang/lib/Driver/ToolChain.cpp @@ -104,7 +104,8 @@ ToolChain::ToolChain(const Driver &D, const llvm::Triple &T, } llvm::Expected> -ToolChain::executeToolChainProgram(StringRef Executable) const { +ToolChain::executeToolChainProgram(StringRef Executable, + unsigned SecondsToWait) const { llvm::SmallString<64> OutputFile; llvm::sys::fs::createTemporaryFile("toolchain-program", "txt", OutputFile); llvm::FileRemover OutputRemover(OutputFile.c_str()); @@ -115,9 +116,8 @@ ToolChain::executeToolChainProgram(StringRef Executable) const { }; std::string ErrorMessage; - if (llvm::sys::ExecuteAndWait(Executable, {}, {}, Redirects, - /* SecondsToWait */ 0, - /*MemoryLimit*/ 0, &ErrorMessage)) + if (llvm::sys::ExecuteAndWait(Executable, {}, {}, Redirects, SecondsToWait, + /*MemoryLimit=*/0, &ErrorMessage)) return llvm::createStringError(std::error_code(), Executable + ": " + ErrorMessage); diff --git a/clang/lib/Driver/ToolChains/AMDGPU.cpp b/clang/lib/Driver/ToolChains/AMDGPU.cpp index 9ffea57b005de0085bee4a75bf36793897f66ca8..20f879e2f75cb809a3114cbe03dc84f7a6f369e0 100644 --- a/clang/lib/Driver/ToolChains/AMDGPU.cpp +++ b/clang/lib/Driver/ToolChains/AMDGPU.cpp @@ -645,7 +645,11 @@ void amdgpu::getAMDGPUTargetFeatures(const Driver &D, std::vector &Features) { // Add target ID features to -target-feature options. No diagnostics should // be emitted here since invalid target ID is diagnosed at other places. - StringRef TargetID = Args.getLastArgValue(options::OPT_mcpu_EQ); + StringRef TargetID; + if (Args.hasArg(options::OPT_mcpu_EQ)) + TargetID = Args.getLastArgValue(options::OPT_mcpu_EQ); + else if (Args.hasArg(options::OPT_march_EQ)) + TargetID = Args.getLastArgValue(options::OPT_march_EQ); if (!TargetID.empty()) { llvm::StringMap FeatureMap; auto OptionalGpuArch = parseTargetID(Triple, TargetID, &FeatureMap); @@ -877,7 +881,7 @@ AMDGPUToolChain::getSystemGPUArchs(const ArgList &Args) const { else Program = GetProgramPath("amdgpu-arch"); - auto StdoutOrErr = executeToolChainProgram(Program); + auto StdoutOrErr = executeToolChainProgram(Program, /*SecondsToWait=*/10); if (!StdoutOrErr) return StdoutOrErr.takeError(); diff --git a/clang/lib/Driver/ToolChains/AMDGPUOpenMP.cpp b/clang/lib/Driver/ToolChains/AMDGPUOpenMP.cpp index cca18431ff773240e73aa35a7d49a8e0820b8daf..d17ecb15c82088e4a0afcc6e9d8d57fbef2e7e43 100644 --- a/clang/lib/Driver/ToolChains/AMDGPUOpenMP.cpp +++ b/clang/lib/Driver/ToolChains/AMDGPUOpenMP.cpp @@ -44,14 +44,9 @@ void AMDGPUOpenMPToolChain::addClangTargetOptions( Action::OffloadKind DeviceOffloadingKind) const { HostTC.addClangTargetOptions(DriverArgs, CC1Args, DeviceOffloadingKind); - StringRef GPUArch = DriverArgs.getLastArgValue(options::OPT_march_EQ); - assert(!GPUArch.empty() && "Must have an explicit GPU arch."); - assert(DeviceOffloadingKind == Action::OFK_OpenMP && "Only OpenMP offloading kinds are supported."); - CC1Args.push_back("-target-cpu"); - CC1Args.push_back(DriverArgs.MakeArgStringRef(GPUArch)); CC1Args.push_back("-fcuda-is-device"); if (DriverArgs.hasArg(options::OPT_nogpulib)) diff --git a/clang/lib/Driver/ToolChains/Arch/ARM.cpp b/clang/lib/Driver/ToolChains/Arch/ARM.cpp index a68368c4758651ab9fb60863df294b63285d5582..8ae22cc37a136867a941a7dab1f312f88f544b8b 100644 --- a/clang/lib/Driver/ToolChains/Arch/ARM.cpp +++ b/clang/lib/Driver/ToolChains/Arch/ARM.cpp @@ -799,8 +799,6 @@ fp16_fml_fallthrough: StringRef FrameChainOption = A->getValue(); if (FrameChainOption.starts_with("aapcs")) Features.push_back("+aapcs-frame-chain"); - if (FrameChainOption == "aapcs+leaf") - Features.push_back("+aapcs-frame-chain-leaf"); } // CMSE: Check for target 8M (for -mcmse to be applicable) is performed later. diff --git a/clang/lib/Driver/ToolChains/Arch/RISCV.cpp b/clang/lib/Driver/ToolChains/Arch/RISCV.cpp index 2e2bce8494672fe0e29086fbf768de1d3c256b31..26789b0ba6e098966013048e73ab32b2c7b86035 100644 --- a/clang/lib/Driver/ToolChains/Arch/RISCV.cpp +++ b/clang/lib/Driver/ToolChains/Arch/RISCV.cpp @@ -67,11 +67,6 @@ static void getRISCFeaturesFromMcpu(const Driver &D, const Arg *A, D.Diag(clang::diag::err_drv_unsupported_option_argument) << A->getSpelling() << Mcpu; } - - if (llvm::RISCV::hasFastUnalignedAccess(Mcpu)) { - Features.push_back("+unaligned-scalar-mem"); - Features.push_back("+unaligned-vector-mem"); - } } void riscv::getRISCVTargetFeatures(const Driver &D, const llvm::Triple &Triple, @@ -82,6 +77,8 @@ void riscv::getRISCVTargetFeatures(const Driver &D, const llvm::Triple &Triple, if (!getArchFeatures(D, MArch, Features, Args)) return; + bool CPUFastUnaligned = false; + // If users give march and mcpu, get std extension feature from MArch // and other features (ex. mirco architecture feature) from mcpu if (Arg *A = Args.getLastArg(options::OPT_mcpu_EQ)) { @@ -90,6 +87,9 @@ void riscv::getRISCVTargetFeatures(const Driver &D, const llvm::Triple &Triple, CPU = llvm::sys::getHostCPUName(); getRISCFeaturesFromMcpu(D, A, Triple, CPU, Features); + + if (llvm::RISCV::hasFastUnalignedAccess(CPU)) + CPUFastUnaligned = true; } // Handle features corresponding to "-ffixed-X" options @@ -169,18 +169,23 @@ void riscv::getRISCVTargetFeatures(const Driver &D, const llvm::Triple &Triple, Features.push_back("-relax"); } - // Android requires fast unaligned access on RISCV64. - if (Triple.isAndroid()) { + // If -mstrict-align or -mno-strict-align is passed, use it. Otherwise, the + // unaligned-*-mem is enabled if the CPU supports it or the target is + // Android. + if (const Arg *A = Args.getLastArg(options::OPT_mno_strict_align, + options::OPT_mstrict_align)) { + if (A->getOption().matches(options::OPT_mno_strict_align)) { + Features.push_back("+unaligned-scalar-mem"); + Features.push_back("+unaligned-vector-mem"); + } else { + Features.push_back("-unaligned-scalar-mem"); + Features.push_back("-unaligned-vector-mem"); + } + } else if (CPUFastUnaligned || Triple.isAndroid()) { Features.push_back("+unaligned-scalar-mem"); Features.push_back("+unaligned-vector-mem"); } - // -mstrict-align is default, unless -mno-strict-align is specified. - AddTargetFeature(Args, Features, options::OPT_mno_strict_align, - options::OPT_mstrict_align, "unaligned-scalar-mem"); - AddTargetFeature(Args, Features, options::OPT_mno_strict_align, - options::OPT_mstrict_align, "unaligned-vector-mem"); - // Now add any that the user explicitly requested on the command line, // which may override the defaults. handleTargetFeaturesGroup(D, Triple, Args, Features, diff --git a/clang/lib/Driver/ToolChains/BareMetal.cpp b/clang/lib/Driver/ToolChains/BareMetal.cpp index 221c4815792405a4d02fd02d41245dc1f36db5bc..dd365e62e084e68468ddd42bece4a6b0eb12bc39 100644 --- a/clang/lib/Driver/ToolChains/BareMetal.cpp +++ b/clang/lib/Driver/ToolChains/BareMetal.cpp @@ -429,6 +429,7 @@ void baremetal::Linker::ConstructJob(Compilation &C, const JobAction &JA, ArgStringList CmdArgs; auto &TC = static_cast(getToolChain()); + const Driver &D = getToolChain().getDriver(); const llvm::Triple::ArchType Arch = TC.getArch(); const llvm::Triple &Triple = getToolChain().getEffectiveTriple(); @@ -466,6 +467,19 @@ void baremetal::Linker::ConstructJob(Compilation &C, const JobAction &JA, TC.AddLinkRuntimeLib(Args, CmdArgs); } + if (D.isUsingLTO()) { + assert(!Inputs.empty() && "Must have at least one input."); + // Find the first filename InputInfo object. + auto Input = llvm::find_if( + Inputs, [](const InputInfo &II) -> bool { return II.isFilename(); }); + if (Input == Inputs.end()) + // For a very rare case, all of the inputs to the linker are + // InputArg. If that happens, just use the first InputInfo. + Input = Inputs.begin(); + + addLTOOptions(TC, Args, CmdArgs, Output, *Input, + D.getLTOMode() == LTOK_Thin); + } if (TC.getTriple().isRISCV()) CmdArgs.push_back("-X"); diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp index 4e1c52462e5842c8cce009195ab37e9fd9ff1e71..b8d8ff3db5d1fd5e082bcda4733d3a2352782fa1 100644 --- a/clang/lib/Driver/ToolChains/Clang.cpp +++ b/clang/lib/Driver/ToolChains/Clang.cpp @@ -5678,6 +5678,9 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, case CodeGenOptions::FramePointerKind::None: FPKeepKindStr = "-mframe-pointer=none"; break; + case CodeGenOptions::FramePointerKind::Reserved: + FPKeepKindStr = "-mframe-pointer=reserved"; + break; case CodeGenOptions::FramePointerKind::NonLeaf: FPKeepKindStr = "-mframe-pointer=non-leaf"; break; diff --git a/clang/lib/Driver/ToolChains/CommonArgs.cpp b/clang/lib/Driver/ToolChains/CommonArgs.cpp index 71e993119436aed2cdb3c5caada8fa249b13aba8..2a4c1369f5a734917cadada1c92d5de497d43d6d 100644 --- a/clang/lib/Driver/ToolChains/CommonArgs.cpp +++ b/clang/lib/Driver/ToolChains/CommonArgs.cpp @@ -164,6 +164,14 @@ static bool useFramePointerForTargetByDefault(const llvm::opt::ArgList &Args, return true; } +static bool useLeafFramePointerForTargetByDefault(const llvm::Triple &Triple) { + if (Triple.isAArch64() || Triple.isPS() || Triple.isVE() || + (Triple.isAndroid() && Triple.isRISCV64())) + return false; + + return true; +} + static bool mustUseNonLeafFramePointerForTarget(const llvm::Triple &Triple) { switch (Triple.getArch()) { default: @@ -176,38 +184,91 @@ static bool mustUseNonLeafFramePointerForTarget(const llvm::Triple &Triple) { } } +// True if a target-specific option requires the frame chain to be preserved, +// even if new frame records are not created. +static bool mustMaintainValidFrameChain(const llvm::opt::ArgList &Args, + const llvm::Triple &Triple) { + if (Triple.isARM() || Triple.isThumb()) { + // For 32-bit Arm, the -mframe-chain=aapcs and -mframe-chain=aapcs+leaf + // options require the frame pointer register to be reserved (or point to a + // new AAPCS-compilant frame record), even with -fno-omit-frame-pointer. + if (Arg *A = Args.getLastArg(options::OPT_mframe_chain)) { + StringRef V = A->getValue(); + return V != "none"; + } + return false; + } + return false; +} + +// True if a target-specific option causes -fno-omit-frame-pointer to also +// cause frame records to be created in leaf functions. +static bool framePointerImpliesLeafFramePointer(const llvm::opt::ArgList &Args, + const llvm::Triple &Triple) { + if (Triple.isARM() || Triple.isThumb()) { + // For 32-bit Arm, the -mframe-chain=aapcs+leaf option causes the + // -fno-omit-frame-pointer optiion to imply -mno-omit-leaf-frame-pointer, + // but does not by itself imply either option. + if (Arg *A = Args.getLastArg(options::OPT_mframe_chain)) { + StringRef V = A->getValue(); + return V == "aapcs+leaf"; + } + return false; + } + return false; +} + clang::CodeGenOptions::FramePointerKind getFramePointerKind(const llvm::opt::ArgList &Args, const llvm::Triple &Triple) { - // We have 4 states: + // There are three things to consider here: + // * Should a frame record be created for non-leaf functions? + // * Should a frame record be created for leaf functions? + // * Is the frame pointer register reserved, i.e. must it always point to + // either a new, valid frame record or be un-modified? // - // 00) leaf retained, non-leaf retained - // 01) leaf retained, non-leaf omitted (this is invalid) - // 10) leaf omitted, non-leaf retained - // (what -momit-leaf-frame-pointer was designed for) - // 11) leaf omitted, non-leaf omitted + // Not all combinations of these are valid: + // * It's not useful to have leaf frame records without non-leaf ones. + // * It's not useful to have frame records without reserving the frame + // pointer. // - // "omit" options taking precedence over "no-omit" options is the only way - // to make 3 valid states representable - llvm::opt::Arg *A = - Args.getLastArg(clang::driver::options::OPT_fomit_frame_pointer, - clang::driver::options::OPT_fno_omit_frame_pointer); - - bool OmitFP = A && A->getOption().matches( - clang::driver::options::OPT_fomit_frame_pointer); - bool NoOmitFP = A && A->getOption().matches( - clang::driver::options::OPT_fno_omit_frame_pointer); - bool OmitLeafFP = - Args.hasFlag(clang::driver::options::OPT_momit_leaf_frame_pointer, - clang::driver::options::OPT_mno_omit_leaf_frame_pointer, - Triple.isAArch64() || Triple.isPS() || Triple.isVE() || - (Triple.isAndroid() && Triple.isRISCV64())); - if (NoOmitFP || mustUseNonLeafFramePointerForTarget(Triple) || - (!OmitFP && useFramePointerForTargetByDefault(Args, Triple))) { - if (OmitLeafFP) - return clang::CodeGenOptions::FramePointerKind::NonLeaf; - return clang::CodeGenOptions::FramePointerKind::All; - } + // | Non-leaf | Leaf | Reserved | + // | N | N | N | FramePointerKind::None + // | N | N | Y | FramePointerKind::Reserved + // | N | Y | N | Invalid + // | N | Y | Y | Invalid + // | Y | N | N | Invalid + // | Y | N | Y | FramePointerKind::NonLeaf + // | Y | Y | N | Invalid + // | Y | Y | Y | FramePointerKind::All + // + // The FramePointerKind::Reserved case is currently only reachable for Arm, + // which has the -mframe-chain= option which can (in combination with + // -fno-omit-frame-pointer) specify that the frame chain must be valid, + // without requiring new frame records to be created. + + bool DefaultFP = useFramePointerForTargetByDefault(Args, Triple); + bool EnableFP = + mustUseNonLeafFramePointerForTarget(Triple) || + Args.hasFlag(clang::driver::options::OPT_fno_omit_frame_pointer, + clang::driver::options::OPT_fomit_frame_pointer, DefaultFP); + + bool DefaultLeafFP = + useLeafFramePointerForTargetByDefault(Triple) || + (EnableFP && framePointerImpliesLeafFramePointer(Args, Triple)); + bool EnableLeafFP = Args.hasFlag( + clang::driver::options::OPT_mno_omit_leaf_frame_pointer, + clang::driver::options::OPT_momit_leaf_frame_pointer, DefaultLeafFP); + + bool FPRegReserved = EnableFP || mustMaintainValidFrameChain(Args, Triple); + + if (EnableFP) { + if (EnableLeafFP) + return clang::CodeGenOptions::FramePointerKind::All; + return clang::CodeGenOptions::FramePointerKind::NonLeaf; + } + if (FPRegReserved) + return clang::CodeGenOptions::FramePointerKind::Reserved; return clang::CodeGenOptions::FramePointerKind::None; } diff --git a/clang/lib/Driver/ToolChains/Cuda.cpp b/clang/lib/Driver/ToolChains/Cuda.cpp index d5f93c9c830faa06238b2dc85d179bfa98526a16..2dfc7457b0ac7c1475d9e7b1c9ad2169ea8c55dd 100644 --- a/clang/lib/Driver/ToolChains/Cuda.cpp +++ b/clang/lib/Driver/ToolChains/Cuda.cpp @@ -84,6 +84,8 @@ CudaVersion getCudaVersion(uint32_t raw_version) { return CudaVersion::CUDA_123; if (raw_version < 12050) return CudaVersion::CUDA_124; + if (raw_version < 12060) + return CudaVersion::CUDA_125; return CudaVersion::NEW; } @@ -690,6 +692,7 @@ void NVPTX::getNVPTXTargetFeatures(const Driver &D, const llvm::Triple &Triple, case CudaVersion::CUDA_##CUDA_VER: \ PtxFeature = "+ptx" #PTX_VER; \ break; + CASE_CUDA_VERSION(125, 85); CASE_CUDA_VERSION(124, 84); CASE_CUDA_VERSION(123, 83); CASE_CUDA_VERSION(122, 82); @@ -823,7 +826,7 @@ NVPTXToolChain::getSystemGPUArchs(const ArgList &Args) const { else Program = GetProgramPath("nvptx-arch"); - auto StdoutOrErr = executeToolChainProgram(Program); + auto StdoutOrErr = executeToolChainProgram(Program, /*SecondsToWait=*/10); if (!StdoutOrErr) return StdoutOrErr.takeError(); diff --git a/clang/lib/Driver/ToolChains/Darwin.cpp b/clang/lib/Driver/ToolChains/Darwin.cpp index 593b403a1e3f057e82c5f7ce42f9963c1057f228..ed5737915aa96b0716e7f357ead4f019bdcfcf12 100644 --- a/clang/lib/Driver/ToolChains/Darwin.cpp +++ b/clang/lib/Driver/ToolChains/Darwin.cpp @@ -3448,6 +3448,7 @@ SanitizerMask Darwin::getSupportedSanitizers() const { Res |= SanitizerKind::PointerCompare; Res |= SanitizerKind::PointerSubtract; Res |= SanitizerKind::Leak; + Res |= SanitizerKind::NumericalStability; Res |= SanitizerKind::Fuzzer; Res |= SanitizerKind::FuzzerNoLink; Res |= SanitizerKind::ObjCCast; diff --git a/clang/lib/Driver/ToolChains/Flang.cpp b/clang/lib/Driver/ToolChains/Flang.cpp index 42ca060186fd8bdce79a4cda14a54305a9ad3127..42b45dba2bd31116d8b8a6434f845755950c13b7 100644 --- a/clang/lib/Driver/ToolChains/Flang.cpp +++ b/clang/lib/Driver/ToolChains/Flang.cpp @@ -765,6 +765,9 @@ void Flang::ConstructJob(Compilation &C, const JobAction &JA, CmdArgs.push_back("-fopenmp"); Args.AddAllArgs(CmdArgs, options::OPT_fopenmp_version_EQ); + if (Args.hasArg(options::OPT_fopenmp_force_usm)) + CmdArgs.push_back("-fopenmp-force-usm"); + // FIXME: Clang supports a whole bunch more flags here. break; default: @@ -799,6 +802,9 @@ void Flang::ConstructJob(Compilation &C, const JobAction &JA, case CodeGenOptions::FramePointerKind::None: FPKeepKindStr = "-mframe-pointer=none"; break; + case CodeGenOptions::FramePointerKind::Reserved: + FPKeepKindStr = "-mframe-pointer=reserved"; + break; case CodeGenOptions::FramePointerKind::NonLeaf: FPKeepKindStr = "-mframe-pointer=non-leaf"; break; diff --git a/clang/lib/Driver/ToolChains/Linux.cpp b/clang/lib/Driver/ToolChains/Linux.cpp index db2c20d7b461d0a782ce6b4dd5a498903cc5e204..2c583ac724a2a23a6c669fa1619a1e001fa492ee 100644 --- a/clang/lib/Driver/ToolChains/Linux.cpp +++ b/clang/lib/Driver/ToolChains/Linux.cpp @@ -826,6 +826,9 @@ SanitizerMask Linux::getSupportedSanitizers() const { if (IsX86_64 || IsAArch64) { Res |= SanitizerKind::KernelHWAddress; } + if (IsX86_64 || IsAArch64) + Res |= SanitizerKind::NumericalStability; + // Work around "Cannot represent a difference across sections". if (getTriple().getArch() == llvm::Triple::ppc64) Res &= ~SanitizerKind::Function; diff --git a/clang/lib/ExtractAPI/Serialization/SymbolGraphSerializer.cpp b/clang/lib/ExtractAPI/Serialization/SymbolGraphSerializer.cpp index 08e711cafae280c761c35751d7ce0e8d495fe6f2..6e56ee5b573f66af612d0ebcfe9444abdb04bd3f 100644 --- a/clang/lib/ExtractAPI/Serialization/SymbolGraphSerializer.cpp +++ b/clang/lib/ExtractAPI/Serialization/SymbolGraphSerializer.cpp @@ -31,7 +31,6 @@ using namespace clang; using namespace clang::extractapi; using namespace llvm; -using namespace llvm::json; namespace { @@ -1036,9 +1035,9 @@ void SymbolGraphSerializer::serializeGraphToStream( ExtendedModule &&EM) { Object Root = serializeGraph(ModuleName, std::move(EM)); if (Options.Compact) - OS << formatv("{0}", Value(std::move(Root))) << "\n"; + OS << formatv("{0}", json::Value(std::move(Root))) << "\n"; else - OS << formatv("{0:2}", Value(std::move(Root))) << "\n"; + OS << formatv("{0:2}", json::Value(std::move(Root))) << "\n"; } void SymbolGraphSerializer::serializeMainSymbolGraph( diff --git a/clang/lib/Format/ContinuationIndenter.cpp b/clang/lib/Format/ContinuationIndenter.cpp index 6b9fbfe0ebf53fad85a71e9688f2354a0545d20e..b07360425ca6e1ad9951af9ffaa49d818738ddb4 100644 --- a/clang/lib/Format/ContinuationIndenter.cpp +++ b/clang/lib/Format/ContinuationIndenter.cpp @@ -1257,6 +1257,11 @@ unsigned ContinuationIndenter::getNewLineColumn(const LineState &State) { } return CurrentState.Indent; } + if (Current.is(TT_TrailingReturnArrow) && + Previous.isOneOf(tok::kw_noexcept, tok::kw_mutable, tok::kw_constexpr, + tok::kw_consteval, tok::kw_static, TT_AttributeSquare)) { + return ContinuationIndent; + } if ((Current.isOneOf(tok::r_brace, tok::r_square) || (Current.is(tok::greater) && (Style.isProto() || Style.isTableGen()))) && State.Stack.size() > 1) { @@ -1712,7 +1717,7 @@ void ContinuationIndenter::moveStatePastFakeLParens(LineState &State, (!Previous || Previous->isNot(tok::kw_return) || (Style.Language != FormatStyle::LK_Java && PrecedenceLevel > 0)) && (Style.AlignAfterOpenBracket != FormatStyle::BAS_DontAlign || - PrecedenceLevel != prec::Comma || Current.NestingLevel == 0) && + PrecedenceLevel > prec::Comma || Current.NestingLevel == 0) && (!Style.isTableGen() || (Previous && Previous->isOneOf(TT_TableGenDAGArgListComma, TT_TableGenDAGArgListCommaToBreak)))) { diff --git a/clang/lib/Format/TokenAnnotator.cpp b/clang/lib/Format/TokenAnnotator.cpp index 26c0aa36bdcb64f9cfc98efd5a8cb139df179607..1fe3b61a5a81f2deae3c648525efaebc822770a0 100644 --- a/clang/lib/Format/TokenAnnotator.cpp +++ b/clang/lib/Format/TokenAnnotator.cpp @@ -1358,6 +1358,8 @@ private: Line.First->startsSequence(tok::kw_export, Keywords.kw_module) || Line.First->startsSequence(tok::kw_export, Keywords.kw_import)) { Tok->setType(TT_ModulePartitionColon); + } else if (Line.First->is(tok::kw_asm)) { + Tok->setType(TT_InlineASMColon); } else if (Contexts.back().ColonIsDictLiteral || Style.isProto()) { Tok->setType(TT_DictLiteral); if (Style.Language == FormatStyle::LK_TextProto) { @@ -1425,13 +1427,6 @@ private: // This handles a special macro in ObjC code where selectors including // the colon are passed as macro arguments. Tok->setType(TT_ObjCMethodExpr); - } else if (Contexts.back().ContextKind == tok::l_paren && - !Line.InPragmaDirective) { - if (Style.isTableGen() && Contexts.back().IsTableGenDAGArg) { - Tok->setType(TT_TableGenDAGArgListColon); - break; - } - Tok->setType(TT_InlineASMColon); } break; case tok::pipe: diff --git a/clang/lib/Format/UnwrappedLineParser.cpp b/clang/lib/Format/UnwrappedLineParser.cpp index d6061c2666c2ad87f606eb39768c580822d75823..eb96b54ec4c962481bd498fc7d0504f3cef2d520 100644 --- a/clang/lib/Format/UnwrappedLineParser.cpp +++ b/clang/lib/Format/UnwrappedLineParser.cpp @@ -1181,10 +1181,10 @@ void UnwrappedLineParser::parsePPDefine() { Line->InMacroBody = true; if (Style.SkipMacroDefinitionBody) { - do { + while (!eof()) { FormatTok->Finalized = true; - nextToken(); - } while (!eof()); + FormatTok = Tokens->getNextToken(); + } addUnwrappedLine(); return; } diff --git a/clang/lib/Frontend/FrontendActions.cpp b/clang/lib/Frontend/FrontendActions.cpp index 1812b85860f64cf835d77efef2ad8d01c3acf2e2..4f064321997a2268047b7634e09a803ce0ab8fb0 100644 --- a/clang/lib/Frontend/FrontendActions.cpp +++ b/clang/lib/Frontend/FrontendActions.cpp @@ -1169,8 +1169,8 @@ void PrintDependencyDirectivesSourceMinimizerAction::ExecuteAction() { llvm::SmallVector Tokens; llvm::SmallVector Directives; if (scanSourceForDependencyDirectives( - FromFile.getBuffer(), Tokens, Directives, CI.getLangOpts(), - &CI.getDiagnostics(), SM.getLocForStartOfFile(SM.getMainFileID()))) { + FromFile.getBuffer(), Tokens, Directives, &CI.getDiagnostics(), + SM.getLocForStartOfFile(SM.getMainFileID()))) { assert(CI.getDiagnostics().hasErrorOccurred() && "no errors reported for failure"); diff --git a/clang/lib/Index/CommentToXML.cpp b/clang/lib/Index/CommentToXML.cpp index 3372fbba4383173bfcd97e2c6c156a8cc010dba9..cd7226e71171c2391d270e51143032b52a0d0fd7 100644 --- a/clang/lib/Index/CommentToXML.cpp +++ b/clang/lib/Index/CommentToXML.cpp @@ -546,7 +546,8 @@ public: void visitParagraphComment(const ParagraphComment *C); void appendParagraphCommentWithKind(const ParagraphComment *C, - StringRef Kind); + StringRef ParagraphKind, + StringRef PrependBodyText); void visitBlockCommandComment(const BlockCommandComment *C); void visitParamCommandComment(const ParamCommandComment *C); @@ -680,15 +681,15 @@ CommentASTToXMLConverter::visitHTMLEndTagComment(const HTMLEndTagComment *C) { Result << "></" << C->getTagName() << ">"; } -void -CommentASTToXMLConverter::visitParagraphComment(const ParagraphComment *C) { - appendParagraphCommentWithKind(C, StringRef()); +void CommentASTToXMLConverter::visitParagraphComment( + const ParagraphComment *C) { + appendParagraphCommentWithKind(C, StringRef(), StringRef()); } void CommentASTToXMLConverter::appendParagraphCommentWithKind( - const ParagraphComment *C, - StringRef ParagraphKind) { - if (C->isWhitespace()) + const ParagraphComment *C, StringRef ParagraphKind, + StringRef PrependBodyText) { + if (C->isWhitespace() && PrependBodyText.empty()) return; if (ParagraphKind.empty()) @@ -696,8 +697,11 @@ void CommentASTToXMLConverter::appendParagraphCommentWithKind( else Result << ""; - for (Comment::child_iterator I = C->child_begin(), E = C->child_end(); - I != E; ++I) { + if (!PrependBodyText.empty()) + Result << PrependBodyText << " "; + + for (Comment::child_iterator I = C->child_begin(), E = C->child_end(); I != E; + ++I) { visit(*I); } Result << ""; @@ -706,8 +710,15 @@ void CommentASTToXMLConverter::appendParagraphCommentWithKind( void CommentASTToXMLConverter::visitBlockCommandComment( const BlockCommandComment *C) { StringRef ParagraphKind; + StringRef ExceptionType; - switch (C->getCommandID()) { + const unsigned CommandID = C->getCommandID(); + const CommandInfo *Info = Traits.getCommandInfo(CommandID); + if (Info->IsThrowsCommand && C->getNumArgs() > 0) { + ExceptionType = C->getArgText(0); + } + + switch (CommandID) { case CommandTraits::KCI_attention: case CommandTraits::KCI_author: case CommandTraits::KCI_authors: @@ -732,7 +743,8 @@ void CommentASTToXMLConverter::visitBlockCommandComment( break; } - appendParagraphCommentWithKind(C->getParagraph(), ParagraphKind); + appendParagraphCommentWithKind(C->getParagraph(), ParagraphKind, + ExceptionType); } void CommentASTToXMLConverter::visitParamCommandComment( diff --git a/clang/lib/Index/IndexBody.cpp b/clang/lib/Index/IndexBody.cpp index 08136baa5d408e9355c9d8309a48f8a2e1eb7bd5..c18daf7faa74979e9ed442e86bd4b53196c271d8 100644 --- a/clang/lib/Index/IndexBody.cpp +++ b/clang/lib/Index/IndexBody.cpp @@ -268,7 +268,7 @@ public: } return true; }; - bool IsPropCall = Containing && isa(Containing); + bool IsPropCall = isa_and_nonnull(Containing); // Implicit property message sends are not 'implicit'. if ((E->isImplicit() || IsPropCall) && !(IsPropCall && diff --git a/clang/lib/Interpreter/IncrementalParser.cpp b/clang/lib/Interpreter/IncrementalParser.cpp index 5bc8385d874a16869edd75fdd22088237a834671..a8d0294fb6151bd057d8dd228fba6eaa208757ac 100644 --- a/clang/lib/Interpreter/IncrementalParser.cpp +++ b/clang/lib/Interpreter/IncrementalParser.cpp @@ -413,7 +413,8 @@ void IncrementalParser::CleanUpPTU(PartialTranslationUnit &PTU) { if (!ND) continue; // Check if we need to clean up the IdResolver chain. - if (ND->getDeclName().getFETokenInfo()) + if (ND->getDeclName().getFETokenInfo() && !D->getLangOpts().ObjC && + !D->getLangOpts().CPlusPlus) getCI()->getSema().IdResolver.RemoveDecl(ND); } } diff --git a/clang/lib/Interpreter/Interpreter.cpp b/clang/lib/Interpreter/Interpreter.cpp index 683f87e8c8c79e36ed90da00151fc400708f3e87..7a95278914276af695d7fe234b29da2fae599a3a 100644 --- a/clang/lib/Interpreter/Interpreter.cpp +++ b/clang/lib/Interpreter/Interpreter.cpp @@ -42,6 +42,9 @@ #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/raw_ostream.h" #include "llvm/TargetParser/Host.h" + +#include + using namespace clang; // FIXME: Figure out how to unify with namespace init_convenience from @@ -270,14 +273,10 @@ Interpreter::~Interpreter() { // can't find the precise resource directory in unittests so we have to hard // code them. const char *const Runtimes = R"( + #define __CLANG_REPL__ 1 #ifdef __cplusplus + #define EXTERN_C extern "C" void *__clang_Interpreter_SetValueWithAlloc(void*, void*, void*); - void __clang_Interpreter_SetValueNoAlloc(void*, void*, void*); - void __clang_Interpreter_SetValueNoAlloc(void*, void*, void*, void*); - void __clang_Interpreter_SetValueNoAlloc(void*, void*, void*, float); - void __clang_Interpreter_SetValueNoAlloc(void*, void*, void*, double); - void __clang_Interpreter_SetValueNoAlloc(void*, void*, void*, long double); - void __clang_Interpreter_SetValueNoAlloc(void*,void*,void*,unsigned long long); struct __clang_Interpreter_NewTag{} __ci_newtag; void* operator new(__SIZE_TYPE__, void* __p, __clang_Interpreter_NewTag) noexcept; template @@ -289,7 +288,11 @@ const char *const Runtimes = R"( void __clang_Interpreter_SetValueCopyArr(const T (*Src)[N], void* Placement, unsigned long Size) { __clang_Interpreter_SetValueCopyArr(Src[0], Placement, Size); } +#else + #define EXTERN_C extern #endif // __cplusplus + + EXTERN_C void __clang_Interpreter_SetValueNoAlloc(void *This, void *OutVal, void *OpaqueType, ...); )"; llvm::Expected> @@ -588,15 +591,17 @@ std::unique_ptr Interpreter::FindRuntimeInterface() { if (!LookupInterface(ValuePrintingInfo[NoAlloc], MagicRuntimeInterface[NoAlloc])) return nullptr; - if (!LookupInterface(ValuePrintingInfo[WithAlloc], - MagicRuntimeInterface[WithAlloc])) - return nullptr; - if (!LookupInterface(ValuePrintingInfo[CopyArray], - MagicRuntimeInterface[CopyArray])) - return nullptr; - if (!LookupInterface(ValuePrintingInfo[NewTag], - MagicRuntimeInterface[NewTag])) - return nullptr; + if (Ctx.getLangOpts().CPlusPlus) { + if (!LookupInterface(ValuePrintingInfo[WithAlloc], + MagicRuntimeInterface[WithAlloc])) + return nullptr; + if (!LookupInterface(ValuePrintingInfo[CopyArray], + MagicRuntimeInterface[CopyArray])) + return nullptr; + if (!LookupInterface(ValuePrintingInfo[NewTag], + MagicRuntimeInterface[NewTag])) + return nullptr; + } return createInProcessRuntimeInterfaceBuilder(*this, Ctx, S); } @@ -855,69 +860,81 @@ __clang_Interpreter_SetValueWithAlloc(void *This, void *OutVal, return VRef.getPtr(); } -// Pointers, lvalue struct that can take as a reference. -REPL_EXTERNAL_VISIBILITY void -__clang_Interpreter_SetValueNoAlloc(void *This, void *OutVal, void *OpaqueType, - void *Val) { +extern "C" void REPL_EXTERNAL_VISIBILITY __clang_Interpreter_SetValueNoAlloc( + void *This, void *OutVal, void *OpaqueType, ...) { Value &VRef = *(Value *)OutVal; - VRef = Value(static_cast(This), OpaqueType); - VRef.setPtr(Val); -} + Interpreter *I = static_cast(This); + VRef = Value(I, OpaqueType); + if (VRef.isVoid()) + return; -REPL_EXTERNAL_VISIBILITY void -__clang_Interpreter_SetValueNoAlloc(void *This, void *OutVal, - void *OpaqueType) { - Value &VRef = *(Value *)OutVal; - VRef = Value(static_cast(This), OpaqueType); -} + va_list args; + va_start(args, /*last named param*/ OpaqueType); -static void SetValueDataBasedOnQualType(Value &V, unsigned long long Data) { - QualType QT = V.getType(); - if (const auto *ET = QT->getAs()) - QT = ET->getDecl()->getIntegerType(); - - switch (QT->castAs()->getKind()) { - default: - llvm_unreachable("unknown type kind!"); -#define X(type, name) \ - case BuiltinType::name: \ - V.set##name(Data); \ - break; - REPL_BUILTIN_TYPES -#undef X + QualType QT = VRef.getType(); + if (VRef.getKind() == Value::K_PtrOrObj) { + VRef.setPtr(va_arg(args, void *)); + } else { + if (const auto *ET = QT->getAs()) + QT = ET->getDecl()->getIntegerType(); + switch (QT->castAs()->getKind()) { + default: + llvm_unreachable("unknown type kind!"); + break; + // Types shorter than int are resolved as int, else va_arg has UB. + case BuiltinType::Bool: + VRef.setBool(va_arg(args, int)); + break; + case BuiltinType::Char_S: + VRef.setChar_S(va_arg(args, int)); + break; + case BuiltinType::SChar: + VRef.setSChar(va_arg(args, int)); + break; + case BuiltinType::Char_U: + VRef.setChar_U(va_arg(args, unsigned)); + break; + case BuiltinType::UChar: + VRef.setUChar(va_arg(args, unsigned)); + break; + case BuiltinType::Short: + VRef.setShort(va_arg(args, int)); + break; + case BuiltinType::UShort: + VRef.setUShort(va_arg(args, unsigned)); + break; + case BuiltinType::Int: + VRef.setInt(va_arg(args, int)); + break; + case BuiltinType::UInt: + VRef.setUInt(va_arg(args, unsigned)); + break; + case BuiltinType::Long: + VRef.setLong(va_arg(args, long)); + break; + case BuiltinType::ULong: + VRef.setULong(va_arg(args, unsigned long)); + break; + case BuiltinType::LongLong: + VRef.setLongLong(va_arg(args, long long)); + break; + case BuiltinType::ULongLong: + VRef.setULongLong(va_arg(args, unsigned long long)); + break; + // Types shorter than double are resolved as double, else va_arg has UB. + case BuiltinType::Float: + VRef.setFloat(va_arg(args, double)); + break; + case BuiltinType::Double: + VRef.setDouble(va_arg(args, double)); + break; + case BuiltinType::LongDouble: + VRef.setLongDouble(va_arg(args, long double)); + break; + // See REPL_BUILTIN_TYPES. + } } -} - -REPL_EXTERNAL_VISIBILITY void -__clang_Interpreter_SetValueNoAlloc(void *This, void *OutVal, void *OpaqueType, - unsigned long long Val) { - Value &VRef = *(Value *)OutVal; - VRef = Value(static_cast(This), OpaqueType); - SetValueDataBasedOnQualType(VRef, Val); -} - -REPL_EXTERNAL_VISIBILITY void -__clang_Interpreter_SetValueNoAlloc(void *This, void *OutVal, void *OpaqueType, - float Val) { - Value &VRef = *(Value *)OutVal; - VRef = Value(static_cast(This), OpaqueType); - VRef.setFloat(Val); -} - -REPL_EXTERNAL_VISIBILITY void -__clang_Interpreter_SetValueNoAlloc(void *This, void *OutVal, void *OpaqueType, - double Val) { - Value &VRef = *(Value *)OutVal; - VRef = Value(static_cast(This), OpaqueType); - VRef.setDouble(Val); -} - -REPL_EXTERNAL_VISIBILITY void -__clang_Interpreter_SetValueNoAlloc(void *This, void *OutVal, void *OpaqueType, - long double Val) { - Value &VRef = *(Value *)OutVal; - VRef = Value(static_cast(This), OpaqueType); - VRef.setLongDouble(Val); + va_end(args); } // A trampoline to work around the fact that operator placement new cannot diff --git a/clang/lib/Lex/DependencyDirectivesScanner.cpp b/clang/lib/Lex/DependencyDirectivesScanner.cpp index fda54d314eef6c0d0981e615d98dbccc6246c124..0971daa1f36663f0bb17177e1b65f84dfddfc786 100644 --- a/clang/lib/Lex/DependencyDirectivesScanner.cpp +++ b/clang/lib/Lex/DependencyDirectivesScanner.cpp @@ -62,17 +62,14 @@ struct DirectiveWithTokens { struct Scanner { Scanner(StringRef Input, SmallVectorImpl &Tokens, - DiagnosticsEngine *Diags, SourceLocation InputSourceLoc, - const LangOptions &LangOpts) + DiagnosticsEngine *Diags, SourceLocation InputSourceLoc) : Input(Input), Tokens(Tokens), Diags(Diags), - InputSourceLoc(InputSourceLoc), - LangOpts(getLangOptsForDepScanning(LangOpts)), - TheLexer(InputSourceLoc, this->LangOpts, Input.begin(), Input.begin(), + InputSourceLoc(InputSourceLoc), LangOpts(getLangOptsForDepScanning()), + TheLexer(InputSourceLoc, LangOpts, Input.begin(), Input.begin(), Input.end()) {} - static LangOptions - getLangOptsForDepScanning(const LangOptions &invocationLangOpts) { - LangOptions LangOpts(invocationLangOpts); + static LangOptions getLangOptsForDepScanning() { + LangOptions LangOpts; // Set the lexer to use 'tok::at' for '@', instead of 'tok::unknown'. LangOpts.ObjC = true; LangOpts.LineComment = true; @@ -703,7 +700,7 @@ bool Scanner::lex_Pragma(const char *&First, const char *const End) { SmallVector DiscardTokens; const char *Begin = Buffer.c_str(); Scanner PragmaScanner{StringRef(Begin, Buffer.size()), DiscardTokens, Diags, - InputSourceLoc, LangOptions()}; + InputSourceLoc}; PragmaScanner.TheLexer.setParsingPreprocessorDirective(true); if (PragmaScanner.lexPragma(Begin, Buffer.end())) @@ -953,10 +950,9 @@ bool Scanner::scan(SmallVectorImpl &Directives) { bool clang::scanSourceForDependencyDirectives( StringRef Input, SmallVectorImpl &Tokens, - SmallVectorImpl &Directives, const LangOptions &LangOpts, - DiagnosticsEngine *Diags, SourceLocation InputSourceLoc) { - return Scanner(Input, Tokens, Diags, InputSourceLoc, LangOpts) - .scan(Directives); + SmallVectorImpl &Directives, DiagnosticsEngine *Diags, + SourceLocation InputSourceLoc) { + return Scanner(Input, Tokens, Diags, InputSourceLoc).scan(Directives); } void clang::printDependencyDirectivesAsSource( diff --git a/clang/lib/Lex/PPMacroExpansion.cpp b/clang/lib/Lex/PPMacroExpansion.cpp index 8af4a97d00cb8285e4f1fce23ed8818415acec39..f085b94371644276975afa0f2f9e539e1c18064d 100644 --- a/clang/lib/Lex/PPMacroExpansion.cpp +++ b/clang/lib/Lex/PPMacroExpansion.cpp @@ -226,7 +226,7 @@ void Preprocessor::updateModuleMacroInfo(const IdentifierInfo *II, bool IsSystemMacro = true; bool IsAmbiguous = false; if (auto *MD = Info.MD) { - while (MD && isa(MD)) + while (isa_and_nonnull(MD)) MD = MD->getPrevious(); if (auto *DMD = dyn_cast_or_null(MD)) { MI = DMD->getInfo(); diff --git a/clang/lib/Parse/ParseOpenACC.cpp b/clang/lib/Parse/ParseOpenACC.cpp index 63afc18783a1f7cf652fdacc810d20e1fc863459..0261e8ea3c9b76ab4e081ba08de3dc0bd4a1d3e3 100644 --- a/clang/lib/Parse/ParseOpenACC.cpp +++ b/clang/lib/Parse/ParseOpenACC.cpp @@ -571,6 +571,7 @@ bool doesDirectiveHaveAssociatedStmt(OpenACCDirectiveKind DirKind) { case OpenACCDirectiveKind::Parallel: case OpenACCDirectiveKind::Serial: case OpenACCDirectiveKind::Kernels: + case OpenACCDirectiveKind::Loop: return true; } llvm_unreachable("Unhandled directive->assoc stmt"); @@ -1131,6 +1132,8 @@ Parser::OpenACCClauseParseResult Parser::ParseOpenACCClauseParams( // clause, as we are a 'single token' clause. ParsedClause.setEndLoc(ClauseLoc); } + } else { + ParsedClause.setEndLoc(ClauseLoc); } return OpenACCSuccess( Actions.OpenACC().ActOnClause(ExistingClauses, ParsedClause)); @@ -1447,13 +1450,14 @@ StmtResult Parser::ParseOpenACCDirectiveStmt() { return StmtError(); StmtResult AssocStmt; - + SemaOpenACC::AssociatedStmtRAII AssocStmtRAII(getActions().OpenACC(), + DirInfo.DirKind); if (doesDirectiveHaveAssociatedStmt(DirInfo.DirKind)) { ParsingOpenACCDirectiveRAII DirScope(*this, /*Value=*/false); ParseScope ACCScope(this, getOpenACCScopeFlags(DirInfo.DirKind)); - AssocStmt = getActions().OpenACC().ActOnAssociatedStmt(DirInfo.DirKind, - ParseStatement()); + AssocStmt = getActions().OpenACC().ActOnAssociatedStmt( + DirInfo.StartLoc, DirInfo.DirKind, ParseStatement()); } return getActions().OpenACC().ActOnEndStmtDirective( diff --git a/clang/lib/Parse/ParseStmt.cpp b/clang/lib/Parse/ParseStmt.cpp index c25203243ee49bccf6f78f68eb5a02f242a0722e..16a5b7483ec1c3b6bee991a014c7f4725784e781 100644 --- a/clang/lib/Parse/ParseStmt.cpp +++ b/clang/lib/Parse/ParseStmt.cpp @@ -571,11 +571,8 @@ StmtResult Parser::ParseExprStatement(ParsedStmtContext StmtCtx) { } Token *CurTok = nullptr; - // If the semicolon is missing at the end of REPL input, consider if - // we want to do value printing. Note this is only enabled in C++ mode - // since part of the implementation requires C++ language features. // Note we shouldn't eat the token since the callback needs it. - if (Tok.is(tok::annot_repl_input_end) && Actions.getLangOpts().CPlusPlus) + if (Tok.is(tok::annot_repl_input_end)) CurTok = &Tok; else // Otherwise, eat the semicolon. diff --git a/clang/lib/Sema/AnalysisBasedWarnings.cpp b/clang/lib/Sema/AnalysisBasedWarnings.cpp index b9d0b59ef1db7373bf04c0f05e1559d72d3e40d0..0f604c61fa3af98b11ab90574e14d784ea1652f4 100644 --- a/clang/lib/Sema/AnalysisBasedWarnings.cpp +++ b/clang/lib/Sema/AnalysisBasedWarnings.cpp @@ -442,7 +442,7 @@ static ControlFlowKind CheckFallThrough(AnalysisDeclContext &AC) { if (!live[B->getBlockID()]) { if (B->pred_begin() == B->pred_end()) { const Stmt *Term = B->getTerminatorStmt(); - if (Term && isa(Term)) + if (isa_and_nonnull(Term)) // When not adding EH edges from calls, catch clauses // can otherwise seem dead. Avoid noting them as dead. count += reachable_code::ScanReachableFromBlock(B, live); @@ -1100,7 +1100,7 @@ namespace { // issue a warn_fallthrough_attr_unreachable for them. for (const auto *B : *Cfg) { const Stmt *L = B->getLabel(); - if (L && isa(L) && ReachableBlocks.insert(B).second) + if (isa_and_nonnull(L) && ReachableBlocks.insert(B).second) BlockQueue.push_back(B); } @@ -1128,7 +1128,7 @@ namespace { if (!P) continue; const Stmt *Term = P->getTerminatorStmt(); - if (Term && isa(Term)) + if (isa_and_nonnull(Term)) continue; // Switch statement, good. const SwitchCase *SW = dyn_cast_or_null(P->getLabel()); @@ -1327,7 +1327,7 @@ static void DiagnoseSwitchLabelsFallthrough(Sema &S, AnalysisDeclContext &AC, B = *B->succ_begin(); Term = B->getTerminatorStmt(); } - if (!(B->empty() && Term && isa(Term))) { + if (!(B->empty() && isa_and_nonnull(Term))) { Preprocessor &PP = S.getPreprocessor(); StringRef AnnotationSpelling = getFallthroughAttrSpelling(PP, L); SmallString<64> TextToInsert(AnnotationSpelling); diff --git a/clang/lib/Sema/Scope.cpp b/clang/lib/Sema/Scope.cpp index c08073e80ff3dcecafc777942dcbfa05cde2621a..5bc7e79a681869c32c38f7d54064393d896fe311 100644 --- a/clang/lib/Sema/Scope.cpp +++ b/clang/lib/Sema/Scope.cpp @@ -228,7 +228,11 @@ void Scope::dumpImpl(raw_ostream &OS) const { {CompoundStmtScope, "CompoundStmtScope"}, {ClassInheritanceScope, "ClassInheritanceScope"}, {CatchScope, "CatchScope"}, + {ConditionVarScope, "ConditionVarScope"}, + {OpenMPOrderClauseScope, "OpenMPOrderClauseScope"}, + {LambdaScope, "LambdaScope"}, {OpenACCComputeConstructScope, "OpenACCComputeConstructScope"}, + {TypeAliasScope, "TypeAliasScope"}, {FriendScope, "FriendScope"}, }; diff --git a/clang/lib/Sema/SemaAMDGPU.cpp b/clang/lib/Sema/SemaAMDGPU.cpp index c446cc1d042a4a60b0c68ec5212228fb49c180e8..d11bc9eec3301943bd3a431e372d554c8f10ba3e 100644 --- a/clang/lib/Sema/SemaAMDGPU.cpp +++ b/clang/lib/Sema/SemaAMDGPU.cpp @@ -31,9 +31,9 @@ bool SemaAMDGPU::CheckAMDGCNBuiltinFunctionCall(unsigned BuiltinID, constexpr const int SizeIdx = 2; llvm::APSInt Size; Expr *ArgExpr = TheCall->getArg(SizeIdx); - ExprResult R = SemaRef.VerifyIntegerConstantExpression(ArgExpr, &Size); - if (R.isInvalid()) - return true; + [[maybe_unused]] ExprResult R = + SemaRef.VerifyIntegerConstantExpression(ArgExpr, &Size); + assert(!R.isInvalid()); switch (Size.getSExtValue()) { case 1: case 2: diff --git a/clang/lib/Sema/SemaAvailability.cpp b/clang/lib/Sema/SemaAvailability.cpp index 330cd602297d46d7914180b4789e6a33887c6a79..3e5f90b450367b5cc8cc48592bd976a8064f2b7c 100644 --- a/clang/lib/Sema/SemaAvailability.cpp +++ b/clang/lib/Sema/SemaAvailability.cpp @@ -12,6 +12,7 @@ #include "clang/AST/Attr.h" #include "clang/AST/Decl.h" +#include "clang/AST/DeclTemplate.h" #include "clang/AST/RecursiveASTVisitor.h" #include "clang/Basic/DiagnosticSema.h" #include "clang/Basic/IdentifierTable.h" @@ -46,6 +47,10 @@ static const AvailabilityAttr *getAttrForPlatform(ASTContext &Context, // Check each AvailabilityAttr to find the one for this platform. // For multiple attributes with the same platform try to find one for this // environment. + // The attribute is always on the FunctionDecl, not on the + // FunctionTemplateDecl. + if (const auto *FTD = dyn_cast(D)) + D = FTD->getTemplatedDecl(); for (const auto *A : D->attrs()) { if (const auto *Avail = dyn_cast(A)) { // FIXME: this is copied from CheckAvailability. We should try to diff --git a/clang/lib/Sema/SemaCUDA.cpp b/clang/lib/Sema/SemaCUDA.cpp index 80ea43dc5316eb2932c4a339c8f3115edb1b6171..580b9872c6a1def607eca70f60f8a76c4685add4 100644 --- a/clang/lib/Sema/SemaCUDA.cpp +++ b/clang/lib/Sema/SemaCUDA.cpp @@ -1018,24 +1018,33 @@ void SemaCUDA::checkTargetOverload(FunctionDecl *NewFD, // HD/global functions "exist" in some sense on both the host and device, so // should have the same implementation on both sides. if (NewTarget != OldTarget && - ((NewTarget == CUDAFunctionTarget::HostDevice && - !(getLangOpts().OffloadImplicitHostDeviceTemplates && - isImplicitHostDeviceFunction(NewFD) && - OldTarget == CUDAFunctionTarget::Device)) || - (OldTarget == CUDAFunctionTarget::HostDevice && - !(getLangOpts().OffloadImplicitHostDeviceTemplates && - isImplicitHostDeviceFunction(OldFD) && - NewTarget == CUDAFunctionTarget::Device)) || - (NewTarget == CUDAFunctionTarget::Global) || - (OldTarget == CUDAFunctionTarget::Global)) && !SemaRef.IsOverload(NewFD, OldFD, /* UseMemberUsingDeclRules = */ false, /* ConsiderCudaAttrs = */ false)) { - Diag(NewFD->getLocation(), diag::err_cuda_ovl_target) - << llvm::to_underlying(NewTarget) << NewFD->getDeclName() - << llvm::to_underlying(OldTarget) << OldFD; - Diag(OldFD->getLocation(), diag::note_previous_declaration); - NewFD->setInvalidDecl(); - break; + if ((NewTarget == CUDAFunctionTarget::HostDevice && + !(getLangOpts().OffloadImplicitHostDeviceTemplates && + isImplicitHostDeviceFunction(NewFD) && + OldTarget == CUDAFunctionTarget::Device)) || + (OldTarget == CUDAFunctionTarget::HostDevice && + !(getLangOpts().OffloadImplicitHostDeviceTemplates && + isImplicitHostDeviceFunction(OldFD) && + NewTarget == CUDAFunctionTarget::Device)) || + (NewTarget == CUDAFunctionTarget::Global) || + (OldTarget == CUDAFunctionTarget::Global)) { + Diag(NewFD->getLocation(), diag::err_cuda_ovl_target) + << llvm::to_underlying(NewTarget) << NewFD->getDeclName() + << llvm::to_underlying(OldTarget) << OldFD; + Diag(OldFD->getLocation(), diag::note_previous_declaration); + NewFD->setInvalidDecl(); + break; + } + if ((NewTarget == CUDAFunctionTarget::Host && + OldTarget == CUDAFunctionTarget::Device) || + (NewTarget == CUDAFunctionTarget::Device && + OldTarget == CUDAFunctionTarget::Host)) { + Diag(NewFD->getLocation(), diag::warn_offload_incompatible_redeclare) + << llvm::to_underlying(NewTarget) << llvm::to_underlying(OldTarget); + Diag(OldFD->getLocation(), diag::note_previous_declaration); + } } } } diff --git a/clang/lib/Sema/SemaCXXScopeSpec.cpp b/clang/lib/Sema/SemaCXXScopeSpec.cpp index c405fbc0aa421be9702cd23c3b23eb008fa60b1c..da88b6cae6e361ba3327096a47e3ba169ede27f5 100644 --- a/clang/lib/Sema/SemaCXXScopeSpec.cpp +++ b/clang/lib/Sema/SemaCXXScopeSpec.cpp @@ -974,7 +974,7 @@ bool Sema::ActOnCXXNestedNameSpecifier(Scope *S, R.setBegin(SS.getRange().getBegin()); Diag(CCLoc, diag::err_non_type_template_in_nested_name_specifier) - << (TD && isa(TD)) << Template << R; + << isa_and_nonnull(TD) << Template << R; NoteAllFoundTemplates(Template); return true; } diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp index 300af02239779f57b309351eece6a9cdcbfee796..07cd0727eb3f4a2cb68c1c990a53858b0efd4ae0 100644 --- a/clang/lib/Sema/SemaChecking.cpp +++ b/clang/lib/Sema/SemaChecking.cpp @@ -3839,11 +3839,11 @@ void Sema::checkCall(NamedDecl *FDecl, const FunctionProtoType *Proto, if (CallType != VariadicDoesNotApply && (!FD || FD->getBuiltinID() != Builtin::BI__noop)) { unsigned NumParams = Proto ? Proto->getNumParams() - : FDecl && isa(FDecl) - ? cast(FDecl)->getNumParams() - : FDecl && isa(FDecl) - ? cast(FDecl)->param_size() - : 0; + : isa_and_nonnull(FDecl) + ? cast(FDecl)->getNumParams() + : isa_and_nonnull(FDecl) + ? cast(FDecl)->param_size() + : 0; for (unsigned ArgIdx = NumParams; ArgIdx < Args.size(); ++ArgIdx) { // Args[ArgIdx] can be null in malformed code. diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index a6734ef8c30aa8b6c35b29d8239089ea32d09e7d..4b9b735f1cfb43a9735117a7dcfb18d06ef6e7ce 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -2288,7 +2288,8 @@ void Sema::ActOnPopScope(SourceLocation Loc, Scope *S) { // Partial translation units that are created in incremental processing must // not clean up the IdResolver because PTUs should take into account the // declarations that came from previous PTUs. - if (!PP.isIncrementalProcessingEnabled() || getLangOpts().ObjC) + if (!PP.isIncrementalProcessingEnabled() || getLangOpts().ObjC || + getLangOpts().CPlusPlus) IdResolver.RemoveDecl(D); // Warn on it if we are shadowing a declaration. diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp index 3c28da1b077cd5f6dab90ae998b9f78fedde432a..37f0df2a6a27d5ff65bdc1e077ac6f33a986c881 100644 --- a/clang/lib/Sema/SemaDeclCXX.cpp +++ b/clang/lib/Sema/SemaDeclCXX.cpp @@ -1806,6 +1806,7 @@ static unsigned getRecordDiagFromTagKind(TagTypeKind Tag) { static bool CheckConstexprFunctionBody(Sema &SemaRef, const FunctionDecl *Dcl, Stmt *Body, Sema::CheckConstexprKind Kind); +static bool CheckConstexprMissingReturn(Sema &SemaRef, const FunctionDecl *Dcl); // Check whether a function declaration satisfies the requirements of a // constexpr function definition or a constexpr constructor definition. If so, @@ -2411,20 +2412,9 @@ static bool CheckConstexprFunctionBody(Sema &SemaRef, const FunctionDecl *Dcl, } } else { if (ReturnStmts.empty()) { - // C++1y doesn't require constexpr functions to contain a 'return' - // statement. We still do, unless the return type might be void, because - // otherwise if there's no return statement, the function cannot - // be used in a core constant expression. - bool OK = SemaRef.getLangOpts().CPlusPlus14 && - (Dcl->getReturnType()->isVoidType() || - Dcl->getReturnType()->isDependentType()); switch (Kind) { case Sema::CheckConstexprKind::Diagnose: - SemaRef.Diag(Dcl->getLocation(), - OK ? diag::warn_cxx11_compat_constexpr_body_no_return - : diag::err_constexpr_body_no_return) - << Dcl->isConsteval(); - if (!OK) + if (!CheckConstexprMissingReturn(SemaRef, Dcl)) return false; break; @@ -2494,6 +2484,28 @@ static bool CheckConstexprFunctionBody(Sema &SemaRef, const FunctionDecl *Dcl, return true; } +static bool CheckConstexprMissingReturn(Sema &SemaRef, + const FunctionDecl *Dcl) { + bool IsVoidOrDependentType = Dcl->getReturnType()->isVoidType() || + Dcl->getReturnType()->isDependentType(); + // Skip emitting a missing return error diagnostic for non-void functions + // since C++23 no longer mandates constexpr functions to yield constant + // expressions. + if (SemaRef.getLangOpts().CPlusPlus23 && !IsVoidOrDependentType) + return true; + + // C++14 doesn't require constexpr functions to contain a 'return' + // statement. We still do, unless the return type might be void, because + // otherwise if there's no return statement, the function cannot + // be used in a core constant expression. + bool OK = SemaRef.getLangOpts().CPlusPlus14 && IsVoidOrDependentType; + SemaRef.Diag(Dcl->getLocation(), + OK ? diag::warn_cxx11_compat_constexpr_body_no_return + : diag::err_constexpr_body_no_return) + << Dcl->isConsteval(); + return OK; +} + bool Sema::CheckImmediateEscalatingFunctionDefinition( FunctionDecl *FD, const sema::FunctionScopeInfo *FSI) { if (!getLangOpts().CPlusPlus20 || !FD->isImmediateEscalating()) @@ -13079,7 +13091,10 @@ NamedDecl *Sema::BuildUsingDeclaration( // A using-declaration shall not name a namespace. if (R.getAsSingle()) { Diag(IdentLoc, diag::err_using_decl_can_not_refer_to_namespace) - << SS.getRange(); + << SS.getRange(); + // Suggest using 'using namespace ...' instead. + Diag(SS.getBeginLoc(), diag::note_namespace_using_decl) + << FixItHint::CreateInsertion(SS.getBeginLoc(), "namespace "); return BuildInvalid(); } diff --git a/clang/lib/Sema/SemaExceptionSpec.cpp b/clang/lib/Sema/SemaExceptionSpec.cpp index 41bf273d12f2f32441253cb75eddb92419281deb..17acfca6b01126213027d3572b45744054b995fd 100644 --- a/clang/lib/Sema/SemaExceptionSpec.cpp +++ b/clang/lib/Sema/SemaExceptionSpec.cpp @@ -1425,6 +1425,7 @@ CanThrowResult Sema::canThrow(const Stmt *S) { // Most statements can throw if any substatement can throw. case Stmt::OpenACCComputeConstructClass: + case Stmt::OpenACCLoopConstructClass: case Stmt::AttributedStmtClass: case Stmt::BreakStmtClass: case Stmt::CapturedStmtClass: diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index a50d5c9d6cdc9b1cdc4981b69f05998ac9dffcb8..76145f291887cbed0c499cb3ccc15cbfd6fa76d3 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -5572,9 +5572,10 @@ ExprResult Sema::BuildCXXDefaultArgExpr(SourceLocation CallLoc, Res = Immediate.TransformInitializer(Param->getInit(), /*NotCopy=*/false); }); - if (Res.isUsable()) - Res = ConvertParamDefaultArgument(Param, Res.get(), - Res.get()->getBeginLoc()); + if (Res.isInvalid()) + return ExprError(); + Res = ConvertParamDefaultArgument(Param, Res.get(), + Res.get()->getBeginLoc()); if (Res.isInvalid()) return ExprError(); Init = Res.get(); @@ -5608,10 +5609,9 @@ ExprResult Sema::BuildCXXDefaultInitExpr(SourceLocation Loc, FieldDecl *Field) { InitializationContext.emplace(Loc, Field, CurContext); Expr *Init = nullptr; - bool HasRewrittenInit = false; bool NestedDefaultChecking = isCheckingDefaultArgumentOrInitializer(); - bool InLifetimeExtendingContext = isInLifetimeExtendingContext(); + EnterExpressionEvaluationContext EvalContext( *this, ExpressionEvaluationContext::PotentiallyEvaluated, Field); @@ -5646,36 +5646,19 @@ ExprResult Sema::BuildCXXDefaultInitExpr(SourceLocation Loc, FieldDecl *Field) { ImmediateCallVisitor V(getASTContext()); if (!NestedDefaultChecking) V.TraverseDecl(Field); - - // CWG1815 - // Support lifetime extension of temporary created by aggregate - // initialization using a default member initializer. We should always rebuild - // the initializer if it contains any temporaries (if the initializer - // expression is an ExprWithCleanups). Then make sure the normal lifetime - // extension code recurses into the default initializer and does lifetime - // extension when warranted. - bool ContainsAnyTemporaries = - isa_and_present(Field->getInClassInitializer()); - if (V.HasImmediateCalls || InLifetimeExtendingContext || - ContainsAnyTemporaries) { - HasRewrittenInit = true; + if (V.HasImmediateCalls) { ExprEvalContexts.back().DelayedDefaultInitializationContext = {Loc, Field, CurContext}; ExprEvalContexts.back().IsCurrentlyCheckingDefaultArgumentOrInitializer = NestedDefaultChecking; - // Pass down lifetime extending flag, and collect temporaries in - // CreateMaterializeTemporaryExpr when we rewrite the call argument. - keepInLifetimeExtendingContext(); + EnsureImmediateInvocationInDefaultArgs Immediate(*this); ExprResult Res; - - // Rebuild CXXDefaultInitExpr might cause diagnostics. - SFINAETrap Trap(*this); runWithSufficientStackSpace(Loc, [&] { Res = Immediate.TransformInitializer(Field->getInClassInitializer(), /*CXXDirectInit=*/false); }); - if (Res.isUsable()) + if (!Res.isInvalid()) Res = ConvertMemberDefaultInitExpression(Field, Res.get(), Loc); if (Res.isInvalid()) { Field->setInvalidDecl(); @@ -5702,7 +5685,7 @@ ExprResult Sema::BuildCXXDefaultInitExpr(SourceLocation Loc, FieldDecl *Field) { return CXXDefaultInitExpr::Create(Context, InitializationContext->Loc, Field, InitializationContext->Context, - HasRewrittenInit ? Init : nullptr); + Init); } // DR1351: @@ -5813,6 +5796,27 @@ static TypoCorrection TryTypoCorrectionForCall(Sema &S, Expr *Fn, return TypoCorrection(); } +// [C++26][[expr.unary.op]/p4 +// A pointer to member is only formed when an explicit & +// is used and its operand is a qualified-id not enclosed in parentheses. +static bool isParenthetizedAndQualifiedAddressOfExpr(Expr *Fn) { + if (!isa(Fn)) + return false; + + Fn = Fn->IgnoreParens(); + + auto *UO = dyn_cast(Fn); + if (!UO || UO->getOpcode() != clang::UO_AddrOf) + return false; + if (auto *DRE = dyn_cast(UO->getSubExpr()->IgnoreParens())) { + assert(isa(DRE->getDecl()) && "expected a function"); + return DRE->hasQualifier(); + } + if (auto *OVL = dyn_cast(UO->getSubExpr()->IgnoreParens())) + return OVL->getQualifier(); + return false; +} + /// ConvertArgumentsForCall - Converts the arguments specified in /// Args/NumArgs to the parameter types of the function FDecl with /// function prototype Proto. Call is the call expression itself, and @@ -5834,8 +5838,10 @@ Sema::ConvertArgumentsForCall(CallExpr *Call, Expr *Fn, // C99 6.5.2.2p7 - the arguments are implicitly converted, as if by // assignment, to the types of the corresponding parameter, ... + + bool AddressOf = isParenthetizedAndQualifiedAddressOfExpr(Fn); bool HasExplicitObjectParameter = - FDecl && FDecl->hasCXXExplicitFunctionObjectParameter(); + !AddressOf && FDecl && FDecl->hasCXXExplicitFunctionObjectParameter(); unsigned ExplicitObjectParameterOffset = HasExplicitObjectParameter ? 1 : 0; unsigned NumParams = Proto->getNumParams(); bool Invalid = false; @@ -6546,7 +6552,7 @@ ExprResult Sema::BuildCallExpr(Scope *Scope, Expr *Fn, SourceLocation LParenLoc, OverloadExpr::FindResult find = OverloadExpr::find(Fn); // We aren't supposed to apply this logic if there's an '&' involved. - if (!find.HasFormOfMemberPointer) { + if (!find.HasFormOfMemberPointer || find.IsAddressOfOperandWithParen) { if (Expr::hasAnyTypeDependentArguments(ArgExprs)) return CallExpr::Create(Context, Fn, ArgExprs, Context.DependentTy, VK_PRValue, RParenLoc, CurFPFeatureOverrides()); diff --git a/clang/lib/Sema/SemaExprCXX.cpp b/clang/lib/Sema/SemaExprCXX.cpp index 4487c618862c5e9efe37385dbad71eaa028c6b5d..f3af8dee6b090ce7ad594c7e371cf8ed68d32ca2 100644 --- a/clang/lib/Sema/SemaExprCXX.cpp +++ b/clang/lib/Sema/SemaExprCXX.cpp @@ -1555,6 +1555,9 @@ Sema::BuildCXXTypeConstructExpr(TypeSourceInfo *TInfo, bool ListInitialization) { QualType Ty = TInfo->getType(); SourceLocation TyBeginLoc = TInfo->getTypeLoc().getBeginLoc(); + + assert((!ListInitialization || Exprs.size() == 1) && + "List initialization must have exactly one expression."); SourceRange FullRange = SourceRange(TyBeginLoc, RParenOrBraceLoc); InitializedEntity Entity = @@ -2071,7 +2074,7 @@ ExprResult Sema::BuildCXXNew(SourceRange Range, bool UseGlobal, if (DirectInitRange.isValid()) { assert(Initializer && "Have parens but no initializer."); InitStyle = CXXNewInitializationStyle::Parens; - } else if (Initializer && isa(Initializer)) + } else if (isa_and_nonnull(Initializer)) InitStyle = CXXNewInitializationStyle::Braces; else { assert((!Initializer || isa(Initializer) || @@ -3820,7 +3823,7 @@ Sema::ActOnCXXDelete(SourceLocation StartLoc, bool UseGlobal, // Otherwise, the usual operator delete[] should be the // function we just found. - else if (OperatorDelete && isa(OperatorDelete)) + else if (isa_and_nonnull(OperatorDelete)) UsualArrayDeleteWantsSize = UsualDeallocFnInfo(*this, DeclAccessPair::make(OperatorDelete, AS_public)) @@ -5126,6 +5129,7 @@ static bool CheckUnaryTypeTraitTypeCompleteness(Sema &S, TypeTrait UTT, case UTT_IsStandardLayout: case UTT_IsPOD: case UTT_IsLiteral: + case UTT_IsBitwiseCloneable: // By analogy, is_trivially_relocatable and is_trivially_equality_comparable // impose the same constraints. case UTT_IsTriviallyRelocatable: @@ -5619,6 +5623,8 @@ static bool EvaluateUnaryTypeTrait(Sema &Self, TypeTrait UTT, return C.hasUniqueObjectRepresentations(T); case UTT_IsTriviallyRelocatable: return T.isTriviallyRelocatableType(C); + case UTT_IsBitwiseCloneable: + return T.isBitwiseCloneableType(C); case UTT_IsReferenceable: return T.isReferenceable(); case UTT_CanPassInRegs: @@ -8589,7 +8595,7 @@ static void CheckIfAnyEnclosingLambdasMustCaptureAnyPotentialCaptures( assert(S.CurContext->isDependentContext()); #ifndef NDEBUG DeclContext *DC = S.CurContext; - while (DC && isa(DC)) + while (isa_and_nonnull(DC)) DC = DC->getParent(); assert( CurrentLSI->CallOperator == DC && @@ -9166,7 +9172,7 @@ ExprResult Sema::ActOnFinishFullExpr(Expr *FE, SourceLocation CC, // - Teach the handful of places that iterate over FunctionScopes to // stop at the outermost enclosing lexical scope." DeclContext *DC = CurContext; - while (DC && isa(DC)) + while (isa_and_nonnull(DC)) DC = DC->getParent(); const bool IsInLambdaDeclContext = isLambdaCallOperator(DC); if (IsInLambdaDeclContext && CurrentLSI && diff --git a/clang/lib/Sema/SemaHLSL.cpp b/clang/lib/Sema/SemaHLSL.cpp index 0a2face7afe65a7048d1509d573f11ca9acbdc01..144cdcc0d98ef14d3413e8755f7a120b3d95989b 100644 --- a/clang/lib/Sema/SemaHLSL.cpp +++ b/clang/lib/Sema/SemaHLSL.cpp @@ -146,7 +146,7 @@ HLSLNumThreadsAttr *SemaHLSL::mergeNumThreadsAttr(Decl *D, HLSLShaderAttr * SemaHLSL::mergeShaderAttr(Decl *D, const AttributeCommonInfo &AL, - HLSLShaderAttr::ShaderType ShaderType) { + llvm::Triple::EnvironmentType ShaderType) { if (HLSLShaderAttr *NT = D->getAttr()) { if (NT->getType() != ShaderType) { Diag(NT->getLocation(), diag::err_hlsl_attribute_param_mismatch) << AL; @@ -184,13 +184,12 @@ void SemaHLSL::ActOnTopLevelFunction(FunctionDecl *FD) { if (FD->getName() != TargetInfo.getTargetOpts().HLSLEntry) return; - StringRef Env = TargetInfo.getTriple().getEnvironmentName(); - HLSLShaderAttr::ShaderType ShaderType; - if (HLSLShaderAttr::ConvertStrToShaderType(Env, ShaderType)) { + llvm::Triple::EnvironmentType Env = TargetInfo.getTriple().getEnvironment(); + if (HLSLShaderAttr::isValidShaderType(Env) && Env != llvm::Triple::Library) { if (const auto *Shader = FD->getAttr()) { // The entry point is already annotated - check that it matches the // triple. - if (Shader->getType() != ShaderType) { + if (Shader->getType() != Env) { Diag(Shader->getLocation(), diag::err_hlsl_entry_shader_attr_mismatch) << Shader; FD->setInvalidDecl(); @@ -198,11 +197,11 @@ void SemaHLSL::ActOnTopLevelFunction(FunctionDecl *FD) { } else { // Implicitly add the shader attribute if the entry function isn't // explicitly annotated. - FD->addAttr(HLSLShaderAttr::CreateImplicit(getASTContext(), ShaderType, + FD->addAttr(HLSLShaderAttr::CreateImplicit(getASTContext(), Env, FD->getBeginLoc())); } } else { - switch (TargetInfo.getTriple().getEnvironment()) { + switch (Env) { case llvm::Triple::UnknownEnvironment: case llvm::Triple::Library: break; @@ -215,38 +214,40 @@ void SemaHLSL::ActOnTopLevelFunction(FunctionDecl *FD) { void SemaHLSL::CheckEntryPoint(FunctionDecl *FD) { const auto *ShaderAttr = FD->getAttr(); assert(ShaderAttr && "Entry point has no shader attribute"); - HLSLShaderAttr::ShaderType ST = ShaderAttr->getType(); + llvm::Triple::EnvironmentType ST = ShaderAttr->getType(); switch (ST) { - case HLSLShaderAttr::Pixel: - case HLSLShaderAttr::Vertex: - case HLSLShaderAttr::Geometry: - case HLSLShaderAttr::Hull: - case HLSLShaderAttr::Domain: - case HLSLShaderAttr::RayGeneration: - case HLSLShaderAttr::Intersection: - case HLSLShaderAttr::AnyHit: - case HLSLShaderAttr::ClosestHit: - case HLSLShaderAttr::Miss: - case HLSLShaderAttr::Callable: + case llvm::Triple::Pixel: + case llvm::Triple::Vertex: + case llvm::Triple::Geometry: + case llvm::Triple::Hull: + case llvm::Triple::Domain: + case llvm::Triple::RayGeneration: + case llvm::Triple::Intersection: + case llvm::Triple::AnyHit: + case llvm::Triple::ClosestHit: + case llvm::Triple::Miss: + case llvm::Triple::Callable: if (const auto *NT = FD->getAttr()) { DiagnoseAttrStageMismatch(NT, ST, - {HLSLShaderAttr::Compute, - HLSLShaderAttr::Amplification, - HLSLShaderAttr::Mesh}); + {llvm::Triple::Compute, + llvm::Triple::Amplification, + llvm::Triple::Mesh}); FD->setInvalidDecl(); } break; - case HLSLShaderAttr::Compute: - case HLSLShaderAttr::Amplification: - case HLSLShaderAttr::Mesh: + case llvm::Triple::Compute: + case llvm::Triple::Amplification: + case llvm::Triple::Mesh: if (!FD->hasAttr()) { Diag(FD->getLocation(), diag::err_hlsl_missing_numthreads) - << HLSLShaderAttr::ConvertShaderTypeToStr(ST); + << llvm::Triple::getEnvironmentTypeName(ST); FD->setInvalidDecl(); } break; + default: + llvm_unreachable("Unhandled environment in triple"); } for (ParmVarDecl *Param : FD->parameters()) { @@ -268,14 +269,14 @@ void SemaHLSL::CheckSemanticAnnotation( const HLSLAnnotationAttr *AnnotationAttr) { auto *ShaderAttr = EntryPoint->getAttr(); assert(ShaderAttr && "Entry point has no shader attribute"); - HLSLShaderAttr::ShaderType ST = ShaderAttr->getType(); + llvm::Triple::EnvironmentType ST = ShaderAttr->getType(); switch (AnnotationAttr->getKind()) { case attr::HLSLSV_DispatchThreadID: case attr::HLSLSV_GroupIndex: - if (ST == HLSLShaderAttr::Compute) + if (ST == llvm::Triple::Compute) return; - DiagnoseAttrStageMismatch(AnnotationAttr, ST, {HLSLShaderAttr::Compute}); + DiagnoseAttrStageMismatch(AnnotationAttr, ST, {llvm::Triple::Compute}); break; default: llvm_unreachable("Unknown HLSLAnnotationAttr"); @@ -283,16 +284,16 @@ void SemaHLSL::CheckSemanticAnnotation( } void SemaHLSL::DiagnoseAttrStageMismatch( - const Attr *A, HLSLShaderAttr::ShaderType Stage, - std::initializer_list AllowedStages) { + const Attr *A, llvm::Triple::EnvironmentType Stage, + std::initializer_list AllowedStages) { SmallVector StageStrings; llvm::transform(AllowedStages, std::back_inserter(StageStrings), - [](HLSLShaderAttr::ShaderType ST) { + [](llvm::Triple::EnvironmentType ST) { return StringRef( - HLSLShaderAttr::ConvertShaderTypeToStr(ST)); + HLSLShaderAttr::ConvertEnvironmentTypeToStr(ST)); }); Diag(A->getLoc(), diag::err_hlsl_attr_unsupported_in_stage) - << A << HLSLShaderAttr::ConvertShaderTypeToStr(Stage) + << A << llvm::Triple::getEnvironmentTypeName(Stage) << (AllowedStages.size() != 1) << join(StageStrings, ", "); } @@ -430,8 +431,8 @@ void SemaHLSL::handleShaderAttr(Decl *D, const ParsedAttr &AL) { if (!SemaRef.checkStringLiteralArgumentAttr(AL, 0, Str, &ArgLoc)) return; - HLSLShaderAttr::ShaderType ShaderType; - if (!HLSLShaderAttr::ConvertStrToShaderType(Str, ShaderType)) { + llvm::Triple::EnvironmentType ShaderType; + if (!HLSLShaderAttr::ConvertStrToEnvironmentType(Str, ShaderType)) { Diag(AL.getLoc(), diag::warn_attribute_type_not_supported) << AL << Str << ArgLoc; return; @@ -549,16 +550,22 @@ class DiagnoseHLSLAvailability // // Maps FunctionDecl to an unsigned number that represents the set of shader // environments the function has been scanned for. - // Since HLSLShaderAttr::ShaderType enum is generated from Attr.td and is - // defined without any assigned values, it is guaranteed to be numbered - // sequentially from 0 up and we can use it to 'index' individual bits - // in the set. + // The llvm::Triple::EnvironmentType enum values for shader stages guaranteed + // to be numbered from llvm::Triple::Pixel to llvm::Triple::Amplification + // (verified by static_asserts in Triple.cpp), we can use it to index + // individual bits in the set, as long as we shift the values to start with 0 + // by subtracting the value of llvm::Triple::Pixel first. + // // The N'th bit in the set will be set if the function has been scanned - // in shader environment whose ShaderType integer value equals N. + // in shader environment whose llvm::Triple::EnvironmentType integer value + // equals (llvm::Triple::Pixel + N). + // // For example, if a function has been scanned in compute and pixel stage - // environment, the value will be 0x21 (100001 binary) because - // (int)HLSLShaderAttr::ShaderType::Pixel == 1 and - // (int)HLSLShaderAttr::ShaderType::Compute == 5. + // environment, the value will be 0x21 (100001 binary) because: + // + // (int)(llvm::Triple::Pixel - llvm::Triple::Pixel) == 0 + // (int)(llvm::Triple::Compute - llvm::Triple::Pixel) == 5 + // // A FunctionDecl is mapped to 0 (or not included in the map) if it has not // been scanned in any environment. llvm::DenseMap ScannedDecls; @@ -574,12 +581,16 @@ class DiagnoseHLSLAvailability bool ReportOnlyShaderStageIssues; // Helper methods for dealing with current stage context / environment - void SetShaderStageContext(HLSLShaderAttr::ShaderType ShaderType) { + void SetShaderStageContext(llvm::Triple::EnvironmentType ShaderType) { static_assert(sizeof(unsigned) >= 4); - assert((unsigned)ShaderType < 31); // 31 is reserved for "unknown" - - CurrentShaderEnvironment = HLSLShaderAttr::getTypeAsEnvironment(ShaderType); - CurrentShaderStageBit = (1 << ShaderType); + assert(HLSLShaderAttr::isValidShaderType(ShaderType)); + assert((unsigned)(ShaderType - llvm::Triple::Pixel) < 31 && + "ShaderType is too big for this bitmap"); // 31 is reserved for + // "unknown" + + unsigned bitmapIndex = ShaderType - llvm::Triple::Pixel; + CurrentShaderEnvironment = ShaderType; + CurrentShaderStageBit = (1 << bitmapIndex); } void SetUnknownShaderStageContext() { diff --git a/clang/lib/Sema/SemaInit.cpp b/clang/lib/Sema/SemaInit.cpp index 9ed3e8a0df025227bbac7f817c101a9bff7d09af..7244f3ef4e829e1b1062499c6d10a3db187cea31 100644 --- a/clang/lib/Sema/SemaInit.cpp +++ b/clang/lib/Sema/SemaInit.cpp @@ -2194,7 +2194,7 @@ void InitListChecker::CheckStructUnionTypes( // Designated inits always initialize fields, so if we see one, all // remaining base classes have no explicit initializer. - if (Init && isa(Init)) + if (isa_and_nonnull(Init)) Init = nullptr; // C++ [over.match.class.deduct]p1.6: @@ -6350,7 +6350,7 @@ void InitializationSequence::InitializeFrom(Sema &S, // class member of array type from a parenthesized initializer list. else if (S.getLangOpts().CPlusPlus && Entity.getKind() == InitializedEntity::EK_Member && - Initializer && isa(Initializer)) { + isa_and_nonnull(Initializer)) { TryListInitialization(S, Entity, Kind, cast(Initializer), *this, TreatUnavailableAsInvalid); AddParenthesizedArrayInitStep(DestType); @@ -8063,6 +8063,11 @@ static void visitLocalsRetainedByInitializer(IndirectLocalPath &Path, enum PathLifetimeKind { /// Lifetime-extend along this path. Extend, + /// We should lifetime-extend, but we don't because (due to technical + /// limitations) we can't. This happens for default member initializers, + /// which we don't clone for every use, so we don't have a unique + /// MaterializeTemporaryExpr to update. + ShouldExtend, /// Do not lifetime extend along this path. NoExtend }; @@ -8074,7 +8079,7 @@ shouldLifetimeExtendThroughPath(const IndirectLocalPath &Path) { PathLifetimeKind Kind = PathLifetimeKind::Extend; for (auto Elem : Path) { if (Elem.Kind == IndirectLocalPathEntry::DefaultInit) - Kind = PathLifetimeKind::Extend; + Kind = PathLifetimeKind::ShouldExtend; else if (Elem.Kind != IndirectLocalPathEntry::LambdaCaptureInit) return PathLifetimeKind::NoExtend; } @@ -8194,6 +8199,18 @@ void Sema::checkInitializerLifetime(const InitializedEntity &Entity, ExtendingEntity->allocateManglingNumber()); // Also visit the temporaries lifetime-extended by this initializer. return true; + + case PathLifetimeKind::ShouldExtend: + // We're supposed to lifetime-extend the temporary along this path (per + // the resolution of DR1815), but we don't support that yet. + // + // FIXME: Properly handle this situation. Perhaps the easiest approach + // would be to clone the initializer expression on each use that would + // lifetime extend its temporaries. + Diag(DiagLoc, diag::warn_unsupported_lifetime_extension) + << RK << DiagRange; + break; + case PathLifetimeKind::NoExtend: // If the path goes through the initialization of a variable or field, // it can't possibly reach a temporary created in this full-expression. @@ -8776,7 +8793,7 @@ ExprResult InitializationSequence::Perform(Sema &S, // constant expressions here in order to perform narrowing checks =( EnterExpressionEvaluationContext Evaluated( S, EnterExpressionEvaluationContext::InitList, - CurInit.get() && isa(CurInit.get())); + isa_and_nonnull(CurInit.get())); // C++ [class.abstract]p2: // no objects of an abstract class can be created except as subobjects diff --git a/clang/lib/Sema/SemaOpenACC.cpp b/clang/lib/Sema/SemaOpenACC.cpp index 5b4d01860c0bd4b19df5aa440233cbc7d9857075..97586a037eee4c17d7994f8e0480fd24f42b14c7 100644 --- a/clang/lib/Sema/SemaOpenACC.cpp +++ b/clang/lib/Sema/SemaOpenACC.cpp @@ -33,6 +33,7 @@ bool diagnoseConstructAppertainment(SemaOpenACC &S, OpenACCDirectiveKind K, case OpenACCDirectiveKind::Parallel: case OpenACCDirectiveKind::Serial: case OpenACCDirectiveKind::Kernels: + case OpenACCDirectiveKind::Loop: if (!IsStmt) return S.Diag(StartLoc, diag::err_acc_construct_appertainment) << K; break; @@ -284,6 +285,30 @@ bool doesClauseApplyToDirective(OpenACCDirectiveKind DirectiveKind, return false; } + case OpenACCClauseKind::Seq: + switch (DirectiveKind) { + case OpenACCDirectiveKind::Loop: + case OpenACCDirectiveKind::Routine: + case OpenACCDirectiveKind::ParallelLoop: + case OpenACCDirectiveKind::SerialLoop: + case OpenACCDirectiveKind::KernelsLoop: + return true; + default: + return false; + } + + case OpenACCClauseKind::Independent: + case OpenACCClauseKind::Auto: + switch (DirectiveKind) { + case OpenACCDirectiveKind::Loop: + case OpenACCDirectiveKind::ParallelLoop: + case OpenACCDirectiveKind::SerialLoop: + case OpenACCDirectiveKind::KernelsLoop: + return true; + default: + return false; + } + case OpenACCClauseKind::Reduction: switch (DirectiveKind) { case OpenACCDirectiveKind::Parallel: @@ -340,519 +365,795 @@ bool checkAlreadyHasClauseOfKind( return false; } -/// Implement check from OpenACC3.3: section 2.5.4: -/// Only the async, wait, num_gangs, num_workers, and vector_length clauses may -/// follow a device_type clause. bool checkValidAfterDeviceType( SemaOpenACC &S, const OpenACCDeviceTypeClause &DeviceTypeClause, const SemaOpenACC::OpenACCParsedClause &NewClause) { - // This is only a requirement on compute constructs so far, so this is fine - // otherwise. - if (!isOpenACCComputeDirectiveKind(NewClause.getDirectiveKind())) + // This is only a requirement on compute and loop constructs so far, so this + // is fine otherwise. + if (!isOpenACCComputeDirectiveKind(NewClause.getDirectiveKind()) && + NewClause.getDirectiveKind() != OpenACCDirectiveKind::Loop) return false; - switch (NewClause.getClauseKind()) { - case OpenACCClauseKind::Async: - case OpenACCClauseKind::Wait: - case OpenACCClauseKind::NumGangs: - case OpenACCClauseKind::NumWorkers: - case OpenACCClauseKind::VectorLength: - case OpenACCClauseKind::DType: - case OpenACCClauseKind::DeviceType: + + // OpenACC3.3: Section 2.4: Clauses that precede any device_type clause are + // default clauses. Clauses that follow a device_type clause up to the end of + // the directive or up to the next device_type clause are device-specific + // clauses for the device types specified in the device_type argument. + // + // The above implies that despite what the individual text says, these are + // valid. + if (NewClause.getClauseKind() == OpenACCClauseKind::DType || + NewClause.getClauseKind() == OpenACCClauseKind::DeviceType) return false; - default: - S.Diag(NewClause.getBeginLoc(), diag::err_acc_clause_after_device_type) - << NewClause.getClauseKind() << DeviceTypeClause.getClauseKind(); - S.Diag(DeviceTypeClause.getBeginLoc(), diag::note_acc_previous_clause_here); - return true; + + // Implement check from OpenACC3.3: section 2.5.4: + // Only the async, wait, num_gangs, num_workers, and vector_length clauses may + // follow a device_type clause. + if (isOpenACCComputeDirectiveKind(NewClause.getDirectiveKind())) { + switch (NewClause.getClauseKind()) { + case OpenACCClauseKind::Async: + case OpenACCClauseKind::Wait: + case OpenACCClauseKind::NumGangs: + case OpenACCClauseKind::NumWorkers: + case OpenACCClauseKind::VectorLength: + return false; + default: + break; + } + } else if (NewClause.getDirectiveKind() == OpenACCDirectiveKind::Loop) { + // Implement check from OpenACC3.3: section 2.9: + // Only the collapse, gang, worker, vector, seq, independent, auto, and tile + // clauses may follow a device_type clause. + switch (NewClause.getClauseKind()) { + case OpenACCClauseKind::Collapse: + case OpenACCClauseKind::Gang: + case OpenACCClauseKind::Worker: + case OpenACCClauseKind::Vector: + case OpenACCClauseKind::Seq: + case OpenACCClauseKind::Independent: + case OpenACCClauseKind::Auto: + case OpenACCClauseKind::Tile: + return false; + default: + break; + } } + S.Diag(NewClause.getBeginLoc(), diag::err_acc_clause_after_device_type) + << NewClause.getClauseKind() << DeviceTypeClause.getClauseKind() + << isOpenACCComputeDirectiveKind(NewClause.getDirectiveKind()) + << NewClause.getDirectiveKind(); + S.Diag(DeviceTypeClause.getBeginLoc(), diag::note_acc_previous_clause_here); + return true; } -} // namespace -SemaOpenACC::SemaOpenACC(Sema &S) : SemaBase(S) {} +class SemaOpenACCClauseVisitor { + SemaOpenACC &SemaRef; + ASTContext &Ctx; + ArrayRef ExistingClauses; + bool NotImplemented = false; -OpenACCClause * -SemaOpenACC::ActOnClause(ArrayRef ExistingClauses, - OpenACCParsedClause &Clause) { - if (Clause.getClauseKind() == OpenACCClauseKind::Invalid) + OpenACCClause *isNotImplemented() { + NotImplemented = true; return nullptr; + } - // Diagnose that we don't support this clause on this directive. - if (!doesClauseApplyToDirective(Clause.getDirectiveKind(), - Clause.getClauseKind())) { - Diag(Clause.getBeginLoc(), diag::err_acc_clause_appertainment) - << Clause.getDirectiveKind() << Clause.getClauseKind(); - return nullptr; +public: + SemaOpenACCClauseVisitor(SemaOpenACC &S, + ArrayRef ExistingClauses) + : SemaRef(S), Ctx(S.getASTContext()), ExistingClauses(ExistingClauses) {} + // Once we've implemented everything, we shouldn't need this infrastructure. + // But in the meantime, we use this to help decide whether the clause was + // handled for this directive. + bool diagNotImplemented() { return NotImplemented; } + + OpenACCClause *Visit(SemaOpenACC::OpenACCParsedClause &Clause) { + switch (Clause.getClauseKind()) { + case OpenACCClauseKind::Gang: + case OpenACCClauseKind::Worker: + case OpenACCClauseKind::Vector: { + // TODO OpenACC: These are only implemented enough for the 'seq' diagnostic, + // otherwise treats itself as unimplemented. When we implement these, we + // can remove them from here. + + // OpenACC 3.3 2.9: + // A 'gang', 'worker', or 'vector' clause may not appear if a 'seq' clause + // appears. + const auto *Itr = + llvm::find_if(ExistingClauses, llvm::IsaPred); + + if (Itr != ExistingClauses.end()) { + SemaRef.Diag(Clause.getBeginLoc(), diag::err_acc_clause_cannot_combine) + << Clause.getClauseKind() << (*Itr)->getClauseKind(); + SemaRef.Diag((*Itr)->getBeginLoc(), diag::note_acc_previous_clause_here); + } + return isNotImplemented(); } - if (const auto *DevTypeClause = - llvm::find_if(ExistingClauses, - [&](const OpenACCClause *C) { - return isa(C); - }); - DevTypeClause != ExistingClauses.end()) { - if (checkValidAfterDeviceType( - *this, *cast(*DevTypeClause), Clause)) - return nullptr; +#define VISIT_CLAUSE(CLAUSE_NAME) \ + case OpenACCClauseKind::CLAUSE_NAME: \ + return Visit##CLAUSE_NAME##Clause(Clause); +#define CLAUSE_ALIAS(ALIAS, CLAUSE_NAME, DEPRECATED) \ + case OpenACCClauseKind::ALIAS: \ + if (DEPRECATED) \ + SemaRef.Diag(Clause.getBeginLoc(), diag::warn_acc_deprecated_alias_name) \ + << Clause.getClauseKind() << OpenACCClauseKind::CLAUSE_NAME; \ + return Visit##CLAUSE_NAME##Clause(Clause); +#include "clang/Basic/OpenACCClauses.def" + default: + return isNotImplemented(); + } + llvm_unreachable("Invalid clause kind"); } - switch (Clause.getClauseKind()) { - case OpenACCClauseKind::Default: { - // Restrictions only properly implemented on 'compute' constructs, and - // 'compute' constructs are the only construct that can do anything with - // this yet, so skip/treat as unimplemented in this case. - if (!isOpenACCComputeDirectiveKind(Clause.getDirectiveKind())) - break; +#define VISIT_CLAUSE(CLAUSE_NAME) \ + OpenACCClause *Visit##CLAUSE_NAME##Clause( \ + SemaOpenACC::OpenACCParsedClause &Clause); +#include "clang/Basic/OpenACCClauses.def" +}; - // Don't add an invalid clause to the AST. - if (Clause.getDefaultClauseKind() == OpenACCDefaultClauseKind::Invalid) - return nullptr; +OpenACCClause *SemaOpenACCClauseVisitor::VisitDefaultClause( + SemaOpenACC::OpenACCParsedClause &Clause) { + // Restrictions only properly implemented on 'compute' constructs, and + // 'compute' constructs are the only construct that can do anything with + // this yet, so skip/treat as unimplemented in this case. + if (!isOpenACCComputeDirectiveKind(Clause.getDirectiveKind())) + return isNotImplemented(); + + // Don't add an invalid clause to the AST. + if (Clause.getDefaultClauseKind() == OpenACCDefaultClauseKind::Invalid) + return nullptr; - // OpenACC 3.3, Section 2.5.4: - // At most one 'default' clause may appear, and it must have a value of - // either 'none' or 'present'. - // Second half of the sentence is diagnosed during parsing. - if (checkAlreadyHasClauseOfKind(*this, ExistingClauses, Clause)) - return nullptr; + // OpenACC 3.3, Section 2.5.4: + // At most one 'default' clause may appear, and it must have a value of + // either 'none' or 'present'. + // Second half of the sentence is diagnosed during parsing. + if (checkAlreadyHasClauseOfKind(SemaRef, ExistingClauses, Clause)) + return nullptr; - return OpenACCDefaultClause::Create( - getASTContext(), Clause.getDefaultClauseKind(), Clause.getBeginLoc(), - Clause.getLParenLoc(), Clause.getEndLoc()); - } + return OpenACCDefaultClause::Create( + Ctx, Clause.getDefaultClauseKind(), Clause.getBeginLoc(), + Clause.getLParenLoc(), Clause.getEndLoc()); +} - case OpenACCClauseKind::If: { - // Restrictions only properly implemented on 'compute' constructs, and - // 'compute' constructs are the only construct that can do anything with - // this yet, so skip/treat as unimplemented in this case. - if (!isOpenACCComputeDirectiveKind(Clause.getDirectiveKind())) - break; +OpenACCClause *SemaOpenACCClauseVisitor::VisitIfClause( + SemaOpenACC::OpenACCParsedClause &Clause) { + // Restrictions only properly implemented on 'compute' constructs, and + // 'compute' constructs are the only construct that can do anything with + // this yet, so skip/treat as unimplemented in this case. + if (!isOpenACCComputeDirectiveKind(Clause.getDirectiveKind())) + return isNotImplemented(); + + // There is no prose in the standard that says duplicates aren't allowed, + // but this diagnostic is present in other compilers, as well as makes + // sense. + if (checkAlreadyHasClauseOfKind(SemaRef, ExistingClauses, Clause)) + return nullptr; - // There is no prose in the standard that says duplicates aren't allowed, - // but this diagnostic is present in other compilers, as well as makes - // sense. - if (checkAlreadyHasClauseOfKind(*this, ExistingClauses, Clause)) - return nullptr; + // The parser has ensured that we have a proper condition expr, so there + // isn't really much to do here. - // The parser has ensured that we have a proper condition expr, so there - // isn't really much to do here. + // If the 'if' clause is true, it makes the 'self' clause have no effect, + // diagnose that here. + // TODO OpenACC: When we add these two to other constructs, we might not + // want to warn on this (for example, 'update'). + const auto *Itr = + llvm::find_if(ExistingClauses, llvm::IsaPred); + if (Itr != ExistingClauses.end()) { + SemaRef.Diag(Clause.getBeginLoc(), diag::warn_acc_if_self_conflict); + SemaRef.Diag((*Itr)->getBeginLoc(), diag::note_acc_previous_clause_here); + } - // If the 'if' clause is true, it makes the 'self' clause have no effect, - // diagnose that here. - // TODO OpenACC: When we add these two to other constructs, we might not - // want to warn on this (for example, 'update'). - const auto *Itr = - llvm::find_if(ExistingClauses, llvm::IsaPred); - if (Itr != ExistingClauses.end()) { - Diag(Clause.getBeginLoc(), diag::warn_acc_if_self_conflict); - Diag((*Itr)->getBeginLoc(), diag::note_acc_previous_clause_here); - } + return OpenACCIfClause::Create(Ctx, Clause.getBeginLoc(), + Clause.getLParenLoc(), + Clause.getConditionExpr(), Clause.getEndLoc()); +} - return OpenACCIfClause::Create( - getASTContext(), Clause.getBeginLoc(), Clause.getLParenLoc(), - Clause.getConditionExpr(), Clause.getEndLoc()); - } +OpenACCClause *SemaOpenACCClauseVisitor::VisitSelfClause( + SemaOpenACC::OpenACCParsedClause &Clause) { + // Restrictions only properly implemented on 'compute' constructs, and + // 'compute' constructs are the only construct that can do anything with + // this yet, so skip/treat as unimplemented in this case. + if (!isOpenACCComputeDirectiveKind(Clause.getDirectiveKind())) + return isNotImplemented(); + + // TODO OpenACC: When we implement this for 'update', this takes a + // 'var-list' instead of a condition expression, so semantics/handling has + // to happen differently here. + + // There is no prose in the standard that says duplicates aren't allowed, + // but this diagnostic is present in other compilers, as well as makes + // sense. + if (checkAlreadyHasClauseOfKind(SemaRef, ExistingClauses, Clause)) + return nullptr; - case OpenACCClauseKind::Self: { - // Restrictions only properly implemented on 'compute' constructs, and - // 'compute' constructs are the only construct that can do anything with - // this yet, so skip/treat as unimplemented in this case. - if (!isOpenACCComputeDirectiveKind(Clause.getDirectiveKind())) - break; + // If the 'if' clause is true, it makes the 'self' clause have no effect, + // diagnose that here. + // TODO OpenACC: When we add these two to other constructs, we might not + // want to warn on this (for example, 'update'). + const auto *Itr = + llvm::find_if(ExistingClauses, llvm::IsaPred); + if (Itr != ExistingClauses.end()) { + SemaRef.Diag(Clause.getBeginLoc(), diag::warn_acc_if_self_conflict); + SemaRef.Diag((*Itr)->getBeginLoc(), diag::note_acc_previous_clause_here); + } + return OpenACCSelfClause::Create( + Ctx, Clause.getBeginLoc(), Clause.getLParenLoc(), + Clause.getConditionExpr(), Clause.getEndLoc()); +} - // TODO OpenACC: When we implement this for 'update', this takes a - // 'var-list' instead of a condition expression, so semantics/handling has - // to happen differently here. +OpenACCClause *SemaOpenACCClauseVisitor::VisitNumGangsClause( + SemaOpenACC::OpenACCParsedClause &Clause) { + // Restrictions only properly implemented on 'compute' constructs, and + // 'compute' constructs are the only construct that can do anything with + // this yet, so skip/treat as unimplemented in this case. + if (!isOpenACCComputeDirectiveKind(Clause.getDirectiveKind())) + return isNotImplemented(); + + // There is no prose in the standard that says duplicates aren't allowed, + // but this diagnostic is present in other compilers, as well as makes + // sense. + if (checkAlreadyHasClauseOfKind(SemaRef, ExistingClauses, Clause)) + return nullptr; - // There is no prose in the standard that says duplicates aren't allowed, - // but this diagnostic is present in other compilers, as well as makes - // sense. - if (checkAlreadyHasClauseOfKind(*this, ExistingClauses, Clause)) + // num_gangs requires at least 1 int expr in all forms. Diagnose here, but + // allow us to continue, an empty clause might be useful for future + // diagnostics. + if (Clause.getIntExprs().empty()) + SemaRef.Diag(Clause.getBeginLoc(), diag::err_acc_num_gangs_num_args) + << /*NoArgs=*/0; + + unsigned MaxArgs = + (Clause.getDirectiveKind() == OpenACCDirectiveKind::Parallel || + Clause.getDirectiveKind() == OpenACCDirectiveKind::ParallelLoop) + ? 3 + : 1; + // The max number of args differs between parallel and other constructs. + // Again, allow us to continue for the purposes of future diagnostics. + if (Clause.getIntExprs().size() > MaxArgs) + SemaRef.Diag(Clause.getBeginLoc(), diag::err_acc_num_gangs_num_args) + << /*NoArgs=*/1 << Clause.getDirectiveKind() << MaxArgs + << Clause.getIntExprs().size(); + + // OpenACC 3.3 Section 2.5.4: + // A reduction clause may not appear on a parallel construct with a + // num_gangs clause that has more than one argument. + if (Clause.getDirectiveKind() == OpenACCDirectiveKind::Parallel && + Clause.getIntExprs().size() > 1) { + auto *Parallel = + llvm::find_if(ExistingClauses, llvm::IsaPred); + + if (Parallel != ExistingClauses.end()) { + SemaRef.Diag(Clause.getBeginLoc(), + diag::err_acc_reduction_num_gangs_conflict) + << Clause.getIntExprs().size(); + SemaRef.Diag((*Parallel)->getBeginLoc(), + diag::note_acc_previous_clause_here); return nullptr; - - // If the 'if' clause is true, it makes the 'self' clause have no effect, - // diagnose that here. - // TODO OpenACC: When we add these two to other constructs, we might not - // want to warn on this (for example, 'update'). - const auto *Itr = - llvm::find_if(ExistingClauses, llvm::IsaPred); - if (Itr != ExistingClauses.end()) { - Diag(Clause.getBeginLoc(), diag::warn_acc_if_self_conflict); - Diag((*Itr)->getBeginLoc(), diag::note_acc_previous_clause_here); } - - return OpenACCSelfClause::Create( - getASTContext(), Clause.getBeginLoc(), Clause.getLParenLoc(), - Clause.getConditionExpr(), Clause.getEndLoc()); } - case OpenACCClauseKind::NumGangs: { - // Restrictions only properly implemented on 'compute' constructs, and - // 'compute' constructs are the only construct that can do anything with - // this yet, so skip/treat as unimplemented in this case. - if (!isOpenACCComputeDirectiveKind(Clause.getDirectiveKind())) - break; + return OpenACCNumGangsClause::Create( + Ctx, Clause.getBeginLoc(), Clause.getLParenLoc(), Clause.getIntExprs(), + Clause.getEndLoc()); +} - // There is no prose in the standard that says duplicates aren't allowed, - // but this diagnostic is present in other compilers, as well as makes - // sense. - if (checkAlreadyHasClauseOfKind(*this, ExistingClauses, Clause)) - return nullptr; +OpenACCClause *SemaOpenACCClauseVisitor::VisitNumWorkersClause( + SemaOpenACC::OpenACCParsedClause &Clause) { + // Restrictions only properly implemented on 'compute' constructs, and + // 'compute' constructs are the only construct that can do anything with + // this yet, so skip/treat as unimplemented in this case. + if (!isOpenACCComputeDirectiveKind(Clause.getDirectiveKind())) + return isNotImplemented(); + + // There is no prose in the standard that says duplicates aren't allowed, + // but this diagnostic is present in other compilers, as well as makes + // sense. + if (checkAlreadyHasClauseOfKind(SemaRef, ExistingClauses, Clause)) + return nullptr; - if (Clause.getIntExprs().empty()) - Diag(Clause.getBeginLoc(), diag::err_acc_num_gangs_num_args) - << /*NoArgs=*/0; - - unsigned MaxArgs = - (Clause.getDirectiveKind() == OpenACCDirectiveKind::Parallel || - Clause.getDirectiveKind() == OpenACCDirectiveKind::ParallelLoop) - ? 3 - : 1; - if (Clause.getIntExprs().size() > MaxArgs) - Diag(Clause.getBeginLoc(), diag::err_acc_num_gangs_num_args) - << /*NoArgs=*/1 << Clause.getDirectiveKind() << MaxArgs - << Clause.getIntExprs().size(); + assert(Clause.getIntExprs().size() == 1 && + "Invalid number of expressions for NumWorkers"); + return OpenACCNumWorkersClause::Create( + Ctx, Clause.getBeginLoc(), Clause.getLParenLoc(), Clause.getIntExprs()[0], + Clause.getEndLoc()); +} - // OpenACC 3.3 Section 2.5.4: - // A reduction clause may not appear on a parallel construct with a - // num_gangs clause that has more than one argument. - if (Clause.getDirectiveKind() == OpenACCDirectiveKind::Parallel && - Clause.getIntExprs().size() > 1) { - auto *Parallel = - llvm::find_if(ExistingClauses, llvm::IsaPred); - - if (Parallel != ExistingClauses.end()) { - Diag(Clause.getBeginLoc(), diag::err_acc_reduction_num_gangs_conflict) - << Clause.getIntExprs().size(); - Diag((*Parallel)->getBeginLoc(), diag::note_acc_previous_clause_here); - return nullptr; - } - } +OpenACCClause *SemaOpenACCClauseVisitor::VisitVectorLengthClause( + SemaOpenACC::OpenACCParsedClause &Clause) { + // Restrictions only properly implemented on 'compute' constructs, and + // 'compute' constructs are the only construct that can do anything with + // this yet, so skip/treat as unimplemented in this case. + if (!isOpenACCComputeDirectiveKind(Clause.getDirectiveKind())) + return isNotImplemented(); + + // There is no prose in the standard that says duplicates aren't allowed, + // but this diagnostic is present in other compilers, as well as makes + // sense. + if (checkAlreadyHasClauseOfKind(SemaRef, ExistingClauses, Clause)) + return nullptr; - // Create the AST node for the clause even if the number of expressions is - // incorrect. - return OpenACCNumGangsClause::Create( - getASTContext(), Clause.getBeginLoc(), Clause.getLParenLoc(), - Clause.getIntExprs(), Clause.getEndLoc()); - break; - } - case OpenACCClauseKind::NumWorkers: { - // Restrictions only properly implemented on 'compute' constructs, and - // 'compute' constructs are the only construct that can do anything with - // this yet, so skip/treat as unimplemented in this case. - if (!isOpenACCComputeDirectiveKind(Clause.getDirectiveKind())) - break; + assert(Clause.getIntExprs().size() == 1 && + "Invalid number of expressions for NumWorkers"); + return OpenACCVectorLengthClause::Create( + Ctx, Clause.getBeginLoc(), Clause.getLParenLoc(), Clause.getIntExprs()[0], + Clause.getEndLoc()); +} - // There is no prose in the standard that says duplicates aren't allowed, - // but this diagnostic is present in other compilers, as well as makes - // sense. - if (checkAlreadyHasClauseOfKind(*this, ExistingClauses, Clause)) - return nullptr; +OpenACCClause *SemaOpenACCClauseVisitor::VisitAsyncClause( + SemaOpenACC::OpenACCParsedClause &Clause) { + // Restrictions only properly implemented on 'compute' constructs, and + // 'compute' constructs are the only construct that can do anything with + // this yet, so skip/treat as unimplemented in this case. + if (!isOpenACCComputeDirectiveKind(Clause.getDirectiveKind())) + return isNotImplemented(); + + // There is no prose in the standard that says duplicates aren't allowed, + // but this diagnostic is present in other compilers, as well as makes + // sense. + if (checkAlreadyHasClauseOfKind(SemaRef, ExistingClauses, Clause)) + return nullptr; - assert(Clause.getIntExprs().size() == 1 && - "Invalid number of expressions for NumWorkers"); - return OpenACCNumWorkersClause::Create( - getASTContext(), Clause.getBeginLoc(), Clause.getLParenLoc(), - Clause.getIntExprs()[0], Clause.getEndLoc()); - } - case OpenACCClauseKind::VectorLength: { - // Restrictions only properly implemented on 'compute' constructs, and - // 'compute' constructs are the only construct that can do anything with - // this yet, so skip/treat as unimplemented in this case. - if (!isOpenACCComputeDirectiveKind(Clause.getDirectiveKind())) - break; + assert(Clause.getNumIntExprs() < 2 && + "Invalid number of expressions for Async"); + return OpenACCAsyncClause::Create( + Ctx, Clause.getBeginLoc(), Clause.getLParenLoc(), + Clause.getNumIntExprs() != 0 ? Clause.getIntExprs()[0] : nullptr, + Clause.getEndLoc()); +} - // There is no prose in the standard that says duplicates aren't allowed, - // but this diagnostic is present in other compilers, as well as makes - // sense. - if (checkAlreadyHasClauseOfKind(*this, ExistingClauses, Clause)) - return nullptr; +OpenACCClause *SemaOpenACCClauseVisitor::VisitPrivateClause( + SemaOpenACC::OpenACCParsedClause &Clause) { + // Restrictions only properly implemented on 'compute' and 'loop' + // constructs, and 'compute'/'loop' constructs are the only construct that + // can do anything with this yet, so skip/treat as unimplemented in this + // case. + if (!isOpenACCComputeDirectiveKind(Clause.getDirectiveKind()) && + Clause.getDirectiveKind() != OpenACCDirectiveKind::Loop) + return isNotImplemented(); + + // ActOnVar ensured that everything is a valid variable reference, so there + // really isn't anything to do here. GCC does some duplicate-finding, though + // it isn't apparent in the standard where this is justified. + + return OpenACCPrivateClause::Create(Ctx, Clause.getBeginLoc(), + Clause.getLParenLoc(), + Clause.getVarList(), Clause.getEndLoc()); +} - assert(Clause.getIntExprs().size() == 1 && - "Invalid number of expressions for VectorLength"); - return OpenACCVectorLengthClause::Create( - getASTContext(), Clause.getBeginLoc(), Clause.getLParenLoc(), - Clause.getIntExprs()[0], Clause.getEndLoc()); - } - case OpenACCClauseKind::Async: { - // Restrictions only properly implemented on 'compute' constructs, and - // 'compute' constructs are the only construct that can do anything with - // this yet, so skip/treat as unimplemented in this case. - if (!isOpenACCComputeDirectiveKind(Clause.getDirectiveKind())) - break; +OpenACCClause *SemaOpenACCClauseVisitor::VisitFirstPrivateClause( + SemaOpenACC::OpenACCParsedClause &Clause) { + // Restrictions only properly implemented on 'compute' constructs, and + // 'compute' constructs are the only construct that can do anything with + // this yet, so skip/treat as unimplemented in this case. + if (!isOpenACCComputeDirectiveKind(Clause.getDirectiveKind())) + return isNotImplemented(); + + // ActOnVar ensured that everything is a valid variable reference, so there + // really isn't anything to do here. GCC does some duplicate-finding, though + // it isn't apparent in the standard where this is justified. + + return OpenACCFirstPrivateClause::Create( + Ctx, Clause.getBeginLoc(), Clause.getLParenLoc(), Clause.getVarList(), + Clause.getEndLoc()); +} - // There is no prose in the standard that says duplicates aren't allowed, - // but this diagnostic is present in other compilers, as well as makes - // sense. - if (checkAlreadyHasClauseOfKind(*this, ExistingClauses, Clause)) - return nullptr; +OpenACCClause *SemaOpenACCClauseVisitor::VisitNoCreateClause( + SemaOpenACC::OpenACCParsedClause &Clause) { + // Restrictions only properly implemented on 'compute' constructs, and + // 'compute' constructs are the only construct that can do anything with + // this yet, so skip/treat as unimplemented in this case. + if (!isOpenACCComputeDirectiveKind(Clause.getDirectiveKind())) + return isNotImplemented(); + // ActOnVar ensured that everything is a valid variable reference, so there + // really isn't anything to do here. GCC does some duplicate-finding, though + // it isn't apparent in the standard where this is justified. + + return OpenACCNoCreateClause::Create(Ctx, Clause.getBeginLoc(), + Clause.getLParenLoc(), + Clause.getVarList(), Clause.getEndLoc()); +} - assert(Clause.getNumIntExprs() < 2 && - "Invalid number of expressions for Async"); +OpenACCClause *SemaOpenACCClauseVisitor::VisitPresentClause( + SemaOpenACC::OpenACCParsedClause &Clause) { + // Restrictions only properly implemented on 'compute' constructs, and + // 'compute' constructs are the only construct that can do anything with + // this yet, so skip/treat as unimplemented in this case. + if (!isOpenACCComputeDirectiveKind(Clause.getDirectiveKind())) + return isNotImplemented(); + // ActOnVar ensured that everything is a valid variable reference, so there + // really isn't anything to do here. GCC does some duplicate-finding, though + // it isn't apparent in the standard where this is justified. + + return OpenACCPresentClause::Create(Ctx, Clause.getBeginLoc(), + Clause.getLParenLoc(), + Clause.getVarList(), Clause.getEndLoc()); +} - return OpenACCAsyncClause::Create( - getASTContext(), Clause.getBeginLoc(), Clause.getLParenLoc(), - Clause.getNumIntExprs() != 0 ? Clause.getIntExprs()[0] : nullptr, - Clause.getEndLoc()); - } - case OpenACCClauseKind::Private: { - // Restrictions only properly implemented on 'compute' constructs, and - // 'compute' constructs are the only construct that can do anything with - // this yet, so skip/treat as unimplemented in this case. - if (!isOpenACCComputeDirectiveKind(Clause.getDirectiveKind())) - break; +OpenACCClause *SemaOpenACCClauseVisitor::VisitCopyClause( + SemaOpenACC::OpenACCParsedClause &Clause) { + // Restrictions only properly implemented on 'compute' constructs, and + // 'compute' constructs are the only construct that can do anything with + // this yet, so skip/treat as unimplemented in this case. + if (!isOpenACCComputeDirectiveKind(Clause.getDirectiveKind())) + return isNotImplemented(); + // ActOnVar ensured that everything is a valid variable reference, so there + // really isn't anything to do here. GCC does some duplicate-finding, though + // it isn't apparent in the standard where this is justified. + + return OpenACCCopyClause::Create( + Ctx, Clause.getClauseKind(), Clause.getBeginLoc(), Clause.getLParenLoc(), + Clause.getVarList(), Clause.getEndLoc()); +} - // ActOnVar ensured that everything is a valid variable reference, so there - // really isn't anything to do here. GCC does some duplicate-finding, though - // it isn't apparent in the standard where this is justified. +OpenACCClause *SemaOpenACCClauseVisitor::VisitCopyInClause( + SemaOpenACC::OpenACCParsedClause &Clause) { + // Restrictions only properly implemented on 'compute' constructs, and + // 'compute' constructs are the only construct that can do anything with + // this yet, so skip/treat as unimplemented in this case. + if (!isOpenACCComputeDirectiveKind(Clause.getDirectiveKind())) + return isNotImplemented(); + // ActOnVar ensured that everything is a valid variable reference, so there + // really isn't anything to do here. GCC does some duplicate-finding, though + // it isn't apparent in the standard where this is justified. + + return OpenACCCopyInClause::Create( + Ctx, Clause.getClauseKind(), Clause.getBeginLoc(), Clause.getLParenLoc(), + Clause.isReadOnly(), Clause.getVarList(), Clause.getEndLoc()); +} - return OpenACCPrivateClause::Create( - getASTContext(), Clause.getBeginLoc(), Clause.getLParenLoc(), - Clause.getVarList(), Clause.getEndLoc()); - } - case OpenACCClauseKind::FirstPrivate: { - // Restrictions only properly implemented on 'compute' constructs, and - // 'compute' constructs are the only construct that can do anything with - // this yet, so skip/treat as unimplemented in this case. - if (!isOpenACCComputeDirectiveKind(Clause.getDirectiveKind())) - break; +OpenACCClause *SemaOpenACCClauseVisitor::VisitCopyOutClause( + SemaOpenACC::OpenACCParsedClause &Clause) { + // Restrictions only properly implemented on 'compute' constructs, and + // 'compute' constructs are the only construct that can do anything with + // this yet, so skip/treat as unimplemented in this case. + if (!isOpenACCComputeDirectiveKind(Clause.getDirectiveKind())) + return isNotImplemented(); + // ActOnVar ensured that everything is a valid variable reference, so there + // really isn't anything to do here. GCC does some duplicate-finding, though + // it isn't apparent in the standard where this is justified. + + return OpenACCCopyOutClause::Create( + Ctx, Clause.getClauseKind(), Clause.getBeginLoc(), Clause.getLParenLoc(), + Clause.isZero(), Clause.getVarList(), Clause.getEndLoc()); +} - // ActOnVar ensured that everything is a valid variable reference, so there - // really isn't anything to do here. GCC does some duplicate-finding, though - // it isn't apparent in the standard where this is justified. +OpenACCClause *SemaOpenACCClauseVisitor::VisitCreateClause( + SemaOpenACC::OpenACCParsedClause &Clause) { + // Restrictions only properly implemented on 'compute' constructs, and + // 'compute' constructs are the only construct that can do anything with + // this yet, so skip/treat as unimplemented in this case. + if (!isOpenACCComputeDirectiveKind(Clause.getDirectiveKind())) + return isNotImplemented(); + // ActOnVar ensured that everything is a valid variable reference, so there + // really isn't anything to do here. GCC does some duplicate-finding, though + // it isn't apparent in the standard where this is justified. + + return OpenACCCreateClause::Create( + Ctx, Clause.getClauseKind(), Clause.getBeginLoc(), Clause.getLParenLoc(), + Clause.isZero(), Clause.getVarList(), Clause.getEndLoc()); +} - return OpenACCFirstPrivateClause::Create( - getASTContext(), Clause.getBeginLoc(), Clause.getLParenLoc(), - Clause.getVarList(), Clause.getEndLoc()); - } - case OpenACCClauseKind::NoCreate: { - // Restrictions only properly implemented on 'compute' constructs, and - // 'compute' constructs are the only construct that can do anything with - // this yet, so skip/treat as unimplemented in this case. - if (!isOpenACCComputeDirectiveKind(Clause.getDirectiveKind())) - break; +OpenACCClause *SemaOpenACCClauseVisitor::VisitAttachClause( + SemaOpenACC::OpenACCParsedClause &Clause) { + // Restrictions only properly implemented on 'compute' constructs, and + // 'compute' constructs are the only construct that can do anything with + // this yet, so skip/treat as unimplemented in this case. + if (!isOpenACCComputeDirectiveKind(Clause.getDirectiveKind())) + return isNotImplemented(); + + // ActOnVar ensured that everything is a valid variable reference, but we + // still have to make sure it is a pointer type. + llvm::SmallVector VarList{Clause.getVarList().begin(), + Clause.getVarList().end()}; + VarList.erase(std::remove_if(VarList.begin(), VarList.end(), + [&](Expr *E) { + return SemaRef.CheckVarIsPointerType( + OpenACCClauseKind::Attach, E); + }), + VarList.end()); + Clause.setVarListDetails(VarList, + /*IsReadOnly=*/false, /*IsZero=*/false); + return OpenACCAttachClause::Create(Ctx, Clause.getBeginLoc(), + Clause.getLParenLoc(), Clause.getVarList(), + Clause.getEndLoc()); +} - // ActOnVar ensured that everything is a valid variable reference, so there - // really isn't anything to do here. GCC does some duplicate-finding, though - // it isn't apparent in the standard where this is justified. +OpenACCClause *SemaOpenACCClauseVisitor::VisitDevicePtrClause( + SemaOpenACC::OpenACCParsedClause &Clause) { + // Restrictions only properly implemented on 'compute' constructs, and + // 'compute' constructs are the only construct that can do anything with + // this yet, so skip/treat as unimplemented in this case. + if (!isOpenACCComputeDirectiveKind(Clause.getDirectiveKind())) + return isNotImplemented(); + + // ActOnVar ensured that everything is a valid variable reference, but we + // still have to make sure it is a pointer type. + llvm::SmallVector VarList{Clause.getVarList().begin(), + Clause.getVarList().end()}; + VarList.erase(std::remove_if(VarList.begin(), VarList.end(), + [&](Expr *E) { + return SemaRef.CheckVarIsPointerType( + OpenACCClauseKind::DevicePtr, E); + }), + VarList.end()); + Clause.setVarListDetails(VarList, + /*IsReadOnly=*/false, /*IsZero=*/false); + + return OpenACCDevicePtrClause::Create( + Ctx, Clause.getBeginLoc(), Clause.getLParenLoc(), Clause.getVarList(), + Clause.getEndLoc()); +} - return OpenACCNoCreateClause::Create( - getASTContext(), Clause.getBeginLoc(), Clause.getLParenLoc(), - Clause.getVarList(), Clause.getEndLoc()); - } - case OpenACCClauseKind::Present: { - // Restrictions only properly implemented on 'compute' constructs, and - // 'compute' constructs are the only construct that can do anything with - // this yet, so skip/treat as unimplemented in this case. - if (!isOpenACCComputeDirectiveKind(Clause.getDirectiveKind())) - break; +OpenACCClause *SemaOpenACCClauseVisitor::VisitWaitClause( + SemaOpenACC::OpenACCParsedClause &Clause) { + // Restrictions only properly implemented on 'compute' constructs, and + // 'compute' constructs are the only construct that can do anything with + // this yet, so skip/treat as unimplemented in this case. + if (!isOpenACCComputeDirectiveKind(Clause.getDirectiveKind())) + return isNotImplemented(); + + return OpenACCWaitClause::Create( + Ctx, Clause.getBeginLoc(), Clause.getLParenLoc(), Clause.getDevNumExpr(), + Clause.getQueuesLoc(), Clause.getQueueIdExprs(), Clause.getEndLoc()); +} - // ActOnVar ensured that everything is a valid variable reference, so there - // really isn't anything to do here. GCC does some duplicate-finding, though - // it isn't apparent in the standard where this is justified. +OpenACCClause *SemaOpenACCClauseVisitor::VisitDeviceTypeClause( + SemaOpenACC::OpenACCParsedClause &Clause) { + // Restrictions only properly implemented on 'compute' and 'loop' + // constructs, and 'compute'/'loop' constructs are the only construct that + // can do anything with this yet, so skip/treat as unimplemented in this + // case. + if (!isOpenACCComputeDirectiveKind(Clause.getDirectiveKind()) && + Clause.getDirectiveKind() != OpenACCDirectiveKind::Loop) + return isNotImplemented(); + + // TODO OpenACC: Once we get enough of the CodeGen implemented that we have + // a source for the list of valid architectures, we need to warn on unknown + // identifiers here. + + return OpenACCDeviceTypeClause::Create( + Ctx, Clause.getClauseKind(), Clause.getBeginLoc(), Clause.getLParenLoc(), + Clause.getDeviceTypeArchitectures(), Clause.getEndLoc()); +} - return OpenACCPresentClause::Create( - getASTContext(), Clause.getBeginLoc(), Clause.getLParenLoc(), - Clause.getVarList(), Clause.getEndLoc()); +OpenACCClause *SemaOpenACCClauseVisitor::VisitAutoClause( + SemaOpenACC::OpenACCParsedClause &Clause) { + // Restrictions only properly implemented on 'loop' constructs, and it is + // the only construct that can do anything with this, so skip/treat as + // unimplemented for the combined constructs. + if (Clause.getDirectiveKind() != OpenACCDirectiveKind::Loop) + return isNotImplemented(); + + // OpenACC 3.3 2.9: + // Only one of the seq, independent, and auto clauses may appear. + const auto *Itr = + llvm::find_if(ExistingClauses, + llvm::IsaPred); + if (Itr != ExistingClauses.end()) { + SemaRef.Diag(Clause.getBeginLoc(), diag::err_acc_loop_spec_conflict) + << Clause.getClauseKind() << Clause.getDirectiveKind(); + SemaRef.Diag((*Itr)->getBeginLoc(), diag::note_acc_previous_clause_here); + return nullptr; } - case OpenACCClauseKind::PresentOrCopy: - case OpenACCClauseKind::PCopy: - Diag(Clause.getBeginLoc(), diag::warn_acc_deprecated_alias_name) - << Clause.getClauseKind() << OpenACCClauseKind::Copy; - LLVM_FALLTHROUGH; - case OpenACCClauseKind::Copy: { - // Restrictions only properly implemented on 'compute' constructs, and - // 'compute' constructs are the only construct that can do anything with - // this yet, so skip/treat as unimplemented in this case. - if (!isOpenACCComputeDirectiveKind(Clause.getDirectiveKind())) - break; - // ActOnVar ensured that everything is a valid variable reference, so there - // really isn't anything to do here. GCC does some duplicate-finding, though - // it isn't apparent in the standard where this is justified. + return OpenACCAutoClause::Create(Ctx, Clause.getBeginLoc(), + Clause.getEndLoc()); +} - return OpenACCCopyClause::Create( - getASTContext(), Clause.getClauseKind(), Clause.getBeginLoc(), - Clause.getLParenLoc(), Clause.getVarList(), Clause.getEndLoc()); +OpenACCClause *SemaOpenACCClauseVisitor::VisitIndependentClause( + SemaOpenACC::OpenACCParsedClause &Clause) { + // Restrictions only properly implemented on 'loop' constructs, and it is + // the only construct that can do anything with this, so skip/treat as + // unimplemented for the combined constructs. + if (Clause.getDirectiveKind() != OpenACCDirectiveKind::Loop) + return isNotImplemented(); + + // OpenACC 3.3 2.9: + // Only one of the seq, independent, and auto clauses may appear. + const auto *Itr = llvm::find_if( + ExistingClauses, llvm::IsaPred); + if (Itr != ExistingClauses.end()) { + SemaRef.Diag(Clause.getBeginLoc(), diag::err_acc_loop_spec_conflict) + << Clause.getClauseKind() << Clause.getDirectiveKind(); + SemaRef.Diag((*Itr)->getBeginLoc(), diag::note_acc_previous_clause_here); + return nullptr; } - case OpenACCClauseKind::PresentOrCopyIn: - case OpenACCClauseKind::PCopyIn: - Diag(Clause.getBeginLoc(), diag::warn_acc_deprecated_alias_name) - << Clause.getClauseKind() << OpenACCClauseKind::CopyIn; - LLVM_FALLTHROUGH; - case OpenACCClauseKind::CopyIn: { - // Restrictions only properly implemented on 'compute' constructs, and - // 'compute' constructs are the only construct that can do anything with - // this yet, so skip/treat as unimplemented in this case. - if (!isOpenACCComputeDirectiveKind(Clause.getDirectiveKind())) - break; - // ActOnVar ensured that everything is a valid variable reference, so there - // really isn't anything to do here. GCC does some duplicate-finding, though - // it isn't apparent in the standard where this is justified. + return OpenACCIndependentClause::Create(Ctx, Clause.getBeginLoc(), + Clause.getEndLoc()); +} - return OpenACCCopyInClause::Create( - getASTContext(), Clause.getClauseKind(), Clause.getBeginLoc(), - Clause.getLParenLoc(), Clause.isReadOnly(), Clause.getVarList(), - Clause.getEndLoc()); +OpenACCClause *SemaOpenACCClauseVisitor::VisitSeqClause( + SemaOpenACC::OpenACCParsedClause &Clause) { + // Restrictions only properly implemented on 'loop' constructs, and it is + // the only construct that can do anything with this, so skip/treat as + // unimplemented for the combined constructs. + if (Clause.getDirectiveKind() != OpenACCDirectiveKind::Loop) + return isNotImplemented(); + + // OpenACC 3.3 2.9: + // Only one of the seq, independent, and auto clauses may appear. + const auto *Itr = + llvm::find_if(ExistingClauses, + llvm::IsaPred); + if (Itr != ExistingClauses.end()) { + SemaRef.Diag(Clause.getBeginLoc(), diag::err_acc_loop_spec_conflict) + << Clause.getClauseKind() << Clause.getDirectiveKind(); + SemaRef.Diag((*Itr)->getBeginLoc(), diag::note_acc_previous_clause_here); + return nullptr; } - case OpenACCClauseKind::PresentOrCopyOut: - case OpenACCClauseKind::PCopyOut: - Diag(Clause.getBeginLoc(), diag::warn_acc_deprecated_alias_name) - << Clause.getClauseKind() << OpenACCClauseKind::CopyOut; - LLVM_FALLTHROUGH; - case OpenACCClauseKind::CopyOut: { - // Restrictions only properly implemented on 'compute' constructs, and - // 'compute' constructs are the only construct that can do anything with - // this yet, so skip/treat as unimplemented in this case. - if (!isOpenACCComputeDirectiveKind(Clause.getDirectiveKind())) - break; - // ActOnVar ensured that everything is a valid variable reference, so there - // really isn't anything to do here. GCC does some duplicate-finding, though - // it isn't apparent in the standard where this is justified. + // OpenACC 3.3 2.9: + // A 'gang', 'worker', or 'vector' clause may not appear if a 'seq' clause + // appears. + Itr = llvm::find_if(ExistingClauses, + llvm::IsaPred); - return OpenACCCopyOutClause::Create( - getASTContext(), Clause.getClauseKind(), Clause.getBeginLoc(), - Clause.getLParenLoc(), Clause.isZero(), Clause.getVarList(), - Clause.getEndLoc()); + if (Itr != ExistingClauses.end()) { + SemaRef.Diag(Clause.getBeginLoc(), diag::err_acc_clause_cannot_combine) + << Clause.getClauseKind() << (*Itr)->getClauseKind(); + SemaRef.Diag((*Itr)->getBeginLoc(), diag::note_acc_previous_clause_here); + return nullptr; } - case OpenACCClauseKind::PresentOrCreate: - case OpenACCClauseKind::PCreate: - Diag(Clause.getBeginLoc(), diag::warn_acc_deprecated_alias_name) - << Clause.getClauseKind() << OpenACCClauseKind::Create; - LLVM_FALLTHROUGH; - case OpenACCClauseKind::Create: { - // Restrictions only properly implemented on 'compute' constructs, and - // 'compute' constructs are the only construct that can do anything with - // this yet, so skip/treat as unimplemented in this case. - if (!isOpenACCComputeDirectiveKind(Clause.getDirectiveKind())) - break; - // ActOnVar ensured that everything is a valid variable reference, so there - // really isn't anything to do here. GCC does some duplicate-finding, though - // it isn't apparent in the standard where this is justified. + // TODO OpenACC: 2.9 ~ line 2010 specifies that the associated loop has some + // restrictions when there is a 'seq' clause in place. We probably need to + // implement that. + return OpenACCSeqClause::Create(Ctx, Clause.getBeginLoc(), + Clause.getEndLoc()); +} - return OpenACCCreateClause::Create(getASTContext(), Clause.getClauseKind(), - Clause.getBeginLoc(), - Clause.getLParenLoc(), Clause.isZero(), - Clause.getVarList(), Clause.getEndLoc()); +OpenACCClause *SemaOpenACCClauseVisitor::VisitReductionClause( + SemaOpenACC::OpenACCParsedClause &Clause) { + // Restrictions only properly implemented on 'compute' constructs, and + // 'compute' constructs are the only construct that can do anything with + // this yet, so skip/treat as unimplemented in this case. + if (!isOpenACCComputeDirectiveKind(Clause.getDirectiveKind())) + return isNotImplemented(); + + // OpenACC 3.3 Section 2.5.4: + // A reduction clause may not appear on a parallel construct with a + // num_gangs clause that has more than one argument. + if (Clause.getDirectiveKind() == OpenACCDirectiveKind::Parallel) { + auto NumGangsClauses = llvm::make_filter_range( + ExistingClauses, llvm::IsaPred); + + for (auto *NGC : NumGangsClauses) { + unsigned NumExprs = + cast(NGC)->getIntExprs().size(); + + if (NumExprs > 1) { + SemaRef.Diag(Clause.getBeginLoc(), + diag::err_acc_reduction_num_gangs_conflict) + << NumExprs; + SemaRef.Diag(NGC->getBeginLoc(), diag::note_acc_previous_clause_here); + return nullptr; + } + } } - case OpenACCClauseKind::Attach: { - // Restrictions only properly implemented on 'compute' constructs, and - // 'compute' constructs are the only construct that can do anything with - // this yet, so skip/treat as unimplemented in this case. - if (!isOpenACCComputeDirectiveKind(Clause.getDirectiveKind())) - break; - // ActOnVar ensured that everything is a valid variable reference, but we - // still have to make sure it is a pointer type. - llvm::SmallVector VarList{Clause.getVarList().begin(), - Clause.getVarList().end()}; - VarList.erase(std::remove_if(VarList.begin(), VarList.end(), [&](Expr *E) { - return CheckVarIsPointerType(OpenACCClauseKind::Attach, E); - }), VarList.end()); - Clause.setVarListDetails(VarList, - /*IsReadOnly=*/false, /*IsZero=*/false); - - return OpenACCAttachClause::Create(getASTContext(), Clause.getBeginLoc(), - Clause.getLParenLoc(), - Clause.getVarList(), Clause.getEndLoc()); - } - case OpenACCClauseKind::DevicePtr: { - // Restrictions only properly implemented on 'compute' constructs, and - // 'compute' constructs are the only construct that can do anything with - // this yet, so skip/treat as unimplemented in this case. - if (!isOpenACCComputeDirectiveKind(Clause.getDirectiveKind())) - break; + SmallVector ValidVars; - // ActOnVar ensured that everything is a valid variable reference, but we - // still have to make sure it is a pointer type. - llvm::SmallVector VarList{Clause.getVarList().begin(), - Clause.getVarList().end()}; - VarList.erase(std::remove_if(VarList.begin(), VarList.end(), [&](Expr *E) { - return CheckVarIsPointerType(OpenACCClauseKind::DevicePtr, E); - }), VarList.end()); - Clause.setVarListDetails(VarList, - /*IsReadOnly=*/false, /*IsZero=*/false); - - return OpenACCDevicePtrClause::Create( - getASTContext(), Clause.getBeginLoc(), Clause.getLParenLoc(), - Clause.getVarList(), Clause.getEndLoc()); - } - case OpenACCClauseKind::Wait: { - // Restrictions only properly implemented on 'compute' constructs, and - // 'compute' constructs are the only construct that can do anything with - // this yet, so skip/treat as unimplemented in this case. - if (!isOpenACCComputeDirectiveKind(Clause.getDirectiveKind())) - break; + for (Expr *Var : Clause.getVarList()) { + ExprResult Res = SemaRef.CheckReductionVar(Var); - return OpenACCWaitClause::Create( - getASTContext(), Clause.getBeginLoc(), Clause.getLParenLoc(), - Clause.getDevNumExpr(), Clause.getQueuesLoc(), Clause.getQueueIdExprs(), - Clause.getEndLoc()); + if (Res.isUsable()) + ValidVars.push_back(Res.get()); } - case OpenACCClauseKind::DType: - case OpenACCClauseKind::DeviceType: { - // Restrictions only properly implemented on 'compute' constructs, and - // 'compute' constructs are the only construct that can do anything with - // this yet, so skip/treat as unimplemented in this case. - if (!isOpenACCComputeDirectiveKind(Clause.getDirectiveKind())) - break; - // TODO OpenACC: Once we get enough of the CodeGen implemented that we have - // a source for the list of valid architectures, we need to warn on unknown - // identifiers here. + return OpenACCReductionClause::Create( + Ctx, Clause.getBeginLoc(), Clause.getLParenLoc(), Clause.getReductionOp(), + ValidVars, Clause.getEndLoc()); +} - return OpenACCDeviceTypeClause::Create( - getASTContext(), Clause.getClauseKind(), Clause.getBeginLoc(), - Clause.getLParenLoc(), Clause.getDeviceTypeArchitectures(), - Clause.getEndLoc()); - } - case OpenACCClauseKind::Reduction: { - // Restrictions only properly implemented on 'compute' constructs, and - // 'compute' constructs are the only construct that can do anything with - // this yet, so skip/treat as unimplemented in this case. - if (!isOpenACCComputeDirectiveKind(Clause.getDirectiveKind())) - break; +} // namespace - // OpenACC 3.3 Section 2.5.4: - // A reduction clause may not appear on a parallel construct with a - // num_gangs clause that has more than one argument. - if (Clause.getDirectiveKind() == OpenACCDirectiveKind::Parallel) { - auto NumGangsClauses = llvm::make_filter_range( - ExistingClauses, llvm::IsaPred); - - for (auto *NGC : NumGangsClauses) { - unsigned NumExprs = - cast(NGC)->getIntExprs().size(); - - if (NumExprs > 1) { - Diag(Clause.getBeginLoc(), diag::err_acc_reduction_num_gangs_conflict) - << NumExprs; - Diag(NGC->getBeginLoc(), diag::note_acc_previous_clause_here); - return nullptr; - } - } - } +SemaOpenACC::SemaOpenACC(Sema &S) : SemaBase(S) {} - SmallVector ValidVars; +SemaOpenACC::AssociatedStmtRAII::AssociatedStmtRAII(SemaOpenACC &S, + OpenACCDirectiveKind DK) + : SemaRef(S), WasInsideComputeConstruct(S.InsideComputeConstruct), + DirKind(DK) { + // Compute constructs end up taking their 'loop'. + if (DirKind == OpenACCDirectiveKind::Parallel || + DirKind == OpenACCDirectiveKind::Serial || + DirKind == OpenACCDirectiveKind::Kernels) { + SemaRef.InsideComputeConstruct = true; + SemaRef.ParentlessLoopConstructs.swap(ParentlessLoopConstructs); + } +} - for (Expr *Var : Clause.getVarList()) { - ExprResult Res = CheckReductionVar(Var); +SemaOpenACC::AssociatedStmtRAII::~AssociatedStmtRAII() { + SemaRef.InsideComputeConstruct = WasInsideComputeConstruct; + if (DirKind == OpenACCDirectiveKind::Parallel || + DirKind == OpenACCDirectiveKind::Serial || + DirKind == OpenACCDirectiveKind::Kernels) { + assert(SemaRef.ParentlessLoopConstructs.empty() && + "Didn't consume loop construct list?"); + SemaRef.ParentlessLoopConstructs.swap(ParentlessLoopConstructs); + } +} - if (Res.isUsable()) - ValidVars.push_back(Res.get()); - } +OpenACCClause * +SemaOpenACC::ActOnClause(ArrayRef ExistingClauses, + OpenACCParsedClause &Clause) { + if (Clause.getClauseKind() == OpenACCClauseKind::Invalid) + return nullptr; - return OpenACCReductionClause::Create( - getASTContext(), Clause.getBeginLoc(), Clause.getLParenLoc(), - Clause.getReductionOp(), ValidVars, Clause.getEndLoc()); + // Diagnose that we don't support this clause on this directive. + if (!doesClauseApplyToDirective(Clause.getDirectiveKind(), + Clause.getClauseKind())) { + Diag(Clause.getBeginLoc(), diag::err_acc_clause_appertainment) + << Clause.getDirectiveKind() << Clause.getClauseKind(); + return nullptr; } - default: - break; + + if (const auto *DevTypeClause = + llvm::find_if(ExistingClauses, + [&](const OpenACCClause *C) { + return isa(C); + }); + DevTypeClause != ExistingClauses.end()) { + if (checkValidAfterDeviceType( + *this, *cast(*DevTypeClause), Clause)) + return nullptr; } - Diag(Clause.getBeginLoc(), diag::warn_acc_clause_unimplemented) - << Clause.getClauseKind(); - return nullptr; + SemaOpenACCClauseVisitor Visitor{*this, ExistingClauses}; + OpenACCClause *Result = Visitor.Visit(Clause); + assert((!Result || Result->getClauseKind() == Clause.getClauseKind()) && + "Created wrong clause?"); + + if (Visitor.diagNotImplemented()) + Diag(Clause.getBeginLoc(), diag::warn_acc_clause_unimplemented) + << Clause.getClauseKind(); + + return Result; + + // switch (Clause.getClauseKind()) { + // case OpenACCClauseKind::PresentOrCopy: + // case OpenACCClauseKind::PCopy: + // Diag(Clause.getBeginLoc(), diag::warn_acc_deprecated_alias_name) + // << Clause.getClauseKind() << OpenACCClauseKind::Copy; + // LLVM_FALLTHROUGH; + // case OpenACCClauseKind::PresentOrCreate: + // case OpenACCClauseKind::PCreate: + // Diag(Clause.getBeginLoc(), diag::warn_acc_deprecated_alias_name) + // << Clause.getClauseKind() << OpenACCClauseKind::Create; + // LLVM_FALLTHROUGH; + // + // + // + // + // case OpenACCClauseKind::DType: + // + // + // + // + // + // + // + // + // case OpenACCClauseKind::Gang: + // case OpenACCClauseKind::Worker: + // case OpenACCClauseKind::Vector: { + // // OpenACC 3.3 2.9: + // // A 'gang', 'worker', or 'vector' clause may not appear if a 'seq' + // clause + // // appears. + // const auto *Itr = + // llvm::find_if(ExistingClauses, llvm::IsaPred); + // + // if (Itr != ExistingClauses.end()) { + // Diag(Clause.getBeginLoc(), diag::err_acc_clause_cannot_combine) + // << Clause.getClauseKind() << (*Itr)->getClauseKind(); + // Diag((*Itr)->getBeginLoc(), diag::note_acc_previous_clause_here); + // } + // // Not yet implemented, so immediately drop to the 'not yet implemented' + // // diagnostic. + // break; + // } + // */ + } /// OpenACC 3.3 section 2.5.15: @@ -927,6 +1228,7 @@ void SemaOpenACC::ActOnConstruct(OpenACCDirectiveKind K, case OpenACCDirectiveKind::Parallel: case OpenACCDirectiveKind::Serial: case OpenACCDirectiveKind::Kernels: + case OpenACCDirectiveKind::Loop: // Nothing to do here, there is no real legalization that needs to happen // here as these constructs do not take any arguments. break; @@ -1348,16 +1650,34 @@ StmtResult SemaOpenACC::ActOnEndStmtDirective(OpenACCDirectiveKind K, return StmtError(); case OpenACCDirectiveKind::Parallel: case OpenACCDirectiveKind::Serial: - case OpenACCDirectiveKind::Kernels: - // TODO OpenACC: Add clauses to the construct here. - return OpenACCComputeConstruct::Create( + case OpenACCDirectiveKind::Kernels: { + auto *ComputeConstruct = OpenACCComputeConstruct::Create( getASTContext(), K, StartLoc, DirLoc, EndLoc, Clauses, + AssocStmt.isUsable() ? AssocStmt.get() : nullptr, + ParentlessLoopConstructs); + + ParentlessLoopConstructs.clear(); + return ComputeConstruct; + } + case OpenACCDirectiveKind::Loop: { + auto *LoopConstruct = OpenACCLoopConstruct::Create( + getASTContext(), StartLoc, DirLoc, EndLoc, Clauses, AssocStmt.isUsable() ? AssocStmt.get() : nullptr); + + // If we are in the scope of a compute construct, add this to the list of + // loop constructs that need assigning to the next closing compute + // construct. + if (InsideComputeConstruct) + ParentlessLoopConstructs.push_back(LoopConstruct); + + return LoopConstruct; + } } llvm_unreachable("Unhandled case in directive handling?"); } -StmtResult SemaOpenACC::ActOnAssociatedStmt(OpenACCDirectiveKind K, +StmtResult SemaOpenACC::ActOnAssociatedStmt(SourceLocation DirectiveLoc, + OpenACCDirectiveKind K, StmtResult AssocStmt) { switch (K) { default: @@ -1375,6 +1695,17 @@ StmtResult SemaOpenACC::ActOnAssociatedStmt(OpenACCDirectiveKind K, // an interpretation of it is to allow this and treat the initializer as // the 'structured block'. return AssocStmt; + case OpenACCDirectiveKind::Loop: + if (AssocStmt.isUsable() && + !isa(AssocStmt.get())) { + Diag(AssocStmt.get()->getBeginLoc(), diag::err_acc_loop_not_for_loop); + Diag(DirectiveLoc, diag::note_acc_construct_here) << K; + return StmtError(); + } + // TODO OpenACC: 2.9 ~ line 2010 specifies that the associated loop has some + // restrictions when there is a 'seq' clause in place. We probably need to + // implement that, including piping in the clauses here. + return AssocStmt; } llvm_unreachable("Invalid associated statement application"); } diff --git a/clang/lib/Sema/SemaOpenMP.cpp b/clang/lib/Sema/SemaOpenMP.cpp index 6e6815328e91394136652ac57040e7e11c2dabf3..5c759aedf9798a7e72143659a1f25f7310d7745e 100644 --- a/clang/lib/Sema/SemaOpenMP.cpp +++ b/clang/lib/Sema/SemaOpenMP.cpp @@ -6198,18 +6198,17 @@ public: // unless the assume-no-nested-parallelism flag has been specified. // OpenMP API runtime library calls do not inhibit parallel loop // translation, regardless of the assume-no-nested-parallelism. - if (C) { - bool IsOpenMPAPI = false; - auto *FD = dyn_cast_or_null(C->getCalleeDecl()); - if (FD) { - std::string Name = FD->getNameInfo().getAsString(); - IsOpenMPAPI = Name.find("omp_") == 0; - } - TeamsLoopCanBeParallelFor = - IsOpenMPAPI || SemaRef.getLangOpts().OpenMPNoNestedParallelism; - if (!TeamsLoopCanBeParallelFor) - return; - } + bool IsOpenMPAPI = false; + auto *FD = dyn_cast_or_null(C->getCalleeDecl()); + if (FD) { + std::string Name = FD->getNameInfo().getAsString(); + IsOpenMPAPI = Name.find("omp_") == 0; + } + TeamsLoopCanBeParallelFor = + IsOpenMPAPI || SemaRef.getLangOpts().OpenMPNoNestedParallelism; + if (!TeamsLoopCanBeParallelFor) + return; + for (const Stmt *Child : C->children()) if (Child) Visit(Child); @@ -24331,7 +24330,7 @@ SemaOpenMP::ActOnOpenMPHasDeviceAddrClause(ArrayRef VarList, OMPClause *SemaOpenMP::ActOnOpenMPAllocateClause( Expr *Allocator, ArrayRef VarList, SourceLocation StartLoc, - SourceLocation ColonLoc, SourceLocation LParenLoc, SourceLocation EndLoc) { + SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc) { if (Allocator) { // OpenMP [2.11.4 allocate Clause, Description] // allocator is an expression of omp_allocator_handle_t type. diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp index 6c4ce1022ae274df0aa07b3d08a304c2b5ac2803..1b4bcdcb51160b29f62990c691f08f41acc716a7 100644 --- a/clang/lib/Sema/SemaOverload.cpp +++ b/clang/lib/Sema/SemaOverload.cpp @@ -6972,6 +6972,7 @@ void Sema::AddOverloadCandidate( Candidate.IsSurrogate = false; Candidate.IsADLCandidate = IsADLCandidate; Candidate.IgnoreObjectArgument = false; + Candidate.TookAddressOfOverload = false; Candidate.ExplicitCallArguments = Args.size(); // Explicit functions are not actually candidates at all if we're not @@ -7546,10 +7547,24 @@ Sema::AddMethodCandidate(CXXMethodDecl *Method, DeclAccessPair FoundDecl, CandidateSet.getRewriteInfo().getRewriteKind(Method, PO); Candidate.IsSurrogate = false; Candidate.IgnoreObjectArgument = false; + Candidate.TookAddressOfOverload = + CandidateSet.getKind() == OverloadCandidateSet::CSK_AddressOfOverloadSet; Candidate.ExplicitCallArguments = Args.size(); - unsigned NumParams = Method->getNumExplicitParams(); - unsigned ExplicitOffset = Method->isExplicitObjectMemberFunction() ? 1 : 0; + bool IgnoreExplicitObject = + (Method->isExplicitObjectMemberFunction() && + CandidateSet.getKind() == + OverloadCandidateSet::CSK_AddressOfOverloadSet); + bool ImplicitObjectMethodTreatedAsStatic = + CandidateSet.getKind() == + OverloadCandidateSet::CSK_AddressOfOverloadSet && + Method->isImplicitObjectMemberFunction(); + + unsigned ExplicitOffset = + !IgnoreExplicitObject && Method->isExplicitObjectMemberFunction() ? 1 : 0; + + unsigned NumParams = Method->getNumParams() - ExplicitOffset + + int(ImplicitObjectMethodTreatedAsStatic); // (C++ 13.3.2p2): A candidate function having fewer than m // parameters is viable only if it has an ellipsis in its parameter @@ -7567,7 +7582,10 @@ Sema::AddMethodCandidate(CXXMethodDecl *Method, DeclAccessPair FoundDecl, // (8.3.6). For the purposes of overload resolution, the // parameter list is truncated on the right, so that there are // exactly m parameters. - unsigned MinRequiredArgs = Method->getMinRequiredExplicitArguments(); + unsigned MinRequiredArgs = Method->getMinRequiredArguments() - + ExplicitOffset + + int(ImplicitObjectMethodTreatedAsStatic); + if (Args.size() < MinRequiredArgs && !PartialOverloading) { // Not enough arguments. Candidate.Viable = false; @@ -7637,7 +7655,14 @@ Sema::AddMethodCandidate(CXXMethodDecl *Method, DeclAccessPair FoundDecl, // exist for each argument an implicit conversion sequence // (13.3.3.1) that converts that argument to the corresponding // parameter of F. - QualType ParamType = Proto->getParamType(ArgIdx + ExplicitOffset); + QualType ParamType; + if (ImplicitObjectMethodTreatedAsStatic) { + ParamType = ArgIdx == 0 + ? Method->getFunctionObjectParameterReferenceType() + : Proto->getParamType(ArgIdx - 1); + } else { + ParamType = Proto->getParamType(ArgIdx + ExplicitOffset); + } Candidate.Conversions[ConvIdx] = TryCopyInitialization(*this, Args[ArgIdx], ParamType, SuppressUserConversions, @@ -7718,6 +7743,7 @@ void Sema::AddMethodTemplateCandidate( Candidate.IgnoreObjectArgument = cast(Candidate.Function)->isStatic() || ObjectType.isNull(); + Candidate.TookAddressOfOverload = false; Candidate.ExplicitCallArguments = Args.size(); if (Result == TemplateDeductionResult::NonDependentConversionFailure) Candidate.FailureKind = ovl_fail_bad_conversion; @@ -7808,6 +7834,7 @@ void Sema::AddTemplateOverloadCandidate( Candidate.IgnoreObjectArgument = isa(Candidate.Function) && !isa(Candidate.Function); + Candidate.TookAddressOfOverload = false; Candidate.ExplicitCallArguments = Args.size(); if (Result == TemplateDeductionResult::NonDependentConversionFailure) Candidate.FailureKind = ovl_fail_bad_conversion; @@ -7999,6 +8026,7 @@ void Sema::AddConversionCandidate( Candidate.Function = Conversion; Candidate.IsSurrogate = false; Candidate.IgnoreObjectArgument = false; + Candidate.TookAddressOfOverload = false; Candidate.FinalConversion.setAsIdentityConversion(); Candidate.FinalConversion.setFromType(ConvType); Candidate.FinalConversion.setAllToTypes(ToType); @@ -8201,6 +8229,7 @@ void Sema::AddTemplateConversionCandidate( Candidate.FailureKind = ovl_fail_bad_deduction; Candidate.IsSurrogate = false; Candidate.IgnoreObjectArgument = false; + Candidate.TookAddressOfOverload = false; Candidate.ExplicitCallArguments = 1; Candidate.DeductionFailure = MakeDeductionFailureInfo(Context, Result, Info); @@ -8241,6 +8270,7 @@ void Sema::AddSurrogateCandidate(CXXConversionDecl *Conversion, Candidate.Viable = true; Candidate.IsSurrogate = true; Candidate.IgnoreObjectArgument = false; + Candidate.TookAddressOfOverload = false; Candidate.ExplicitCallArguments = Args.size(); // Determine the implicit conversion sequence for the implicit @@ -8466,6 +8496,7 @@ void Sema::AddBuiltinCandidate(QualType *ParamTys, ArrayRef Args, Candidate.Function = nullptr; Candidate.IsSurrogate = false; Candidate.IgnoreObjectArgument = false; + Candidate.TookAddressOfOverload = false; std::copy(ParamTys, ParamTys + Args.size(), Candidate.BuiltinParamTypes); // Determine the implicit conversion sequences for each of the @@ -10930,6 +10961,12 @@ OverloadCandidateSet::BestViableFunction(Sema &S, SourceLocation Loc, if (Best->Function && Best->Function->isDeleted()) return OR_Deleted; + if (auto *M = dyn_cast_or_null(Best->Function); + Kind == CSK_AddressOfOverloadSet && M && + M->isImplicitObjectMemberFunction()) { + return OR_No_Viable_Function; + } + if (!EquivalentCands.empty()) S.diagnoseEquivalentInternalLinkageDeclarations(Loc, Best->Function, EquivalentCands); @@ -11517,9 +11554,10 @@ static void DiagnoseBadConversion(Sema &S, OverloadCandidate *Cand, /// candidates. This is not covered by the more general DiagnoseArityMismatch() /// over a candidate in any candidate set. static bool CheckArityMismatch(Sema &S, OverloadCandidate *Cand, - unsigned NumArgs) { + unsigned NumArgs, bool IsAddressOf = false) { FunctionDecl *Fn = Cand->Function; - unsigned MinParams = Fn->getMinRequiredArguments(); + unsigned MinParams = Fn->getMinRequiredExplicitArguments() + + ((IsAddressOf && !Fn->isStatic()) ? 1 : 0); // With invalid overloaded operators, it's possible that we think we // have an arity mismatch when in fact it looks like we have the @@ -11547,7 +11585,8 @@ static bool CheckArityMismatch(Sema &S, OverloadCandidate *Cand, /// General arity mismatch diagnosis over a candidate in a candidate set. static void DiagnoseArityMismatch(Sema &S, NamedDecl *Found, Decl *D, - unsigned NumFormalArgs) { + unsigned NumFormalArgs, + bool IsAddressOf = false) { assert(isa(D) && "The templated declaration should at least be a function" " when diagnosing bad template argument deduction due to too many" @@ -11557,12 +11596,17 @@ static void DiagnoseArityMismatch(Sema &S, NamedDecl *Found, Decl *D, // TODO: treat calls to a missing default constructor as a special case const auto *FnTy = Fn->getType()->castAs(); - unsigned MinParams = Fn->getMinRequiredExplicitArguments(); + unsigned MinParams = Fn->getMinRequiredExplicitArguments() + + ((IsAddressOf && !Fn->isStatic()) ? 1 : 0); // at least / at most / exactly - bool HasExplicitObjectParam = Fn->hasCXXExplicitFunctionObjectParameter(); - unsigned ParamCount = FnTy->getNumParams() - (HasExplicitObjectParam ? 1 : 0); + bool HasExplicitObjectParam = + !IsAddressOf && Fn->hasCXXExplicitFunctionObjectParameter(); + + unsigned ParamCount = + Fn->getNumNonObjectParams() + ((IsAddressOf && !Fn->isStatic()) ? 1 : 0); unsigned mode, modeCount; + if (NumFormalArgs < MinParams) { if (MinParams != ParamCount || FnTy->isVariadic() || FnTy->isTemplateVariadic()) @@ -11582,7 +11626,7 @@ static void DiagnoseArityMismatch(Sema &S, NamedDecl *Found, Decl *D, std::pair FnKindPair = ClassifyOverloadCandidate(S, Found, Fn, CRK_None, Description); - if (modeCount == 1 && + if (modeCount == 1 && !IsAddressOf && Fn->getParamDecl(HasExplicitObjectParam ? 1 : 0)->getDeclName()) S.Diag(Fn->getLocation(), diag::note_ovl_candidate_arity_one) << (unsigned)FnKindPair.first << (unsigned)FnKindPair.second @@ -11601,8 +11645,9 @@ static void DiagnoseArityMismatch(Sema &S, NamedDecl *Found, Decl *D, /// Arity mismatch diagnosis specific to a function overload candidate. static void DiagnoseArityMismatch(Sema &S, OverloadCandidate *Cand, unsigned NumFormalArgs) { - if (!CheckArityMismatch(S, Cand, NumFormalArgs)) - DiagnoseArityMismatch(S, Cand->FoundDecl, Cand->Function, NumFormalArgs); + if (!CheckArityMismatch(S, Cand, NumFormalArgs, Cand->TookAddressOfOverload)) + DiagnoseArityMismatch(S, Cand->FoundDecl, Cand->Function, NumFormalArgs, + Cand->TookAddressOfOverload); } static TemplateDecl *getDescribedTemplate(Decl *Templated) { @@ -12042,6 +12087,13 @@ static void NoteFunctionCandidate(Sema &S, OverloadCandidate *Cand, Cand->FailureKind != ovl_fail_bad_conversion) return; + // Skip implicit member functions when trying to resolve + // the address of a an overload set for a function pointer. + if (Cand->TookAddressOfOverload && + !Cand->Function->hasCXXExplicitFunctionObjectParameter() && + !Cand->Function->isStatic()) + return; + // Note deleted candidates, but only if they're viable. if (Cand->Viable) { if (Fn->isDeleted()) { @@ -14085,6 +14137,21 @@ static ExprResult FinishOverloadedCallExpr(Sema &SemaRef, Scope *S, Expr *Fn, } case OR_No_Viable_Function: { + if (*Best != CandidateSet->end() && + CandidateSet->getKind() == + clang::OverloadCandidateSet::CSK_AddressOfOverloadSet) { + if (CXXMethodDecl *M = + dyn_cast_if_present((*Best)->Function); + M && M->isImplicitObjectMemberFunction()) { + CandidateSet->NoteCandidates( + PartialDiagnosticAt( + Fn->getBeginLoc(), + SemaRef.PDiag(diag::err_member_call_without_object) << 0 << M), + SemaRef, OCD_AmbiguousCandidates, Args); + return ExprError(); + } + } + // Try to recover by looking for viable functions which the user might // have meant to call. ExprResult Recovery = BuildRecoveryCallExpr(SemaRef, S, Fn, ULE, LParenLoc, @@ -14176,8 +14243,10 @@ ExprResult Sema::BuildOverloadedCallExpr(Scope *S, Expr *Fn, Expr *ExecConfig, bool AllowTypoCorrection, bool CalleesAddressIsTaken) { - OverloadCandidateSet CandidateSet(Fn->getExprLoc(), - OverloadCandidateSet::CSK_Normal); + OverloadCandidateSet CandidateSet( + Fn->getExprLoc(), CalleesAddressIsTaken + ? OverloadCandidateSet::CSK_AddressOfOverloadSet + : OverloadCandidateSet::CSK_Normal); ExprResult result; if (buildOverloadedCallSet(S, Fn, ULE, Args, LParenLoc, &CandidateSet, @@ -16342,9 +16411,9 @@ ExprResult Sema::FixOverloadedFunctionReference(Expr *E, DeclAccessPair Found, assert(UnOp->getOpcode() == UO_AddrOf && "Can only take the address of an overloaded function"); if (CXXMethodDecl *Method = dyn_cast(Fn)) { - if (Method->isStatic()) { - // Do nothing: static member functions aren't any different - // from non-member functions. + if (!Method->isImplicitObjectMemberFunction()) { + // Do nothing: the address of static and + // explicit object member functions is a (non-member) function pointer. } else { // Fix the subexpression, which really has to be an // UnresolvedLookupExpr holding an overloaded member function @@ -16402,7 +16471,10 @@ ExprResult Sema::FixOverloadedFunctionReference(Expr *E, DeclAccessPair Found, } QualType Type = Fn->getType(); - ExprValueKind ValueKind = getLangOpts().CPlusPlus ? VK_LValue : VK_PRValue; + ExprValueKind ValueKind = + getLangOpts().CPlusPlus && !Fn->hasCXXExplicitFunctionObjectParameter() + ? VK_LValue + : VK_PRValue; // FIXME: Duplicated from BuildDeclarationNameExpr. if (unsigned BID = Fn->getBuiltinID()) { diff --git a/clang/lib/Sema/SemaStmt.cpp b/clang/lib/Sema/SemaStmt.cpp index 57465d4a77ac2964b202398166073e3ba03085fa..411e9af26f2b7b287baba7fa8c47b8e3ac89c915 100644 --- a/clang/lib/Sema/SemaStmt.cpp +++ b/clang/lib/Sema/SemaStmt.cpp @@ -3701,7 +3701,7 @@ bool Sema::DeduceFunctionTypeFromReturnExpr(FunctionDecl *FD, if (isLambdaConversionOperator(FD)) return false; - if (RetExpr && isa(RetExpr)) { + if (isa_and_nonnull(RetExpr)) { // If the deduction is for a return statement and the initializer is // a braced-init-list, the program is ill-formed. Diag(RetExpr->getExprLoc(), diff --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp index 40a759ea330de4548c2e8ccf26c6a59c06256332..a032e3ec6f63535d656b6b65f0d3aec89e5ee038 100644 --- a/clang/lib/Sema/SemaTemplate.cpp +++ b/clang/lib/Sema/SemaTemplate.cpp @@ -1936,7 +1936,7 @@ DeclResult Sema::CheckClassTemplate( // We may have found the injected-class-name of a class template, // class template partial specialization, or class template specialization. // In these cases, grab the template that is being defined or specialized. - if (!PrevClassTemplate && PrevDecl && isa(PrevDecl) && + if (!PrevClassTemplate && isa_and_nonnull(PrevDecl) && cast(PrevDecl)->isInjectedClassName()) { PrevDecl = cast(PrevDecl->getDeclContext()); PrevClassTemplate diff --git a/clang/lib/Sema/SemaTemplateDeduction.cpp b/clang/lib/Sema/SemaTemplateDeduction.cpp index 1011db2d2830dcd41919b229d339b94c03d99e5f..befeb38e1fe5bc63ec3b2a02b68e12c93f4f599c 100644 --- a/clang/lib/Sema/SemaTemplateDeduction.cpp +++ b/clang/lib/Sema/SemaTemplateDeduction.cpp @@ -712,13 +712,6 @@ DeduceTemplateSpecArguments(Sema &S, TemplateParameterList *TemplateParams, if (const auto *TD = TNA.getAsTemplateDecl(); TD && TD->isTypeAlias()) return TemplateDeductionResult::Success; - // Perform template argument deduction for the template name. - if (auto Result = - DeduceTemplateArguments(S, TemplateParams, TNP, TNA, Info, - SA->template_arguments(), Deduced); - Result != TemplateDeductionResult::Success) - return Result; - // FIXME: To preserve sugar, the TST needs to carry sugared resolved // arguments. ArrayRef AResolved = @@ -726,6 +719,12 @@ DeduceTemplateSpecArguments(Sema &S, TemplateParameterList *TemplateParams, ->castAs() ->template_arguments(); + // Perform template argument deduction for the template name. + if (auto Result = DeduceTemplateArguments(S, TemplateParams, TNP, TNA, Info, + AResolved, Deduced); + Result != TemplateDeductionResult::Success) + return Result; + // Perform template argument deduction on each template // argument. Ignore any missing/extra arguments, since they could be // filled in by default arguments. diff --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h index 70603ba6c27178b256187ccfbddaa4d8e39e5dc9..3bfda09d5f80fccf4ffd473927ce7f45dd82fbf3 100644 --- a/clang/lib/Sema/TreeTransform.h +++ b/clang/lib/Sema/TreeTransform.h @@ -4041,6 +4041,15 @@ public: EndLoc, Clauses, StrBlock); } + StmtResult RebuildOpenACCLoopConstruct(SourceLocation BeginLoc, + SourceLocation DirLoc, + SourceLocation EndLoc, + ArrayRef Clauses, + StmtResult Loop) { + return getSema().OpenACC().ActOnEndStmtDirective( + OpenACCDirectiveKind::Loop, BeginLoc, DirLoc, EndLoc, Clauses, Loop); + } + private: TypeLoc TransformTypeInObjectScope(TypeLoc TL, QualType ObjectType, @@ -11487,6 +11496,31 @@ void OpenACCClauseTransform::VisitDeviceTypeClause( C.getArchitectures(), ParsedClause.getEndLoc()); } +template +void OpenACCClauseTransform::VisitAutoClause( + const OpenACCAutoClause &C) { + // Nothing to do, so just create a new node. + NewClause = OpenACCAutoClause::Create(Self.getSema().getASTContext(), + ParsedClause.getBeginLoc(), + ParsedClause.getEndLoc()); +} + +template +void OpenACCClauseTransform::VisitIndependentClause( + const OpenACCIndependentClause &C) { + NewClause = OpenACCIndependentClause::Create(Self.getSema().getASTContext(), + ParsedClause.getBeginLoc(), + ParsedClause.getEndLoc()); +} + +template +void OpenACCClauseTransform::VisitSeqClause( + const OpenACCSeqClause &C) { + NewClause = OpenACCSeqClause::Create(Self.getSema().getASTContext(), + ParsedClause.getBeginLoc(), + ParsedClause.getEndLoc()); +} + template void OpenACCClauseTransform::VisitReductionClause( const OpenACCReductionClause &C) { @@ -11541,8 +11575,6 @@ template StmtResult TreeTransform::TransformOpenACCComputeConstruct( OpenACCComputeConstruct *C) { getSema().OpenACC().ActOnConstruct(C->getDirectiveKind(), C->getBeginLoc()); - // FIXME: When implementing this for constructs that can take arguments, we - // should do Sema for them here. if (getSema().OpenACC().ActOnStartStmtDirective(C->getDirectiveKind(), C->getBeginLoc())) @@ -11551,17 +11583,44 @@ StmtResult TreeTransform::TransformOpenACCComputeConstruct( llvm::SmallVector TransformedClauses = getDerived().TransformOpenACCClauseList(C->getDirectiveKind(), C->clauses()); - // Transform Structured Block. + SemaOpenACC::AssociatedStmtRAII AssocStmtRAII(getSema().OpenACC(), + C->getDirectiveKind()); StmtResult StrBlock = getDerived().TransformStmt(C->getStructuredBlock()); - StrBlock = - getSema().OpenACC().ActOnAssociatedStmt(C->getDirectiveKind(), StrBlock); + StrBlock = getSema().OpenACC().ActOnAssociatedStmt( + C->getBeginLoc(), C->getDirectiveKind(), StrBlock); return getDerived().RebuildOpenACCComputeConstruct( C->getDirectiveKind(), C->getBeginLoc(), C->getDirectiveLoc(), C->getEndLoc(), TransformedClauses, StrBlock); } +template +StmtResult +TreeTransform::TransformOpenACCLoopConstruct(OpenACCLoopConstruct *C) { + + getSema().OpenACC().ActOnConstruct(C->getDirectiveKind(), C->getBeginLoc()); + + if (getSema().OpenACC().ActOnStartStmtDirective(C->getDirectiveKind(), + C->getBeginLoc())) + return StmtError(); + + llvm::SmallVector TransformedClauses = + getDerived().TransformOpenACCClauseList(C->getDirectiveKind(), + C->clauses()); + + // Transform Loop. + SemaOpenACC::AssociatedStmtRAII AssocStmtRAII(getSema().OpenACC(), + C->getDirectiveKind()); + StmtResult Loop = getDerived().TransformStmt(C->getLoop()); + Loop = getSema().OpenACC().ActOnAssociatedStmt(C->getBeginLoc(), + C->getDirectiveKind(), Loop); + + return getDerived().RebuildOpenACCLoopConstruct( + C->getBeginLoc(), C->getDirectiveLoc(), C->getEndLoc(), + TransformedClauses, Loop); +} + //===----------------------------------------------------------------------===// // Expression transformation //===----------------------------------------------------------------------===// @@ -14113,13 +14172,6 @@ TreeTransform::TransformCXXTemporaryObjectExpr( if (TransformExprs(E->getArgs(), E->getNumArgs(), true, Args, &ArgumentChanged)) return ExprError(); - - if (E->isListInitialization() && !E->isStdInitListInitialization()) { - ExprResult Res = RebuildInitList(E->getBeginLoc(), Args, E->getEndLoc()); - if (Res.isInvalid()) - return ExprError(); - Args = {Res.get()}; - } } if (!getDerived().AlwaysRebuild() && @@ -14131,9 +14183,12 @@ TreeTransform::TransformCXXTemporaryObjectExpr( return SemaRef.MaybeBindToTemporary(E); } + // FIXME: We should just pass E->isListInitialization(), but we're not + // prepared to handle list-initialization without a child InitListExpr. SourceLocation LParenLoc = T->getTypeLoc().getEndLoc(); return getDerived().RebuildCXXTemporaryObjectExpr( - T, LParenLoc, Args, E->getEndLoc(), E->isListInitialization()); + T, LParenLoc, Args, E->getEndLoc(), + /*ListInitialization=*/LParenLoc.isInvalid()); } template diff --git a/clang/lib/Serialization/ASTReader.cpp b/clang/lib/Serialization/ASTReader.cpp index 2bc00e1bb3e38b5d86cefad7d7a27ff3e21a41a2..59338b44db32f34932e3abb5e55932b7392210fd 100644 --- a/clang/lib/Serialization/ASTReader.cpp +++ b/clang/lib/Serialization/ASTReader.cpp @@ -1658,7 +1658,7 @@ bool ASTReader::ReadSLocEntry(int ID) { unsigned NumFileDecls = Record[7]; if (NumFileDecls && ContextObj) { - const LocalDeclID *FirstDecl = F->FileSortedDecls + Record[6]; + const unaligned_decl_id_t *FirstDecl = F->FileSortedDecls + Record[6]; assert(F->FileSortedDecls && "FILE_SORTED_DECLS not encountered yet ?"); FileDeclIDs[FID] = FileDeclsInfo(F, llvm::ArrayRef(FirstDecl, NumFileDecls)); @@ -3377,26 +3377,11 @@ llvm::Error ASTReader::ReadASTBlock(ModuleFile &F, "duplicate DECL_OFFSET record in AST file"); F.DeclOffsets = (const DeclOffset *)Blob.data(); F.LocalNumDecls = Record[0]; - unsigned LocalBaseDeclID = Record[1]; - F.BaseDeclID = getTotalNumDecls(); - - if (F.LocalNumDecls > 0) { - // Introduce the global -> local mapping for declarations within this - // module. - GlobalDeclMap.insert(std::make_pair( - GlobalDeclID(getTotalNumDecls() + NUM_PREDEF_DECL_IDS), &F)); - - // Introduce the local -> global mapping for declarations within this - // module. - F.DeclRemap.insertOrReplace( - std::make_pair(LocalBaseDeclID, F.BaseDeclID - LocalBaseDeclID)); - - // Introduce the global -> local mapping for declarations within this - // module. - F.GlobalToLocalDeclIDs[&F] = LocalBaseDeclID; + F.BaseDeclIndex = getTotalNumDecls(); + if (F.LocalNumDecls > 0) DeclsLoaded.resize(DeclsLoaded.size() + F.LocalNumDecls); - } + break; } @@ -3631,7 +3616,7 @@ llvm::Error ASTReader::ReadASTBlock(ModuleFile &F, break; case FILE_SORTED_DECLS: - F.FileSortedDecls = (const LocalDeclID *)Blob.data(); + F.FileSortedDecls = (const unaligned_decl_id_t *)Blob.data(); F.NumFileSortedDecls = Record[0]; break; @@ -4058,7 +4043,6 @@ void ASTReader::ReadModuleOffsetMap(ModuleFile &F) const { RemapBuilder PreprocessedEntityRemap(F.PreprocessedEntityRemap); RemapBuilder SubmoduleRemap(F.SubmoduleRemap); RemapBuilder SelectorRemap(F.SelectorRemap); - RemapBuilder DeclRemap(F.DeclRemap); RemapBuilder TypeRemap(F.TypeRemap); auto &ImportedModuleVector = F.TransitiveImports; @@ -4097,8 +4081,6 @@ void ASTReader::ReadModuleOffsetMap(ModuleFile &F) const { endian::readNext(Data); uint32_t SelectorIDOffset = endian::readNext(Data); - uint32_t DeclIDOffset = - endian::readNext(Data); uint32_t TypeIndexOffset = endian::readNext(Data); @@ -4116,11 +4098,7 @@ void ASTReader::ReadModuleOffsetMap(ModuleFile &F) const { PreprocessedEntityRemap); mapOffset(SubmoduleIDOffset, OM->BaseSubmoduleID, SubmoduleRemap); mapOffset(SelectorIDOffset, OM->BaseSelectorID, SelectorRemap); - mapOffset(DeclIDOffset, OM->BaseDeclID, DeclRemap); mapOffset(TypeIndexOffset, OM->BaseTypeIndex, TypeRemap); - - // Global -> local mappings. - F.GlobalToLocalDeclIDs[OM] = DeclIDOffset; } } @@ -4645,7 +4623,7 @@ ASTReader::ASTReadResult ASTReader::ReadAST(StringRef FileName, ModuleKind Type, // that we load any additional categories. if (ContextObj) { for (unsigned I = 0, N = ObjCClassesLoaded.size(); I != N; ++I) { - loadObjCCategories(GlobalDeclID(ObjCClassesLoaded[I]->getGlobalID()), + loadObjCCategories(ObjCClassesLoaded[I]->getGlobalID(), ObjCClassesLoaded[I], PreviousGeneration); } } @@ -7644,18 +7622,25 @@ CXXBaseSpecifier *ASTReader::GetExternalCXXBaseSpecifiers(uint64_t Offset) { GlobalDeclID ASTReader::getGlobalDeclID(ModuleFile &F, LocalDeclID LocalID) const { - DeclID ID = LocalID.get(); - if (ID < NUM_PREDEF_DECL_IDS) - return GlobalDeclID(ID); + if (LocalID.get() < NUM_PREDEF_DECL_IDS) + return GlobalDeclID(LocalID.get()); + + unsigned OwningModuleFileIndex = LocalID.getModuleFileIndex(); + DeclID ID = LocalID.getLocalDeclIndex(); if (!F.ModuleOffsetMap.empty()) ReadModuleOffsetMap(F); - ContinuousRangeMap::iterator I = - F.DeclRemap.find(ID - NUM_PREDEF_DECL_IDS); - assert(I != F.DeclRemap.end() && "Invalid index into decl index remap"); + ModuleFile *OwningModuleFile = + OwningModuleFileIndex == 0 + ? &F + : F.TransitiveImports[OwningModuleFileIndex - 1]; - return GlobalDeclID(ID + I->second); + if (OwningModuleFileIndex == 0) + ID -= NUM_PREDEF_DECL_IDS; + + uint64_t NewModuleFileIndex = OwningModuleFile->Index + 1; + return GlobalDeclID(ID, NewModuleFileIndex); } bool ASTReader::isDeclIDFromModule(GlobalDeclID ID, ModuleFile &M) const { @@ -7663,31 +7648,33 @@ bool ASTReader::isDeclIDFromModule(GlobalDeclID ID, ModuleFile &M) const { if (ID.get() < NUM_PREDEF_DECL_IDS) return false; - return ID.get() - NUM_PREDEF_DECL_IDS >= M.BaseDeclID && - ID.get() - NUM_PREDEF_DECL_IDS < M.BaseDeclID + M.LocalNumDecls; + unsigned ModuleFileIndex = ID.getModuleFileIndex(); + return M.Index == ModuleFileIndex - 1; } -ModuleFile *ASTReader::getOwningModuleFile(const Decl *D) { +ModuleFile *ASTReader::getOwningModuleFile(GlobalDeclID ID) const { + // Predefined decls aren't from any module. + if (ID.get() < NUM_PREDEF_DECL_IDS) + return nullptr; + + uint64_t ModuleFileIndex = ID.getModuleFileIndex(); + assert(ModuleFileIndex && "Untranslated Local Decl?"); + + return &getModuleManager()[ModuleFileIndex - 1]; +} + +ModuleFile *ASTReader::getOwningModuleFile(const Decl *D) const { if (!D->isFromASTFile()) return nullptr; - GlobalDeclMapType::const_iterator I = - GlobalDeclMap.find(GlobalDeclID(D->getGlobalID())); - assert(I != GlobalDeclMap.end() && "Corrupted global declaration map"); - return I->second; + + return getOwningModuleFile(D->getGlobalID()); } SourceLocation ASTReader::getSourceLocationForDeclID(GlobalDeclID ID) { if (ID.get() < NUM_PREDEF_DECL_IDS) return SourceLocation(); - unsigned Index = ID.get() - NUM_PREDEF_DECL_IDS; - - if (Index > DeclsLoaded.size()) { - Error("declaration ID out-of-range for AST file"); - return SourceLocation(); - } - - if (Decl *D = DeclsLoaded[Index]) + if (Decl *D = GetExistingDecl(ID)) return D->getLocation(); SourceLocation Loc; @@ -7754,8 +7741,19 @@ static Decl *getPredefinedDecl(ASTContext &Context, PredefinedDeclIDs ID) { llvm_unreachable("PredefinedDeclIDs unknown enum value"); } +unsigned ASTReader::translateGlobalDeclIDToIndex(GlobalDeclID GlobalID) const { + ModuleFile *OwningModuleFile = getOwningModuleFile(GlobalID); + if (!OwningModuleFile) { + assert(GlobalID.get() < NUM_PREDEF_DECL_IDS && "Untransalted Global ID?"); + return GlobalID.get(); + } + + return OwningModuleFile->BaseDeclIndex + GlobalID.getLocalDeclIndex(); +} + Decl *ASTReader::GetExistingDecl(GlobalDeclID ID) { assert(ContextObj && "reading decl with no AST context"); + if (ID.get() < NUM_PREDEF_DECL_IDS) { Decl *D = getPredefinedDecl(*ContextObj, (PredefinedDeclIDs)ID); if (D) { @@ -7768,7 +7766,7 @@ Decl *ASTReader::GetExistingDecl(GlobalDeclID ID) { return D; } - unsigned Index = ID.get() - NUM_PREDEF_DECL_IDS; + unsigned Index = translateGlobalDeclIDToIndex(ID); if (Index >= DeclsLoaded.size()) { assert(0 && "declaration ID out-of-range for AST file"); @@ -7783,7 +7781,7 @@ Decl *ASTReader::GetDecl(GlobalDeclID ID) { if (ID.get() < NUM_PREDEF_DECL_IDS) return GetExistingDecl(ID); - unsigned Index = ID.get() - NUM_PREDEF_DECL_IDS; + unsigned Index = translateGlobalDeclIDToIndex(ID); if (Index >= DeclsLoaded.size()) { assert(0 && "declaration ID out-of-range for AST file"); @@ -7802,20 +7800,31 @@ Decl *ASTReader::GetDecl(GlobalDeclID ID) { LocalDeclID ASTReader::mapGlobalIDToModuleFileGlobalID(ModuleFile &M, GlobalDeclID GlobalID) { - DeclID ID = GlobalID.get(); - if (ID < NUM_PREDEF_DECL_IDS) + if (GlobalID.get() < NUM_PREDEF_DECL_IDS) + return LocalDeclID(GlobalID.get()); + + if (!M.ModuleOffsetMap.empty()) + ReadModuleOffsetMap(M); + + ModuleFile *Owner = getOwningModuleFile(GlobalID); + DeclID ID = GlobalID.getLocalDeclIndex(); + + if (Owner == &M) { + ID += NUM_PREDEF_DECL_IDS; return LocalDeclID(ID); + } - GlobalDeclMapType::const_iterator I = GlobalDeclMap.find(GlobalID); - assert(I != GlobalDeclMap.end() && "Corrupted global declaration map"); - ModuleFile *Owner = I->second; + uint64_t OrignalModuleFileIndex = 0; + for (unsigned I = 0; I < M.TransitiveImports.size(); I++) + if (M.TransitiveImports[I] == Owner) { + OrignalModuleFileIndex = I + 1; + break; + } - llvm::DenseMap::iterator Pos = - M.GlobalToLocalDeclIDs.find(Owner); - if (Pos == M.GlobalToLocalDeclIDs.end()) + if (!OrignalModuleFileIndex) return LocalDeclID(); - return LocalDeclID(ID - Owner->BaseDeclID + Pos->second); + return LocalDeclID(ID, OrignalModuleFileIndex); } GlobalDeclID ASTReader::ReadDeclID(ModuleFile &F, const RecordData &Record, @@ -7894,32 +7903,34 @@ void ASTReader::FindExternalLexicalDecls( namespace { -class DeclIDComp { +class UnalignedDeclIDComp { ASTReader &Reader; ModuleFile &Mod; public: - DeclIDComp(ASTReader &Reader, ModuleFile &M) : Reader(Reader), Mod(M) {} + UnalignedDeclIDComp(ASTReader &Reader, ModuleFile &M) + : Reader(Reader), Mod(M) {} - bool operator()(LocalDeclID L, LocalDeclID R) const { + bool operator()(unaligned_decl_id_t L, unaligned_decl_id_t R) const { SourceLocation LHS = getLocation(L); SourceLocation RHS = getLocation(R); return Reader.getSourceManager().isBeforeInTranslationUnit(LHS, RHS); } - bool operator()(SourceLocation LHS, LocalDeclID R) const { + bool operator()(SourceLocation LHS, unaligned_decl_id_t R) const { SourceLocation RHS = getLocation(R); return Reader.getSourceManager().isBeforeInTranslationUnit(LHS, RHS); } - bool operator()(LocalDeclID L, SourceLocation RHS) const { + bool operator()(unaligned_decl_id_t L, SourceLocation RHS) const { SourceLocation LHS = getLocation(L); return Reader.getSourceManager().isBeforeInTranslationUnit(LHS, RHS); } - SourceLocation getLocation(LocalDeclID ID) const { + SourceLocation getLocation(unaligned_decl_id_t ID) const { return Reader.getSourceManager().getFileLoc( - Reader.getSourceLocationForDeclID(Reader.getGlobalDeclID(Mod, ID))); + Reader.getSourceLocationForDeclID( + Reader.getGlobalDeclID(Mod, (LocalDeclID)ID))); } }; @@ -7942,8 +7953,8 @@ void ASTReader::FindFileRegionDecls(FileID File, BeginLoc = SM.getLocForStartOfFile(File).getLocWithOffset(Offset); SourceLocation EndLoc = BeginLoc.getLocWithOffset(Length); - DeclIDComp DIDComp(*this, *DInfo.Mod); - ArrayRef::iterator BeginIt = + UnalignedDeclIDComp DIDComp(*this, *DInfo.Mod); + ArrayRef::iterator BeginIt = llvm::lower_bound(DInfo.Decls, BeginLoc, DIDComp); if (BeginIt != DInfo.Decls.begin()) --BeginIt; @@ -7952,17 +7963,18 @@ void ASTReader::FindFileRegionDecls(FileID File, // to backtrack until we find it otherwise we will fail to report that the // region overlaps with an objc container. while (BeginIt != DInfo.Decls.begin() && - GetDecl(getGlobalDeclID(*DInfo.Mod, *BeginIt)) + GetDecl(getGlobalDeclID(*DInfo.Mod, (LocalDeclID)(*BeginIt))) ->isTopLevelDeclInObjCContainer()) --BeginIt; - ArrayRef::iterator EndIt = + ArrayRef::iterator EndIt = llvm::upper_bound(DInfo.Decls, EndLoc, DIDComp); if (EndIt != DInfo.Decls.end()) ++EndIt; - for (ArrayRef::iterator DIt = BeginIt; DIt != EndIt; ++DIt) - Decls.push_back(GetDecl(getGlobalDeclID(*DInfo.Mod, *DIt))); + for (ArrayRef::iterator DIt = BeginIt; DIt != EndIt; + ++DIt) + Decls.push_back(GetDecl(getGlobalDeclID(*DInfo.Mod, (LocalDeclID)(*DIt)))); } bool @@ -8169,7 +8181,6 @@ LLVM_DUMP_METHOD void ASTReader::dump() { dumpModuleIDMap("Global bit offset map", GlobalBitOffsetsMap); dumpModuleIDMap("Global source location entry map", GlobalSLocEntryMap); dumpModuleIDMap("Global type map", GlobalTypeMap); - dumpModuleIDMap("Global declaration map", GlobalDeclMap); dumpModuleIDMap("Global identifier map", GlobalIdentifierMap); dumpModuleIDMap("Global macro map", GlobalMacroMap); dumpModuleIDMap("Global submodule map", GlobalSubmoduleMap); @@ -9185,7 +9196,7 @@ void ASTRecordReader::readUnresolvedSet(LazyASTUnresolvedSet &Set) { while (NumDecls--) { GlobalDeclID ID = readDeclID(); AccessSpecifier AS = (AccessSpecifier) readInt(); - Set.addLazyDecl(getContext(), ID.get(), AS); + Set.addLazyDecl(getContext(), ID, AS); } } @@ -11944,12 +11955,15 @@ OpenACCClause *ASTRecordReader::readOpenACCClause() { return OpenACCReductionClause::Create(getContext(), BeginLoc, LParenLoc, Op, VarList, EndLoc); } - - case OpenACCClauseKind::Finalize: - case OpenACCClauseKind::IfPresent: case OpenACCClauseKind::Seq: + return OpenACCSeqClause::Create(getContext(), BeginLoc, EndLoc); case OpenACCClauseKind::Independent: + return OpenACCIndependentClause::Create(getContext(), BeginLoc, EndLoc); case OpenACCClauseKind::Auto: + return OpenACCAutoClause::Create(getContext(), BeginLoc, EndLoc); + + case OpenACCClauseKind::Finalize: + case OpenACCClauseKind::IfPresent: case OpenACCClauseKind::Worker: case OpenACCClauseKind::Vector: case OpenACCClauseKind::NoHost: diff --git a/clang/lib/Serialization/ASTReaderDecl.cpp b/clang/lib/Serialization/ASTReaderDecl.cpp index 765c083ce8df8cbb67adc232a962d906c5692ad5..cf2dc32e30b91e3b55a6857609d661da20c1085d 100644 --- a/clang/lib/Serialization/ASTReaderDecl.cpp +++ b/clang/lib/Serialization/ASTReaderDecl.cpp @@ -2924,7 +2924,7 @@ void ASTDeclReader::mergeTemplatePattern(RedeclarableTemplateDecl *D, auto *ExistingPattern = Existing->getTemplatedDecl(); RedeclarableResult Result( /*MergeWith*/ ExistingPattern, - GlobalDeclID(DPattern->getCanonicalDecl()->getGlobalID()), IsKeyDecl); + DPattern->getCanonicalDecl()->getGlobalID(), IsKeyDecl); if (auto *DClass = dyn_cast(DPattern)) { // Merge with any existing definition. @@ -3245,11 +3245,10 @@ bool ASTReader::isConsumerInterestedIn(Decl *D) { /// Get the correct cursor and offset for loading a declaration. ASTReader::RecordLocation ASTReader::DeclCursorForID(GlobalDeclID ID, SourceLocation &Loc) { - GlobalDeclMapType::iterator I = GlobalDeclMap.find(ID); - assert(I != GlobalDeclMap.end() && "Corrupted global declaration map"); - ModuleFile *M = I->second; - const DeclOffset &DOffs = - M->DeclOffsets[ID.get() - M->BaseDeclID - NUM_PREDEF_DECL_IDS]; + ModuleFile *M = getOwningModuleFile(ID); + assert(M); + unsigned LocalDeclIndex = ID.getLocalDeclIndex(); + const DeclOffset &DOffs = M->DeclOffsets[LocalDeclIndex]; Loc = ReadSourceLocation(*M, DOffs.getRawLoc()); return RecordLocation(M, DOffs.getBitOffset(M->DeclsBlockStartOffset)); } @@ -3792,7 +3791,6 @@ void ASTReader::markIncompleteDeclChain(Decl *D) { /// Read the declaration at the given offset from the AST file. Decl *ASTReader::ReadDeclRecord(GlobalDeclID ID) { - unsigned Index = ID.get() - NUM_PREDEF_DECL_IDS; SourceLocation DeclLoc; RecordLocation Loc = DeclCursorForID(ID, DeclLoc); llvm::BitstreamCursor &DeclsCursor = Loc.F->DeclsCursor; @@ -4123,7 +4121,7 @@ Decl *ASTReader::ReadDeclRecord(GlobalDeclID ID) { } assert(D && "Unknown declaration reading AST file"); - LoadedDecl(Index, D); + LoadedDecl(translateGlobalDeclIDToIndex(ID), D); // Set the DeclContext before doing any deserialization, to make sure internal // calls to Decl::getASTContext() by Decl's methods will find the // TranslationUnitDecl without crashing. @@ -4449,7 +4447,7 @@ namespace { M.ObjCCategoriesMap + M.LocalNumObjCCategoriesInMap, Compare); if (Result == M.ObjCCategoriesMap + M.LocalNumObjCCategoriesInMap || - Result->DefinitionID != LocalID) { + Result->getDefinitionID() != LocalID) { // We didn't find anything. If the class definition is in this module // file, then the module files it depends on cannot have any categories, // so suppress further lookup. diff --git a/clang/lib/Serialization/ASTReaderStmt.cpp b/clang/lib/Serialization/ASTReaderStmt.cpp index bea2b94989107071879be807cc3b4a94e67b255a..67ef170251914ea58fb1568bf6b1ce9f3ca0d057 100644 --- a/clang/lib/Serialization/ASTReaderStmt.cpp +++ b/clang/lib/Serialization/ASTReaderStmt.cpp @@ -2810,6 +2810,12 @@ void ASTStmtReader::VisitOpenACCAssociatedStmtConstruct( void ASTStmtReader::VisitOpenACCComputeConstruct(OpenACCComputeConstruct *S) { VisitStmt(S); VisitOpenACCAssociatedStmtConstruct(S); + S->findAndSetChildLoops(); +} + +void ASTStmtReader::VisitOpenACCLoopConstruct(OpenACCLoopConstruct *S) { + VisitStmt(S); + VisitOpenACCAssociatedStmtConstruct(S); } //===----------------------------------------------------------------------===// @@ -4235,6 +4241,11 @@ Stmt *ASTReader::ReadStmtFromStream(ModuleFile &F) { S = OpenACCComputeConstruct::CreateEmpty(Context, NumClauses); break; } + case STMT_OPENACC_LOOP_CONSTRUCT: { + unsigned NumClauses = Record[ASTStmtReader::NumStmtFields]; + S = OpenACCLoopConstruct::CreateEmpty(Context, NumClauses); + break; + } case EXPR_REQUIRES: unsigned numLocalParameters = Record[ASTStmtReader::NumExprFields]; unsigned numRequirement = Record[ASTStmtReader::NumExprFields + 1]; diff --git a/clang/lib/Serialization/ASTWriter.cpp b/clang/lib/Serialization/ASTWriter.cpp index d18dbad983d75b45434faef8599d7fb61191d013..ee3e687636e6a0451816b4f57999985a65db53cd 100644 --- a/clang/lib/Serialization/ASTWriter.cpp +++ b/clang/lib/Serialization/ASTWriter.cpp @@ -3357,12 +3357,10 @@ void ASTWriter::WriteTypeDeclOffsets() { Abbrev = std::make_shared(); Abbrev->Add(BitCodeAbbrevOp(DECL_OFFSET)); Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32)); // # of declarations - Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32)); // base decl ID Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); // declarations block unsigned DeclOffsetAbbrev = Stream.EmitAbbrev(std::move(Abbrev)); { - RecordData::value_type Record[] = {DECL_OFFSET, DeclOffsets.size(), - FirstDeclID.get() - NUM_PREDEF_DECL_IDS}; + RecordData::value_type Record[] = {DECL_OFFSET, DeclOffsets.size()}; Stream.EmitRecordWithBlob(DeclOffsetAbbrev, Record, bytes(DeclOffsets)); } } @@ -5423,7 +5421,6 @@ ASTFileSignature ASTWriter::WriteASTCore(Sema &SemaRef, StringRef isysroot, M.NumPreprocessedEntities); writeBaseIDOrNone(M.BaseSubmoduleID, M.LocalNumSubmodules); writeBaseIDOrNone(M.BaseSelectorID, M.LocalNumSelectors); - writeBaseIDOrNone(M.BaseDeclID, M.LocalNumDecls); writeBaseIDOrNone(M.BaseTypeIndex, M.LocalNumTypes); } } @@ -6618,13 +6615,11 @@ void ASTWriter::ReaderInitialized(ASTReader *Reader) { // Note, this will get called multiple times, once one the reader starts up // and again each time it's done reading a PCH or module. - FirstDeclID = LocalDeclID(NUM_PREDEF_DECL_IDS + Chain->getTotalNumDecls()); FirstTypeID = NUM_PREDEF_TYPE_IDS + Chain->getTotalNumTypes(); FirstIdentID = NUM_PREDEF_IDENT_IDS + Chain->getTotalNumIdentifiers(); FirstMacroID = NUM_PREDEF_MACRO_IDS + Chain->getTotalNumMacros(); FirstSubmoduleID = NUM_PREDEF_SUBMODULE_IDS + Chain->getTotalNumSubmodules(); FirstSelectorID = NUM_PREDEF_SELECTOR_IDS + Chain->getTotalNumSelectors(); - NextDeclID = FirstDeclID; NextTypeID = FirstTypeID; NextIdentID = FirstIdentID; NextMacroID = FirstMacroID; @@ -7975,12 +7970,15 @@ void ASTRecordWriter::writeOpenACCClause(const OpenACCClause *C) { writeOpenACCVarList(RC); return; } - - case OpenACCClauseKind::Finalize: - case OpenACCClauseKind::IfPresent: case OpenACCClauseKind::Seq: case OpenACCClauseKind::Independent: case OpenACCClauseKind::Auto: + // Nothing to do here, there is no additional information beyond the + // begin/end loc and clause kind. + return; + + case OpenACCClauseKind::Finalize: + case OpenACCClauseKind::IfPresent: case OpenACCClauseKind::Worker: case OpenACCClauseKind::Vector: case OpenACCClauseKind::NoHost: diff --git a/clang/lib/Serialization/ASTWriterStmt.cpp b/clang/lib/Serialization/ASTWriterStmt.cpp index 3c586b270fbf4f6c46df9ccb85f09682f2dcdd37..1a98e30e0f89fa9e7bf079c87a291aae23b12779 100644 --- a/clang/lib/Serialization/ASTWriterStmt.cpp +++ b/clang/lib/Serialization/ASTWriterStmt.cpp @@ -2863,6 +2863,12 @@ void ASTStmtWriter::VisitOpenACCComputeConstruct(OpenACCComputeConstruct *S) { Code = serialization::STMT_OPENACC_COMPUTE_CONSTRUCT; } +void ASTStmtWriter::VisitOpenACCLoopConstruct(OpenACCLoopConstruct *S) { + VisitStmt(S); + VisitOpenACCAssociatedStmtConstruct(S); + Code = serialization::STMT_OPENACC_LOOP_CONSTRUCT; +} + //===----------------------------------------------------------------------===// // ASTWriter Implementation //===----------------------------------------------------------------------===// diff --git a/clang/lib/Serialization/ModuleFile.cpp b/clang/lib/Serialization/ModuleFile.cpp index 2c42d33a8f5dd3c937dee7b0c198bcc0a29959ba..f64a59bd9489146e0e6535d730232c92177f1d04 100644 --- a/clang/lib/Serialization/ModuleFile.cpp +++ b/clang/lib/Serialization/ModuleFile.cpp @@ -87,7 +87,6 @@ LLVM_DUMP_METHOD void ModuleFile::dump() { << " Number of types: " << LocalNumTypes << '\n'; dumpLocalRemap("Type index local -> global map", TypeRemap); - llvm::errs() << " Base decl ID: " << BaseDeclID << '\n' + llvm::errs() << " Base decl index: " << BaseDeclIndex << '\n' << " Number of decls: " << LocalNumDecls << '\n'; - dumpLocalRemap("Decl ID local -> global map", DeclRemap); } diff --git a/clang/lib/StaticAnalyzer/Checkers/CMakeLists.txt b/clang/lib/StaticAnalyzer/Checkers/CMakeLists.txt index cd5a3bdd02e4a614a3341e21cb0523dcaaae3d7e..68e829cace495168a79ac37fab9aebb1dbaaff01 100644 --- a/clang/lib/StaticAnalyzer/Checkers/CMakeLists.txt +++ b/clang/lib/StaticAnalyzer/Checkers/CMakeLists.txt @@ -78,6 +78,7 @@ add_clang_library(clangStaticAnalyzerCheckers NoReturnFunctionChecker.cpp NonNullParamChecker.cpp NonnullGlobalConstantsChecker.cpp + NoOwnershipChangeVisitor.cpp NullabilityChecker.cpp NumberObjectConversionChecker.cpp ObjCAtSyncChecker.cpp diff --git a/clang/lib/StaticAnalyzer/Checkers/MallocChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/MallocChecker.cpp index 34af7fb131f5a173d2f80603da5db29659decebe..fe202c79ed62091ae8728bd9fe54d2bb1cdc9918 100644 --- a/clang/lib/StaticAnalyzer/Checkers/MallocChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/MallocChecker.cpp @@ -46,6 +46,7 @@ #include "AllocationState.h" #include "InterCheckerAPI.h" +#include "NoOwnershipChangeVisitor.h" #include "clang/AST/Attr.h" #include "clang/AST/DeclCXX.h" #include "clang/AST/DeclTemplate.h" @@ -60,6 +61,7 @@ #include "clang/Basic/TargetInfo.h" #include "clang/Lex/Lexer.h" #include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h" +#include "clang/StaticAnalyzer/Checkers/Taint.h" #include "clang/StaticAnalyzer/Core/BugReporter/BugType.h" #include "clang/StaticAnalyzer/Core/BugReporter/CommonBugCategories.h" #include "clang/StaticAnalyzer/Core/Checker.h" @@ -78,13 +80,11 @@ #include "clang/StaticAnalyzer/Core/PathSensitive/SymbolManager.h" #include "llvm/ADT/STLExtras.h" #include "llvm/ADT/SetOperations.h" -#include "llvm/ADT/SmallString.h" #include "llvm/ADT/StringExtras.h" #include "llvm/Support/Casting.h" #include "llvm/Support/Compiler.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/raw_ostream.h" -#include #include #include #include @@ -322,6 +322,7 @@ public: CK_NewDeleteLeaksChecker, CK_MismatchedDeallocatorChecker, CK_InnerPointerChecker, + CK_TaintedAllocChecker, CK_NumCheckKinds }; @@ -365,6 +366,7 @@ private: mutable std::unique_ptr BT_MismatchedDealloc; mutable std::unique_ptr BT_OffsetFree[CK_NumCheckKinds]; mutable std::unique_ptr BT_UseZerroAllocated[CK_NumCheckKinds]; + mutable std::unique_ptr BT_TaintedAlloc; #define CHECK_FN(NAME) \ void NAME(const CallEvent &Call, CheckerContext &C) const; @@ -411,7 +413,7 @@ private: bool isFreeingCall(const CallEvent &Call) const; static bool isFreeingOwnershipAttrCall(const FunctionDecl *Func); - friend class NoOwnershipChangeVisitor; + friend class NoMemOwnershipChangeVisitor; CallDescriptionMap AllocatingMemFnMap{ {{CDM::CLibrary, {"alloca"}, 1}, &MallocChecker::checkAlloca}, @@ -462,6 +464,13 @@ private: }; bool isMemCall(const CallEvent &Call) const; + void reportTaintBug(StringRef Msg, ProgramStateRef State, CheckerContext &C, + llvm::ArrayRef TaintedSyms, + AllocationFamily Family) const; + + void checkTaintedness(CheckerContext &C, const CallEvent &Call, + const SVal SizeSVal, ProgramStateRef State, + AllocationFamily Family) const; // TODO: Remove mutable by moving the initializtaion to the registry function. mutable std::optional KernelZeroFlagVal; @@ -521,9 +530,9 @@ private: /// malloc leaves it undefined. /// \param [in] State The \c ProgramState right before allocation. /// \returns The ProgramState right after allocation. - [[nodiscard]] static ProgramStateRef + [[nodiscard]] ProgramStateRef MallocMemAux(CheckerContext &C, const CallEvent &Call, const Expr *SizeEx, - SVal Init, ProgramStateRef State, AllocationFamily Family); + SVal Init, ProgramStateRef State, AllocationFamily Family) const; /// Models memory allocation. /// @@ -534,9 +543,10 @@ private: /// malloc leaves it undefined. /// \param [in] State The \c ProgramState right before allocation. /// \returns The ProgramState right after allocation. - [[nodiscard]] static ProgramStateRef - MallocMemAux(CheckerContext &C, const CallEvent &Call, SVal Size, SVal Init, - ProgramStateRef State, AllocationFamily Family); + [[nodiscard]] ProgramStateRef MallocMemAux(CheckerContext &C, + const CallEvent &Call, SVal Size, + SVal Init, ProgramStateRef State, + AllocationFamily Family) const; // Check if this malloc() for special flags. At present that means M_ZERO or // __GFP_ZERO (in which case, treat it like calloc). @@ -649,8 +659,9 @@ private: /// \param [in] Call The expression that reallocated memory /// \param [in] State The \c ProgramState right before reallocation. /// \returns The ProgramState right after allocation. - [[nodiscard]] static ProgramStateRef - CallocMem(CheckerContext &C, const CallEvent &Call, ProgramStateRef State); + [[nodiscard]] ProgramStateRef CallocMem(CheckerContext &C, + const CallEvent &Call, + ProgramStateRef State) const; /// See if deallocation happens in a suspicious context. If so, escape the /// pointers that otherwise would have been deallocated and return true. @@ -753,61 +764,8 @@ private: //===----------------------------------------------------------------------===// namespace { -class NoOwnershipChangeVisitor final : public NoStateChangeFuncVisitor { - // The symbol whose (lack of) ownership change we are interested in. - SymbolRef Sym; - const MallocChecker &Checker; - using OwnerSet = llvm::SmallPtrSet; - - // Collect which entities point to the allocated memory, and could be - // responsible for deallocating it. - class OwnershipBindingsHandler : public StoreManager::BindingsHandler { - SymbolRef Sym; - OwnerSet &Owners; - - public: - OwnershipBindingsHandler(SymbolRef Sym, OwnerSet &Owners) - : Sym(Sym), Owners(Owners) {} - - bool HandleBinding(StoreManager &SMgr, Store Store, const MemRegion *Region, - SVal Val) override { - if (Val.getAsSymbol() == Sym) - Owners.insert(Region); - return true; - } - - LLVM_DUMP_METHOD void dump() const { dumpToStream(llvm::errs()); } - LLVM_DUMP_METHOD void dumpToStream(llvm::raw_ostream &out) const { - out << "Owners: {\n"; - for (const MemRegion *Owner : Owners) { - out << " "; - Owner->dumpToStream(out); - out << ",\n"; - } - out << "}\n"; - } - }; - +class NoMemOwnershipChangeVisitor final : public NoOwnershipChangeVisitor { protected: - OwnerSet getOwnersAtNode(const ExplodedNode *N) { - OwnerSet Ret; - - ProgramStateRef State = N->getState(); - OwnershipBindingsHandler Handler{Sym, Ret}; - State->getStateManager().getStoreManager().iterBindings(State->getStore(), - Handler); - return Ret; - } - - LLVM_DUMP_METHOD static std::string - getFunctionName(const ExplodedNode *CallEnterN) { - if (const CallExpr *CE = llvm::dyn_cast_or_null( - CallEnterN->getLocationAs()->getCallExpr())) - if (const FunctionDecl *FD = CE->getDirectCallee()) - return FD->getQualifiedNameAsString(); - return ""; - } - /// Syntactically checks whether the callee is a deallocating function. Since /// we have no path-sensitive information on this call (we would need a /// CallEvent instead of a CallExpr for that), its possible that a @@ -816,8 +774,9 @@ protected: /// See namespace `memory_passed_to_fn_call_free_through_fn_ptr` in /// clang/test/Analysis/NewDeleteLeaks.cpp. bool isFreeingCallAsWritten(const CallExpr &Call) const { - if (Checker.FreeingMemFnMap.lookupAsWritten(Call) || - Checker.ReallocatingMemFnMap.lookupAsWritten(Call)) + const auto *MallocChk = static_cast(&Checker); + if (MallocChk->FreeingMemFnMap.lookupAsWritten(Call) || + MallocChk->ReallocatingMemFnMap.lookupAsWritten(Call)) return true; if (const auto *Func = @@ -827,23 +786,21 @@ protected: return false; } + bool hasResourceStateChanged(ProgramStateRef CallEnterState, + ProgramStateRef CallExitEndState) final { + return CallEnterState->get(Sym) != + CallExitEndState->get(Sym); + } + /// Heuristically guess whether the callee intended to free memory. This is /// done syntactically, because we are trying to argue about alternative /// paths of execution, and as a consequence we don't have path-sensitive /// information. - bool doesFnIntendToHandleOwnership(const Decl *Callee, ASTContext &ACtx) { + bool doesFnIntendToHandleOwnership(const Decl *Callee, + ASTContext &ACtx) final { using namespace clang::ast_matchers; const FunctionDecl *FD = dyn_cast(Callee); - // Given that the stack frame was entered, the body should always be - // theoretically obtainable. In case of body farms, the synthesized body - // is not attached to declaration, thus triggering the '!FD->hasBody()' - // branch. That said, would a synthesized body ever intend to handle - // ownership? As of today they don't. And if they did, how would we - // put notes inside it, given that it doesn't match any source locations? - if (!FD || !FD->hasBody()) - return false; - auto Matches = match(findAll(stmt(anyOf(cxxDeleteExpr().bind("delete"), callExpr().bind("call")))), *FD->getBody(), ACtx); @@ -861,30 +818,7 @@ protected: return false; } - bool wasModifiedInFunction(const ExplodedNode *CallEnterN, - const ExplodedNode *CallExitEndN) override { - if (!doesFnIntendToHandleOwnership( - CallExitEndN->getFirstPred()->getLocationContext()->getDecl(), - CallExitEndN->getState()->getAnalysisManager().getASTContext())) - return true; - - if (CallEnterN->getState()->get(Sym) != - CallExitEndN->getState()->get(Sym)) - return true; - - OwnerSet CurrOwners = getOwnersAtNode(CallEnterN); - OwnerSet ExitOwners = getOwnersAtNode(CallExitEndN); - - // Owners in the current set may be purged from the analyzer later on. - // If a variable is dead (is not referenced directly or indirectly after - // some point), it will be removed from the Store before the end of its - // actual lifetime. - // This means that if the ownership status didn't change, CurrOwners - // must be a superset of, but not necessarily equal to ExitOwners. - return !llvm::set_is_subset(ExitOwners, CurrOwners); - } - - static PathDiagnosticPieceRef emitNote(const ExplodedNode *N) { + PathDiagnosticPieceRef emitNote(const ExplodedNode *N) final { PathDiagnosticLocation L = PathDiagnosticLocation::create( N->getLocation(), N->getState()->getStateManager().getContext().getSourceManager()); @@ -893,42 +827,9 @@ protected: "later deallocation"); } - PathDiagnosticPieceRef - maybeEmitNoteForObjCSelf(PathSensitiveBugReport &R, - const ObjCMethodCall &Call, - const ExplodedNode *N) override { - // TODO: Implement. - return nullptr; - } - - PathDiagnosticPieceRef - maybeEmitNoteForCXXThis(PathSensitiveBugReport &R, - const CXXConstructorCall &Call, - const ExplodedNode *N) override { - // TODO: Implement. - return nullptr; - } - - PathDiagnosticPieceRef - maybeEmitNoteForParameters(PathSensitiveBugReport &R, const CallEvent &Call, - const ExplodedNode *N) override { - // TODO: Factor the logic of "what constitutes as an entity being passed - // into a function call" out by reusing the code in - // NoStoreFuncVisitor::maybeEmitNoteForParameters, maybe by incorporating - // the printing technology in UninitializedObject's FieldChainInfo. - ArrayRef Parameters = Call.parameters(); - for (unsigned I = 0; I < Call.getNumArgs() && I < Parameters.size(); ++I) { - SVal V = Call.getArgSVal(I); - if (V.getAsSymbol() == Sym) - return emitNote(N); - } - return nullptr; - } - public: - NoOwnershipChangeVisitor(SymbolRef Sym, const MallocChecker *Checker) - : NoStateChangeFuncVisitor(bugreporter::TrackingKind::Thorough), Sym(Sym), - Checker(*Checker) {} + NoMemOwnershipChangeVisitor(SymbolRef Sym, const MallocChecker *Checker) + : NoOwnershipChangeVisitor(Sym, Checker) {} void Profile(llvm::FoldingSetNodeID &ID) const override { static int Tag = 0; @@ -1695,6 +1596,11 @@ MallocChecker::processNewAllocation(const CXXAllocatorCall &Call, // MallocUpdateRefState() instead of MallocMemAux() which breaks the // existing binding. SVal Target = Call.getObjectUnderConstruction(); + if (Call.getOriginExpr()->isArray()) { + if (auto SizeEx = NE->getArraySize()) + checkTaintedness(C, Call, C.getSVal(*SizeEx), State, AF_CXXNewArray); + } + State = MallocUpdateRefState(C, NE, State, Family, Target); State = ProcessZeroAllocCheck(Call, 0, State, Target); return State; @@ -1779,7 +1685,7 @@ ProgramStateRef MallocChecker::MallocMemAux(CheckerContext &C, const CallEvent &Call, const Expr *SizeEx, SVal Init, ProgramStateRef State, - AllocationFamily Family) { + AllocationFamily Family) const { if (!State) return nullptr; @@ -1787,10 +1693,66 @@ ProgramStateRef MallocChecker::MallocMemAux(CheckerContext &C, return MallocMemAux(C, Call, C.getSVal(SizeEx), Init, State, Family); } +void MallocChecker::reportTaintBug(StringRef Msg, ProgramStateRef State, + CheckerContext &C, + llvm::ArrayRef TaintedSyms, + AllocationFamily Family) const { + if (ExplodedNode *N = C.generateNonFatalErrorNode(State, this)) { + if (!BT_TaintedAlloc) + BT_TaintedAlloc.reset(new BugType(CheckNames[CK_TaintedAllocChecker], + "Tainted Memory Allocation", + categories::TaintedData)); + auto R = std::make_unique(*BT_TaintedAlloc, Msg, N); + for (auto TaintedSym : TaintedSyms) { + R->markInteresting(TaintedSym); + } + C.emitReport(std::move(R)); + } +} + +void MallocChecker::checkTaintedness(CheckerContext &C, const CallEvent &Call, + const SVal SizeSVal, ProgramStateRef State, + AllocationFamily Family) const { + if (!ChecksEnabled[CK_TaintedAllocChecker]) + return; + std::vector TaintedSyms = + taint::getTaintedSymbols(State, SizeSVal); + if (TaintedSyms.empty()) + return; + + SValBuilder &SVB = C.getSValBuilder(); + QualType SizeTy = SVB.getContext().getSizeType(); + QualType CmpTy = SVB.getConditionType(); + // In case the symbol is tainted, we give a warning if the + // size is larger than SIZE_MAX/4 + BasicValueFactory &BVF = SVB.getBasicValueFactory(); + const llvm::APSInt MaxValInt = BVF.getMaxValue(SizeTy); + NonLoc MaxLength = + SVB.makeIntVal(MaxValInt / APSIntType(MaxValInt).getValue(4)); + std::optional SizeNL = SizeSVal.getAs(); + auto Cmp = SVB.evalBinOpNN(State, BO_GE, *SizeNL, MaxLength, CmpTy) + .getAs(); + if (!Cmp) + return; + auto [StateTooLarge, StateNotTooLarge] = State->assume(*Cmp); + if (!StateTooLarge && StateNotTooLarge) { + // We can prove that size is not too large so there is no issue. + return; + } + + std::string Callee = "Memory allocation function"; + if (Call.getCalleeIdentifier()) + Callee = Call.getCalleeIdentifier()->getName().str(); + reportTaintBug( + Callee + " is called with a tainted (potentially attacker controlled) " + "value. Make sure the value is bound checked.", + State, C, TaintedSyms, Family); +} + ProgramStateRef MallocChecker::MallocMemAux(CheckerContext &C, const CallEvent &Call, SVal Size, SVal Init, ProgramStateRef State, - AllocationFamily Family) { + AllocationFamily Family) const { if (!State) return nullptr; @@ -1819,9 +1781,7 @@ ProgramStateRef MallocChecker::MallocMemAux(CheckerContext &C, if (Size.isUndef()) Size = UnknownVal(); - // TODO: If Size is tainted and we cannot prove that it is within - // reasonable bounds, emit a warning that an attacker may - // provoke a memory exhaustion error. + checkTaintedness(C, Call, Size, State, AF_Malloc); // Set the region's extent. State = setDynamicExtent(State, RetVal.getAsRegion(), @@ -2761,7 +2721,7 @@ MallocChecker::ReallocMemAux(CheckerContext &C, const CallEvent &Call, ProgramStateRef MallocChecker::CallocMem(CheckerContext &C, const CallEvent &Call, - ProgramStateRef State) { + ProgramStateRef State) const { if (!State) return nullptr; @@ -2878,7 +2838,7 @@ void MallocChecker::HandleLeak(SymbolRef Sym, ExplodedNode *N, R->markInteresting(Sym); R->addVisitor(Sym, true); if (ShouldRegisterNoOwnershipChangeVisitor) - R->addVisitor(Sym, this); + R->addVisitor(Sym, this); C.emitReport(std::move(R)); } @@ -3734,3 +3694,4 @@ REGISTER_CHECKER(MallocChecker) REGISTER_CHECKER(NewDeleteChecker) REGISTER_CHECKER(NewDeleteLeaksChecker) REGISTER_CHECKER(MismatchedDeallocatorChecker) +REGISTER_CHECKER(TaintedAllocChecker) diff --git a/clang/lib/StaticAnalyzer/Checkers/NoOwnershipChangeVisitor.cpp b/clang/lib/StaticAnalyzer/Checkers/NoOwnershipChangeVisitor.cpp new file mode 100644 index 0000000000000000000000000000000000000000..2ff76679b5ebf744d93a832a7f1c0763521cbab9 --- /dev/null +++ b/clang/lib/StaticAnalyzer/Checkers/NoOwnershipChangeVisitor.cpp @@ -0,0 +1,116 @@ +//===--------------------------------------------------------------*- 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 "NoOwnershipChangeVisitor.h" +#include "clang/StaticAnalyzer/Core/BugReporter/BugReporterVisitors.h" +#include "clang/StaticAnalyzer/Core/PathSensitive/AnalysisManager.h" +#include "clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h" +#include "clang/StaticAnalyzer/Core/PathSensitive/ExplodedGraph.h" +#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState_Fwd.h" +#include "llvm/ADT/SetOperations.h" + +using namespace clang; +using namespace ento; +using OwnerSet = NoOwnershipChangeVisitor::OwnerSet; + +// Collect which entities point to the allocated memory, and could be +// responsible for deallocating it. +class OwnershipBindingsHandler : public StoreManager::BindingsHandler { + SymbolRef Sym; + OwnerSet &Owners; + +public: + OwnershipBindingsHandler(SymbolRef Sym, OwnerSet &Owners) + : Sym(Sym), Owners(Owners) {} + + bool HandleBinding(StoreManager &SMgr, Store Store, const MemRegion *Region, + SVal Val) override { + if (Val.getAsSymbol() == Sym) + Owners.insert(Region); + return true; + } + + LLVM_DUMP_METHOD void dump() const { dumpToStream(llvm::errs()); } + LLVM_DUMP_METHOD void dumpToStream(llvm::raw_ostream &out) const { + out << "Owners: {\n"; + for (const MemRegion *Owner : Owners) { + out << " "; + Owner->dumpToStream(out); + out << ",\n"; + } + out << "}\n"; + } +}; + +OwnerSet NoOwnershipChangeVisitor::getOwnersAtNode(const ExplodedNode *N) { + OwnerSet Ret; + + ProgramStateRef State = N->getState(); + OwnershipBindingsHandler Handler{Sym, Ret}; + State->getStateManager().getStoreManager().iterBindings(State->getStore(), + Handler); + return Ret; +} + +LLVM_DUMP_METHOD std::string +NoOwnershipChangeVisitor::getFunctionName(const ExplodedNode *CallEnterN) { + if (const CallExpr *CE = llvm::dyn_cast_or_null( + CallEnterN->getLocationAs()->getCallExpr())) + if (const FunctionDecl *FD = CE->getDirectCallee()) + return FD->getQualifiedNameAsString(); + return ""; +} + +bool NoOwnershipChangeVisitor::wasModifiedInFunction( + const ExplodedNode *CallEnterN, const ExplodedNode *CallExitEndN) { + const Decl *Callee = + CallExitEndN->getFirstPred()->getLocationContext()->getDecl(); + const FunctionDecl *FD = dyn_cast(Callee); + + // Given that the stack frame was entered, the body should always be + // theoretically obtainable. In case of body farms, the synthesized body + // is not attached to declaration, thus triggering the '!FD->hasBody()' + // branch. That said, would a synthesized body ever intend to handle + // ownership? As of today they don't. And if they did, how would we + // put notes inside it, given that it doesn't match any source locations? + if (!FD || !FD->hasBody()) + return false; + if (!doesFnIntendToHandleOwnership( + Callee, + CallExitEndN->getState()->getAnalysisManager().getASTContext())) + return true; + + if (hasResourceStateChanged(CallEnterN->getState(), CallExitEndN->getState())) + return true; + + OwnerSet CurrOwners = getOwnersAtNode(CallEnterN); + OwnerSet ExitOwners = getOwnersAtNode(CallExitEndN); + + // Owners in the current set may be purged from the analyzer later on. + // If a variable is dead (is not referenced directly or indirectly after + // some point), it will be removed from the Store before the end of its + // actual lifetime. + // This means that if the ownership status didn't change, CurrOwners + // must be a superset of, but not necessarily equal to ExitOwners. + return !llvm::set_is_subset(ExitOwners, CurrOwners); +} + +PathDiagnosticPieceRef NoOwnershipChangeVisitor::maybeEmitNoteForParameters( + PathSensitiveBugReport &R, const CallEvent &Call, const ExplodedNode *N) { + // TODO: Factor the logic of "what constitutes as an entity being passed + // into a function call" out by reusing the code in + // NoStoreFuncVisitor::maybeEmitNoteForParameters, maybe by incorporating + // the printing technology in UninitializedObject's FieldChainInfo. + ArrayRef Parameters = Call.parameters(); + for (unsigned I = 0; I < Call.getNumArgs() && I < Parameters.size(); ++I) { + SVal V = Call.getArgSVal(I); + if (V.getAsSymbol() == Sym) + return emitNote(N); + } + return nullptr; +} diff --git a/clang/lib/StaticAnalyzer/Checkers/NoOwnershipChangeVisitor.h b/clang/lib/StaticAnalyzer/Checkers/NoOwnershipChangeVisitor.h new file mode 100644 index 0000000000000000000000000000000000000000..027f1a156a7c03d2fdc3b9ecda1be3d64a7e9b67 --- /dev/null +++ b/clang/lib/StaticAnalyzer/Checkers/NoOwnershipChangeVisitor.h @@ -0,0 +1,77 @@ +//===--------------------------------------------------------------*- 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 "clang/StaticAnalyzer/Core/BugReporter/BugReporterVisitors.h" +#include "clang/StaticAnalyzer/Core/Checker.h" +#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState_Fwd.h" + +namespace clang { +namespace ento { + +class NoOwnershipChangeVisitor : public NoStateChangeFuncVisitor { +protected: + // The symbol whose (lack of) ownership change we are interested in. + SymbolRef Sym; + const CheckerBase &Checker; + + LLVM_DUMP_METHOD static std::string + getFunctionName(const ExplodedNode *CallEnterN); + + /// Heuristically guess whether the callee intended to free the resource. This + /// is done syntactically, because we are trying to argue about alternative + /// paths of execution, and as a consequence we don't have path-sensitive + /// information. + virtual bool doesFnIntendToHandleOwnership(const Decl *Callee, + ASTContext &ACtx) = 0; + + virtual bool hasResourceStateChanged(ProgramStateRef CallEnterState, + ProgramStateRef CallExitEndState) = 0; + + bool wasModifiedInFunction(const ExplodedNode *CallEnterN, + const ExplodedNode *CallExitEndN) final; + + virtual PathDiagnosticPieceRef emitNote(const ExplodedNode *N) = 0; + + PathDiagnosticPieceRef maybeEmitNoteForObjCSelf(PathSensitiveBugReport &R, + const ObjCMethodCall &Call, + const ExplodedNode *N) final { + // TODO: Implement. + return nullptr; + } + + PathDiagnosticPieceRef maybeEmitNoteForCXXThis(PathSensitiveBugReport &R, + const CXXConstructorCall &Call, + const ExplodedNode *N) final { + // TODO: Implement. + return nullptr; + } + + // Set this to final, effectively dispatch to emitNote. + PathDiagnosticPieceRef + maybeEmitNoteForParameters(PathSensitiveBugReport &R, const CallEvent &Call, + const ExplodedNode *N) final; + +public: + using OwnerSet = llvm::SmallPtrSet; + +private: + OwnerSet getOwnersAtNode(const ExplodedNode *N); + +public: + NoOwnershipChangeVisitor(SymbolRef Sym, const CheckerBase *Checker) + : NoStateChangeFuncVisitor(bugreporter::TrackingKind::Thorough), Sym(Sym), + Checker(*Checker) {} + + void Profile(llvm::FoldingSetNodeID &ID) const override { + static int Tag = 0; + ID.AddPointer(&Tag); + ID.AddPointer(Sym); + } +}; +} // namespace ento +} // namespace clang diff --git a/clang/lib/StaticAnalyzer/Checkers/PointerSubChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/PointerSubChecker.cpp index 2438cf30b39b5944a02af256990d3a7907c309e5..b73534136fdf02019403057c3827b09211da2b7f 100644 --- a/clang/lib/StaticAnalyzer/Checkers/PointerSubChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/PointerSubChecker.cpp @@ -17,6 +17,7 @@ #include "clang/StaticAnalyzer/Core/Checker.h" #include "clang/StaticAnalyzer/Core/CheckerManager.h" #include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h" +#include "clang/StaticAnalyzer/Core/PathSensitive/DynamicExtent.h" #include "llvm/ADT/StringRef.h" using namespace clang; @@ -26,16 +27,88 @@ namespace { class PointerSubChecker : public Checker< check::PreStmt > { const BugType BT{this, "Pointer subtraction"}; + const llvm::StringLiteral Msg_MemRegionDifferent = + "Subtraction of two pointers that do not point into the same array " + "is undefined behavior."; + const llvm::StringLiteral Msg_LargeArrayIndex = + "Using an array index greater than the array size at pointer subtraction " + "is undefined behavior."; + const llvm::StringLiteral Msg_NegativeArrayIndex = + "Using a negative array index at pointer subtraction " + "is undefined behavior."; + const llvm::StringLiteral Msg_BadVarIndex = + "Indexing the address of a variable with other than 1 at this place " + "is undefined behavior."; + + bool checkArrayBounds(CheckerContext &C, const Expr *E, + const ElementRegion *ElemReg, + const MemRegion *Reg) const; + void reportBug(CheckerContext &C, const Expr *E, + const llvm::StringLiteral &Msg) const; public: void checkPreStmt(const BinaryOperator *B, CheckerContext &C) const; }; } +bool PointerSubChecker::checkArrayBounds(CheckerContext &C, const Expr *E, + const ElementRegion *ElemReg, + const MemRegion *Reg) const { + if (!ElemReg) + return true; + + ProgramStateRef State = C.getState(); + const MemRegion *SuperReg = ElemReg->getSuperRegion(); + SValBuilder &SVB = C.getSValBuilder(); + + if (SuperReg == Reg) { + if (const llvm::APSInt *I = SVB.getKnownValue(State, ElemReg->getIndex()); + I && (!I->isOne() && !I->isZero())) + reportBug(C, E, Msg_BadVarIndex); + return false; + } + + DefinedOrUnknownSVal ElemCount = + getDynamicElementCount(State, SuperReg, SVB, ElemReg->getElementType()); + auto IndexTooLarge = SVB.evalBinOp(C.getState(), BO_GT, ElemReg->getIndex(), + ElemCount, SVB.getConditionType()) + .getAs(); + if (IndexTooLarge) { + ProgramStateRef S1, S2; + std::tie(S1, S2) = C.getState()->assume(*IndexTooLarge); + if (S1 && !S2) { + reportBug(C, E, Msg_LargeArrayIndex); + return false; + } + } + auto IndexTooSmall = SVB.evalBinOp(State, BO_LT, ElemReg->getIndex(), + SVB.makeZeroVal(SVB.getArrayIndexType()), + SVB.getConditionType()) + .getAs(); + if (IndexTooSmall) { + ProgramStateRef S1, S2; + std::tie(S1, S2) = State->assume(*IndexTooSmall); + if (S1 && !S2) { + reportBug(C, E, Msg_NegativeArrayIndex); + return false; + } + } + return true; +} + +void PointerSubChecker::reportBug(CheckerContext &C, const Expr *E, + const llvm::StringLiteral &Msg) const { + if (ExplodedNode *N = C.generateNonFatalErrorNode()) { + auto R = std::make_unique(BT, Msg, N); + R->addRange(E->getSourceRange()); + C.emitReport(std::move(R)); + } +} + void PointerSubChecker::checkPreStmt(const BinaryOperator *B, CheckerContext &C) const { // When doing pointer subtraction, if the two pointers do not point to the - // same memory chunk, emit a warning. + // same array, emit a warning. if (B->getOpcode() != BO_Sub) return; @@ -44,28 +117,36 @@ void PointerSubChecker::checkPreStmt(const BinaryOperator *B, const MemRegion *LR = LV.getAsRegion(); const MemRegion *RR = RV.getAsRegion(); - - if (!(LR && RR)) + if (!LR || !RR) return; - const MemRegion *BaseLR = LR->getBaseRegion(); - const MemRegion *BaseRR = RR->getBaseRegion(); + // Allow subtraction of identical pointers. + if (LR == RR) + return; - if (BaseLR == BaseRR) + // No warning if one operand is unknown. + if (isa(LR) || isa(RR)) return; - // Allow arithmetic on different symbolic regions. - if (isa(BaseLR) || isa(BaseRR)) + const auto *ElemLR = dyn_cast(LR); + const auto *ElemRR = dyn_cast(RR); + + if (!checkArrayBounds(C, B->getLHS(), ElemLR, RR)) + return; + if (!checkArrayBounds(C, B->getRHS(), ElemRR, LR)) return; - if (ExplodedNode *N = C.generateNonFatalErrorNode()) { - constexpr llvm::StringLiteral Msg = - "Subtraction of two pointers that do not point to the same memory " - "chunk may cause incorrect result."; - auto R = std::make_unique(BT, Msg, N); - R->addRange(B->getSourceRange()); - C.emitReport(std::move(R)); + if (ElemLR && ElemRR) { + const MemRegion *SuperLR = ElemLR->getSuperRegion(); + const MemRegion *SuperRR = ElemRR->getSuperRegion(); + if (SuperLR == SuperRR) + return; + // Allow arithmetic on different symbolic regions. + if (isa(SuperLR) || isa(SuperRR)) + return; } + + reportBug(C, B, Msg_MemRegionDifferent); } void ento::registerPointerSubChecker(CheckerManager &mgr) { diff --git a/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp b/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp index 793f3a63ea29ea1b60bf4604b983d4a7ba8c96ae..197d67310728519af0fb3924abb1bb2eaff32789 100644 --- a/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp +++ b/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp @@ -1822,6 +1822,7 @@ void ExprEngine::Visit(const Stmt *S, ExplodedNode *Pred, case Stmt::OMPTargetParallelGenericLoopDirectiveClass: case Stmt::CapturedStmtClass: case Stmt::OpenACCComputeConstructClass: + case Stmt::OpenACCLoopConstructClass: case Stmt::OMPUnrollDirectiveClass: case Stmt::OMPMetaDirectiveClass: { const ExplodedNode *node = Bldr.generateSink(S, Pred, Pred->getState()); @@ -1970,45 +1971,33 @@ void ExprEngine::Visit(const Stmt *S, ExplodedNode *Pred, ExplodedNodeSet Tmp; StmtNodeBuilder Bldr2(PreVisit, Tmp, *currBldrCtx); - bool HasRewrittenInit = false; - const Expr *ArgE = nullptr; - if (const auto *DefE = dyn_cast(S)) { + const Expr *ArgE; + if (const auto *DefE = dyn_cast(S)) ArgE = DefE->getExpr(); - HasRewrittenInit = DefE->hasRewrittenInit(); - } else if (const auto *DefE = dyn_cast(S)) { + else if (const auto *DefE = dyn_cast(S)) ArgE = DefE->getExpr(); - HasRewrittenInit = DefE->hasRewrittenInit(); - } else + else llvm_unreachable("unknown constant wrapper kind"); - if (HasRewrittenInit) { - for (auto *N : PreVisit) { - ProgramStateRef state = N->getState(); - const LocationContext *LCtx = N->getLocationContext(); - state = state->BindExpr(S, LCtx, state->getSVal(ArgE, LCtx)); - Bldr2.generateNode(S, N, state); - } - } else { - // If it's not rewritten, the contents of these expressions are not - // actually part of the current function, so we fall back to constant - // evaluation. - bool IsTemporary = false; - if (const auto *MTE = dyn_cast(ArgE)) { - ArgE = MTE->getSubExpr(); - IsTemporary = true; - } - - std::optional ConstantVal = svalBuilder.getConstantVal(ArgE); - const LocationContext *LCtx = Pred->getLocationContext(); - for (auto *I : PreVisit) { - ProgramStateRef State = I->getState(); - State = State->BindExpr(S, LCtx, ConstantVal.value_or(UnknownVal())); - if (IsTemporary) - State = createTemporaryRegionIfNeeded(State, LCtx, cast(S), - cast(S)); + bool IsTemporary = false; + if (const auto *MTE = dyn_cast(ArgE)) { + ArgE = MTE->getSubExpr(); + IsTemporary = true; + } - Bldr2.generateNode(S, I, State); - } + std::optional ConstantVal = svalBuilder.getConstantVal(ArgE); + if (!ConstantVal) + ConstantVal = UnknownVal(); + + const LocationContext *LCtx = Pred->getLocationContext(); + for (const auto I : PreVisit) { + ProgramStateRef State = I->getState(); + State = State->BindExpr(S, LCtx, *ConstantVal); + if (IsTemporary) + State = createTemporaryRegionIfNeeded(State, LCtx, + cast(S), + cast(S)); + Bldr2.generateNode(S, I, State); } getCheckerManager().runCheckersForPostStmt(Dst, Tmp, S, *this); diff --git a/clang/lib/Tooling/DependencyScanning/DependencyScanningFilesystem.cpp b/clang/lib/Tooling/DependencyScanning/DependencyScanningFilesystem.cpp index 66a2f6e0acb63828ad36b116170a310f1d8aabc0..0cab17a34244069f1d1f380e42651eee67755334 100644 --- a/clang/lib/Tooling/DependencyScanning/DependencyScanningFilesystem.cpp +++ b/clang/lib/Tooling/DependencyScanning/DependencyScanningFilesystem.cpp @@ -42,7 +42,7 @@ DependencyScanningWorkerFilesystem::readFile(StringRef Filename) { } bool DependencyScanningWorkerFilesystem::ensureDirectiveTokensArePopulated( - EntryRef Ref, const LangOptions &LangOpts) { + EntryRef Ref) { auto &Entry = Ref.Entry; if (Entry.isError() || Entry.isDirectory()) @@ -66,7 +66,7 @@ bool DependencyScanningWorkerFilesystem::ensureDirectiveTokensArePopulated( // dependencies. if (scanSourceForDependencyDirectives(Contents->Original->getBuffer(), Contents->DepDirectiveTokens, - Directives, LangOpts)) { + Directives)) { Contents->DepDirectiveTokens.clear(); // FIXME: Propagate the diagnostic if desired by the client. Contents->DepDirectives.store(new std::optional()); diff --git a/clang/lib/Tooling/DependencyScanning/DependencyScanningWorker.cpp b/clang/lib/Tooling/DependencyScanning/DependencyScanningWorker.cpp index 07e1960dd90583a7b081c190b2b61acce96347e2..0f82f22d8b9a8c7d1dd360ae39d668565bfec7b3 100644 --- a/clang/lib/Tooling/DependencyScanning/DependencyScanningWorker.cpp +++ b/clang/lib/Tooling/DependencyScanning/DependencyScanningWorker.cpp @@ -364,12 +364,11 @@ public: // Use the dependency scanning optimized file system if requested to do so. if (DepFS) ScanInstance.getPreprocessorOpts().DependencyDirectivesForFile = - [LocalDepFS = DepFS, - &LangOpts = ScanInstance.getLangOpts()](FileEntryRef File) + [LocalDepFS = DepFS](FileEntryRef File) -> std::optional> { if (llvm::ErrorOr Entry = LocalDepFS->getOrCreateFileSystemEntry(File.getName())) - if (LocalDepFS->ensureDirectiveTokensArePopulated(*Entry, LangOpts)) + if (LocalDepFS->ensureDirectiveTokensArePopulated(*Entry)) return Entry->getDirectiveTokens(); return std::nullopt; }; diff --git a/clang/lib/Tooling/Syntax/Tokens.cpp b/clang/lib/Tooling/Syntax/Tokens.cpp index 8d32c45a4a70cf55138ab82be6345171c8e2cd99..0a656dff384217f3975a395a465000211f673257 100644 --- a/clang/lib/Tooling/Syntax/Tokens.cpp +++ b/clang/lib/Tooling/Syntax/Tokens.cpp @@ -383,12 +383,13 @@ llvm::ArrayRef TokenBuffer::spelledTokens(FileID FID) const { return It->second.SpelledTokens; } -const syntax::Token *TokenBuffer::spelledTokenAt(SourceLocation Loc) const { +const syntax::Token * +TokenBuffer::spelledTokenContaining(SourceLocation Loc) const { assert(Loc.isFileID()); const auto *Tok = llvm::partition_point( spelledTokens(SourceMgr->getFileID(Loc)), - [&](const syntax::Token &Tok) { return Tok.location() < Loc; }); - if (!Tok || Tok->location() != Loc) + [&](const syntax::Token &Tok) { return Tok.endLocation() <= Loc; }); + if (!Tok || Loc < Tok->location()) return nullptr; return Tok; } diff --git a/clang/test/AST/Interp/arrays.cpp b/clang/test/AST/Interp/arrays.cpp index dd5064d993e667b72664c6ee29ef88bde444d7dd..6f6fca8c1cfd8eb27e3897ca33a3d4e7c0eec7df 100644 --- a/clang/test/AST/Interp/arrays.cpp +++ b/clang/test/AST/Interp/arrays.cpp @@ -609,3 +609,17 @@ namespace ArrayMemberAccess { bool cond = a->x; } } + +namespace OnePastEndSub { + struct A {}; + constexpr A a[3][3]; + constexpr int diff2 = &a[1][3] - &a[1][0]; /// Used to crash. +} + +static int same_entity_2[3]; +constexpr int *get2() { + // This is a redeclaration of the same entity, even though it doesn't + // inherit the type of the prior declaration. + extern int same_entity_2[]; + return same_entity_2; +} diff --git a/clang/test/AST/Interp/builtin-align-cxx.cpp b/clang/test/AST/Interp/builtin-align-cxx.cpp index c4103953df026a15a98498143f6a964e75646aa9..a1edf307d6c479c57588237ee2934593d41b04bc 100644 --- a/clang/test/AST/Interp/builtin-align-cxx.cpp +++ b/clang/test/AST/Interp/builtin-align-cxx.cpp @@ -202,8 +202,7 @@ static_assert(__builtin_align_down(&align32array[7], 4) == &align32array[4], "") static_assert(__builtin_align_down(&align32array[8], 4) == &align32array[8], ""); // Achieving the same thing using casts to uintptr_t is not allowed: -static_assert((char *)((__UINTPTR_TYPE__)&align32array[7] & ~3) == &align32array[4], ""); // both-error{{not an integral constant expression}} \ - // expected-note {{cast that performs the conversions of a reinterpret_cast is not allowed in a constant expression}} +static_assert((char *)((__UINTPTR_TYPE__)&align32array[7] & ~3) == &align32array[4], ""); // both-error{{not an integral constant expression}} static_assert(__builtin_align_down(&align32array[1], 4) == &align32array[0], ""); static_assert(__builtin_align_down(&align32array[1], 64) == &align32array[0], ""); // both-error{{not an integral constant expression}} diff --git a/clang/test/AST/Interp/c.c b/clang/test/AST/Interp/c.c index f4c7bf16f2f95ee8ae44392fcdf82ac9c3842f8f..1cc450e48def06f9fadc23ef24a70f6b56c9bc24 100644 --- a/clang/test/AST/Interp/c.c +++ b/clang/test/AST/Interp/c.c @@ -66,12 +66,10 @@ _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 '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 {{this conversion is not allowed in a constant expression}} \ - // pedantic-expected-warning {{is a GNU extension}} + // pedantic-warning {{is a GNU extension}} \ + // pedantic-note {{this conversion is not allowed in a constant expression}} struct y {int x,y;}; int a2[(intptr_t)&((struct y*)0)->y]; // all-warning {{folded to constant array}} diff --git a/clang/test/AST/Interp/complex.cpp b/clang/test/AST/Interp/complex.cpp index 09cb620d7b7c398cf1e51312a2ff64af3adc48cf..003f33e092d25feb372860ac0d574a7122f394ac 100644 --- a/clang/test/AST/Interp/complex.cpp +++ b/clang/test/AST/Interp/complex.cpp @@ -115,6 +115,11 @@ static_assert(__imag(Doubles[2]) == 0.0, ""); static_assert(__real(Doubles[3]) == 0.0, ""); static_assert(__imag(Doubles[3]) == 0.0, ""); +static_assert(~(0.5 + 1.5j) == (0.5 + -1.5j), ""); + +static_assert(__extension__ __imag(A) == 0, ""); +static_assert(__imag(__extension__ A) == 0, ""); + void func(void) { __complex__ int arr; _Complex int result; diff --git a/clang/test/AST/Interp/const-eval.c b/clang/test/AST/Interp/const-eval.c index 72c0833a0f6309bd2523017c979d1bbecedfe7fc..eab14c08ec809acc18f02ab42cd57a930329362a 100644 --- a/clang/test/AST/Interp/const-eval.c +++ b/clang/test/AST/Interp/const-eval.c @@ -140,15 +140,8 @@ EVAL_EXPR(47, &x < &x + 1 ? 1 : -1) EVAL_EXPR(48, &x != &x - 1 ? 1 : -1) EVAL_EXPR(49, &x < &x - 100 ? 1 : -1) // ref-error {{not an integer constant expression}} -/// FIXME: Rejecting this is correct, BUT when converting the innermost pointer -/// to an integer, we do not preserve the information where it came from. So when we later -/// create a pointer from it, it also doesn't have that information, which means -/// hasSameBase() for those two pointers will return false. And in those cases, we emit -/// the diagnostic: -/// comparison between '&Test50' and '&(631578)' has unspecified value extern struct Test50S Test50; -EVAL_EXPR(50, &Test50 < (struct Test50S*)((unsigned long)&Test50 + 10)) // both-error {{not an integer constant expression}} \ - // expected-note {{comparison between}} +EVAL_EXPR(50, &Test50 < (struct Test50S*)((unsigned long)&Test50 + 10)) // both-error {{not an integer constant expression}} EVAL_EXPR(51, 0 != (float)1e99) diff --git a/clang/test/AST/Interp/cxx20.cpp b/clang/test/AST/Interp/cxx20.cpp index 000ffe39eb94a73caca71f5704ad6bbce164c1ca..434823644a7a38980d5dd39c438789e2b11572fb 100644 --- a/clang/test/AST/Interp/cxx20.cpp +++ b/clang/test/AST/Interp/cxx20.cpp @@ -774,3 +774,43 @@ void overflowInSwitchCase(int n) { break; } } + +namespace APValues { + int g; + struct A { union { int n, m; }; int *p; int A::*q; char buffer[32]; }; + template constexpr const A &get = a; + constexpr const A &v = get; + constexpr const A &w = get; +} + +namespace self_referencing { + struct S { + S* ptr = nullptr; + constexpr S(int i) : ptr(this) { + if (this == ptr && i) + ptr = nullptr; + } + constexpr ~S() {} + }; + + void test() { + S s(1); + } +} + +namespace GH64949 { + struct f { + int g; // both-note {{subobject declared here}} + constexpr ~f() {} + }; + + class h { + public: + consteval h(char *) {} + f i; + }; + + void test() { h{nullptr}; } // both-error {{call to consteval function 'GH64949::h::h' is not a constant expression}} \ + // both-note {{subobject 'g' is not initialized}} \ + // both-warning {{expression result unused}} +} diff --git a/clang/test/AST/Interp/cxx23.cpp b/clang/test/AST/Interp/cxx23.cpp index c91d52c552b12792f240cb78def8521e566c6338..d0991f3ffdff5e09d2790ddbf73a009fd7712594 100644 --- a/clang/test/AST/Interp/cxx23.cpp +++ b/clang/test/AST/Interp/cxx23.cpp @@ -1,6 +1,6 @@ // UNSUPPORTED: target={{.*}}-zos{{.*}} -// 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=ref,ref20,all,all20 %s +// RUN: %clang_cc1 -std=c++23 -fsyntax-only -fcxx-exceptions -verify=ref,ref23,all %s // 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 @@ -178,3 +178,37 @@ namespace ExplicitLambdaThis { }; static_assert(f()); } + +namespace std { + struct strong_ordering { + int n; + constexpr operator int() const { return n; } + static const strong_ordering less, equal, greater; + }; + constexpr strong_ordering strong_ordering::less = {-1}; + constexpr strong_ordering strong_ordering::equal = {0}; + constexpr strong_ordering strong_ordering::greater = {1}; +} + +namespace UndefinedThreeWay { + struct A { + friend constexpr std::strong_ordering operator<=>(const A&, const A&) = default; // all-note {{declared here}} + }; + + constexpr std::strong_ordering operator<=>(const A&, const A&) noexcept; + constexpr std::strong_ordering (*test_a_threeway)(const A&, const A&) = &operator<=>; + static_assert(!(*test_a_threeway)(A(), A())); // all-error {{static assertion expression is not an integral constant expression}} \ + // all-note {{undefined function 'operator<=>' cannot be used in a constant expression}} +} + +/// FIXME: The new interpreter is missing the "initializer of q is not a constant expression" diagnostics.a +/// That's because the cast from void* to int* is considered fine, but diagnosed. So we don't consider +/// q to be uninitialized. +namespace VoidCast { + constexpr void* p = nullptr; + constexpr int* q = static_cast(p); // all-error {{must be initialized by a constant expression}} \ + // all-note {{cast from 'void *' is not allowed in a constant expression}} \ + // ref-note {{declared here}} + static_assert(q == nullptr); // ref-error {{not an integral constant expression}} \ + // ref-note {{initializer of 'q' is not a constant expression}} +} diff --git a/clang/test/AST/Interp/cxx26.cpp b/clang/test/AST/Interp/cxx26.cpp new file mode 100644 index 0000000000000000000000000000000000000000..0b0e2b21e8201e76881abaa192e91708bf8ed83f --- /dev/null +++ b/clang/test/AST/Interp/cxx26.cpp @@ -0,0 +1,10 @@ +// RUN: %clang_cc1 -std=c++26 -fsyntax-only -fcxx-exceptions -verify=ref,both %s +// RUN: %clang_cc1 -std=c++26 -fsyntax-only -fcxx-exceptions -verify=expected,both %s -fexperimental-new-constant-interpreter + +// both-no-diagnostics + +namespace VoidCast { + constexpr void* p = nullptr; + constexpr int* q = static_cast(p); + static_assert(q == nullptr); +} diff --git a/clang/test/AST/Interp/eval-order.cpp b/clang/test/AST/Interp/eval-order.cpp index aaf2b74510bbfedd396a7a74fc90d42d0eb6da18..7a7ce6a714601ac1bb0aba5d91ec2bf233d1dc01 100644 --- a/clang/test/AST/Interp/eval-order.cpp +++ b/clang/test/AST/Interp/eval-order.cpp @@ -71,8 +71,8 @@ namespace EvalOrder { // Rules 1 and 2 have no effect ('b' is not an expression). // Rule 3: a->*b - // SEQ(A(ud).*B(&UserDefined::n)); FIXME - // SEQ(A(&ud)->*B(&UserDefined::n)); FIXME + SEQ(A(ud).*B(&UserDefined::n)); + SEQ(A(&ud)->*B(&UserDefined::n)); // Rule 4: a(b1, b2, b3) SEQ(A(f)(B(1), B(2), B(3))); // expected-error {{not an integral constant expression}} FIXME \ diff --git a/clang/test/AST/Interp/lambda.cpp b/clang/test/AST/Interp/lambda.cpp index 77e035ce2547036a3f0488669506aa421fc03918..0eb12643b1b7f425be2cd9d028fbd37553eff7de 100644 --- a/clang/test/AST/Interp/lambda.cpp +++ b/clang/test/AST/Interp/lambda.cpp @@ -264,3 +264,19 @@ namespace CaptureDefaults { }; static_assert(f2() == 3, ""); } + +constexpr auto t4 = ([x=42]() consteval { return x; }()); +static_assert(t4 == 42, ""); + +namespace InvalidCapture { + + int &f(int *p); + char &f(...); + void g() { + int n = -1; // both-note {{declared here}} + [=] { + int arr[n]; // both-warning {{variable length arrays in C++ are a Clang extension}} \ + both-note {{read of non-const variable 'n' is not allowed in a constant expression}} + } (); + } +} diff --git a/clang/test/AST/Interp/literals.cpp b/clang/test/AST/Interp/literals.cpp index c160be06dd241cad80004813e87aa3bc729dc82e..5a29013a053a20bbec7b83f65172ba8bba5f6dab 100644 --- a/clang/test/AST/Interp/literals.cpp +++ b/clang/test/AST/Interp/literals.cpp @@ -66,7 +66,12 @@ namespace ScalarTypes { First = 0, }; static_assert(getScalar() == First, ""); - /// FIXME: Member pointers. + + struct S { + int v; + }; + constexpr int S::* MemberPtr = &S::v; + static_assert(getScalar() == nullptr, ""); #if __cplusplus >= 201402L constexpr void Void(int n) { @@ -1204,7 +1209,7 @@ namespace incdecbool { constexpr int externvar1() { // both-error {{never produces a constant expression}} 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}} + // expected-note {{indexing of array without known bound}} } #endif diff --git a/clang/test/AST/Interp/memberpointers.cpp b/clang/test/AST/Interp/memberpointers.cpp new file mode 100644 index 0000000000000000000000000000000000000000..54d73fe86ca18d5781eb2595edd130e1b3b49e47 --- /dev/null +++ b/clang/test/AST/Interp/memberpointers.cpp @@ -0,0 +1,197 @@ +// RUN: %clang_cc1 -std=c++14 -fexperimental-new-constant-interpreter -verify=expected,both %s +// RUN: %clang_cc1 -std=c++14 -verify=ref,both %s + +namespace MemberPointers { + struct A { + constexpr A(int n) : n(n) {} + int n; + constexpr int f() const { return n + 3; } + }; + + constexpr A a(7); + static_assert(A(5).*&A::n == 5, ""); + static_assert((&a)->*&A::n == 7, ""); + static_assert((A(8).*&A::f)() == 11, ""); + static_assert(((&a)->*&A::f)() == 10, ""); + + struct B : A { + constexpr B(int n, int m) : A(n), m(m) {} + int m; + constexpr int g() const { return n + m + 1; } + }; + constexpr B b(9, 13); + static_assert(B(4, 11).*&A::n == 4, ""); + static_assert(B(4, 11).*&B::m == 11, ""); + static_assert(B(4, 11).m == 11, ""); + static_assert(B(4, 11).*(int(A::*))&B::m == 11, ""); + static_assert(B(4, 11).*&B::m == 11, ""); + static_assert((&b)->*&A::n == 9, ""); + static_assert((&b)->*&B::m == 13, ""); + static_assert((&b)->*(int(A::*))&B::m == 13, ""); + static_assert((B(4, 11).*&A::f)() == 7, ""); + static_assert((B(4, 11).*&B::g)() == 16, ""); + + static_assert((B(4, 11).*(int(A::*)() const)&B::g)() == 16, ""); + + static_assert(((&b)->*&A::f)() == 12, ""); + static_assert(((&b)->*&B::g)() == 23, ""); + static_assert(((&b)->*(int(A::*)()const)&B::g)() == 23, ""); + + + struct S { + constexpr S(int m, int n, int (S::*pf)() const, int S::*pn) : + m(m), n(n), pf(pf), pn(pn) {} + constexpr S() : m(), n(), pf(&S::f), pn(&S::n) {} + + constexpr int f() const { return this->*pn; } + virtual int g() const; + + int m, n; + int (S::*pf)() const; + int S::*pn; + }; + + constexpr int S::*pm = &S::m; + constexpr int S::*pn = &S::n; + + constexpr int (S::*pf)() const = &S::f; + constexpr int (S::*pg)() const = &S::g; + + constexpr S s(2, 5, &S::f, &S::m); + + static_assert((s.*&S::f)() == 2, ""); + static_assert((s.*s.pf)() == 2, ""); + + static_assert(pf == &S::f, ""); + + static_assert(pf == s.*&S::pf, ""); + + static_assert(pm == &S::m, ""); + static_assert(pm != pn, ""); + static_assert(s.pn != pn, ""); + static_assert(s.pn == pm, ""); + static_assert(pg != nullptr, ""); + static_assert(pf != nullptr, ""); + static_assert((int S::*)nullptr == nullptr, ""); + static_assert(pg == pg, ""); // both-error {{constant expression}} \ + // both-note {{comparison of pointer to virtual member function 'g' has unspecified value}} + static_assert(pf != pg, ""); // both-error {{constant expression}} \ + // both-note {{comparison of pointer to virtual member function 'g' has unspecified value}} + + template struct T : T { const int X = n;}; + template<> struct T<0> { int n; char k;}; + template<> struct T<30> : T<29> { int m; }; + + T<17> t17; + T<30> t30; + + constexpr int (T<15>::*deepm) = (int(T<10>::*))&T<30>::m; + constexpr int (T<10>::*deepn) = &T<0>::n; + constexpr char (T<10>::*deepk) = &T<0>::k; + + static_assert(&(t17.*deepn) == &t17.n, ""); + static_assert(&(t17.*deepk) == &t17.k, ""); + static_assert(deepn == &T<2>::n, ""); + + constexpr int *pgood = &(t30.*deepm); + constexpr int *pbad = &(t17.*deepm); // both-error {{constant expression}} + static_assert(&(t30.*deepm) == &t30.m, ""); + + static_assert(deepm == &T<50>::m, ""); + static_assert(deepm != deepn, ""); + + constexpr T<5> *p17_5 = &t17; + constexpr T<13> *p17_13 = (T<13>*)p17_5; + constexpr T<23> *p17_23 = (T<23>*)p17_13; // both-error {{constant expression}} \ + // both-note {{cannot cast object of dynamic type 'T<17>' to type 'T<23>'}} + constexpr T<18> *p17_18 = (T<18>*)p17_13; // both-error {{constant expression}} \ + // both-note {{cannot cast object of dynamic type 'T<17>' to type 'T<18>'}} + static_assert(&(p17_5->*(int(T<0>::*))deepn) == &t17.n, ""); + static_assert(&(p17_5->*(int(T<0>::*))deepn), ""); + + + static_assert(&(p17_13->*deepn) == &t17.n, ""); + constexpr int *pbad2 = &(p17_13->*(int(T<9>::*))deepm); // both-error {{constant expression}} + + constexpr T<5> *p30_5 = &t30; + constexpr T<23> *p30_23 = (T<23>*)p30_5; + constexpr T<13> *p30_13 = p30_23; + static_assert(&(p30_13->*deepn) == &t30.n, ""); + static_assert(&(p30_23->*deepn) == &t30.n, ""); + static_assert(&(p30_5->*(int(T<3>::*))deepn) == &t30.n, ""); + + static_assert(&(p30_5->*(int(T<2>::*))deepm) == &t30.m, ""); + static_assert(&(((T<17>*)p30_13)->*deepm) == &t30.m, ""); + static_assert(&(p30_23->*deepm) == &t30.m, ""); + + + /// Added tests not from constant-expression-cxx11.cpp + static_assert(pm, ""); + static_assert(!((int S::*)nullptr), ""); + constexpr int S::*pk = nullptr; + static_assert(!pk, ""); +} + +namespace test3 { + struct nsCSSRect { + }; + static int nsCSSRect::* sides; + nsCSSRect dimenX; + void ParseBoxCornerRadii(int y) { + switch (y) { + } + int& x = dimenX.*sides; + } +} + +void foo() { + class X; + void (X::*d) (); + d = nullptr; /// This calls in the constant interpreter. +} + +namespace { + struct A { int n; }; + struct B { int n; }; + struct C : A, B {}; + struct D { double d; C c; }; + const int &&u = static_cast(0, ((D&&)D{}).*&D::c).n; // both-warning {{left operand of comma operator has no effect}} +} + +/// From SemaTemplate/instantiate-member-pointers.cpp +namespace { + struct Y { + int x; + }; + + template + struct X3 { + X3 &operator=(const T& value) { + return *this; + } + }; + + typedef int Y::*IntMember; + template + struct X4 { + X3 member; + int &getMember(Y& y) { return y.*Member; } + }; + + int &get_X4(X4<&Y::x> x4, Y& y) { + return x4.getMember(y); + } +} + +/// From test/CXX/basic/basic.def.odr/p2.cpp +namespace { + void use(int); + struct S { int x; int f() const; }; + constexpr S *ps = nullptr; + S *const &psr = ps; + + void test() { + use(ps->*&S::x); + use(psr->*&S::x); + } +} diff --git a/clang/test/AST/ast-dump-default-init-json.cpp b/clang/test/AST/ast-dump-default-init-json.cpp index f4949a9c9eedf4f5ac024ac9660c11f57a39b89d..1058b4e3ea4d93d9cbd6003034568a0d038ceb5f 100644 --- a/clang/test/AST/ast-dump-default-init-json.cpp +++ b/clang/test/AST/ast-dump-default-init-json.cpp @@ -789,10 +789,10 @@ void test() { // CHECK-NEXT: "valueCategory": "lvalue", // CHECK-NEXT: "extendingDecl": { // CHECK-NEXT: "id": "0x{{.*}}", -// CHECK-NEXT: "kind": "VarDecl", -// CHECK-NEXT: "name": "b", +// CHECK-NEXT: "kind": "FieldDecl", +// CHECK-NEXT: "name": "a", // CHECK-NEXT: "type": { -// CHECK-NEXT: "qualType": "B" +// CHECK-NEXT: "qualType": "const A &" // CHECK-NEXT: } // CHECK-NEXT: }, // CHECK-NEXT: "storageDuration": "automatic", diff --git a/clang/test/AST/ast-dump-default-init.cpp b/clang/test/AST/ast-dump-default-init.cpp index 26864fbf15424dc6af8815e3cdc02d836f111b51..15b29f04bf21bf6700096a2f1f03577e9d95f312 100644 --- a/clang/test/AST/ast-dump-default-init.cpp +++ b/clang/test/AST/ast-dump-default-init.cpp @@ -13,7 +13,7 @@ void test() { } // CHECK: -CXXDefaultInitExpr 0x{{[^ ]*}} <{{.*}}> 'const A' lvalue has rewritten init // CHECK-NEXT: `-ExprWithCleanups 0x{{[^ ]*}} <{{.*}}> 'const A' lvalue -// CHECK-NEXT: `-MaterializeTemporaryExpr 0x{{[^ ]*}} <{{.*}}> 'const A' lvalue extended by Var 0x{{[^ ]*}} 'b' 'B' +// CHECK-NEXT: `-MaterializeTemporaryExpr 0x{{[^ ]*}} <{{.*}}> 'const A' lvalue extended by Field 0x{{[^ ]*}} 'a' 'const A &' // CHECK-NEXT: `-ImplicitCastExpr 0x{{[^ ]*}} <{{.*}}> 'const A' // CHECK-NEXT: `-CXXFunctionalCastExpr 0x{{[^ ]*}} <{{.*}}> 'A' functional cast to A // CHECK-NEXT: `-InitListExpr 0x{{[^ ]*}} <{{.*}}> 'A' diff --git a/clang/test/AST/ast-print-openacc-loop-construct.cpp b/clang/test/AST/ast-print-openacc-loop-construct.cpp new file mode 100644 index 0000000000000000000000000000000000000000..cde302a66f3af7586f81f074bf884ee840556eca --- /dev/null +++ b/clang/test/AST/ast-print-openacc-loop-construct.cpp @@ -0,0 +1,60 @@ +// RUN: %clang_cc1 -fopenacc -Wno-openacc-deprecated-clause-alias -ast-print %s -o - | FileCheck %s + +struct SomeStruct{}; + +void foo() { +// CHECK: #pragma acc loop +// CHECK-NEXT: for (;;) +// CHECK-NEXT: ; +#pragma acc loop + for(;;); + +// CHECK: #pragma acc loop device_type(SomeStruct) +// CHECK-NEXT: for (;;) +// CHECK-NEXT: ; +#pragma acc loop device_type(SomeStruct) + for(;;); + +// CHECK: #pragma acc loop device_type(int) +// CHECK-NEXT: for (;;) +// CHECK-NEXT: ; +#pragma acc loop device_type(int) + for(;;); + +// CHECK: #pragma acc loop dtype(bool) +// CHECK-NEXT: for (;;) +// CHECK-NEXT: ; +#pragma acc loop dtype(bool) + for(;;); + +// CHECK: #pragma acc loop dtype(AnotherIdent) +// CHECK-NEXT: for (;;) +// CHECK-NEXT: ; +#pragma acc loop dtype(AnotherIdent) + for(;;); + +// CHECK: #pragma acc loop independent +// CHECK-NEXT: for (;;) +// CHECK-NEXT: ; +#pragma acc loop independent + for(;;); +// CHECK: #pragma acc loop seq +// CHECK-NEXT: for (;;) +// CHECK-NEXT: ; +#pragma acc loop seq + for(;;); +// CHECK: #pragma acc loop auto +// CHECK-NEXT: for (;;) +// CHECK-NEXT: ; +#pragma acc loop auto + for(;;); + + int i; + float array[5]; + +// CHECK: #pragma acc loop private(i, array[1], array, array[1:2]) +// CHECK-NEXT: for (;;) +// CHECK-NEXT: ; +#pragma acc loop private(i, array[1], array, array[1:2]) + for(;;); +} diff --git a/clang/test/Analysis/casts.c b/clang/test/Analysis/casts.c index 30cd74be564fdae7a1d3468b937ded10fd848f73..7dad4edfa89b99ac142ee0cfc567174ce398aca7 100644 --- a/clang/test/Analysis/casts.c +++ b/clang/test/Analysis/casts.c @@ -138,7 +138,9 @@ void multiDimensionalArrayPointerCasts(void) { clang_analyzer_eval(y1 == y2); // expected-warning{{TRUE}} // FIXME: should be FALSE (i.e. equal pointers). + // FIXME: pointer subtraction warning might be incorrect clang_analyzer_eval(y1 - y2); // expected-warning{{UNKNOWN}} + // expected-warning@-1{{Subtraction of two pointers that do not point into the same array is undefined behavior}} // FIXME: should be TRUE (i.e. same symbol). clang_analyzer_eval(*y1 == *y2); // expected-warning{{UNKNOWN}} @@ -147,7 +149,9 @@ void multiDimensionalArrayPointerCasts(void) { clang_analyzer_eval(y1 == y3); // expected-warning{{TRUE}} // FIXME: should be FALSE (i.e. equal pointers). + // FIXME: pointer subtraction warning might be incorrect clang_analyzer_eval(y1 - y3); // expected-warning{{UNKNOWN}} + // expected-warning@-1{{Subtraction of two pointers that do not point into the same array is undefined behavior}} // FIXME: should be TRUE (i.e. same symbol). clang_analyzer_eval(*y1 == *y3); // expected-warning{{UNKNOWN}} diff --git a/clang/test/Analysis/cxx-uninitialized-object.cpp b/clang/test/Analysis/cxx-uninitialized-object.cpp index aee0dae15fbfa4b2425da87f559ae69ca20a8b73..e3fa8ae8d7f2957f62c280c6b6b4c9ab1238e6ae 100644 --- a/clang/test/Analysis/cxx-uninitialized-object.cpp +++ b/clang/test/Analysis/cxx-uninitialized-object.cpp @@ -1114,27 +1114,27 @@ void fCXX11MemberInitTest1() { CXX11MemberInitTest1(); } -#ifdef PEDANTIC struct CXX11MemberInitTest2 { struct RecordType { - int a; // expected-note {{uninitialized field 'this->a'}} - int b; // expected-note {{uninitialized field 'this->b'}} + // TODO: we'd expect the note: {{uninitialized field 'this->rec.a'}} + int a; // no-note + // TODO: we'd expect the note: {{uninitialized field 'this->rec.b'}} + int b; // no-note RecordType(int) {} }; - RecordType rec = RecordType(int()); // expected-warning {{2 uninitialized fields}} + RecordType rec = RecordType(int()); int dontGetFilteredByNonPedanticMode = 0; CXX11MemberInitTest2() {} }; void fCXX11MemberInitTest2() { + // TODO: we'd expect the warning: {{2 uninitializeds field}} CXX11MemberInitTest2(); // no-warning } -#endif // PEDANTIC - //===----------------------------------------------------------------------===// // "Esoteric" primitive type tests. //===----------------------------------------------------------------------===// diff --git a/clang/test/Analysis/lifetime-extended-regions.cpp b/clang/test/Analysis/lifetime-extended-regions.cpp index 524f4e0c400d17519b5715f3ee20e62cfad0d8da..4e98bd4b0403ebc89ea84fee70424cd18a5db16c 100644 --- a/clang/test/Analysis/lifetime-extended-regions.cpp +++ b/clang/test/Analysis/lifetime-extended-regions.cpp @@ -120,11 +120,11 @@ void aggregateWithReferences() { clang_analyzer_dump(viaReference); // expected-warning-re {{&lifetime_extended_object{RefAggregate, viaReference, S{{[0-9]+}}} }} clang_analyzer_dump(viaReference.rx); // expected-warning-re {{&lifetime_extended_object{int, viaReference, S{{[0-9]+}}} }} clang_analyzer_dump(viaReference.ry); // expected-warning-re {{&lifetime_extended_object{Composite, viaReference, S{{[0-9]+}}} }} - - // The lifetime lifetime of object bound to reference members of aggregates, - // that are created from default member initializer was extended. - RefAggregate defaultInitExtended{i}; - clang_analyzer_dump(defaultInitExtended.ry); // expected-warning-re {{&lifetime_extended_object{Composite, defaultInitExtended, S{{[0-9]+}}} }} + + // clang does not currently implement extending lifetime of object bound to reference members of aggregates, + // that are created from default member initializer (see `warn_unsupported_lifetime_extension` from `-Wdangling`) + RefAggregate defaultInitExtended{i}; // clang-bug does not extend `Composite` + clang_analyzer_dump(defaultInitExtended.ry); // expected-warning {{Unknown }} } void lambda() { diff --git a/clang/test/Analysis/malloc.c b/clang/test/Analysis/malloc.c index e5cb45ba733524d3a55c601abd9240e06d207354..8ee29aeb324f72ca658a91b9f136fd2d4d1cb5a4 100644 --- a/clang/test/Analysis/malloc.c +++ b/clang/test/Analysis/malloc.c @@ -3,7 +3,9 @@ // RUN: -analyzer-checker=alpha.deadcode.UnreachableCode \ // RUN: -analyzer-checker=alpha.core.CastSize \ // RUN: -analyzer-checker=unix \ -// RUN: -analyzer-checker=debug.ExprInspection +// RUN: -analyzer-checker=debug.ExprInspection \ +// RUN: -analyzer-checker=alpha.security.taint.TaintPropagation \ +// RUN: -analyzer-checker=optin.taint.TaintedAlloc #include "Inputs/system-header-simulator.h" @@ -48,6 +50,45 @@ void myfoo(int *p); void myfooint(int p); char *fooRetPtr(void); +void t1(void) { + size_t size = 0; + scanf("%zu", &size); + int *p = malloc(size); // expected-warning{{malloc is called with a tainted (potentially attacker controlled) value}} + free(p); +} + +void t2(void) { + size_t size = 0; + scanf("%zu", &size); + int *p = calloc(size,2); // expected-warning{{calloc is called with a tainted (potentially attacker controlled) value}} + free(p); +} + +void t3(void) { + size_t size = 0; + scanf("%zu", &size); + if (1024 < size) + return; + int *p = malloc(size); // No warning expected as the the user input is bound + free(p); +} + +void t4(void) { + size_t size = 0; + int *p = malloc(sizeof(int)); + scanf("%zu", &size); + p = (int*) realloc((void*) p, size); // expected-warning{{realloc is called with a tainted (potentially attacker controlled) value}} + free(p); +} + +void t5(void) { + size_t size = 0; + int *p = alloca(sizeof(int)); + scanf("%zu", &size); + p = (int*) alloca(size); // expected-warning{{alloca is called with a tainted (potentially attacker controlled) value}} +} + + void f1(void) { int *p = malloc(12); return; // expected-warning{{Potential leak of memory pointed to by 'p'}} diff --git a/clang/test/Analysis/malloc.cpp b/clang/test/Analysis/malloc.cpp index 300b344ab25d69de9af4dccaf42f993b0f1afaa8..7af1b59e04a5a24a8cd1ff5abf0204611b27e28f 100644 --- a/clang/test/Analysis/malloc.cpp +++ b/clang/test/Analysis/malloc.cpp @@ -3,7 +3,9 @@ // RUN: -analyzer-checker=alpha.deadcode.UnreachableCode \ // RUN: -analyzer-checker=alpha.core.CastSize \ // RUN: -analyzer-checker=unix.Malloc \ -// RUN: -analyzer-checker=cplusplus.NewDelete +// RUN: -analyzer-checker=cplusplus.NewDelete \ +// RUN: -analyzer-checker=alpha.security.taint.TaintPropagation \ +// RUN: -analyzer-checker=optin.taint.TaintedAlloc // RUN: %clang_analyze_cc1 -w -verify %s \ // RUN: -triple i386-unknown-linux-gnu \ @@ -11,14 +13,18 @@ // RUN: -analyzer-checker=alpha.deadcode.UnreachableCode \ // RUN: -analyzer-checker=alpha.core.CastSize \ // RUN: -analyzer-checker=unix.Malloc \ -// RUN: -analyzer-checker=cplusplus.NewDelete +// RUN: -analyzer-checker=cplusplus.NewDelete \ +// RUN: -analyzer-checker=alpha.security.taint.TaintPropagation \ +// RUN: -analyzer-checker=optin.taint.TaintedAlloc // RUN: %clang_analyze_cc1 -w -verify %s -DTEST_INLINABLE_ALLOCATORS \ // RUN: -analyzer-checker=core \ // RUN: -analyzer-checker=alpha.deadcode.UnreachableCode \ // RUN: -analyzer-checker=alpha.core.CastSize \ // RUN: -analyzer-checker=unix.Malloc \ -// RUN: -analyzer-checker=cplusplus.NewDelete +// RUN: -analyzer-checker=cplusplus.NewDelete \ +// RUN: -analyzer-checker=alpha.security.taint.TaintPropagation \ +// RUN: -analyzer-checker=optin.taint.TaintedAlloc // RUN: %clang_analyze_cc1 -w -verify %s -DTEST_INLINABLE_ALLOCATORS \ // RUN: -triple i386-unknown-linux-gnu \ @@ -26,7 +32,9 @@ // RUN: -analyzer-checker=alpha.deadcode.UnreachableCode \ // RUN: -analyzer-checker=alpha.core.CastSize \ // RUN: -analyzer-checker=unix.Malloc \ -// RUN: -analyzer-checker=cplusplus.NewDelete +// RUN: -analyzer-checker=cplusplus.NewDelete \ +// RUN: -analyzer-checker=alpha.security.taint.TaintPropagation \ +// RUN: -analyzer-checker=optin.taint.TaintedAlloc #include "Inputs/system-header-simulator-cxx.h" @@ -36,6 +44,14 @@ void free(void *); void *realloc(void *ptr, size_t size); void *calloc(size_t nmemb, size_t size); char *strdup(const char *s); +int scanf( const char* format, ... ); + +void taintAlloc() { + size_t size = 0; + scanf("%zu", &size); + int *ptr = new int[size];// expected-warning{{Memory allocation function is called with a tainted (potentially attacker controlled) value}} + delete[] ptr; +} void checkThatMallocCheckerIsRunning() { malloc(4); diff --git a/clang/test/Analysis/pointer-sub.c b/clang/test/Analysis/pointer-sub.c new file mode 100644 index 0000000000000000000000000000000000000000..9a446547e2868fc5d26b7471cb01e37c2e640699 --- /dev/null +++ b/clang/test/Analysis/pointer-sub.c @@ -0,0 +1,120 @@ +// RUN: %clang_analyze_cc1 -analyzer-checker=alpha.core.PointerSub -verify %s + +void f1(void) { + int x, y, z[10]; + int d = &y - &x; // expected-warning{{Subtraction of two pointers that do not point into the same array is undefined behavior}} + d = z - &y; // expected-warning{{Subtraction of two pointers that do not point into the same array is undefined behavior}} + d = &x - &x; // no-warning (subtraction of any two identical pointers is allowed) + d = (long *)&x - (long *)&x; + d = (&x + 1) - &x; // no-warning ('&x' is like a single-element array) + d = &x - (&x + 1); // no-warning + d = (&x + 0) - &x; // no-warning + d = (&x - 1) - &x; // expected-warning{{Indexing the address of a variable with other than 1 at this place is undefined behavior}} + d = (&x + 2) - &x; // expected-warning{{Indexing the address of a variable with other than 1 at this place is undefined behavior}} + + d = (z + 9) - z; // no-warning (pointers to same array) + d = (z + 10) - z; // no-warning (pointer to "one after the end") + d = (z + 11) - z; // expected-warning{{Using an array index greater than the array size at pointer subtraction is undefined behavior}} + d = (z - 1) - z; // expected-warning{{Using a negative array index at pointer subtraction is undefined behavior}} +} + +void f2(void) { + int a[10], b[10], c; + int *p = &a[2]; + int *q = &a[8]; + int d = q - p; // no-warning (pointers into the same array) + + q = &b[3]; + d = q - p; // expected-warning{{Subtraction of two pointers that}} + + q = a + 10; + d = q - p; // no warning (use of pointer to one after the end is allowed) + q = a + 11; + d = q - a; // expected-warning{{Using an array index greater than the array size at pointer subtraction is undefined behavior}} + + d = &a[4] - a; // no-warning + d = &a[2] - p; // no-warning + d = &c - p; // expected-warning{{Subtraction of two pointers that}} + + d = (int *)((char *)(&a[4]) + sizeof(int)) - &a[4]; // no-warning (pointers into the same array data) + d = (int *)((char *)(&a[4]) + 1) - &a[4]; // expected-warning{{Subtraction of two pointers that}} +} + +void f3(void) { + int a[3][4]; + int d; + + d = &(a[2]) - &(a[1]); + d = a[2] - a[1]; // expected-warning{{Subtraction of two pointers that}} + d = a[1] - a[1]; + d = &(a[1][2]) - &(a[1][0]); + d = &(a[1][2]) - &(a[0][0]); // expected-warning{{Subtraction of two pointers that}} + + d = (int *)((char *)(&a[2][2]) + sizeof(int)) - &a[2][2]; // expected-warning{{Subtraction of two pointers that}} + d = (int *)((char *)(&a[2][2]) + 1) - &a[2][2]; // expected-warning{{Subtraction of two pointers that}} + d = (int (*)[4])((char *)&a[2] + sizeof(int (*)[4])) - &a[2]; // expected-warning{{Subtraction of two pointers that}} + d = (int (*)[4])((char *)&a[2] + 1) - &a[2]; // expected-warning{{Subtraction of two pointers that}} +} + +void f4(void) { + int n = 4, m = 3; + int a[n][m]; + int (*p)[m] = a; // p == &a[0] + p += 1; // p == &a[1] + + // FIXME: This is a known problem with -Wpointer-arith (https://github.com/llvm/llvm-project/issues/28328) + int d = p - a; // d == 1 // expected-warning{{subtraction of pointers to type 'int[m]' of zero size has undefined behavior}} + + // FIXME: This is a known problem with -Wpointer-arith (https://github.com/llvm/llvm-project/issues/28328) + d = &(a[2]) - &(a[1]); // expected-warning{{subtraction of pointers to type 'int[m]' of zero size has undefined behavior}} + + d = a[2] - a[1]; // expected-warning{{Subtraction of two pointers that}} +} + +typedef struct { + int a; + int b; + int c[10]; + int d[10]; +} S; + +void f5(void) { + S s; + int y; + int d; + + d = &s.b - &s.a; // expected-warning{{Subtraction of two pointers that}} + d = &s.c[0] - &s.a; // expected-warning{{Subtraction of two pointers that}} + d = &s.b - &y; // expected-warning{{Subtraction of two pointers that}} + d = &s.c[3] - &s.c[2]; + d = &s.d[3] - &s.c[2]; // expected-warning{{Subtraction of two pointers that}} + d = s.d - s.c; // expected-warning{{Subtraction of two pointers that}} + + S sa[10]; + d = &sa[2] - &sa[1]; + d = &sa[2].a - &sa[1].b; // expected-warning{{Subtraction of two pointers that}} +} + +void f6(void) { + long long l; + char *a1 = (char *)&l; + int d = a1[3] - l; + + long long la1[3]; + long long la2[3]; + char *pla1 = (char *)la1; + char *pla2 = (char *)la2; + d = pla1[1] - pla1[0]; + d = (long long *)&pla1[1] - &l; // expected-warning{{Subtraction of two pointers that}} + d = &pla2[3] - &pla1[3]; // expected-warning{{Subtraction of two pointers that}} +} + +void f7(int *p) { + int a[10]; + int d = &a[10] - p; // no-warning ('p' is unknown, even if it cannot point into 'a') +} + +void f8(int n) { + int a[10]; + int d = a[n] - a[0]; +} diff --git a/clang/test/Analysis/ptr-arith.c b/clang/test/Analysis/ptr-arith.c index 40c8188704e811bad005ecf176fb94c30129b3a8..f99dfabb0736666399c900410ca27ddf82cb17ff 100644 --- a/clang/test/Analysis/ptr-arith.c +++ b/clang/test/Analysis/ptr-arith.c @@ -1,5 +1,5 @@ -// RUN: %clang_analyze_cc1 -analyzer-checker=alpha.core.FixedAddr,alpha.core.PointerArithm,alpha.core.PointerSub,debug.ExprInspection -Wno-pointer-to-int-cast -verify -triple x86_64-apple-darwin9 -Wno-tautological-pointer-compare -analyzer-config eagerly-assume=false %s -// RUN: %clang_analyze_cc1 -analyzer-checker=alpha.core.FixedAddr,alpha.core.PointerArithm,alpha.core.PointerSub,debug.ExprInspection -Wno-pointer-to-int-cast -verify -triple i686-apple-darwin9 -Wno-tautological-pointer-compare -analyzer-config eagerly-assume=false %s +// RUN: %clang_analyze_cc1 -analyzer-checker=alpha.core.FixedAddr,alpha.core.PointerArithm,debug.ExprInspection -Wno-pointer-to-int-cast -verify -triple x86_64-apple-darwin9 -Wno-tautological-pointer-compare -analyzer-config eagerly-assume=false %s +// RUN: %clang_analyze_cc1 -analyzer-checker=alpha.core.FixedAddr,alpha.core.PointerArithm,debug.ExprInspection -Wno-pointer-to-int-cast -verify -triple i686-apple-darwin9 -Wno-tautological-pointer-compare -analyzer-config eagerly-assume=false %s void clang_analyzer_eval(int); void clang_analyzer_dump(int); @@ -35,16 +35,6 @@ domain_port (const char *domain_b, const char *domain_e, return port; } -void f3(void) { - int x, y; - int d = &y - &x; // expected-warning{{Subtraction of two pointers that do not point to the same memory chunk may cause incorrect result}} - - int a[10]; - int *p = &a[2]; - int *q = &a[8]; - d = q-p; // no-warning -} - void f4(void) { int *p; p = (int*) 0x10000; // expected-warning{{Using a fixed address is not portable because that address will probably not be valid in all environments or platforms}} diff --git a/clang/test/Analysis/taint-diagnostic-visitor.c b/clang/test/Analysis/taint-diagnostic-visitor.c index b8b3710a7013e7112c31d4b886259cbbc56d89de..f51423646e8aeca3e695a8935762fbd9d445f619 100644 --- a/clang/test/Analysis/taint-diagnostic-visitor.c +++ b/clang/test/Analysis/taint-diagnostic-visitor.c @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -analyze -analyzer-checker=alpha.security.taint,core,alpha.security.ArrayBoundV2 -analyzer-output=text -verify %s +// RUN: %clang_cc1 -analyze -analyzer-checker=alpha.security.taint,core,alpha.security.ArrayBoundV2,optin.taint.TaintedAlloc -analyzer-output=text -verify %s // This file is for testing enhanced diagnostics produced by the GenericTaintChecker @@ -115,3 +115,12 @@ void multipleTaintedArgs(void) { system(buf); // expected-warning {{Untrusted data is passed to a system call}} // expected-note@-1{{Untrusted data is passed to a system call}} } + +void testTaintedMalloc(){ + size_t size = 0; + scanf("%zu", &size); // expected-note {{Taint originated here}} + // expected-note@-1 {{Taint propagated to the 2nd argument}} + int *p = malloc(size);// expected-warning{{malloc is called with a tainted (potentially attacker controlled) value}} + // expected-note@-1{{malloc is called with a tainted (potentially attacker controlled) value}} + free(p); +} diff --git a/clang/test/CXX/basic/basic.lookup/basic.lookup.elab/p2.cpp b/clang/test/CXX/basic/basic.lookup/basic.lookup.elab/p2.cpp index a908518f02ea2e49065b1ce15fe4c82aae91e640..c58cbfefc7997c6a2577c53697c883b29390d96d 100644 --- a/clang/test/CXX/basic/basic.lookup/basic.lookup.elab/p2.cpp +++ b/clang/test/CXX/basic/basic.lookup/basic.lookup.elab/p2.cpp @@ -9,7 +9,7 @@ namespace test0 { typedef int A; // expected-note {{declared here}} int test() { - struct A a; // expected-error {{typedef 'A' cannot be referenced with a struct specifier}} + struct A a; // expected-error {{typedef 'A' cannot be referenced with the 'struct' specifier}} return a.foo; } } @@ -18,7 +18,7 @@ namespace test0 { template class A; // expected-note {{declared here}} int test() { - struct A a; // expected-error {{template 'A' cannot be referenced with a struct specifier}} + struct A a; // expected-error {{template 'A' cannot be referenced with the 'struct' specifier}} return a.foo; } } diff --git a/clang/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p6-cxx11.cpp b/clang/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p6-cxx11.cpp index 97b2953b903123c2529f5b8882702db3a009cdd4..473290dd1c191a120080f5b05d5186ea550bdcd8 100644 --- a/clang/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p6-cxx11.cpp +++ b/clang/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p6-cxx11.cpp @@ -1,7 +1,10 @@ // RUN: %clang_cc1 -fsyntax-only -verify %s +// RUN: not %clang_cc1 -fsyntax-only -fdiagnostics-parseable-fixits %s 2>&1 | FileCheck %s namespace A { namespace B { } } +// CHECK: fix-it:"{{.*}}":{[[@LINE+1]]:7-[[@LINE+1]]:7}:"namespace " using A::B; // expected-error{{using declaration cannot refer to a namespace}} + // expected-note@-1 {{did you mean 'using namespace'?}} diff --git a/clang/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p3.cpp b/clang/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p3.cpp index 4416c825226494b413c6c5887af470ac9a322d92..51990ee4341d29b5d1d0502d7d609275d3ee2bde 100644 --- a/clang/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p3.cpp +++ b/clang/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p3.cpp @@ -212,7 +212,7 @@ constexpr int ClassDecl3() { return 0; } -constexpr int NoReturn() {} // expected-error {{no return statement in constexpr function}} +constexpr int NoReturn() {} // beforecxx23-error {{no return statement in constexpr function}} constexpr int MultiReturn() { return 0; // beforecxx14-note {{return statement}} return 0; // beforecxx14-warning {{multiple return statements in constexpr function}} diff --git a/clang/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.type.elab/p2-0x.cpp b/clang/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.type.elab/p2-0x.cpp index f3e79c0aae44a8a85551c980d3515043254fb085..98c9b915c6ce9f0f5f577ebf4a6273ed4a09a4d0 100644 --- a/clang/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.type.elab/p2-0x.cpp +++ b/clang/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.type.elab/p2-0x.cpp @@ -2,18 +2,18 @@ struct A { typedef int type; }; template using X = A; // expected-note {{declared here}} -struct X* p2; // expected-error {{type alias template 'X' cannot be referenced with a struct specifier}} +struct X* p2; // expected-error {{alias template 'X' cannot be referenced with the 'struct' specifier}} template using Id = T; // expected-note {{declared here}} template class F> struct Y { - struct F i; // expected-error {{type alias template 'Id' cannot be referenced with a struct specifier}} + struct F i; // expected-error {{alias template 'Id' cannot be referenced with the 'struct' specifier}} typename F::type j; // ok // FIXME: don't produce the diagnostic both for the definition and the instantiation. template using U = F; // expected-note 2{{declared here}} - struct Y::template U k; // expected-error 2{{type alias template 'U' cannot be referenced with a struct specifier}} + struct Y::template U k; // expected-error 2{{alias template 'U' cannot be referenced with the 'struct' specifier}} typename Y::template U l; // ok }; template struct Y; // expected-note {{requested here}} diff --git a/clang/test/CXX/drs/cwg16xx.cpp b/clang/test/CXX/drs/cwg16xx.cpp index 82ef871939d2c468efc3837384c8f53db695562d..cf6b45ceabf2cc8f85bea33900fe3d3a1a4375f8 100644 --- a/clang/test/CXX/drs/cwg16xx.cpp +++ b/clang/test/CXX/drs/cwg16xx.cpp @@ -483,6 +483,8 @@ namespace cwg1696 { // cwg1696: 7 const A &a = A(); // #cwg1696-D1-a }; D1 d1 = {}; // #cwg1696-d1 + // since-cxx14-warning@-1 {{lifetime extension of temporary created by aggregate initialization using a default member initializer is not yet supported; lifetime of temporary will end at the end of the full-expression}} + // since-cxx14-note@#cwg1696-D1-a {{initializing field 'a' with default member initializer}} struct D2 { const A &a = A(); // #cwg1696-D2-a diff --git a/clang/test/CXX/drs/cwg18xx.cpp b/clang/test/CXX/drs/cwg18xx.cpp index 054ce5a4f4b704fc2fb48e7c2dce9014c88e2a50..323e56f9c527876b1eac21ac68818c0240696fa9 100644 --- a/clang/test/CXX/drs/cwg18xx.cpp +++ b/clang/test/CXX/drs/cwg18xx.cpp @@ -206,28 +206,19 @@ namespace cwg1814 { // cwg1814: yes #endif } -namespace cwg1815 { // cwg1815: 19 +namespace cwg1815 { // cwg1815: no #if __cplusplus >= 201402L - struct A { int &&r = 0; }; + // FIXME: needs codegen test + struct A { int &&r = 0; }; // #cwg1815-A A a = {}; + // since-cxx14-warning@-1 {{lifetime extension of temporary created by aggregate initialization using a default member initializer is not yet supported; lifetime of temporary will end at the end of the full-expression}} FIXME + // since-cxx14-note@#cwg1815-A {{initializing field 'r' with default member initializer}} struct B { int &&r = 0; }; // #cwg1815-B // since-cxx14-error@-1 {{reference member 'r' binds to a temporary object whose lifetime would be shorter than the lifetime of the constructed object}} // since-cxx14-note@#cwg1815-B {{initializing field 'r' with default member initializer}} // since-cxx14-note@#cwg1815-b {{in implicit default constructor for 'cwg1815::B' first required here}} B b; // #cwg1815-b - -#if __cplusplus >= 201703L - struct C { const int &r = 0; }; - constexpr C c = {}; // OK, since cwg1815 - static_assert(c.r == 0); - - constexpr int f() { - A a = {}; // OK, since cwg1815 - return a.r; - } - static_assert(f() == 0); -#endif #endif } diff --git a/clang/test/CXX/drs/cwg1xx.cpp b/clang/test/CXX/drs/cwg1xx.cpp index b39cc21fa4917493f9bda377e1e8d58aeafa563e..e7dddd1ea9278f692bdb44cdba7bedc2e524c080 100644 --- a/clang/test/CXX/drs/cwg1xx.cpp +++ b/clang/test/CXX/drs/cwg1xx.cpp @@ -883,23 +883,21 @@ namespace cwg161 { // cwg161: 3.1 }; } -namespace cwg162 { // cwg162: no +namespace cwg162 { // cwg162: 19 struct A { char &f(char); static int &f(int); void g() { int &a = (&A::f)(0); - // FIXME: expected-error@-1 {{reference to overloaded function could not be resolved; did you mean to call it?}} char &b = (&A::f)('0'); - // expected-error@-1 {{reference to overloaded function could not be resolved; did you mean to call it?}} + // expected-error@-1 {{non-const lvalue reference to type 'char' cannot bind to a value of unrelated type 'int'}} } }; int &c = (&A::f)(0); - // FIXME: expected-error@-1 {{reference to overloaded function could not be resolved; did you mean to call it?}} char &d = (&A::f)('0'); - // expected-error@-1 {{reference to overloaded function could not be resolved; did you mean to call it?}} + // expected-error@-1 {{non-const lvalue reference to type 'char' cannot bind to a value of unrelated type 'int'}} } // cwg163: na diff --git a/clang/test/CXX/drs/cwg26xx.cpp b/clang/test/CXX/drs/cwg26xx.cpp index 05c5d0a4963a5ccb70fd085e0bc92a0424046747..2b17c8101438d1498499b87ca14e823835dd67a5 100644 --- a/clang/test/CXX/drs/cwg26xx.cpp +++ b/clang/test/CXX/drs/cwg26xx.cpp @@ -240,3 +240,30 @@ void test() { } } #endif + + +namespace cwg2692 { // cwg2692: 19 +#if __cplusplus >= 202302L + + struct A { + static void f(A); // #cwg2692-1 + void f(this A); // #cwg2692-2 + + void g(); + }; + + void A::g() { + (&A::f)(A()); + // expected-error@-1 {{call to 'f' is ambiguous}} + // expected-note@#cwg2692-1 {{candidate}} + // expected-note@#cwg2692-2 {{candidate}} + + + + (&A::f)(); + // expected-error@-1 {{no matching function for call to 'f'}} + // expected-note@#cwg2692-1 {{candidate function not viable: requires 1 argument, but 0 were provided}} + // expected-note@#cwg2692-2 {{candidate function not viable: requires 1 argument, but 0 were provided}} + } +#endif +} diff --git a/clang/test/CXX/drs/cwg2771.cpp b/clang/test/CXX/drs/cwg2771.cpp new file mode 100644 index 0000000000000000000000000000000000000000..474660aa284404b5113442c43d342226d1d98ad3 --- /dev/null +++ b/clang/test/CXX/drs/cwg2771.cpp @@ -0,0 +1,19 @@ +// RUN: %clang_cc1 -std=c++23 %s -ast-dump | FileCheck --check-prefixes=CXX23 %s + +namespace cwg2771 { // cwg2771: 18 + +struct A{ + int a; + void cwg2771(){ + int* r = &a; + } +}; +// CXX23: CXXMethodDecl{{.+}}cwg2771 +// CXX23-NEXT: CompoundStmt +// CXX23-NEXT: DeclStmt +// CXX23-NEXT: VarDecl +// CXX23-NEXT: UnaryOperator +// CXX23-NEXT: MemberExpr +// CXX23-NEXT: CXXThisExpr{{.+}}'cwg2771::A *' + +} // namespace cwg2771 diff --git a/clang/test/CXX/drs/cwg2xx.cpp b/clang/test/CXX/drs/cwg2xx.cpp index 2b3131be33057a2ede491a115ec776189a86487d..99916dea9a9120be918f903d3078f72e4e037775 100644 --- a/clang/test/CXX/drs/cwg2xx.cpp +++ b/clang/test/CXX/drs/cwg2xx.cpp @@ -759,7 +759,7 @@ namespace cwg254 { // cwg254: 2.9 typedef typename T::type type; // ok even if this is a typedef-name, because // it's not an elaborated-type-specifier typedef struct T::type foo; - // expected-error@-1 {{typedef 'type' cannot be referenced with a struct specifier}} + // expected-error@-1 {{typedef 'type' cannot be referenced with the 'struct' specifier}} // expected-note@#cwg254-instantiation {{in instantiation of template class 'cwg254::A' requested here}} // expected-note@#cwg254-C {{declared here}} }; @@ -1264,10 +1264,10 @@ namespace cwg298 { // cwg298: 3.1 struct A a; struct B b; - // expected-error@-1 {{typedef 'B' cannot be referenced with a struct specifier}} + // expected-error@-1 {{typedef 'B' cannot be referenced with the 'struct' specifier}} // expected-note@#cwg298-B {{declared here}} struct C c; - // expected-error@-1 {{typedef 'C' cannot be referenced with a struct specifier}} + // expected-error@-1 {{typedef 'C' cannot be referenced with the 'struct' specifier}} // expected-note@#cwg298-C {{declared here}} B::B() {} diff --git a/clang/test/CXX/drs/cwg4xx.cpp b/clang/test/CXX/drs/cwg4xx.cpp index 07162cc28f6b6006606ca7cef1e725516f9bc7a5..98ff7553d989ba186813700c60d423b54288e59f 100644 --- a/clang/test/CXX/drs/cwg4xx.cpp +++ b/clang/test/CXX/drs/cwg4xx.cpp @@ -170,7 +170,7 @@ namespace cwg407 { // cwg407: 3.8 { typedef struct S S; // #cwg407-typedef-S struct S *p; - // expected-error@-1 {{typedef 'S' cannot be referenced with a struct specifier}} + // expected-error@-1 {{typedef 'S' cannot be referenced with the 'struct' specifier}} // expected-note@#cwg407-typedef-S {{declared here}} } } @@ -941,8 +941,10 @@ namespace cwg460 { // cwg460: yes // expected-error@-1 {{using declaration requires a qualified name}} using cwg460::X; // expected-error@-1 {{using declaration cannot refer to a namespace}} + // expected-note@-2 {{did you mean 'using namespace'?}} using X::Q; // expected-error@-1 {{using declaration cannot refer to a namespace}} + // expected-note@-2 {{did you mean 'using namespace'?}} } } diff --git a/clang/test/CXX/special/class.temporary/p6.cpp b/clang/test/CXX/special/class.temporary/p6.cpp index a6d2adfd1fd2c5bac6d063cdd839011bb8828b13..5554363cc69abb5190169e6c181d3c84756cf83d 100644 --- a/clang/test/CXX/special/class.temporary/p6.cpp +++ b/clang/test/CXX/special/class.temporary/p6.cpp @@ -269,40 +269,6 @@ void init_capture_init_list() { // CHECK: } } -void check_dr1815() { // dr1815: yes -#if __cplusplus >= 201402L - - struct A { - int &&r = 0; - ~A() {} - }; - - struct B { - A &&a = A{}; - ~B() {} - }; - B a = {}; - - // CHECK: call {{.*}}block_scope_begin_function - extern void block_scope_begin_function(); - extern void block_scope_end_function(); - block_scope_begin_function(); - { - // CHECK: call void @_ZZ12check_dr1815vEN1BD1Ev - // CHECK: call void @_ZZ12check_dr1815vEN1AD1Ev - B b = {}; - } - // CHECK: call {{.*}}block_scope_end_function - block_scope_end_function(); - - // CHECK: call {{.*}}some_other_function - extern void some_other_function(); - some_other_function(); - // CHECK: call void @_ZZ12check_dr1815vEN1BD1Ev - // CHECK: call void @_ZZ12check_dr1815vEN1AD1Ev -#endif -} - namespace P2718R0 { namespace basic { template using T2 = std::list; diff --git a/clang/test/CXX/temp/temp.decls/temp.friend/p1.cpp b/clang/test/CXX/temp/temp.decls/temp.friend/p1.cpp index 1cf9e1c9f9c0fa39caf6c1d326e68519cee41a62..b8092afaffef3f7e812ae87af5419b9d55c8dad0 100644 --- a/clang/test/CXX/temp/temp.decls/temp.friend/p1.cpp +++ b/clang/test/CXX/temp/temp.decls/temp.friend/p1.cpp @@ -174,7 +174,7 @@ namespace test7 { // This shouldn't crash. template class D { - friend class A; // expected-error {{template 'A' cannot be referenced with a class specifier}} + friend class A; // expected-error {{template 'A' cannot be referenced with the 'class' specifier}} }; template class D; } diff --git a/clang/test/CXX/temp/temp.spec/no-body.cpp b/clang/test/CXX/temp/temp.spec/no-body.cpp index 6d1b82fe1898a48fe091915d8e8c298365246baa..5b0c4be300338007830d02de0a143d2527f7194d 100644 --- a/clang/test/CXX/temp/temp.spec/no-body.cpp +++ b/clang/test/CXX/temp/temp.spec/no-body.cpp @@ -43,7 +43,7 @@ namespace good { // Only good in C++98/03 namespace unsupported { #ifndef FIXING - template struct y; // expected-error {{template 'y' cannot be referenced with a struct specifier}} + template struct y; // expected-error {{template 'y' cannot be referenced with the 'struct' specifier}} #endif } diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vcpopv.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vcpopv.c index 13748be1acc1ac9b2f04540e1e41a47cafc5addc..b87b225b632a5edc23eecbca3f5a59631606f0e1 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vcpopv.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vcpopv.c @@ -16,399 +16,399 @@ #include -// CHECK-LABEL: @test_vcpopv_v_u8mf8( +// CHECK-LABEL: @test_vcpop_v_u8mf8( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vcpopv.nxv1i8.i64( poison, [[VS2:%.*]], i64 [[VL:%.*]]) // CHECK-NEXT: ret [[TMP0]] // -vuint8mf8_t test_vcpopv_v_u8mf8(vuint8mf8_t vs2, size_t vl) { - return __riscv_vcpopv_v_u8mf8(vs2, vl); +vuint8mf8_t test_vcpop_v_u8mf8(vuint8mf8_t vs2, size_t vl) { + return __riscv_vcpop_v_u8mf8(vs2, vl); } -// CHECK-LABEL: @test_vcpopv_v_u8mf4( +// CHECK-LABEL: @test_vcpop_v_u8mf4( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vcpopv.nxv2i8.i64( poison, [[VS2:%.*]], i64 [[VL:%.*]]) // CHECK-NEXT: ret [[TMP0]] // -vuint8mf4_t test_vcpopv_v_u8mf4(vuint8mf4_t vs2, size_t vl) { - return __riscv_vcpopv_v_u8mf4(vs2, vl); +vuint8mf4_t test_vcpop_v_u8mf4(vuint8mf4_t vs2, size_t vl) { + return __riscv_vcpop_v_u8mf4(vs2, vl); } -// CHECK-LABEL: @test_vcpopv_v_u8mf2( +// CHECK-LABEL: @test_vcpop_v_u8mf2( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vcpopv.nxv4i8.i64( poison, [[VS2:%.*]], i64 [[VL:%.*]]) // CHECK-NEXT: ret [[TMP0]] // -vuint8mf2_t test_vcpopv_v_u8mf2(vuint8mf2_t vs2, size_t vl) { - return __riscv_vcpopv_v_u8mf2(vs2, vl); +vuint8mf2_t test_vcpop_v_u8mf2(vuint8mf2_t vs2, size_t vl) { + return __riscv_vcpop_v_u8mf2(vs2, vl); } -// CHECK-LABEL: @test_vcpopv_v_u8m1( +// CHECK-LABEL: @test_vcpop_v_u8m1( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vcpopv.nxv8i8.i64( poison, [[VS2:%.*]], i64 [[VL:%.*]]) // CHECK-NEXT: ret [[TMP0]] // -vuint8m1_t test_vcpopv_v_u8m1(vuint8m1_t vs2, size_t vl) { - return __riscv_vcpopv_v_u8m1(vs2, vl); +vuint8m1_t test_vcpop_v_u8m1(vuint8m1_t vs2, size_t vl) { + return __riscv_vcpop_v_u8m1(vs2, vl); } -// CHECK-LABEL: @test_vcpopv_v_u8m2( +// CHECK-LABEL: @test_vcpop_v_u8m2( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vcpopv.nxv16i8.i64( poison, [[VS2:%.*]], i64 [[VL:%.*]]) // CHECK-NEXT: ret [[TMP0]] // -vuint8m2_t test_vcpopv_v_u8m2(vuint8m2_t vs2, size_t vl) { - return __riscv_vcpopv_v_u8m2(vs2, vl); +vuint8m2_t test_vcpop_v_u8m2(vuint8m2_t vs2, size_t vl) { + return __riscv_vcpop_v_u8m2(vs2, vl); } -// CHECK-LABEL: @test_vcpopv_v_u8m4( +// CHECK-LABEL: @test_vcpop_v_u8m4( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vcpopv.nxv32i8.i64( poison, [[VS2:%.*]], i64 [[VL:%.*]]) // CHECK-NEXT: ret [[TMP0]] // -vuint8m4_t test_vcpopv_v_u8m4(vuint8m4_t vs2, size_t vl) { - return __riscv_vcpopv_v_u8m4(vs2, vl); +vuint8m4_t test_vcpop_v_u8m4(vuint8m4_t vs2, size_t vl) { + return __riscv_vcpop_v_u8m4(vs2, vl); } -// CHECK-LABEL: @test_vcpopv_v_u8m8( +// CHECK-LABEL: @test_vcpop_v_u8m8( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vcpopv.nxv64i8.i64( poison, [[VS2:%.*]], i64 [[VL:%.*]]) // CHECK-NEXT: ret [[TMP0]] // -vuint8m8_t test_vcpopv_v_u8m8(vuint8m8_t vs2, size_t vl) { - return __riscv_vcpopv_v_u8m8(vs2, vl); +vuint8m8_t test_vcpop_v_u8m8(vuint8m8_t vs2, size_t vl) { + return __riscv_vcpop_v_u8m8(vs2, vl); } -// CHECK-LABEL: @test_vcpopv_v_u16mf4( +// CHECK-LABEL: @test_vcpop_v_u16mf4( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vcpopv.nxv1i16.i64( poison, [[VS2:%.*]], i64 [[VL:%.*]]) // CHECK-NEXT: ret [[TMP0]] // -vuint16mf4_t test_vcpopv_v_u16mf4(vuint16mf4_t vs2, size_t vl) { - return __riscv_vcpopv_v_u16mf4(vs2, vl); +vuint16mf4_t test_vcpop_v_u16mf4(vuint16mf4_t vs2, size_t vl) { + return __riscv_vcpop_v_u16mf4(vs2, vl); } -// CHECK-LABEL: @test_vcpopv_v_u16mf2( +// CHECK-LABEL: @test_vcpop_v_u16mf2( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vcpopv.nxv2i16.i64( poison, [[VS2:%.*]], i64 [[VL:%.*]]) // CHECK-NEXT: ret [[TMP0]] // -vuint16mf2_t test_vcpopv_v_u16mf2(vuint16mf2_t vs2, size_t vl) { - return __riscv_vcpopv_v_u16mf2(vs2, vl); +vuint16mf2_t test_vcpop_v_u16mf2(vuint16mf2_t vs2, size_t vl) { + return __riscv_vcpop_v_u16mf2(vs2, vl); } -// CHECK-LABEL: @test_vcpopv_v_u16m1( +// CHECK-LABEL: @test_vcpop_v_u16m1( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vcpopv.nxv4i16.i64( poison, [[VS2:%.*]], i64 [[VL:%.*]]) // CHECK-NEXT: ret [[TMP0]] // -vuint16m1_t test_vcpopv_v_u16m1(vuint16m1_t vs2, size_t vl) { - return __riscv_vcpopv_v_u16m1(vs2, vl); +vuint16m1_t test_vcpop_v_u16m1(vuint16m1_t vs2, size_t vl) { + return __riscv_vcpop_v_u16m1(vs2, vl); } -// CHECK-LABEL: @test_vcpopv_v_u16m2( +// CHECK-LABEL: @test_vcpop_v_u16m2( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vcpopv.nxv8i16.i64( poison, [[VS2:%.*]], i64 [[VL:%.*]]) // CHECK-NEXT: ret [[TMP0]] // -vuint16m2_t test_vcpopv_v_u16m2(vuint16m2_t vs2, size_t vl) { - return __riscv_vcpopv_v_u16m2(vs2, vl); +vuint16m2_t test_vcpop_v_u16m2(vuint16m2_t vs2, size_t vl) { + return __riscv_vcpop_v_u16m2(vs2, vl); } -// CHECK-LABEL: @test_vcpopv_v_u16m4( +// CHECK-LABEL: @test_vcpop_v_u16m4( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vcpopv.nxv16i16.i64( poison, [[VS2:%.*]], i64 [[VL:%.*]]) // CHECK-NEXT: ret [[TMP0]] // -vuint16m4_t test_vcpopv_v_u16m4(vuint16m4_t vs2, size_t vl) { - return __riscv_vcpopv_v_u16m4(vs2, vl); +vuint16m4_t test_vcpop_v_u16m4(vuint16m4_t vs2, size_t vl) { + return __riscv_vcpop_v_u16m4(vs2, vl); } -// CHECK-LABEL: @test_vcpopv_v_u16m8( +// CHECK-LABEL: @test_vcpop_v_u16m8( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vcpopv.nxv32i16.i64( poison, [[VS2:%.*]], i64 [[VL:%.*]]) // CHECK-NEXT: ret [[TMP0]] // -vuint16m8_t test_vcpopv_v_u16m8(vuint16m8_t vs2, size_t vl) { - return __riscv_vcpopv_v_u16m8(vs2, vl); +vuint16m8_t test_vcpop_v_u16m8(vuint16m8_t vs2, size_t vl) { + return __riscv_vcpop_v_u16m8(vs2, vl); } -// CHECK-LABEL: @test_vcpopv_v_u32mf2( +// CHECK-LABEL: @test_vcpop_v_u32mf2( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vcpopv.nxv1i32.i64( poison, [[VS2:%.*]], i64 [[VL:%.*]]) // CHECK-NEXT: ret [[TMP0]] // -vuint32mf2_t test_vcpopv_v_u32mf2(vuint32mf2_t vs2, size_t vl) { - return __riscv_vcpopv_v_u32mf2(vs2, vl); +vuint32mf2_t test_vcpop_v_u32mf2(vuint32mf2_t vs2, size_t vl) { + return __riscv_vcpop_v_u32mf2(vs2, vl); } -// CHECK-LABEL: @test_vcpopv_v_u32m1( +// CHECK-LABEL: @test_vcpop_v_u32m1( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vcpopv.nxv2i32.i64( poison, [[VS2:%.*]], i64 [[VL:%.*]]) // CHECK-NEXT: ret [[TMP0]] // -vuint32m1_t test_vcpopv_v_u32m1(vuint32m1_t vs2, size_t vl) { - return __riscv_vcpopv_v_u32m1(vs2, vl); +vuint32m1_t test_vcpop_v_u32m1(vuint32m1_t vs2, size_t vl) { + return __riscv_vcpop_v_u32m1(vs2, vl); } -// CHECK-LABEL: @test_vcpopv_v_u32m2( +// CHECK-LABEL: @test_vcpop_v_u32m2( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vcpopv.nxv4i32.i64( poison, [[VS2:%.*]], i64 [[VL:%.*]]) // CHECK-NEXT: ret [[TMP0]] // -vuint32m2_t test_vcpopv_v_u32m2(vuint32m2_t vs2, size_t vl) { - return __riscv_vcpopv_v_u32m2(vs2, vl); +vuint32m2_t test_vcpop_v_u32m2(vuint32m2_t vs2, size_t vl) { + return __riscv_vcpop_v_u32m2(vs2, vl); } -// CHECK-LABEL: @test_vcpopv_v_u32m4( +// CHECK-LABEL: @test_vcpop_v_u32m4( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vcpopv.nxv8i32.i64( poison, [[VS2:%.*]], i64 [[VL:%.*]]) // CHECK-NEXT: ret [[TMP0]] // -vuint32m4_t test_vcpopv_v_u32m4(vuint32m4_t vs2, size_t vl) { - return __riscv_vcpopv_v_u32m4(vs2, vl); +vuint32m4_t test_vcpop_v_u32m4(vuint32m4_t vs2, size_t vl) { + return __riscv_vcpop_v_u32m4(vs2, vl); } -// CHECK-LABEL: @test_vcpopv_v_u32m8( +// CHECK-LABEL: @test_vcpop_v_u32m8( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vcpopv.nxv16i32.i64( poison, [[VS2:%.*]], i64 [[VL:%.*]]) // CHECK-NEXT: ret [[TMP0]] // -vuint32m8_t test_vcpopv_v_u32m8(vuint32m8_t vs2, size_t vl) { - return __riscv_vcpopv_v_u32m8(vs2, vl); +vuint32m8_t test_vcpop_v_u32m8(vuint32m8_t vs2, size_t vl) { + return __riscv_vcpop_v_u32m8(vs2, vl); } -// CHECK-LABEL: @test_vcpopv_v_u64m1( +// CHECK-LABEL: @test_vcpop_v_u64m1( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vcpopv.nxv1i64.i64( poison, [[VS2:%.*]], i64 [[VL:%.*]]) // CHECK-NEXT: ret [[TMP0]] // -vuint64m1_t test_vcpopv_v_u64m1(vuint64m1_t vs2, size_t vl) { - return __riscv_vcpopv_v_u64m1(vs2, vl); +vuint64m1_t test_vcpop_v_u64m1(vuint64m1_t vs2, size_t vl) { + return __riscv_vcpop_v_u64m1(vs2, vl); } -// CHECK-LABEL: @test_vcpopv_v_u64m2( +// CHECK-LABEL: @test_vcpop_v_u64m2( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vcpopv.nxv2i64.i64( poison, [[VS2:%.*]], i64 [[VL:%.*]]) // CHECK-NEXT: ret [[TMP0]] // -vuint64m2_t test_vcpopv_v_u64m2(vuint64m2_t vs2, size_t vl) { - return __riscv_vcpopv_v_u64m2(vs2, vl); +vuint64m2_t test_vcpop_v_u64m2(vuint64m2_t vs2, size_t vl) { + return __riscv_vcpop_v_u64m2(vs2, vl); } -// CHECK-LABEL: @test_vcpopv_v_u64m4( +// CHECK-LABEL: @test_vcpop_v_u64m4( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vcpopv.nxv4i64.i64( poison, [[VS2:%.*]], i64 [[VL:%.*]]) // CHECK-NEXT: ret [[TMP0]] // -vuint64m4_t test_vcpopv_v_u64m4(vuint64m4_t vs2, size_t vl) { - return __riscv_vcpopv_v_u64m4(vs2, vl); +vuint64m4_t test_vcpop_v_u64m4(vuint64m4_t vs2, size_t vl) { + return __riscv_vcpop_v_u64m4(vs2, vl); } -// CHECK-LABEL: @test_vcpopv_v_u64m8( +// CHECK-LABEL: @test_vcpop_v_u64m8( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vcpopv.nxv8i64.i64( poison, [[VS2:%.*]], i64 [[VL:%.*]]) // CHECK-NEXT: ret [[TMP0]] // -vuint64m8_t test_vcpopv_v_u64m8(vuint64m8_t vs2, size_t vl) { - return __riscv_vcpopv_v_u64m8(vs2, vl); +vuint64m8_t test_vcpop_v_u64m8(vuint64m8_t vs2, size_t vl) { + return __riscv_vcpop_v_u64m8(vs2, vl); } -// CHECK-LABEL: @test_vcpopv_v_u8mf8_m( +// CHECK-LABEL: @test_vcpop_v_u8mf8_m( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vcpopv.mask.nxv1i8.i64( poison, [[VS2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]], i64 3) // CHECK-NEXT: ret [[TMP0]] // -vuint8mf8_t test_vcpopv_v_u8mf8_m(vbool64_t mask, vuint8mf8_t vs2, size_t vl) { - return __riscv_vcpopv_v_u8mf8_m(mask, vs2, vl); +vuint8mf8_t test_vcpop_v_u8mf8_m(vbool64_t mask, vuint8mf8_t vs2, size_t vl) { + return __riscv_vcpop_v_u8mf8_m(mask, vs2, vl); } -// CHECK-LABEL: @test_vcpopv_v_u8mf4_m( +// CHECK-LABEL: @test_vcpop_v_u8mf4_m( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vcpopv.mask.nxv2i8.i64( poison, [[VS2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]], i64 3) // CHECK-NEXT: ret [[TMP0]] // -vuint8mf4_t test_vcpopv_v_u8mf4_m(vbool32_t mask, vuint8mf4_t vs2, size_t vl) { - return __riscv_vcpopv_v_u8mf4_m(mask, vs2, vl); +vuint8mf4_t test_vcpop_v_u8mf4_m(vbool32_t mask, vuint8mf4_t vs2, size_t vl) { + return __riscv_vcpop_v_u8mf4_m(mask, vs2, vl); } -// CHECK-LABEL: @test_vcpopv_v_u8mf2_m( +// CHECK-LABEL: @test_vcpop_v_u8mf2_m( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vcpopv.mask.nxv4i8.i64( poison, [[VS2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]], i64 3) // CHECK-NEXT: ret [[TMP0]] // -vuint8mf2_t test_vcpopv_v_u8mf2_m(vbool16_t mask, vuint8mf2_t vs2, size_t vl) { - return __riscv_vcpopv_v_u8mf2_m(mask, vs2, vl); +vuint8mf2_t test_vcpop_v_u8mf2_m(vbool16_t mask, vuint8mf2_t vs2, size_t vl) { + return __riscv_vcpop_v_u8mf2_m(mask, vs2, vl); } -// CHECK-LABEL: @test_vcpopv_v_u8m1_m( +// CHECK-LABEL: @test_vcpop_v_u8m1_m( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vcpopv.mask.nxv8i8.i64( poison, [[VS2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]], i64 3) // CHECK-NEXT: ret [[TMP0]] // -vuint8m1_t test_vcpopv_v_u8m1_m(vbool8_t mask, vuint8m1_t vs2, size_t vl) { - return __riscv_vcpopv_v_u8m1_m(mask, vs2, vl); +vuint8m1_t test_vcpop_v_u8m1_m(vbool8_t mask, vuint8m1_t vs2, size_t vl) { + return __riscv_vcpop_v_u8m1_m(mask, vs2, vl); } -// CHECK-LABEL: @test_vcpopv_v_u8m2_m( +// CHECK-LABEL: @test_vcpop_v_u8m2_m( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vcpopv.mask.nxv16i8.i64( poison, [[VS2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]], i64 3) // CHECK-NEXT: ret [[TMP0]] // -vuint8m2_t test_vcpopv_v_u8m2_m(vbool4_t mask, vuint8m2_t vs2, size_t vl) { - return __riscv_vcpopv_v_u8m2_m(mask, vs2, vl); +vuint8m2_t test_vcpop_v_u8m2_m(vbool4_t mask, vuint8m2_t vs2, size_t vl) { + return __riscv_vcpop_v_u8m2_m(mask, vs2, vl); } -// CHECK-LABEL: @test_vcpopv_v_u8m4_m( +// CHECK-LABEL: @test_vcpop_v_u8m4_m( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vcpopv.mask.nxv32i8.i64( poison, [[VS2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]], i64 3) // CHECK-NEXT: ret [[TMP0]] // -vuint8m4_t test_vcpopv_v_u8m4_m(vbool2_t mask, vuint8m4_t vs2, size_t vl) { - return __riscv_vcpopv_v_u8m4_m(mask, vs2, vl); +vuint8m4_t test_vcpop_v_u8m4_m(vbool2_t mask, vuint8m4_t vs2, size_t vl) { + return __riscv_vcpop_v_u8m4_m(mask, vs2, vl); } -// CHECK-LABEL: @test_vcpopv_v_u8m8_m( +// CHECK-LABEL: @test_vcpop_v_u8m8_m( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vcpopv.mask.nxv64i8.i64( poison, [[VS2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]], i64 3) // CHECK-NEXT: ret [[TMP0]] // -vuint8m8_t test_vcpopv_v_u8m8_m(vbool1_t mask, vuint8m8_t vs2, size_t vl) { - return __riscv_vcpopv_v_u8m8_m(mask, vs2, vl); +vuint8m8_t test_vcpop_v_u8m8_m(vbool1_t mask, vuint8m8_t vs2, size_t vl) { + return __riscv_vcpop_v_u8m8_m(mask, vs2, vl); } -// CHECK-LABEL: @test_vcpopv_v_u16mf4_m( +// CHECK-LABEL: @test_vcpop_v_u16mf4_m( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vcpopv.mask.nxv1i16.i64( poison, [[VS2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]], i64 3) // CHECK-NEXT: ret [[TMP0]] // -vuint16mf4_t test_vcpopv_v_u16mf4_m(vbool64_t mask, vuint16mf4_t vs2, size_t vl) { - return __riscv_vcpopv_v_u16mf4_m(mask, vs2, vl); +vuint16mf4_t test_vcpop_v_u16mf4_m(vbool64_t mask, vuint16mf4_t vs2, size_t vl) { + return __riscv_vcpop_v_u16mf4_m(mask, vs2, vl); } -// CHECK-LABEL: @test_vcpopv_v_u16mf2_m( +// CHECK-LABEL: @test_vcpop_v_u16mf2_m( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vcpopv.mask.nxv2i16.i64( poison, [[VS2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]], i64 3) // CHECK-NEXT: ret [[TMP0]] // -vuint16mf2_t test_vcpopv_v_u16mf2_m(vbool32_t mask, vuint16mf2_t vs2, size_t vl) { - return __riscv_vcpopv_v_u16mf2_m(mask, vs2, vl); +vuint16mf2_t test_vcpop_v_u16mf2_m(vbool32_t mask, vuint16mf2_t vs2, size_t vl) { + return __riscv_vcpop_v_u16mf2_m(mask, vs2, vl); } -// CHECK-LABEL: @test_vcpopv_v_u16m1_m( +// CHECK-LABEL: @test_vcpop_v_u16m1_m( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vcpopv.mask.nxv4i16.i64( poison, [[VS2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]], i64 3) // CHECK-NEXT: ret [[TMP0]] // -vuint16m1_t test_vcpopv_v_u16m1_m(vbool16_t mask, vuint16m1_t vs2, size_t vl) { - return __riscv_vcpopv_v_u16m1_m(mask, vs2, vl); +vuint16m1_t test_vcpop_v_u16m1_m(vbool16_t mask, vuint16m1_t vs2, size_t vl) { + return __riscv_vcpop_v_u16m1_m(mask, vs2, vl); } -// CHECK-LABEL: @test_vcpopv_v_u16m2_m( +// CHECK-LABEL: @test_vcpop_v_u16m2_m( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vcpopv.mask.nxv8i16.i64( poison, [[VS2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]], i64 3) // CHECK-NEXT: ret [[TMP0]] // -vuint16m2_t test_vcpopv_v_u16m2_m(vbool8_t mask, vuint16m2_t vs2, size_t vl) { - return __riscv_vcpopv_v_u16m2_m(mask, vs2, vl); +vuint16m2_t test_vcpop_v_u16m2_m(vbool8_t mask, vuint16m2_t vs2, size_t vl) { + return __riscv_vcpop_v_u16m2_m(mask, vs2, vl); } -// CHECK-LABEL: @test_vcpopv_v_u16m4_m( +// CHECK-LABEL: @test_vcpop_v_u16m4_m( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vcpopv.mask.nxv16i16.i64( poison, [[VS2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]], i64 3) // CHECK-NEXT: ret [[TMP0]] // -vuint16m4_t test_vcpopv_v_u16m4_m(vbool4_t mask, vuint16m4_t vs2, size_t vl) { - return __riscv_vcpopv_v_u16m4_m(mask, vs2, vl); +vuint16m4_t test_vcpop_v_u16m4_m(vbool4_t mask, vuint16m4_t vs2, size_t vl) { + return __riscv_vcpop_v_u16m4_m(mask, vs2, vl); } -// CHECK-LABEL: @test_vcpopv_v_u16m8_m( +// CHECK-LABEL: @test_vcpop_v_u16m8_m( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vcpopv.mask.nxv32i16.i64( poison, [[VS2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]], i64 3) // CHECK-NEXT: ret [[TMP0]] // -vuint16m8_t test_vcpopv_v_u16m8_m(vbool2_t mask, vuint16m8_t vs2, size_t vl) { - return __riscv_vcpopv_v_u16m8_m(mask, vs2, vl); +vuint16m8_t test_vcpop_v_u16m8_m(vbool2_t mask, vuint16m8_t vs2, size_t vl) { + return __riscv_vcpop_v_u16m8_m(mask, vs2, vl); } -// CHECK-LABEL: @test_vcpopv_v_u32mf2_m( +// CHECK-LABEL: @test_vcpop_v_u32mf2_m( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vcpopv.mask.nxv1i32.i64( poison, [[VS2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]], i64 3) // CHECK-NEXT: ret [[TMP0]] // -vuint32mf2_t test_vcpopv_v_u32mf2_m(vbool64_t mask, vuint32mf2_t vs2, size_t vl) { - return __riscv_vcpopv_v_u32mf2_m(mask, vs2, vl); +vuint32mf2_t test_vcpop_v_u32mf2_m(vbool64_t mask, vuint32mf2_t vs2, size_t vl) { + return __riscv_vcpop_v_u32mf2_m(mask, vs2, vl); } -// CHECK-LABEL: @test_vcpopv_v_u32m1_m( +// CHECK-LABEL: @test_vcpop_v_u32m1_m( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vcpopv.mask.nxv2i32.i64( poison, [[VS2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]], i64 3) // CHECK-NEXT: ret [[TMP0]] // -vuint32m1_t test_vcpopv_v_u32m1_m(vbool32_t mask, vuint32m1_t vs2, size_t vl) { - return __riscv_vcpopv_v_u32m1_m(mask, vs2, vl); +vuint32m1_t test_vcpop_v_u32m1_m(vbool32_t mask, vuint32m1_t vs2, size_t vl) { + return __riscv_vcpop_v_u32m1_m(mask, vs2, vl); } -// CHECK-LABEL: @test_vcpopv_v_u32m2_m( +// CHECK-LABEL: @test_vcpop_v_u32m2_m( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vcpopv.mask.nxv4i32.i64( poison, [[VS2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]], i64 3) // CHECK-NEXT: ret [[TMP0]] // -vuint32m2_t test_vcpopv_v_u32m2_m(vbool16_t mask, vuint32m2_t vs2, size_t vl) { - return __riscv_vcpopv_v_u32m2_m(mask, vs2, vl); +vuint32m2_t test_vcpop_v_u32m2_m(vbool16_t mask, vuint32m2_t vs2, size_t vl) { + return __riscv_vcpop_v_u32m2_m(mask, vs2, vl); } -// CHECK-LABEL: @test_vcpopv_v_u32m4_m( +// CHECK-LABEL: @test_vcpop_v_u32m4_m( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vcpopv.mask.nxv8i32.i64( poison, [[VS2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]], i64 3) // CHECK-NEXT: ret [[TMP0]] // -vuint32m4_t test_vcpopv_v_u32m4_m(vbool8_t mask, vuint32m4_t vs2, size_t vl) { - return __riscv_vcpopv_v_u32m4_m(mask, vs2, vl); +vuint32m4_t test_vcpop_v_u32m4_m(vbool8_t mask, vuint32m4_t vs2, size_t vl) { + return __riscv_vcpop_v_u32m4_m(mask, vs2, vl); } -// CHECK-LABEL: @test_vcpopv_v_u32m8_m( +// CHECK-LABEL: @test_vcpop_v_u32m8_m( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vcpopv.mask.nxv16i32.i64( poison, [[VS2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]], i64 3) // CHECK-NEXT: ret [[TMP0]] // -vuint32m8_t test_vcpopv_v_u32m8_m(vbool4_t mask, vuint32m8_t vs2, size_t vl) { - return __riscv_vcpopv_v_u32m8_m(mask, vs2, vl); +vuint32m8_t test_vcpop_v_u32m8_m(vbool4_t mask, vuint32m8_t vs2, size_t vl) { + return __riscv_vcpop_v_u32m8_m(mask, vs2, vl); } -// CHECK-LABEL: @test_vcpopv_v_u64m1_m( +// CHECK-LABEL: @test_vcpop_v_u64m1_m( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vcpopv.mask.nxv1i64.i64( poison, [[VS2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]], i64 3) // CHECK-NEXT: ret [[TMP0]] // -vuint64m1_t test_vcpopv_v_u64m1_m(vbool64_t mask, vuint64m1_t vs2, size_t vl) { - return __riscv_vcpopv_v_u64m1_m(mask, vs2, vl); +vuint64m1_t test_vcpop_v_u64m1_m(vbool64_t mask, vuint64m1_t vs2, size_t vl) { + return __riscv_vcpop_v_u64m1_m(mask, vs2, vl); } -// CHECK-LABEL: @test_vcpopv_v_u64m2_m( +// CHECK-LABEL: @test_vcpop_v_u64m2_m( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vcpopv.mask.nxv2i64.i64( poison, [[VS2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]], i64 3) // CHECK-NEXT: ret [[TMP0]] // -vuint64m2_t test_vcpopv_v_u64m2_m(vbool32_t mask, vuint64m2_t vs2, size_t vl) { - return __riscv_vcpopv_v_u64m2_m(mask, vs2, vl); +vuint64m2_t test_vcpop_v_u64m2_m(vbool32_t mask, vuint64m2_t vs2, size_t vl) { + return __riscv_vcpop_v_u64m2_m(mask, vs2, vl); } -// CHECK-LABEL: @test_vcpopv_v_u64m4_m( +// CHECK-LABEL: @test_vcpop_v_u64m4_m( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vcpopv.mask.nxv4i64.i64( poison, [[VS2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]], i64 3) // CHECK-NEXT: ret [[TMP0]] // -vuint64m4_t test_vcpopv_v_u64m4_m(vbool16_t mask, vuint64m4_t vs2, size_t vl) { - return __riscv_vcpopv_v_u64m4_m(mask, vs2, vl); +vuint64m4_t test_vcpop_v_u64m4_m(vbool16_t mask, vuint64m4_t vs2, size_t vl) { + return __riscv_vcpop_v_u64m4_m(mask, vs2, vl); } -// CHECK-LABEL: @test_vcpopv_v_u64m8_m( +// CHECK-LABEL: @test_vcpop_v_u64m8_m( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vcpopv.mask.nxv8i64.i64( poison, [[VS2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]], i64 3) // CHECK-NEXT: ret [[TMP0]] // -vuint64m8_t test_vcpopv_v_u64m8_m(vbool8_t mask, vuint64m8_t vs2, size_t vl) { - return __riscv_vcpopv_v_u64m8_m(mask, vs2, vl); +vuint64m8_t test_vcpop_v_u64m8_m(vbool8_t mask, vuint64m8_t vs2, size_t vl) { + return __riscv_vcpop_v_u64m8_m(mask, vs2, vl); } diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vcpopv.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vcpopv.c index adb0ac9ee5d79a3e4050a2fb5998d58719551be1..5625b19f57f3ad6230a1a81bc6fc73c9e51e066a 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vcpopv.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/vcpopv.c @@ -16,399 +16,399 @@ #include -// CHECK-LABEL: @test_vcpopv_v_u8mf8( +// CHECK-LABEL: @test_vcpop_v_u8mf8( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vcpopv.nxv1i8.i64( poison, [[VS2:%.*]], i64 [[VL:%.*]]) // CHECK-NEXT: ret [[TMP0]] // -vuint8mf8_t test_vcpopv_v_u8mf8(vuint8mf8_t vs2, size_t vl) { - return __riscv_vcpopv(vs2, vl); +vuint8mf8_t test_vcpop_v_u8mf8(vuint8mf8_t vs2, size_t vl) { + return __riscv_vcpop(vs2, vl); } -// CHECK-LABEL: @test_vcpopv_v_u8mf4( +// CHECK-LABEL: @test_vcpop_v_u8mf4( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vcpopv.nxv2i8.i64( poison, [[VS2:%.*]], i64 [[VL:%.*]]) // CHECK-NEXT: ret [[TMP0]] // -vuint8mf4_t test_vcpopv_v_u8mf4(vuint8mf4_t vs2, size_t vl) { - return __riscv_vcpopv(vs2, vl); +vuint8mf4_t test_vcpop_v_u8mf4(vuint8mf4_t vs2, size_t vl) { + return __riscv_vcpop(vs2, vl); } -// CHECK-LABEL: @test_vcpopv_v_u8mf2( +// CHECK-LABEL: @test_vcpop_v_u8mf2( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vcpopv.nxv4i8.i64( poison, [[VS2:%.*]], i64 [[VL:%.*]]) // CHECK-NEXT: ret [[TMP0]] // -vuint8mf2_t test_vcpopv_v_u8mf2(vuint8mf2_t vs2, size_t vl) { - return __riscv_vcpopv(vs2, vl); +vuint8mf2_t test_vcpop_v_u8mf2(vuint8mf2_t vs2, size_t vl) { + return __riscv_vcpop(vs2, vl); } -// CHECK-LABEL: @test_vcpopv_v_u8m1( +// CHECK-LABEL: @test_vcpop_v_u8m1( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vcpopv.nxv8i8.i64( poison, [[VS2:%.*]], i64 [[VL:%.*]]) // CHECK-NEXT: ret [[TMP0]] // -vuint8m1_t test_vcpopv_v_u8m1(vuint8m1_t vs2, size_t vl) { - return __riscv_vcpopv(vs2, vl); +vuint8m1_t test_vcpop_v_u8m1(vuint8m1_t vs2, size_t vl) { + return __riscv_vcpop(vs2, vl); } -// CHECK-LABEL: @test_vcpopv_v_u8m2( +// CHECK-LABEL: @test_vcpop_v_u8m2( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vcpopv.nxv16i8.i64( poison, [[VS2:%.*]], i64 [[VL:%.*]]) // CHECK-NEXT: ret [[TMP0]] // -vuint8m2_t test_vcpopv_v_u8m2(vuint8m2_t vs2, size_t vl) { - return __riscv_vcpopv(vs2, vl); +vuint8m2_t test_vcpop_v_u8m2(vuint8m2_t vs2, size_t vl) { + return __riscv_vcpop(vs2, vl); } -// CHECK-LABEL: @test_vcpopv_v_u8m4( +// CHECK-LABEL: @test_vcpop_v_u8m4( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vcpopv.nxv32i8.i64( poison, [[VS2:%.*]], i64 [[VL:%.*]]) // CHECK-NEXT: ret [[TMP0]] // -vuint8m4_t test_vcpopv_v_u8m4(vuint8m4_t vs2, size_t vl) { - return __riscv_vcpopv(vs2, vl); +vuint8m4_t test_vcpop_v_u8m4(vuint8m4_t vs2, size_t vl) { + return __riscv_vcpop(vs2, vl); } -// CHECK-LABEL: @test_vcpopv_v_u8m8( +// CHECK-LABEL: @test_vcpop_v_u8m8( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vcpopv.nxv64i8.i64( poison, [[VS2:%.*]], i64 [[VL:%.*]]) // CHECK-NEXT: ret [[TMP0]] // -vuint8m8_t test_vcpopv_v_u8m8(vuint8m8_t vs2, size_t vl) { - return __riscv_vcpopv(vs2, vl); +vuint8m8_t test_vcpop_v_u8m8(vuint8m8_t vs2, size_t vl) { + return __riscv_vcpop(vs2, vl); } -// CHECK-LABEL: @test_vcpopv_v_u16mf4( +// CHECK-LABEL: @test_vcpop_v_u16mf4( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vcpopv.nxv1i16.i64( poison, [[VS2:%.*]], i64 [[VL:%.*]]) // CHECK-NEXT: ret [[TMP0]] // -vuint16mf4_t test_vcpopv_v_u16mf4(vuint16mf4_t vs2, size_t vl) { - return __riscv_vcpopv(vs2, vl); +vuint16mf4_t test_vcpop_v_u16mf4(vuint16mf4_t vs2, size_t vl) { + return __riscv_vcpop(vs2, vl); } -// CHECK-LABEL: @test_vcpopv_v_u16mf2( +// CHECK-LABEL: @test_vcpop_v_u16mf2( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vcpopv.nxv2i16.i64( poison, [[VS2:%.*]], i64 [[VL:%.*]]) // CHECK-NEXT: ret [[TMP0]] // -vuint16mf2_t test_vcpopv_v_u16mf2(vuint16mf2_t vs2, size_t vl) { - return __riscv_vcpopv(vs2, vl); +vuint16mf2_t test_vcpop_v_u16mf2(vuint16mf2_t vs2, size_t vl) { + return __riscv_vcpop(vs2, vl); } -// CHECK-LABEL: @test_vcpopv_v_u16m1( +// CHECK-LABEL: @test_vcpop_v_u16m1( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vcpopv.nxv4i16.i64( poison, [[VS2:%.*]], i64 [[VL:%.*]]) // CHECK-NEXT: ret [[TMP0]] // -vuint16m1_t test_vcpopv_v_u16m1(vuint16m1_t vs2, size_t vl) { - return __riscv_vcpopv(vs2, vl); +vuint16m1_t test_vcpop_v_u16m1(vuint16m1_t vs2, size_t vl) { + return __riscv_vcpop(vs2, vl); } -// CHECK-LABEL: @test_vcpopv_v_u16m2( +// CHECK-LABEL: @test_vcpop_v_u16m2( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vcpopv.nxv8i16.i64( poison, [[VS2:%.*]], i64 [[VL:%.*]]) // CHECK-NEXT: ret [[TMP0]] // -vuint16m2_t test_vcpopv_v_u16m2(vuint16m2_t vs2, size_t vl) { - return __riscv_vcpopv(vs2, vl); +vuint16m2_t test_vcpop_v_u16m2(vuint16m2_t vs2, size_t vl) { + return __riscv_vcpop(vs2, vl); } -// CHECK-LABEL: @test_vcpopv_v_u16m4( +// CHECK-LABEL: @test_vcpop_v_u16m4( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vcpopv.nxv16i16.i64( poison, [[VS2:%.*]], i64 [[VL:%.*]]) // CHECK-NEXT: ret [[TMP0]] // -vuint16m4_t test_vcpopv_v_u16m4(vuint16m4_t vs2, size_t vl) { - return __riscv_vcpopv(vs2, vl); +vuint16m4_t test_vcpop_v_u16m4(vuint16m4_t vs2, size_t vl) { + return __riscv_vcpop(vs2, vl); } -// CHECK-LABEL: @test_vcpopv_v_u16m8( +// CHECK-LABEL: @test_vcpop_v_u16m8( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vcpopv.nxv32i16.i64( poison, [[VS2:%.*]], i64 [[VL:%.*]]) // CHECK-NEXT: ret [[TMP0]] // -vuint16m8_t test_vcpopv_v_u16m8(vuint16m8_t vs2, size_t vl) { - return __riscv_vcpopv(vs2, vl); +vuint16m8_t test_vcpop_v_u16m8(vuint16m8_t vs2, size_t vl) { + return __riscv_vcpop(vs2, vl); } -// CHECK-LABEL: @test_vcpopv_v_u32mf2( +// CHECK-LABEL: @test_vcpop_v_u32mf2( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vcpopv.nxv1i32.i64( poison, [[VS2:%.*]], i64 [[VL:%.*]]) // CHECK-NEXT: ret [[TMP0]] // -vuint32mf2_t test_vcpopv_v_u32mf2(vuint32mf2_t vs2, size_t vl) { - return __riscv_vcpopv(vs2, vl); +vuint32mf2_t test_vcpop_v_u32mf2(vuint32mf2_t vs2, size_t vl) { + return __riscv_vcpop(vs2, vl); } -// CHECK-LABEL: @test_vcpopv_v_u32m1( +// CHECK-LABEL: @test_vcpop_v_u32m1( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vcpopv.nxv2i32.i64( poison, [[VS2:%.*]], i64 [[VL:%.*]]) // CHECK-NEXT: ret [[TMP0]] // -vuint32m1_t test_vcpopv_v_u32m1(vuint32m1_t vs2, size_t vl) { - return __riscv_vcpopv(vs2, vl); +vuint32m1_t test_vcpop_v_u32m1(vuint32m1_t vs2, size_t vl) { + return __riscv_vcpop(vs2, vl); } -// CHECK-LABEL: @test_vcpopv_v_u32m2( +// CHECK-LABEL: @test_vcpop_v_u32m2( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vcpopv.nxv4i32.i64( poison, [[VS2:%.*]], i64 [[VL:%.*]]) // CHECK-NEXT: ret [[TMP0]] // -vuint32m2_t test_vcpopv_v_u32m2(vuint32m2_t vs2, size_t vl) { - return __riscv_vcpopv(vs2, vl); +vuint32m2_t test_vcpop_v_u32m2(vuint32m2_t vs2, size_t vl) { + return __riscv_vcpop(vs2, vl); } -// CHECK-LABEL: @test_vcpopv_v_u32m4( +// CHECK-LABEL: @test_vcpop_v_u32m4( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vcpopv.nxv8i32.i64( poison, [[VS2:%.*]], i64 [[VL:%.*]]) // CHECK-NEXT: ret [[TMP0]] // -vuint32m4_t test_vcpopv_v_u32m4(vuint32m4_t vs2, size_t vl) { - return __riscv_vcpopv(vs2, vl); +vuint32m4_t test_vcpop_v_u32m4(vuint32m4_t vs2, size_t vl) { + return __riscv_vcpop(vs2, vl); } -// CHECK-LABEL: @test_vcpopv_v_u32m8( +// CHECK-LABEL: @test_vcpop_v_u32m8( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vcpopv.nxv16i32.i64( poison, [[VS2:%.*]], i64 [[VL:%.*]]) // CHECK-NEXT: ret [[TMP0]] // -vuint32m8_t test_vcpopv_v_u32m8(vuint32m8_t vs2, size_t vl) { - return __riscv_vcpopv(vs2, vl); +vuint32m8_t test_vcpop_v_u32m8(vuint32m8_t vs2, size_t vl) { + return __riscv_vcpop(vs2, vl); } -// CHECK-LABEL: @test_vcpopv_v_u64m1( +// CHECK-LABEL: @test_vcpop_v_u64m1( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vcpopv.nxv1i64.i64( poison, [[VS2:%.*]], i64 [[VL:%.*]]) // CHECK-NEXT: ret [[TMP0]] // -vuint64m1_t test_vcpopv_v_u64m1(vuint64m1_t vs2, size_t vl) { - return __riscv_vcpopv(vs2, vl); +vuint64m1_t test_vcpop_v_u64m1(vuint64m1_t vs2, size_t vl) { + return __riscv_vcpop(vs2, vl); } -// CHECK-LABEL: @test_vcpopv_v_u64m2( +// CHECK-LABEL: @test_vcpop_v_u64m2( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vcpopv.nxv2i64.i64( poison, [[VS2:%.*]], i64 [[VL:%.*]]) // CHECK-NEXT: ret [[TMP0]] // -vuint64m2_t test_vcpopv_v_u64m2(vuint64m2_t vs2, size_t vl) { - return __riscv_vcpopv(vs2, vl); +vuint64m2_t test_vcpop_v_u64m2(vuint64m2_t vs2, size_t vl) { + return __riscv_vcpop(vs2, vl); } -// CHECK-LABEL: @test_vcpopv_v_u64m4( +// CHECK-LABEL: @test_vcpop_v_u64m4( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vcpopv.nxv4i64.i64( poison, [[VS2:%.*]], i64 [[VL:%.*]]) // CHECK-NEXT: ret [[TMP0]] // -vuint64m4_t test_vcpopv_v_u64m4(vuint64m4_t vs2, size_t vl) { - return __riscv_vcpopv(vs2, vl); +vuint64m4_t test_vcpop_v_u64m4(vuint64m4_t vs2, size_t vl) { + return __riscv_vcpop(vs2, vl); } -// CHECK-LABEL: @test_vcpopv_v_u64m8( +// CHECK-LABEL: @test_vcpop_v_u64m8( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vcpopv.nxv8i64.i64( poison, [[VS2:%.*]], i64 [[VL:%.*]]) // CHECK-NEXT: ret [[TMP0]] // -vuint64m8_t test_vcpopv_v_u64m8(vuint64m8_t vs2, size_t vl) { - return __riscv_vcpopv(vs2, vl); +vuint64m8_t test_vcpop_v_u64m8(vuint64m8_t vs2, size_t vl) { + return __riscv_vcpop(vs2, vl); } -// CHECK-LABEL: @test_vcpopv_v_u8mf8_m( +// CHECK-LABEL: @test_vcpop_v_u8mf8_m( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vcpopv.mask.nxv1i8.i64( poison, [[VS2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]], i64 3) // CHECK-NEXT: ret [[TMP0]] // -vuint8mf8_t test_vcpopv_v_u8mf8_m(vbool64_t mask, vuint8mf8_t vs2, size_t vl) { - return __riscv_vcpopv(mask, vs2, vl); +vuint8mf8_t test_vcpop_v_u8mf8_m(vbool64_t mask, vuint8mf8_t vs2, size_t vl) { + return __riscv_vcpop(mask, vs2, vl); } -// CHECK-LABEL: @test_vcpopv_v_u8mf4_m( +// CHECK-LABEL: @test_vcpop_v_u8mf4_m( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vcpopv.mask.nxv2i8.i64( poison, [[VS2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]], i64 3) // CHECK-NEXT: ret [[TMP0]] // -vuint8mf4_t test_vcpopv_v_u8mf4_m(vbool32_t mask, vuint8mf4_t vs2, size_t vl) { - return __riscv_vcpopv(mask, vs2, vl); +vuint8mf4_t test_vcpop_v_u8mf4_m(vbool32_t mask, vuint8mf4_t vs2, size_t vl) { + return __riscv_vcpop(mask, vs2, vl); } -// CHECK-LABEL: @test_vcpopv_v_u8mf2_m( +// CHECK-LABEL: @test_vcpop_v_u8mf2_m( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vcpopv.mask.nxv4i8.i64( poison, [[VS2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]], i64 3) // CHECK-NEXT: ret [[TMP0]] // -vuint8mf2_t test_vcpopv_v_u8mf2_m(vbool16_t mask, vuint8mf2_t vs2, size_t vl) { - return __riscv_vcpopv(mask, vs2, vl); +vuint8mf2_t test_vcpop_v_u8mf2_m(vbool16_t mask, vuint8mf2_t vs2, size_t vl) { + return __riscv_vcpop(mask, vs2, vl); } -// CHECK-LABEL: @test_vcpopv_v_u8m1_m( +// CHECK-LABEL: @test_vcpop_v_u8m1_m( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vcpopv.mask.nxv8i8.i64( poison, [[VS2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]], i64 3) // CHECK-NEXT: ret [[TMP0]] // -vuint8m1_t test_vcpopv_v_u8m1_m(vbool8_t mask, vuint8m1_t vs2, size_t vl) { - return __riscv_vcpopv(mask, vs2, vl); +vuint8m1_t test_vcpop_v_u8m1_m(vbool8_t mask, vuint8m1_t vs2, size_t vl) { + return __riscv_vcpop(mask, vs2, vl); } -// CHECK-LABEL: @test_vcpopv_v_u8m2_m( +// CHECK-LABEL: @test_vcpop_v_u8m2_m( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vcpopv.mask.nxv16i8.i64( poison, [[VS2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]], i64 3) // CHECK-NEXT: ret [[TMP0]] // -vuint8m2_t test_vcpopv_v_u8m2_m(vbool4_t mask, vuint8m2_t vs2, size_t vl) { - return __riscv_vcpopv(mask, vs2, vl); +vuint8m2_t test_vcpop_v_u8m2_m(vbool4_t mask, vuint8m2_t vs2, size_t vl) { + return __riscv_vcpop(mask, vs2, vl); } -// CHECK-LABEL: @test_vcpopv_v_u8m4_m( +// CHECK-LABEL: @test_vcpop_v_u8m4_m( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vcpopv.mask.nxv32i8.i64( poison, [[VS2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]], i64 3) // CHECK-NEXT: ret [[TMP0]] // -vuint8m4_t test_vcpopv_v_u8m4_m(vbool2_t mask, vuint8m4_t vs2, size_t vl) { - return __riscv_vcpopv(mask, vs2, vl); +vuint8m4_t test_vcpop_v_u8m4_m(vbool2_t mask, vuint8m4_t vs2, size_t vl) { + return __riscv_vcpop(mask, vs2, vl); } -// CHECK-LABEL: @test_vcpopv_v_u8m8_m( +// CHECK-LABEL: @test_vcpop_v_u8m8_m( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vcpopv.mask.nxv64i8.i64( poison, [[VS2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]], i64 3) // CHECK-NEXT: ret [[TMP0]] // -vuint8m8_t test_vcpopv_v_u8m8_m(vbool1_t mask, vuint8m8_t vs2, size_t vl) { - return __riscv_vcpopv(mask, vs2, vl); +vuint8m8_t test_vcpop_v_u8m8_m(vbool1_t mask, vuint8m8_t vs2, size_t vl) { + return __riscv_vcpop(mask, vs2, vl); } -// CHECK-LABEL: @test_vcpopv_v_u16mf4_m( +// CHECK-LABEL: @test_vcpop_v_u16mf4_m( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vcpopv.mask.nxv1i16.i64( poison, [[VS2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]], i64 3) // CHECK-NEXT: ret [[TMP0]] // -vuint16mf4_t test_vcpopv_v_u16mf4_m(vbool64_t mask, vuint16mf4_t vs2, size_t vl) { - return __riscv_vcpopv(mask, vs2, vl); +vuint16mf4_t test_vcpop_v_u16mf4_m(vbool64_t mask, vuint16mf4_t vs2, size_t vl) { + return __riscv_vcpop(mask, vs2, vl); } -// CHECK-LABEL: @test_vcpopv_v_u16mf2_m( +// CHECK-LABEL: @test_vcpop_v_u16mf2_m( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vcpopv.mask.nxv2i16.i64( poison, [[VS2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]], i64 3) // CHECK-NEXT: ret [[TMP0]] // -vuint16mf2_t test_vcpopv_v_u16mf2_m(vbool32_t mask, vuint16mf2_t vs2, size_t vl) { - return __riscv_vcpopv(mask, vs2, vl); +vuint16mf2_t test_vcpop_v_u16mf2_m(vbool32_t mask, vuint16mf2_t vs2, size_t vl) { + return __riscv_vcpop(mask, vs2, vl); } -// CHECK-LABEL: @test_vcpopv_v_u16m1_m( +// CHECK-LABEL: @test_vcpop_v_u16m1_m( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vcpopv.mask.nxv4i16.i64( poison, [[VS2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]], i64 3) // CHECK-NEXT: ret [[TMP0]] // -vuint16m1_t test_vcpopv_v_u16m1_m(vbool16_t mask, vuint16m1_t vs2, size_t vl) { - return __riscv_vcpopv(mask, vs2, vl); +vuint16m1_t test_vcpop_v_u16m1_m(vbool16_t mask, vuint16m1_t vs2, size_t vl) { + return __riscv_vcpop(mask, vs2, vl); } -// CHECK-LABEL: @test_vcpopv_v_u16m2_m( +// CHECK-LABEL: @test_vcpop_v_u16m2_m( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vcpopv.mask.nxv8i16.i64( poison, [[VS2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]], i64 3) // CHECK-NEXT: ret [[TMP0]] // -vuint16m2_t test_vcpopv_v_u16m2_m(vbool8_t mask, vuint16m2_t vs2, size_t vl) { - return __riscv_vcpopv(mask, vs2, vl); +vuint16m2_t test_vcpop_v_u16m2_m(vbool8_t mask, vuint16m2_t vs2, size_t vl) { + return __riscv_vcpop(mask, vs2, vl); } -// CHECK-LABEL: @test_vcpopv_v_u16m4_m( +// CHECK-LABEL: @test_vcpop_v_u16m4_m( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vcpopv.mask.nxv16i16.i64( poison, [[VS2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]], i64 3) // CHECK-NEXT: ret [[TMP0]] // -vuint16m4_t test_vcpopv_v_u16m4_m(vbool4_t mask, vuint16m4_t vs2, size_t vl) { - return __riscv_vcpopv(mask, vs2, vl); +vuint16m4_t test_vcpop_v_u16m4_m(vbool4_t mask, vuint16m4_t vs2, size_t vl) { + return __riscv_vcpop(mask, vs2, vl); } -// CHECK-LABEL: @test_vcpopv_v_u16m8_m( +// CHECK-LABEL: @test_vcpop_v_u16m8_m( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vcpopv.mask.nxv32i16.i64( poison, [[VS2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]], i64 3) // CHECK-NEXT: ret [[TMP0]] // -vuint16m8_t test_vcpopv_v_u16m8_m(vbool2_t mask, vuint16m8_t vs2, size_t vl) { - return __riscv_vcpopv(mask, vs2, vl); +vuint16m8_t test_vcpop_v_u16m8_m(vbool2_t mask, vuint16m8_t vs2, size_t vl) { + return __riscv_vcpop(mask, vs2, vl); } -// CHECK-LABEL: @test_vcpopv_v_u32mf2_m( +// CHECK-LABEL: @test_vcpop_v_u32mf2_m( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vcpopv.mask.nxv1i32.i64( poison, [[VS2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]], i64 3) // CHECK-NEXT: ret [[TMP0]] // -vuint32mf2_t test_vcpopv_v_u32mf2_m(vbool64_t mask, vuint32mf2_t vs2, size_t vl) { - return __riscv_vcpopv(mask, vs2, vl); +vuint32mf2_t test_vcpop_v_u32mf2_m(vbool64_t mask, vuint32mf2_t vs2, size_t vl) { + return __riscv_vcpop(mask, vs2, vl); } -// CHECK-LABEL: @test_vcpopv_v_u32m1_m( +// CHECK-LABEL: @test_vcpop_v_u32m1_m( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vcpopv.mask.nxv2i32.i64( poison, [[VS2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]], i64 3) // CHECK-NEXT: ret [[TMP0]] // -vuint32m1_t test_vcpopv_v_u32m1_m(vbool32_t mask, vuint32m1_t vs2, size_t vl) { - return __riscv_vcpopv(mask, vs2, vl); +vuint32m1_t test_vcpop_v_u32m1_m(vbool32_t mask, vuint32m1_t vs2, size_t vl) { + return __riscv_vcpop(mask, vs2, vl); } -// CHECK-LABEL: @test_vcpopv_v_u32m2_m( +// CHECK-LABEL: @test_vcpop_v_u32m2_m( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vcpopv.mask.nxv4i32.i64( poison, [[VS2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]], i64 3) // CHECK-NEXT: ret [[TMP0]] // -vuint32m2_t test_vcpopv_v_u32m2_m(vbool16_t mask, vuint32m2_t vs2, size_t vl) { - return __riscv_vcpopv(mask, vs2, vl); +vuint32m2_t test_vcpop_v_u32m2_m(vbool16_t mask, vuint32m2_t vs2, size_t vl) { + return __riscv_vcpop(mask, vs2, vl); } -// CHECK-LABEL: @test_vcpopv_v_u32m4_m( +// CHECK-LABEL: @test_vcpop_v_u32m4_m( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vcpopv.mask.nxv8i32.i64( poison, [[VS2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]], i64 3) // CHECK-NEXT: ret [[TMP0]] // -vuint32m4_t test_vcpopv_v_u32m4_m(vbool8_t mask, vuint32m4_t vs2, size_t vl) { - return __riscv_vcpopv(mask, vs2, vl); +vuint32m4_t test_vcpop_v_u32m4_m(vbool8_t mask, vuint32m4_t vs2, size_t vl) { + return __riscv_vcpop(mask, vs2, vl); } -// CHECK-LABEL: @test_vcpopv_v_u32m8_m( +// CHECK-LABEL: @test_vcpop_v_u32m8_m( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vcpopv.mask.nxv16i32.i64( poison, [[VS2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]], i64 3) // CHECK-NEXT: ret [[TMP0]] // -vuint32m8_t test_vcpopv_v_u32m8_m(vbool4_t mask, vuint32m8_t vs2, size_t vl) { - return __riscv_vcpopv(mask, vs2, vl); +vuint32m8_t test_vcpop_v_u32m8_m(vbool4_t mask, vuint32m8_t vs2, size_t vl) { + return __riscv_vcpop(mask, vs2, vl); } -// CHECK-LABEL: @test_vcpopv_v_u64m1_m( +// CHECK-LABEL: @test_vcpop_v_u64m1_m( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vcpopv.mask.nxv1i64.i64( poison, [[VS2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]], i64 3) // CHECK-NEXT: ret [[TMP0]] // -vuint64m1_t test_vcpopv_v_u64m1_m(vbool64_t mask, vuint64m1_t vs2, size_t vl) { - return __riscv_vcpopv(mask, vs2, vl); +vuint64m1_t test_vcpop_v_u64m1_m(vbool64_t mask, vuint64m1_t vs2, size_t vl) { + return __riscv_vcpop(mask, vs2, vl); } -// CHECK-LABEL: @test_vcpopv_v_u64m2_m( +// CHECK-LABEL: @test_vcpop_v_u64m2_m( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vcpopv.mask.nxv2i64.i64( poison, [[VS2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]], i64 3) // CHECK-NEXT: ret [[TMP0]] // -vuint64m2_t test_vcpopv_v_u64m2_m(vbool32_t mask, vuint64m2_t vs2, size_t vl) { - return __riscv_vcpopv(mask, vs2, vl); +vuint64m2_t test_vcpop_v_u64m2_m(vbool32_t mask, vuint64m2_t vs2, size_t vl) { + return __riscv_vcpop(mask, vs2, vl); } -// CHECK-LABEL: @test_vcpopv_v_u64m4_m( +// CHECK-LABEL: @test_vcpop_v_u64m4_m( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vcpopv.mask.nxv4i64.i64( poison, [[VS2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]], i64 3) // CHECK-NEXT: ret [[TMP0]] // -vuint64m4_t test_vcpopv_v_u64m4_m(vbool16_t mask, vuint64m4_t vs2, size_t vl) { - return __riscv_vcpopv(mask, vs2, vl); +vuint64m4_t test_vcpop_v_u64m4_m(vbool16_t mask, vuint64m4_t vs2, size_t vl) { + return __riscv_vcpop(mask, vs2, vl); } -// CHECK-LABEL: @test_vcpopv_v_u64m8_m( +// CHECK-LABEL: @test_vcpop_v_u64m8_m( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vcpopv.mask.nxv8i64.i64( poison, [[VS2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]], i64 3) // CHECK-NEXT: ret [[TMP0]] // -vuint64m8_t test_vcpopv_v_u64m8_m(vbool8_t mask, vuint64m8_t vs2, size_t vl) { - return __riscv_vcpopv(mask, vs2, vl); +vuint64m8_t test_vcpop_v_u64m8_m(vbool8_t mask, vuint64m8_t vs2, size_t vl) { + return __riscv_vcpop(mask, vs2, vl); } diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vcpopv.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vcpopv.c index 8a1f2e1beec1107121657d48f08161c7f1ce969e..3a110339b5f18f05bb918358a743695b28d1169b 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vcpopv.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/vcpopv.c @@ -16,795 +16,795 @@ #include -// CHECK-LABEL: @test_vcpopv_v_u8mf8_tu( +// CHECK-LABEL: @test_vcpop_v_u8mf8_tu( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vcpopv.nxv1i8.i64( [[MASKEDOFF:%.*]], [[VS2:%.*]], i64 [[VL:%.*]]) // CHECK-NEXT: ret [[TMP0]] // -vuint8mf8_t test_vcpopv_v_u8mf8_tu(vuint8mf8_t maskedoff, vuint8mf8_t vs2, size_t vl) { - return __riscv_vcpopv_v_u8mf8_tu(maskedoff, vs2, vl); +vuint8mf8_t test_vcpop_v_u8mf8_tu(vuint8mf8_t maskedoff, vuint8mf8_t vs2, size_t vl) { + return __riscv_vcpop_v_u8mf8_tu(maskedoff, vs2, vl); } -// CHECK-LABEL: @test_vcpopv_v_u8mf4_tu( +// CHECK-LABEL: @test_vcpop_v_u8mf4_tu( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vcpopv.nxv2i8.i64( [[MASKEDOFF:%.*]], [[VS2:%.*]], i64 [[VL:%.*]]) // CHECK-NEXT: ret [[TMP0]] // -vuint8mf4_t test_vcpopv_v_u8mf4_tu(vuint8mf4_t maskedoff, vuint8mf4_t vs2, size_t vl) { - return __riscv_vcpopv_v_u8mf4_tu(maskedoff, vs2, vl); +vuint8mf4_t test_vcpop_v_u8mf4_tu(vuint8mf4_t maskedoff, vuint8mf4_t vs2, size_t vl) { + return __riscv_vcpop_v_u8mf4_tu(maskedoff, vs2, vl); } -// CHECK-LABEL: @test_vcpopv_v_u8mf2_tu( +// CHECK-LABEL: @test_vcpop_v_u8mf2_tu( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vcpopv.nxv4i8.i64( [[MASKEDOFF:%.*]], [[VS2:%.*]], i64 [[VL:%.*]]) // CHECK-NEXT: ret [[TMP0]] // -vuint8mf2_t test_vcpopv_v_u8mf2_tu(vuint8mf2_t maskedoff, vuint8mf2_t vs2, size_t vl) { - return __riscv_vcpopv_v_u8mf2_tu(maskedoff, vs2, vl); +vuint8mf2_t test_vcpop_v_u8mf2_tu(vuint8mf2_t maskedoff, vuint8mf2_t vs2, size_t vl) { + return __riscv_vcpop_v_u8mf2_tu(maskedoff, vs2, vl); } -// CHECK-LABEL: @test_vcpopv_v_u8m1_tu( +// CHECK-LABEL: @test_vcpop_v_u8m1_tu( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vcpopv.nxv8i8.i64( [[MASKEDOFF:%.*]], [[VS2:%.*]], i64 [[VL:%.*]]) // CHECK-NEXT: ret [[TMP0]] // -vuint8m1_t test_vcpopv_v_u8m1_tu(vuint8m1_t maskedoff, vuint8m1_t vs2, size_t vl) { - return __riscv_vcpopv_v_u8m1_tu(maskedoff, vs2, vl); +vuint8m1_t test_vcpop_v_u8m1_tu(vuint8m1_t maskedoff, vuint8m1_t vs2, size_t vl) { + return __riscv_vcpop_v_u8m1_tu(maskedoff, vs2, vl); } -// CHECK-LABEL: @test_vcpopv_v_u8m2_tu( +// CHECK-LABEL: @test_vcpop_v_u8m2_tu( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vcpopv.nxv16i8.i64( [[MASKEDOFF:%.*]], [[VS2:%.*]], i64 [[VL:%.*]]) // CHECK-NEXT: ret [[TMP0]] // -vuint8m2_t test_vcpopv_v_u8m2_tu(vuint8m2_t maskedoff, vuint8m2_t vs2, size_t vl) { - return __riscv_vcpopv_v_u8m2_tu(maskedoff, vs2, vl); +vuint8m2_t test_vcpop_v_u8m2_tu(vuint8m2_t maskedoff, vuint8m2_t vs2, size_t vl) { + return __riscv_vcpop_v_u8m2_tu(maskedoff, vs2, vl); } -// CHECK-LABEL: @test_vcpopv_v_u8m4_tu( +// CHECK-LABEL: @test_vcpop_v_u8m4_tu( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vcpopv.nxv32i8.i64( [[MASKEDOFF:%.*]], [[VS2:%.*]], i64 [[VL:%.*]]) // CHECK-NEXT: ret [[TMP0]] // -vuint8m4_t test_vcpopv_v_u8m4_tu(vuint8m4_t maskedoff, vuint8m4_t vs2, size_t vl) { - return __riscv_vcpopv_v_u8m4_tu(maskedoff, vs2, vl); +vuint8m4_t test_vcpop_v_u8m4_tu(vuint8m4_t maskedoff, vuint8m4_t vs2, size_t vl) { + return __riscv_vcpop_v_u8m4_tu(maskedoff, vs2, vl); } -// CHECK-LABEL: @test_vcpopv_v_u8m8_tu( +// CHECK-LABEL: @test_vcpop_v_u8m8_tu( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vcpopv.nxv64i8.i64( [[MASKEDOFF:%.*]], [[VS2:%.*]], i64 [[VL:%.*]]) // CHECK-NEXT: ret [[TMP0]] // -vuint8m8_t test_vcpopv_v_u8m8_tu(vuint8m8_t maskedoff, vuint8m8_t vs2, size_t vl) { - return __riscv_vcpopv_v_u8m8_tu(maskedoff, vs2, vl); +vuint8m8_t test_vcpop_v_u8m8_tu(vuint8m8_t maskedoff, vuint8m8_t vs2, size_t vl) { + return __riscv_vcpop_v_u8m8_tu(maskedoff, vs2, vl); } -// CHECK-LABEL: @test_vcpopv_v_u16mf4_tu( +// CHECK-LABEL: @test_vcpop_v_u16mf4_tu( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vcpopv.nxv1i16.i64( [[MASKEDOFF:%.*]], [[VS2:%.*]], i64 [[VL:%.*]]) // CHECK-NEXT: ret [[TMP0]] // -vuint16mf4_t test_vcpopv_v_u16mf4_tu(vuint16mf4_t maskedoff, vuint16mf4_t vs2, size_t vl) { - return __riscv_vcpopv_v_u16mf4_tu(maskedoff, vs2, vl); +vuint16mf4_t test_vcpop_v_u16mf4_tu(vuint16mf4_t maskedoff, vuint16mf4_t vs2, size_t vl) { + return __riscv_vcpop_v_u16mf4_tu(maskedoff, vs2, vl); } -// CHECK-LABEL: @test_vcpopv_v_u16mf2_tu( +// CHECK-LABEL: @test_vcpop_v_u16mf2_tu( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vcpopv.nxv2i16.i64( [[MASKEDOFF:%.*]], [[VS2:%.*]], i64 [[VL:%.*]]) // CHECK-NEXT: ret [[TMP0]] // -vuint16mf2_t test_vcpopv_v_u16mf2_tu(vuint16mf2_t maskedoff, vuint16mf2_t vs2, size_t vl) { - return __riscv_vcpopv_v_u16mf2_tu(maskedoff, vs2, vl); +vuint16mf2_t test_vcpop_v_u16mf2_tu(vuint16mf2_t maskedoff, vuint16mf2_t vs2, size_t vl) { + return __riscv_vcpop_v_u16mf2_tu(maskedoff, vs2, vl); } -// CHECK-LABEL: @test_vcpopv_v_u16m1_tu( +// CHECK-LABEL: @test_vcpop_v_u16m1_tu( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vcpopv.nxv4i16.i64( [[MASKEDOFF:%.*]], [[VS2:%.*]], i64 [[VL:%.*]]) // CHECK-NEXT: ret [[TMP0]] // -vuint16m1_t test_vcpopv_v_u16m1_tu(vuint16m1_t maskedoff, vuint16m1_t vs2, size_t vl) { - return __riscv_vcpopv_v_u16m1_tu(maskedoff, vs2, vl); +vuint16m1_t test_vcpop_v_u16m1_tu(vuint16m1_t maskedoff, vuint16m1_t vs2, size_t vl) { + return __riscv_vcpop_v_u16m1_tu(maskedoff, vs2, vl); } -// CHECK-LABEL: @test_vcpopv_v_u16m2_tu( +// CHECK-LABEL: @test_vcpop_v_u16m2_tu( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vcpopv.nxv8i16.i64( [[MASKEDOFF:%.*]], [[VS2:%.*]], i64 [[VL:%.*]]) // CHECK-NEXT: ret [[TMP0]] // -vuint16m2_t test_vcpopv_v_u16m2_tu(vuint16m2_t maskedoff, vuint16m2_t vs2, size_t vl) { - return __riscv_vcpopv_v_u16m2_tu(maskedoff, vs2, vl); +vuint16m2_t test_vcpop_v_u16m2_tu(vuint16m2_t maskedoff, vuint16m2_t vs2, size_t vl) { + return __riscv_vcpop_v_u16m2_tu(maskedoff, vs2, vl); } -// CHECK-LABEL: @test_vcpopv_v_u16m4_tu( +// CHECK-LABEL: @test_vcpop_v_u16m4_tu( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vcpopv.nxv16i16.i64( [[MASKEDOFF:%.*]], [[VS2:%.*]], i64 [[VL:%.*]]) // CHECK-NEXT: ret [[TMP0]] // -vuint16m4_t test_vcpopv_v_u16m4_tu(vuint16m4_t maskedoff, vuint16m4_t vs2, size_t vl) { - return __riscv_vcpopv_v_u16m4_tu(maskedoff, vs2, vl); +vuint16m4_t test_vcpop_v_u16m4_tu(vuint16m4_t maskedoff, vuint16m4_t vs2, size_t vl) { + return __riscv_vcpop_v_u16m4_tu(maskedoff, vs2, vl); } -// CHECK-LABEL: @test_vcpopv_v_u16m8_tu( +// CHECK-LABEL: @test_vcpop_v_u16m8_tu( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vcpopv.nxv32i16.i64( [[MASKEDOFF:%.*]], [[VS2:%.*]], i64 [[VL:%.*]]) // CHECK-NEXT: ret [[TMP0]] // -vuint16m8_t test_vcpopv_v_u16m8_tu(vuint16m8_t maskedoff, vuint16m8_t vs2, size_t vl) { - return __riscv_vcpopv_v_u16m8_tu(maskedoff, vs2, vl); +vuint16m8_t test_vcpop_v_u16m8_tu(vuint16m8_t maskedoff, vuint16m8_t vs2, size_t vl) { + return __riscv_vcpop_v_u16m8_tu(maskedoff, vs2, vl); } -// CHECK-LABEL: @test_vcpopv_v_u32mf2_tu( +// CHECK-LABEL: @test_vcpop_v_u32mf2_tu( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vcpopv.nxv1i32.i64( [[MASKEDOFF:%.*]], [[VS2:%.*]], i64 [[VL:%.*]]) // CHECK-NEXT: ret [[TMP0]] // -vuint32mf2_t test_vcpopv_v_u32mf2_tu(vuint32mf2_t maskedoff, vuint32mf2_t vs2, size_t vl) { - return __riscv_vcpopv_v_u32mf2_tu(maskedoff, vs2, vl); +vuint32mf2_t test_vcpop_v_u32mf2_tu(vuint32mf2_t maskedoff, vuint32mf2_t vs2, size_t vl) { + return __riscv_vcpop_v_u32mf2_tu(maskedoff, vs2, vl); } -// CHECK-LABEL: @test_vcpopv_v_u32m1_tu( +// CHECK-LABEL: @test_vcpop_v_u32m1_tu( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vcpopv.nxv2i32.i64( [[MASKEDOFF:%.*]], [[VS2:%.*]], i64 [[VL:%.*]]) // CHECK-NEXT: ret [[TMP0]] // -vuint32m1_t test_vcpopv_v_u32m1_tu(vuint32m1_t maskedoff, vuint32m1_t vs2, size_t vl) { - return __riscv_vcpopv_v_u32m1_tu(maskedoff, vs2, vl); +vuint32m1_t test_vcpop_v_u32m1_tu(vuint32m1_t maskedoff, vuint32m1_t vs2, size_t vl) { + return __riscv_vcpop_v_u32m1_tu(maskedoff, vs2, vl); } -// CHECK-LABEL: @test_vcpopv_v_u32m2_tu( +// CHECK-LABEL: @test_vcpop_v_u32m2_tu( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vcpopv.nxv4i32.i64( [[MASKEDOFF:%.*]], [[VS2:%.*]], i64 [[VL:%.*]]) // CHECK-NEXT: ret [[TMP0]] // -vuint32m2_t test_vcpopv_v_u32m2_tu(vuint32m2_t maskedoff, vuint32m2_t vs2, size_t vl) { - return __riscv_vcpopv_v_u32m2_tu(maskedoff, vs2, vl); +vuint32m2_t test_vcpop_v_u32m2_tu(vuint32m2_t maskedoff, vuint32m2_t vs2, size_t vl) { + return __riscv_vcpop_v_u32m2_tu(maskedoff, vs2, vl); } -// CHECK-LABEL: @test_vcpopv_v_u32m4_tu( +// CHECK-LABEL: @test_vcpop_v_u32m4_tu( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vcpopv.nxv8i32.i64( [[MASKEDOFF:%.*]], [[VS2:%.*]], i64 [[VL:%.*]]) // CHECK-NEXT: ret [[TMP0]] // -vuint32m4_t test_vcpopv_v_u32m4_tu(vuint32m4_t maskedoff, vuint32m4_t vs2, size_t vl) { - return __riscv_vcpopv_v_u32m4_tu(maskedoff, vs2, vl); +vuint32m4_t test_vcpop_v_u32m4_tu(vuint32m4_t maskedoff, vuint32m4_t vs2, size_t vl) { + return __riscv_vcpop_v_u32m4_tu(maskedoff, vs2, vl); } -// CHECK-LABEL: @test_vcpopv_v_u32m8_tu( +// CHECK-LABEL: @test_vcpop_v_u32m8_tu( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vcpopv.nxv16i32.i64( [[MASKEDOFF:%.*]], [[VS2:%.*]], i64 [[VL:%.*]]) // CHECK-NEXT: ret [[TMP0]] // -vuint32m8_t test_vcpopv_v_u32m8_tu(vuint32m8_t maskedoff, vuint32m8_t vs2, size_t vl) { - return __riscv_vcpopv_v_u32m8_tu(maskedoff, vs2, vl); +vuint32m8_t test_vcpop_v_u32m8_tu(vuint32m8_t maskedoff, vuint32m8_t vs2, size_t vl) { + return __riscv_vcpop_v_u32m8_tu(maskedoff, vs2, vl); } -// CHECK-LABEL: @test_vcpopv_v_u64m1_tu( +// CHECK-LABEL: @test_vcpop_v_u64m1_tu( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vcpopv.nxv1i64.i64( [[MASKEDOFF:%.*]], [[VS2:%.*]], i64 [[VL:%.*]]) // CHECK-NEXT: ret [[TMP0]] // -vuint64m1_t test_vcpopv_v_u64m1_tu(vuint64m1_t maskedoff, vuint64m1_t vs2, size_t vl) { - return __riscv_vcpopv_v_u64m1_tu(maskedoff, vs2, vl); +vuint64m1_t test_vcpop_v_u64m1_tu(vuint64m1_t maskedoff, vuint64m1_t vs2, size_t vl) { + return __riscv_vcpop_v_u64m1_tu(maskedoff, vs2, vl); } -// CHECK-LABEL: @test_vcpopv_v_u64m2_tu( +// CHECK-LABEL: @test_vcpop_v_u64m2_tu( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vcpopv.nxv2i64.i64( [[MASKEDOFF:%.*]], [[VS2:%.*]], i64 [[VL:%.*]]) // CHECK-NEXT: ret [[TMP0]] // -vuint64m2_t test_vcpopv_v_u64m2_tu(vuint64m2_t maskedoff, vuint64m2_t vs2, size_t vl) { - return __riscv_vcpopv_v_u64m2_tu(maskedoff, vs2, vl); +vuint64m2_t test_vcpop_v_u64m2_tu(vuint64m2_t maskedoff, vuint64m2_t vs2, size_t vl) { + return __riscv_vcpop_v_u64m2_tu(maskedoff, vs2, vl); } -// CHECK-LABEL: @test_vcpopv_v_u64m4_tu( +// CHECK-LABEL: @test_vcpop_v_u64m4_tu( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vcpopv.nxv4i64.i64( [[MASKEDOFF:%.*]], [[VS2:%.*]], i64 [[VL:%.*]]) // CHECK-NEXT: ret [[TMP0]] // -vuint64m4_t test_vcpopv_v_u64m4_tu(vuint64m4_t maskedoff, vuint64m4_t vs2, size_t vl) { - return __riscv_vcpopv_v_u64m4_tu(maskedoff, vs2, vl); +vuint64m4_t test_vcpop_v_u64m4_tu(vuint64m4_t maskedoff, vuint64m4_t vs2, size_t vl) { + return __riscv_vcpop_v_u64m4_tu(maskedoff, vs2, vl); } -// CHECK-LABEL: @test_vcpopv_v_u64m8_tu( +// CHECK-LABEL: @test_vcpop_v_u64m8_tu( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vcpopv.nxv8i64.i64( [[MASKEDOFF:%.*]], [[VS2:%.*]], i64 [[VL:%.*]]) // CHECK-NEXT: ret [[TMP0]] // -vuint64m8_t test_vcpopv_v_u64m8_tu(vuint64m8_t maskedoff, vuint64m8_t vs2, size_t vl) { - return __riscv_vcpopv_v_u64m8_tu(maskedoff, vs2, vl); +vuint64m8_t test_vcpop_v_u64m8_tu(vuint64m8_t maskedoff, vuint64m8_t vs2, size_t vl) { + return __riscv_vcpop_v_u64m8_tu(maskedoff, vs2, vl); } -// CHECK-LABEL: @test_vcpopv_v_u8mf8_tum( +// CHECK-LABEL: @test_vcpop_v_u8mf8_tum( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vcpopv.mask.nxv1i8.i64( [[MASKEDOFF:%.*]], [[VS2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]], i64 2) // CHECK-NEXT: ret [[TMP0]] // -vuint8mf8_t test_vcpopv_v_u8mf8_tum(vbool64_t mask, vuint8mf8_t maskedoff, vuint8mf8_t vs2, size_t vl) { - return __riscv_vcpopv_v_u8mf8_tum(mask, maskedoff, vs2, vl); +vuint8mf8_t test_vcpop_v_u8mf8_tum(vbool64_t mask, vuint8mf8_t maskedoff, vuint8mf8_t vs2, size_t vl) { + return __riscv_vcpop_v_u8mf8_tum(mask, maskedoff, vs2, vl); } -// CHECK-LABEL: @test_vcpopv_v_u8mf4_tum( +// CHECK-LABEL: @test_vcpop_v_u8mf4_tum( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vcpopv.mask.nxv2i8.i64( [[MASKEDOFF:%.*]], [[VS2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]], i64 2) // CHECK-NEXT: ret [[TMP0]] // -vuint8mf4_t test_vcpopv_v_u8mf4_tum(vbool32_t mask, vuint8mf4_t maskedoff, vuint8mf4_t vs2, size_t vl) { - return __riscv_vcpopv_v_u8mf4_tum(mask, maskedoff, vs2, vl); +vuint8mf4_t test_vcpop_v_u8mf4_tum(vbool32_t mask, vuint8mf4_t maskedoff, vuint8mf4_t vs2, size_t vl) { + return __riscv_vcpop_v_u8mf4_tum(mask, maskedoff, vs2, vl); } -// CHECK-LABEL: @test_vcpopv_v_u8mf2_tum( +// CHECK-LABEL: @test_vcpop_v_u8mf2_tum( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vcpopv.mask.nxv4i8.i64( [[MASKEDOFF:%.*]], [[VS2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]], i64 2) // CHECK-NEXT: ret [[TMP0]] // -vuint8mf2_t test_vcpopv_v_u8mf2_tum(vbool16_t mask, vuint8mf2_t maskedoff, vuint8mf2_t vs2, size_t vl) { - return __riscv_vcpopv_v_u8mf2_tum(mask, maskedoff, vs2, vl); +vuint8mf2_t test_vcpop_v_u8mf2_tum(vbool16_t mask, vuint8mf2_t maskedoff, vuint8mf2_t vs2, size_t vl) { + return __riscv_vcpop_v_u8mf2_tum(mask, maskedoff, vs2, vl); } -// CHECK-LABEL: @test_vcpopv_v_u8m1_tum( +// CHECK-LABEL: @test_vcpop_v_u8m1_tum( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vcpopv.mask.nxv8i8.i64( [[MASKEDOFF:%.*]], [[VS2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]], i64 2) // CHECK-NEXT: ret [[TMP0]] // -vuint8m1_t test_vcpopv_v_u8m1_tum(vbool8_t mask, vuint8m1_t maskedoff, vuint8m1_t vs2, size_t vl) { - return __riscv_vcpopv_v_u8m1_tum(mask, maskedoff, vs2, vl); +vuint8m1_t test_vcpop_v_u8m1_tum(vbool8_t mask, vuint8m1_t maskedoff, vuint8m1_t vs2, size_t vl) { + return __riscv_vcpop_v_u8m1_tum(mask, maskedoff, vs2, vl); } -// CHECK-LABEL: @test_vcpopv_v_u8m2_tum( +// CHECK-LABEL: @test_vcpop_v_u8m2_tum( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vcpopv.mask.nxv16i8.i64( [[MASKEDOFF:%.*]], [[VS2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]], i64 2) // CHECK-NEXT: ret [[TMP0]] // -vuint8m2_t test_vcpopv_v_u8m2_tum(vbool4_t mask, vuint8m2_t maskedoff, vuint8m2_t vs2, size_t vl) { - return __riscv_vcpopv_v_u8m2_tum(mask, maskedoff, vs2, vl); +vuint8m2_t test_vcpop_v_u8m2_tum(vbool4_t mask, vuint8m2_t maskedoff, vuint8m2_t vs2, size_t vl) { + return __riscv_vcpop_v_u8m2_tum(mask, maskedoff, vs2, vl); } -// CHECK-LABEL: @test_vcpopv_v_u8m4_tum( +// CHECK-LABEL: @test_vcpop_v_u8m4_tum( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vcpopv.mask.nxv32i8.i64( [[MASKEDOFF:%.*]], [[VS2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]], i64 2) // CHECK-NEXT: ret [[TMP0]] // -vuint8m4_t test_vcpopv_v_u8m4_tum(vbool2_t mask, vuint8m4_t maskedoff, vuint8m4_t vs2, size_t vl) { - return __riscv_vcpopv_v_u8m4_tum(mask, maskedoff, vs2, vl); +vuint8m4_t test_vcpop_v_u8m4_tum(vbool2_t mask, vuint8m4_t maskedoff, vuint8m4_t vs2, size_t vl) { + return __riscv_vcpop_v_u8m4_tum(mask, maskedoff, vs2, vl); } -// CHECK-LABEL: @test_vcpopv_v_u8m8_tum( +// CHECK-LABEL: @test_vcpop_v_u8m8_tum( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vcpopv.mask.nxv64i8.i64( [[MASKEDOFF:%.*]], [[VS2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]], i64 2) // CHECK-NEXT: ret [[TMP0]] // -vuint8m8_t test_vcpopv_v_u8m8_tum(vbool1_t mask, vuint8m8_t maskedoff, vuint8m8_t vs2, size_t vl) { - return __riscv_vcpopv_v_u8m8_tum(mask, maskedoff, vs2, vl); +vuint8m8_t test_vcpop_v_u8m8_tum(vbool1_t mask, vuint8m8_t maskedoff, vuint8m8_t vs2, size_t vl) { + return __riscv_vcpop_v_u8m8_tum(mask, maskedoff, vs2, vl); } -// CHECK-LABEL: @test_vcpopv_v_u16mf4_tum( +// CHECK-LABEL: @test_vcpop_v_u16mf4_tum( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vcpopv.mask.nxv1i16.i64( [[MASKEDOFF:%.*]], [[VS2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]], i64 2) // CHECK-NEXT: ret [[TMP0]] // -vuint16mf4_t test_vcpopv_v_u16mf4_tum(vbool64_t mask, vuint16mf4_t maskedoff, vuint16mf4_t vs2, size_t vl) { - return __riscv_vcpopv_v_u16mf4_tum(mask, maskedoff, vs2, vl); +vuint16mf4_t test_vcpop_v_u16mf4_tum(vbool64_t mask, vuint16mf4_t maskedoff, vuint16mf4_t vs2, size_t vl) { + return __riscv_vcpop_v_u16mf4_tum(mask, maskedoff, vs2, vl); } -// CHECK-LABEL: @test_vcpopv_v_u16mf2_tum( +// CHECK-LABEL: @test_vcpop_v_u16mf2_tum( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vcpopv.mask.nxv2i16.i64( [[MASKEDOFF:%.*]], [[VS2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]], i64 2) // CHECK-NEXT: ret [[TMP0]] // -vuint16mf2_t test_vcpopv_v_u16mf2_tum(vbool32_t mask, vuint16mf2_t maskedoff, vuint16mf2_t vs2, size_t vl) { - return __riscv_vcpopv_v_u16mf2_tum(mask, maskedoff, vs2, vl); +vuint16mf2_t test_vcpop_v_u16mf2_tum(vbool32_t mask, vuint16mf2_t maskedoff, vuint16mf2_t vs2, size_t vl) { + return __riscv_vcpop_v_u16mf2_tum(mask, maskedoff, vs2, vl); } -// CHECK-LABEL: @test_vcpopv_v_u16m1_tum( +// CHECK-LABEL: @test_vcpop_v_u16m1_tum( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vcpopv.mask.nxv4i16.i64( [[MASKEDOFF:%.*]], [[VS2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]], i64 2) // CHECK-NEXT: ret [[TMP0]] // -vuint16m1_t test_vcpopv_v_u16m1_tum(vbool16_t mask, vuint16m1_t maskedoff, vuint16m1_t vs2, size_t vl) { - return __riscv_vcpopv_v_u16m1_tum(mask, maskedoff, vs2, vl); +vuint16m1_t test_vcpop_v_u16m1_tum(vbool16_t mask, vuint16m1_t maskedoff, vuint16m1_t vs2, size_t vl) { + return __riscv_vcpop_v_u16m1_tum(mask, maskedoff, vs2, vl); } -// CHECK-LABEL: @test_vcpopv_v_u16m2_tum( +// CHECK-LABEL: @test_vcpop_v_u16m2_tum( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vcpopv.mask.nxv8i16.i64( [[MASKEDOFF:%.*]], [[VS2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]], i64 2) // CHECK-NEXT: ret [[TMP0]] // -vuint16m2_t test_vcpopv_v_u16m2_tum(vbool8_t mask, vuint16m2_t maskedoff, vuint16m2_t vs2, size_t vl) { - return __riscv_vcpopv_v_u16m2_tum(mask, maskedoff, vs2, vl); +vuint16m2_t test_vcpop_v_u16m2_tum(vbool8_t mask, vuint16m2_t maskedoff, vuint16m2_t vs2, size_t vl) { + return __riscv_vcpop_v_u16m2_tum(mask, maskedoff, vs2, vl); } -// CHECK-LABEL: @test_vcpopv_v_u16m4_tum( +// CHECK-LABEL: @test_vcpop_v_u16m4_tum( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vcpopv.mask.nxv16i16.i64( [[MASKEDOFF:%.*]], [[VS2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]], i64 2) // CHECK-NEXT: ret [[TMP0]] // -vuint16m4_t test_vcpopv_v_u16m4_tum(vbool4_t mask, vuint16m4_t maskedoff, vuint16m4_t vs2, size_t vl) { - return __riscv_vcpopv_v_u16m4_tum(mask, maskedoff, vs2, vl); +vuint16m4_t test_vcpop_v_u16m4_tum(vbool4_t mask, vuint16m4_t maskedoff, vuint16m4_t vs2, size_t vl) { + return __riscv_vcpop_v_u16m4_tum(mask, maskedoff, vs2, vl); } -// CHECK-LABEL: @test_vcpopv_v_u16m8_tum( +// CHECK-LABEL: @test_vcpop_v_u16m8_tum( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vcpopv.mask.nxv32i16.i64( [[MASKEDOFF:%.*]], [[VS2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]], i64 2) // CHECK-NEXT: ret [[TMP0]] // -vuint16m8_t test_vcpopv_v_u16m8_tum(vbool2_t mask, vuint16m8_t maskedoff, vuint16m8_t vs2, size_t vl) { - return __riscv_vcpopv_v_u16m8_tum(mask, maskedoff, vs2, vl); +vuint16m8_t test_vcpop_v_u16m8_tum(vbool2_t mask, vuint16m8_t maskedoff, vuint16m8_t vs2, size_t vl) { + return __riscv_vcpop_v_u16m8_tum(mask, maskedoff, vs2, vl); } -// CHECK-LABEL: @test_vcpopv_v_u32mf2_tum( +// CHECK-LABEL: @test_vcpop_v_u32mf2_tum( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vcpopv.mask.nxv1i32.i64( [[MASKEDOFF:%.*]], [[VS2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]], i64 2) // CHECK-NEXT: ret [[TMP0]] // -vuint32mf2_t test_vcpopv_v_u32mf2_tum(vbool64_t mask, vuint32mf2_t maskedoff, vuint32mf2_t vs2, size_t vl) { - return __riscv_vcpopv_v_u32mf2_tum(mask, maskedoff, vs2, vl); +vuint32mf2_t test_vcpop_v_u32mf2_tum(vbool64_t mask, vuint32mf2_t maskedoff, vuint32mf2_t vs2, size_t vl) { + return __riscv_vcpop_v_u32mf2_tum(mask, maskedoff, vs2, vl); } -// CHECK-LABEL: @test_vcpopv_v_u32m1_tum( +// CHECK-LABEL: @test_vcpop_v_u32m1_tum( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vcpopv.mask.nxv2i32.i64( [[MASKEDOFF:%.*]], [[VS2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]], i64 2) // CHECK-NEXT: ret [[TMP0]] // -vuint32m1_t test_vcpopv_v_u32m1_tum(vbool32_t mask, vuint32m1_t maskedoff, vuint32m1_t vs2, size_t vl) { - return __riscv_vcpopv_v_u32m1_tum(mask, maskedoff, vs2, vl); +vuint32m1_t test_vcpop_v_u32m1_tum(vbool32_t mask, vuint32m1_t maskedoff, vuint32m1_t vs2, size_t vl) { + return __riscv_vcpop_v_u32m1_tum(mask, maskedoff, vs2, vl); } -// CHECK-LABEL: @test_vcpopv_v_u32m2_tum( +// CHECK-LABEL: @test_vcpop_v_u32m2_tum( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vcpopv.mask.nxv4i32.i64( [[MASKEDOFF:%.*]], [[VS2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]], i64 2) // CHECK-NEXT: ret [[TMP0]] // -vuint32m2_t test_vcpopv_v_u32m2_tum(vbool16_t mask, vuint32m2_t maskedoff, vuint32m2_t vs2, size_t vl) { - return __riscv_vcpopv_v_u32m2_tum(mask, maskedoff, vs2, vl); +vuint32m2_t test_vcpop_v_u32m2_tum(vbool16_t mask, vuint32m2_t maskedoff, vuint32m2_t vs2, size_t vl) { + return __riscv_vcpop_v_u32m2_tum(mask, maskedoff, vs2, vl); } -// CHECK-LABEL: @test_vcpopv_v_u32m4_tum( +// CHECK-LABEL: @test_vcpop_v_u32m4_tum( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vcpopv.mask.nxv8i32.i64( [[MASKEDOFF:%.*]], [[VS2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]], i64 2) // CHECK-NEXT: ret [[TMP0]] // -vuint32m4_t test_vcpopv_v_u32m4_tum(vbool8_t mask, vuint32m4_t maskedoff, vuint32m4_t vs2, size_t vl) { - return __riscv_vcpopv_v_u32m4_tum(mask, maskedoff, vs2, vl); +vuint32m4_t test_vcpop_v_u32m4_tum(vbool8_t mask, vuint32m4_t maskedoff, vuint32m4_t vs2, size_t vl) { + return __riscv_vcpop_v_u32m4_tum(mask, maskedoff, vs2, vl); } -// CHECK-LABEL: @test_vcpopv_v_u32m8_tum( +// CHECK-LABEL: @test_vcpop_v_u32m8_tum( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vcpopv.mask.nxv16i32.i64( [[MASKEDOFF:%.*]], [[VS2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]], i64 2) // CHECK-NEXT: ret [[TMP0]] // -vuint32m8_t test_vcpopv_v_u32m8_tum(vbool4_t mask, vuint32m8_t maskedoff, vuint32m8_t vs2, size_t vl) { - return __riscv_vcpopv_v_u32m8_tum(mask, maskedoff, vs2, vl); +vuint32m8_t test_vcpop_v_u32m8_tum(vbool4_t mask, vuint32m8_t maskedoff, vuint32m8_t vs2, size_t vl) { + return __riscv_vcpop_v_u32m8_tum(mask, maskedoff, vs2, vl); } -// CHECK-LABEL: @test_vcpopv_v_u64m1_tum( +// CHECK-LABEL: @test_vcpop_v_u64m1_tum( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vcpopv.mask.nxv1i64.i64( [[MASKEDOFF:%.*]], [[VS2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]], i64 2) // CHECK-NEXT: ret [[TMP0]] // -vuint64m1_t test_vcpopv_v_u64m1_tum(vbool64_t mask, vuint64m1_t maskedoff, vuint64m1_t vs2, size_t vl) { - return __riscv_vcpopv_v_u64m1_tum(mask, maskedoff, vs2, vl); +vuint64m1_t test_vcpop_v_u64m1_tum(vbool64_t mask, vuint64m1_t maskedoff, vuint64m1_t vs2, size_t vl) { + return __riscv_vcpop_v_u64m1_tum(mask, maskedoff, vs2, vl); } -// CHECK-LABEL: @test_vcpopv_v_u64m2_tum( +// CHECK-LABEL: @test_vcpop_v_u64m2_tum( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vcpopv.mask.nxv2i64.i64( [[MASKEDOFF:%.*]], [[VS2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]], i64 2) // CHECK-NEXT: ret [[TMP0]] // -vuint64m2_t test_vcpopv_v_u64m2_tum(vbool32_t mask, vuint64m2_t maskedoff, vuint64m2_t vs2, size_t vl) { - return __riscv_vcpopv_v_u64m2_tum(mask, maskedoff, vs2, vl); +vuint64m2_t test_vcpop_v_u64m2_tum(vbool32_t mask, vuint64m2_t maskedoff, vuint64m2_t vs2, size_t vl) { + return __riscv_vcpop_v_u64m2_tum(mask, maskedoff, vs2, vl); } -// CHECK-LABEL: @test_vcpopv_v_u64m4_tum( +// CHECK-LABEL: @test_vcpop_v_u64m4_tum( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vcpopv.mask.nxv4i64.i64( [[MASKEDOFF:%.*]], [[VS2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]], i64 2) // CHECK-NEXT: ret [[TMP0]] // -vuint64m4_t test_vcpopv_v_u64m4_tum(vbool16_t mask, vuint64m4_t maskedoff, vuint64m4_t vs2, size_t vl) { - return __riscv_vcpopv_v_u64m4_tum(mask, maskedoff, vs2, vl); +vuint64m4_t test_vcpop_v_u64m4_tum(vbool16_t mask, vuint64m4_t maskedoff, vuint64m4_t vs2, size_t vl) { + return __riscv_vcpop_v_u64m4_tum(mask, maskedoff, vs2, vl); } -// CHECK-LABEL: @test_vcpopv_v_u64m8_tum( +// CHECK-LABEL: @test_vcpop_v_u64m8_tum( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vcpopv.mask.nxv8i64.i64( [[MASKEDOFF:%.*]], [[VS2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]], i64 2) // CHECK-NEXT: ret [[TMP0]] // -vuint64m8_t test_vcpopv_v_u64m8_tum(vbool8_t mask, vuint64m8_t maskedoff, vuint64m8_t vs2, size_t vl) { - return __riscv_vcpopv_v_u64m8_tum(mask, maskedoff, vs2, vl); +vuint64m8_t test_vcpop_v_u64m8_tum(vbool8_t mask, vuint64m8_t maskedoff, vuint64m8_t vs2, size_t vl) { + return __riscv_vcpop_v_u64m8_tum(mask, maskedoff, vs2, vl); } -// CHECK-LABEL: @test_vcpopv_v_u8mf8_tumu( +// CHECK-LABEL: @test_vcpop_v_u8mf8_tumu( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vcpopv.mask.nxv1i8.i64( [[MASKEDOFF:%.*]], [[VS2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]], i64 0) // CHECK-NEXT: ret [[TMP0]] // -vuint8mf8_t test_vcpopv_v_u8mf8_tumu(vbool64_t mask, vuint8mf8_t maskedoff, vuint8mf8_t vs2, size_t vl) { - return __riscv_vcpopv_v_u8mf8_tumu(mask, maskedoff, vs2, vl); +vuint8mf8_t test_vcpop_v_u8mf8_tumu(vbool64_t mask, vuint8mf8_t maskedoff, vuint8mf8_t vs2, size_t vl) { + return __riscv_vcpop_v_u8mf8_tumu(mask, maskedoff, vs2, vl); } -// CHECK-LABEL: @test_vcpopv_v_u8mf4_tumu( +// CHECK-LABEL: @test_vcpop_v_u8mf4_tumu( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vcpopv.mask.nxv2i8.i64( [[MASKEDOFF:%.*]], [[VS2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]], i64 0) // CHECK-NEXT: ret [[TMP0]] // -vuint8mf4_t test_vcpopv_v_u8mf4_tumu(vbool32_t mask, vuint8mf4_t maskedoff, vuint8mf4_t vs2, size_t vl) { - return __riscv_vcpopv_v_u8mf4_tumu(mask, maskedoff, vs2, vl); +vuint8mf4_t test_vcpop_v_u8mf4_tumu(vbool32_t mask, vuint8mf4_t maskedoff, vuint8mf4_t vs2, size_t vl) { + return __riscv_vcpop_v_u8mf4_tumu(mask, maskedoff, vs2, vl); } -// CHECK-LABEL: @test_vcpopv_v_u8mf2_tumu( +// CHECK-LABEL: @test_vcpop_v_u8mf2_tumu( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vcpopv.mask.nxv4i8.i64( [[MASKEDOFF:%.*]], [[VS2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]], i64 0) // CHECK-NEXT: ret [[TMP0]] // -vuint8mf2_t test_vcpopv_v_u8mf2_tumu(vbool16_t mask, vuint8mf2_t maskedoff, vuint8mf2_t vs2, size_t vl) { - return __riscv_vcpopv_v_u8mf2_tumu(mask, maskedoff, vs2, vl); +vuint8mf2_t test_vcpop_v_u8mf2_tumu(vbool16_t mask, vuint8mf2_t maskedoff, vuint8mf2_t vs2, size_t vl) { + return __riscv_vcpop_v_u8mf2_tumu(mask, maskedoff, vs2, vl); } -// CHECK-LABEL: @test_vcpopv_v_u8m1_tumu( +// CHECK-LABEL: @test_vcpop_v_u8m1_tumu( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vcpopv.mask.nxv8i8.i64( [[MASKEDOFF:%.*]], [[VS2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]], i64 0) // CHECK-NEXT: ret [[TMP0]] // -vuint8m1_t test_vcpopv_v_u8m1_tumu(vbool8_t mask, vuint8m1_t maskedoff, vuint8m1_t vs2, size_t vl) { - return __riscv_vcpopv_v_u8m1_tumu(mask, maskedoff, vs2, vl); +vuint8m1_t test_vcpop_v_u8m1_tumu(vbool8_t mask, vuint8m1_t maskedoff, vuint8m1_t vs2, size_t vl) { + return __riscv_vcpop_v_u8m1_tumu(mask, maskedoff, vs2, vl); } -// CHECK-LABEL: @test_vcpopv_v_u8m2_tumu( +// CHECK-LABEL: @test_vcpop_v_u8m2_tumu( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vcpopv.mask.nxv16i8.i64( [[MASKEDOFF:%.*]], [[VS2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]], i64 0) // CHECK-NEXT: ret [[TMP0]] // -vuint8m2_t test_vcpopv_v_u8m2_tumu(vbool4_t mask, vuint8m2_t maskedoff, vuint8m2_t vs2, size_t vl) { - return __riscv_vcpopv_v_u8m2_tumu(mask, maskedoff, vs2, vl); +vuint8m2_t test_vcpop_v_u8m2_tumu(vbool4_t mask, vuint8m2_t maskedoff, vuint8m2_t vs2, size_t vl) { + return __riscv_vcpop_v_u8m2_tumu(mask, maskedoff, vs2, vl); } -// CHECK-LABEL: @test_vcpopv_v_u8m4_tumu( +// CHECK-LABEL: @test_vcpop_v_u8m4_tumu( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vcpopv.mask.nxv32i8.i64( [[MASKEDOFF:%.*]], [[VS2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]], i64 0) // CHECK-NEXT: ret [[TMP0]] // -vuint8m4_t test_vcpopv_v_u8m4_tumu(vbool2_t mask, vuint8m4_t maskedoff, vuint8m4_t vs2, size_t vl) { - return __riscv_vcpopv_v_u8m4_tumu(mask, maskedoff, vs2, vl); +vuint8m4_t test_vcpop_v_u8m4_tumu(vbool2_t mask, vuint8m4_t maskedoff, vuint8m4_t vs2, size_t vl) { + return __riscv_vcpop_v_u8m4_tumu(mask, maskedoff, vs2, vl); } -// CHECK-LABEL: @test_vcpopv_v_u8m8_tumu( +// CHECK-LABEL: @test_vcpop_v_u8m8_tumu( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vcpopv.mask.nxv64i8.i64( [[MASKEDOFF:%.*]], [[VS2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]], i64 0) // CHECK-NEXT: ret [[TMP0]] // -vuint8m8_t test_vcpopv_v_u8m8_tumu(vbool1_t mask, vuint8m8_t maskedoff, vuint8m8_t vs2, size_t vl) { - return __riscv_vcpopv_v_u8m8_tumu(mask, maskedoff, vs2, vl); +vuint8m8_t test_vcpop_v_u8m8_tumu(vbool1_t mask, vuint8m8_t maskedoff, vuint8m8_t vs2, size_t vl) { + return __riscv_vcpop_v_u8m8_tumu(mask, maskedoff, vs2, vl); } -// CHECK-LABEL: @test_vcpopv_v_u16mf4_tumu( +// CHECK-LABEL: @test_vcpop_v_u16mf4_tumu( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vcpopv.mask.nxv1i16.i64( [[MASKEDOFF:%.*]], [[VS2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]], i64 0) // CHECK-NEXT: ret [[TMP0]] // -vuint16mf4_t test_vcpopv_v_u16mf4_tumu(vbool64_t mask, vuint16mf4_t maskedoff, vuint16mf4_t vs2, size_t vl) { - return __riscv_vcpopv_v_u16mf4_tumu(mask, maskedoff, vs2, vl); +vuint16mf4_t test_vcpop_v_u16mf4_tumu(vbool64_t mask, vuint16mf4_t maskedoff, vuint16mf4_t vs2, size_t vl) { + return __riscv_vcpop_v_u16mf4_tumu(mask, maskedoff, vs2, vl); } -// CHECK-LABEL: @test_vcpopv_v_u16mf2_tumu( +// CHECK-LABEL: @test_vcpop_v_u16mf2_tumu( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vcpopv.mask.nxv2i16.i64( [[MASKEDOFF:%.*]], [[VS2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]], i64 0) // CHECK-NEXT: ret [[TMP0]] // -vuint16mf2_t test_vcpopv_v_u16mf2_tumu(vbool32_t mask, vuint16mf2_t maskedoff, vuint16mf2_t vs2, size_t vl) { - return __riscv_vcpopv_v_u16mf2_tumu(mask, maskedoff, vs2, vl); +vuint16mf2_t test_vcpop_v_u16mf2_tumu(vbool32_t mask, vuint16mf2_t maskedoff, vuint16mf2_t vs2, size_t vl) { + return __riscv_vcpop_v_u16mf2_tumu(mask, maskedoff, vs2, vl); } -// CHECK-LABEL: @test_vcpopv_v_u16m1_tumu( +// CHECK-LABEL: @test_vcpop_v_u16m1_tumu( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vcpopv.mask.nxv4i16.i64( [[MASKEDOFF:%.*]], [[VS2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]], i64 0) // CHECK-NEXT: ret [[TMP0]] // -vuint16m1_t test_vcpopv_v_u16m1_tumu(vbool16_t mask, vuint16m1_t maskedoff, vuint16m1_t vs2, size_t vl) { - return __riscv_vcpopv_v_u16m1_tumu(mask, maskedoff, vs2, vl); +vuint16m1_t test_vcpop_v_u16m1_tumu(vbool16_t mask, vuint16m1_t maskedoff, vuint16m1_t vs2, size_t vl) { + return __riscv_vcpop_v_u16m1_tumu(mask, maskedoff, vs2, vl); } -// CHECK-LABEL: @test_vcpopv_v_u16m2_tumu( +// CHECK-LABEL: @test_vcpop_v_u16m2_tumu( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vcpopv.mask.nxv8i16.i64( [[MASKEDOFF:%.*]], [[VS2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]], i64 0) // CHECK-NEXT: ret [[TMP0]] // -vuint16m2_t test_vcpopv_v_u16m2_tumu(vbool8_t mask, vuint16m2_t maskedoff, vuint16m2_t vs2, size_t vl) { - return __riscv_vcpopv_v_u16m2_tumu(mask, maskedoff, vs2, vl); +vuint16m2_t test_vcpop_v_u16m2_tumu(vbool8_t mask, vuint16m2_t maskedoff, vuint16m2_t vs2, size_t vl) { + return __riscv_vcpop_v_u16m2_tumu(mask, maskedoff, vs2, vl); } -// CHECK-LABEL: @test_vcpopv_v_u16m4_tumu( +// CHECK-LABEL: @test_vcpop_v_u16m4_tumu( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vcpopv.mask.nxv16i16.i64( [[MASKEDOFF:%.*]], [[VS2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]], i64 0) // CHECK-NEXT: ret [[TMP0]] // -vuint16m4_t test_vcpopv_v_u16m4_tumu(vbool4_t mask, vuint16m4_t maskedoff, vuint16m4_t vs2, size_t vl) { - return __riscv_vcpopv_v_u16m4_tumu(mask, maskedoff, vs2, vl); +vuint16m4_t test_vcpop_v_u16m4_tumu(vbool4_t mask, vuint16m4_t maskedoff, vuint16m4_t vs2, size_t vl) { + return __riscv_vcpop_v_u16m4_tumu(mask, maskedoff, vs2, vl); } -// CHECK-LABEL: @test_vcpopv_v_u16m8_tumu( +// CHECK-LABEL: @test_vcpop_v_u16m8_tumu( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vcpopv.mask.nxv32i16.i64( [[MASKEDOFF:%.*]], [[VS2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]], i64 0) // CHECK-NEXT: ret [[TMP0]] // -vuint16m8_t test_vcpopv_v_u16m8_tumu(vbool2_t mask, vuint16m8_t maskedoff, vuint16m8_t vs2, size_t vl) { - return __riscv_vcpopv_v_u16m8_tumu(mask, maskedoff, vs2, vl); +vuint16m8_t test_vcpop_v_u16m8_tumu(vbool2_t mask, vuint16m8_t maskedoff, vuint16m8_t vs2, size_t vl) { + return __riscv_vcpop_v_u16m8_tumu(mask, maskedoff, vs2, vl); } -// CHECK-LABEL: @test_vcpopv_v_u32mf2_tumu( +// CHECK-LABEL: @test_vcpop_v_u32mf2_tumu( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vcpopv.mask.nxv1i32.i64( [[MASKEDOFF:%.*]], [[VS2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]], i64 0) // CHECK-NEXT: ret [[TMP0]] // -vuint32mf2_t test_vcpopv_v_u32mf2_tumu(vbool64_t mask, vuint32mf2_t maskedoff, vuint32mf2_t vs2, size_t vl) { - return __riscv_vcpopv_v_u32mf2_tumu(mask, maskedoff, vs2, vl); +vuint32mf2_t test_vcpop_v_u32mf2_tumu(vbool64_t mask, vuint32mf2_t maskedoff, vuint32mf2_t vs2, size_t vl) { + return __riscv_vcpop_v_u32mf2_tumu(mask, maskedoff, vs2, vl); } -// CHECK-LABEL: @test_vcpopv_v_u32m1_tumu( +// CHECK-LABEL: @test_vcpop_v_u32m1_tumu( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vcpopv.mask.nxv2i32.i64( [[MASKEDOFF:%.*]], [[VS2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]], i64 0) // CHECK-NEXT: ret [[TMP0]] // -vuint32m1_t test_vcpopv_v_u32m1_tumu(vbool32_t mask, vuint32m1_t maskedoff, vuint32m1_t vs2, size_t vl) { - return __riscv_vcpopv_v_u32m1_tumu(mask, maskedoff, vs2, vl); +vuint32m1_t test_vcpop_v_u32m1_tumu(vbool32_t mask, vuint32m1_t maskedoff, vuint32m1_t vs2, size_t vl) { + return __riscv_vcpop_v_u32m1_tumu(mask, maskedoff, vs2, vl); } -// CHECK-LABEL: @test_vcpopv_v_u32m2_tumu( +// CHECK-LABEL: @test_vcpop_v_u32m2_tumu( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vcpopv.mask.nxv4i32.i64( [[MASKEDOFF:%.*]], [[VS2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]], i64 0) // CHECK-NEXT: ret [[TMP0]] // -vuint32m2_t test_vcpopv_v_u32m2_tumu(vbool16_t mask, vuint32m2_t maskedoff, vuint32m2_t vs2, size_t vl) { - return __riscv_vcpopv_v_u32m2_tumu(mask, maskedoff, vs2, vl); +vuint32m2_t test_vcpop_v_u32m2_tumu(vbool16_t mask, vuint32m2_t maskedoff, vuint32m2_t vs2, size_t vl) { + return __riscv_vcpop_v_u32m2_tumu(mask, maskedoff, vs2, vl); } -// CHECK-LABEL: @test_vcpopv_v_u32m4_tumu( +// CHECK-LABEL: @test_vcpop_v_u32m4_tumu( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vcpopv.mask.nxv8i32.i64( [[MASKEDOFF:%.*]], [[VS2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]], i64 0) // CHECK-NEXT: ret [[TMP0]] // -vuint32m4_t test_vcpopv_v_u32m4_tumu(vbool8_t mask, vuint32m4_t maskedoff, vuint32m4_t vs2, size_t vl) { - return __riscv_vcpopv_v_u32m4_tumu(mask, maskedoff, vs2, vl); +vuint32m4_t test_vcpop_v_u32m4_tumu(vbool8_t mask, vuint32m4_t maskedoff, vuint32m4_t vs2, size_t vl) { + return __riscv_vcpop_v_u32m4_tumu(mask, maskedoff, vs2, vl); } -// CHECK-LABEL: @test_vcpopv_v_u32m8_tumu( +// CHECK-LABEL: @test_vcpop_v_u32m8_tumu( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vcpopv.mask.nxv16i32.i64( [[MASKEDOFF:%.*]], [[VS2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]], i64 0) // CHECK-NEXT: ret [[TMP0]] // -vuint32m8_t test_vcpopv_v_u32m8_tumu(vbool4_t mask, vuint32m8_t maskedoff, vuint32m8_t vs2, size_t vl) { - return __riscv_vcpopv_v_u32m8_tumu(mask, maskedoff, vs2, vl); +vuint32m8_t test_vcpop_v_u32m8_tumu(vbool4_t mask, vuint32m8_t maskedoff, vuint32m8_t vs2, size_t vl) { + return __riscv_vcpop_v_u32m8_tumu(mask, maskedoff, vs2, vl); } -// CHECK-LABEL: @test_vcpopv_v_u64m1_tumu( +// CHECK-LABEL: @test_vcpop_v_u64m1_tumu( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vcpopv.mask.nxv1i64.i64( [[MASKEDOFF:%.*]], [[VS2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]], i64 0) // CHECK-NEXT: ret [[TMP0]] // -vuint64m1_t test_vcpopv_v_u64m1_tumu(vbool64_t mask, vuint64m1_t maskedoff, vuint64m1_t vs2, size_t vl) { - return __riscv_vcpopv_v_u64m1_tumu(mask, maskedoff, vs2, vl); +vuint64m1_t test_vcpop_v_u64m1_tumu(vbool64_t mask, vuint64m1_t maskedoff, vuint64m1_t vs2, size_t vl) { + return __riscv_vcpop_v_u64m1_tumu(mask, maskedoff, vs2, vl); } -// CHECK-LABEL: @test_vcpopv_v_u64m2_tumu( +// CHECK-LABEL: @test_vcpop_v_u64m2_tumu( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vcpopv.mask.nxv2i64.i64( [[MASKEDOFF:%.*]], [[VS2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]], i64 0) // CHECK-NEXT: ret [[TMP0]] // -vuint64m2_t test_vcpopv_v_u64m2_tumu(vbool32_t mask, vuint64m2_t maskedoff, vuint64m2_t vs2, size_t vl) { - return __riscv_vcpopv_v_u64m2_tumu(mask, maskedoff, vs2, vl); +vuint64m2_t test_vcpop_v_u64m2_tumu(vbool32_t mask, vuint64m2_t maskedoff, vuint64m2_t vs2, size_t vl) { + return __riscv_vcpop_v_u64m2_tumu(mask, maskedoff, vs2, vl); } -// CHECK-LABEL: @test_vcpopv_v_u64m4_tumu( +// CHECK-LABEL: @test_vcpop_v_u64m4_tumu( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vcpopv.mask.nxv4i64.i64( [[MASKEDOFF:%.*]], [[VS2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]], i64 0) // CHECK-NEXT: ret [[TMP0]] // -vuint64m4_t test_vcpopv_v_u64m4_tumu(vbool16_t mask, vuint64m4_t maskedoff, vuint64m4_t vs2, size_t vl) { - return __riscv_vcpopv_v_u64m4_tumu(mask, maskedoff, vs2, vl); +vuint64m4_t test_vcpop_v_u64m4_tumu(vbool16_t mask, vuint64m4_t maskedoff, vuint64m4_t vs2, size_t vl) { + return __riscv_vcpop_v_u64m4_tumu(mask, maskedoff, vs2, vl); } -// CHECK-LABEL: @test_vcpopv_v_u64m8_tumu( +// CHECK-LABEL: @test_vcpop_v_u64m8_tumu( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vcpopv.mask.nxv8i64.i64( [[MASKEDOFF:%.*]], [[VS2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]], i64 0) // CHECK-NEXT: ret [[TMP0]] // -vuint64m8_t test_vcpopv_v_u64m8_tumu(vbool8_t mask, vuint64m8_t maskedoff, vuint64m8_t vs2, size_t vl) { - return __riscv_vcpopv_v_u64m8_tumu(mask, maskedoff, vs2, vl); +vuint64m8_t test_vcpop_v_u64m8_tumu(vbool8_t mask, vuint64m8_t maskedoff, vuint64m8_t vs2, size_t vl) { + return __riscv_vcpop_v_u64m8_tumu(mask, maskedoff, vs2, vl); } -// CHECK-LABEL: @test_vcpopv_v_u8mf8_mu( +// CHECK-LABEL: @test_vcpop_v_u8mf8_mu( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vcpopv.mask.nxv1i8.i64( [[MASKEDOFF:%.*]], [[VS2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]], i64 1) // CHECK-NEXT: ret [[TMP0]] // -vuint8mf8_t test_vcpopv_v_u8mf8_mu(vbool64_t mask, vuint8mf8_t maskedoff, vuint8mf8_t vs2, size_t vl) { - return __riscv_vcpopv_v_u8mf8_mu(mask, maskedoff, vs2, vl); +vuint8mf8_t test_vcpop_v_u8mf8_mu(vbool64_t mask, vuint8mf8_t maskedoff, vuint8mf8_t vs2, size_t vl) { + return __riscv_vcpop_v_u8mf8_mu(mask, maskedoff, vs2, vl); } -// CHECK-LABEL: @test_vcpopv_v_u8mf4_mu( +// CHECK-LABEL: @test_vcpop_v_u8mf4_mu( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vcpopv.mask.nxv2i8.i64( [[MASKEDOFF:%.*]], [[VS2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]], i64 1) // CHECK-NEXT: ret [[TMP0]] // -vuint8mf4_t test_vcpopv_v_u8mf4_mu(vbool32_t mask, vuint8mf4_t maskedoff, vuint8mf4_t vs2, size_t vl) { - return __riscv_vcpopv_v_u8mf4_mu(mask, maskedoff, vs2, vl); +vuint8mf4_t test_vcpop_v_u8mf4_mu(vbool32_t mask, vuint8mf4_t maskedoff, vuint8mf4_t vs2, size_t vl) { + return __riscv_vcpop_v_u8mf4_mu(mask, maskedoff, vs2, vl); } -// CHECK-LABEL: @test_vcpopv_v_u8mf2_mu( +// CHECK-LABEL: @test_vcpop_v_u8mf2_mu( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vcpopv.mask.nxv4i8.i64( [[MASKEDOFF:%.*]], [[VS2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]], i64 1) // CHECK-NEXT: ret [[TMP0]] // -vuint8mf2_t test_vcpopv_v_u8mf2_mu(vbool16_t mask, vuint8mf2_t maskedoff, vuint8mf2_t vs2, size_t vl) { - return __riscv_vcpopv_v_u8mf2_mu(mask, maskedoff, vs2, vl); +vuint8mf2_t test_vcpop_v_u8mf2_mu(vbool16_t mask, vuint8mf2_t maskedoff, vuint8mf2_t vs2, size_t vl) { + return __riscv_vcpop_v_u8mf2_mu(mask, maskedoff, vs2, vl); } -// CHECK-LABEL: @test_vcpopv_v_u8m1_mu( +// CHECK-LABEL: @test_vcpop_v_u8m1_mu( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vcpopv.mask.nxv8i8.i64( [[MASKEDOFF:%.*]], [[VS2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]], i64 1) // CHECK-NEXT: ret [[TMP0]] // -vuint8m1_t test_vcpopv_v_u8m1_mu(vbool8_t mask, vuint8m1_t maskedoff, vuint8m1_t vs2, size_t vl) { - return __riscv_vcpopv_v_u8m1_mu(mask, maskedoff, vs2, vl); +vuint8m1_t test_vcpop_v_u8m1_mu(vbool8_t mask, vuint8m1_t maskedoff, vuint8m1_t vs2, size_t vl) { + return __riscv_vcpop_v_u8m1_mu(mask, maskedoff, vs2, vl); } -// CHECK-LABEL: @test_vcpopv_v_u8m2_mu( +// CHECK-LABEL: @test_vcpop_v_u8m2_mu( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vcpopv.mask.nxv16i8.i64( [[MASKEDOFF:%.*]], [[VS2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]], i64 1) // CHECK-NEXT: ret [[TMP0]] // -vuint8m2_t test_vcpopv_v_u8m2_mu(vbool4_t mask, vuint8m2_t maskedoff, vuint8m2_t vs2, size_t vl) { - return __riscv_vcpopv_v_u8m2_mu(mask, maskedoff, vs2, vl); +vuint8m2_t test_vcpop_v_u8m2_mu(vbool4_t mask, vuint8m2_t maskedoff, vuint8m2_t vs2, size_t vl) { + return __riscv_vcpop_v_u8m2_mu(mask, maskedoff, vs2, vl); } -// CHECK-LABEL: @test_vcpopv_v_u8m4_mu( +// CHECK-LABEL: @test_vcpop_v_u8m4_mu( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vcpopv.mask.nxv32i8.i64( [[MASKEDOFF:%.*]], [[VS2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]], i64 1) // CHECK-NEXT: ret [[TMP0]] // -vuint8m4_t test_vcpopv_v_u8m4_mu(vbool2_t mask, vuint8m4_t maskedoff, vuint8m4_t vs2, size_t vl) { - return __riscv_vcpopv_v_u8m4_mu(mask, maskedoff, vs2, vl); +vuint8m4_t test_vcpop_v_u8m4_mu(vbool2_t mask, vuint8m4_t maskedoff, vuint8m4_t vs2, size_t vl) { + return __riscv_vcpop_v_u8m4_mu(mask, maskedoff, vs2, vl); } -// CHECK-LABEL: @test_vcpopv_v_u8m8_mu( +// CHECK-LABEL: @test_vcpop_v_u8m8_mu( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vcpopv.mask.nxv64i8.i64( [[MASKEDOFF:%.*]], [[VS2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]], i64 1) // CHECK-NEXT: ret [[TMP0]] // -vuint8m8_t test_vcpopv_v_u8m8_mu(vbool1_t mask, vuint8m8_t maskedoff, vuint8m8_t vs2, size_t vl) { - return __riscv_vcpopv_v_u8m8_mu(mask, maskedoff, vs2, vl); +vuint8m8_t test_vcpop_v_u8m8_mu(vbool1_t mask, vuint8m8_t maskedoff, vuint8m8_t vs2, size_t vl) { + return __riscv_vcpop_v_u8m8_mu(mask, maskedoff, vs2, vl); } -// CHECK-LABEL: @test_vcpopv_v_u16mf4_mu( +// CHECK-LABEL: @test_vcpop_v_u16mf4_mu( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vcpopv.mask.nxv1i16.i64( [[MASKEDOFF:%.*]], [[VS2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]], i64 1) // CHECK-NEXT: ret [[TMP0]] // -vuint16mf4_t test_vcpopv_v_u16mf4_mu(vbool64_t mask, vuint16mf4_t maskedoff, vuint16mf4_t vs2, size_t vl) { - return __riscv_vcpopv_v_u16mf4_mu(mask, maskedoff, vs2, vl); +vuint16mf4_t test_vcpop_v_u16mf4_mu(vbool64_t mask, vuint16mf4_t maskedoff, vuint16mf4_t vs2, size_t vl) { + return __riscv_vcpop_v_u16mf4_mu(mask, maskedoff, vs2, vl); } -// CHECK-LABEL: @test_vcpopv_v_u16mf2_mu( +// CHECK-LABEL: @test_vcpop_v_u16mf2_mu( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vcpopv.mask.nxv2i16.i64( [[MASKEDOFF:%.*]], [[VS2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]], i64 1) // CHECK-NEXT: ret [[TMP0]] // -vuint16mf2_t test_vcpopv_v_u16mf2_mu(vbool32_t mask, vuint16mf2_t maskedoff, vuint16mf2_t vs2, size_t vl) { - return __riscv_vcpopv_v_u16mf2_mu(mask, maskedoff, vs2, vl); +vuint16mf2_t test_vcpop_v_u16mf2_mu(vbool32_t mask, vuint16mf2_t maskedoff, vuint16mf2_t vs2, size_t vl) { + return __riscv_vcpop_v_u16mf2_mu(mask, maskedoff, vs2, vl); } -// CHECK-LABEL: @test_vcpopv_v_u16m1_mu( +// CHECK-LABEL: @test_vcpop_v_u16m1_mu( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vcpopv.mask.nxv4i16.i64( [[MASKEDOFF:%.*]], [[VS2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]], i64 1) // CHECK-NEXT: ret [[TMP0]] // -vuint16m1_t test_vcpopv_v_u16m1_mu(vbool16_t mask, vuint16m1_t maskedoff, vuint16m1_t vs2, size_t vl) { - return __riscv_vcpopv_v_u16m1_mu(mask, maskedoff, vs2, vl); +vuint16m1_t test_vcpop_v_u16m1_mu(vbool16_t mask, vuint16m1_t maskedoff, vuint16m1_t vs2, size_t vl) { + return __riscv_vcpop_v_u16m1_mu(mask, maskedoff, vs2, vl); } -// CHECK-LABEL: @test_vcpopv_v_u16m2_mu( +// CHECK-LABEL: @test_vcpop_v_u16m2_mu( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vcpopv.mask.nxv8i16.i64( [[MASKEDOFF:%.*]], [[VS2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]], i64 1) // CHECK-NEXT: ret [[TMP0]] // -vuint16m2_t test_vcpopv_v_u16m2_mu(vbool8_t mask, vuint16m2_t maskedoff, vuint16m2_t vs2, size_t vl) { - return __riscv_vcpopv_v_u16m2_mu(mask, maskedoff, vs2, vl); +vuint16m2_t test_vcpop_v_u16m2_mu(vbool8_t mask, vuint16m2_t maskedoff, vuint16m2_t vs2, size_t vl) { + return __riscv_vcpop_v_u16m2_mu(mask, maskedoff, vs2, vl); } -// CHECK-LABEL: @test_vcpopv_v_u16m4_mu( +// CHECK-LABEL: @test_vcpop_v_u16m4_mu( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vcpopv.mask.nxv16i16.i64( [[MASKEDOFF:%.*]], [[VS2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]], i64 1) // CHECK-NEXT: ret [[TMP0]] // -vuint16m4_t test_vcpopv_v_u16m4_mu(vbool4_t mask, vuint16m4_t maskedoff, vuint16m4_t vs2, size_t vl) { - return __riscv_vcpopv_v_u16m4_mu(mask, maskedoff, vs2, vl); +vuint16m4_t test_vcpop_v_u16m4_mu(vbool4_t mask, vuint16m4_t maskedoff, vuint16m4_t vs2, size_t vl) { + return __riscv_vcpop_v_u16m4_mu(mask, maskedoff, vs2, vl); } -// CHECK-LABEL: @test_vcpopv_v_u16m8_mu( +// CHECK-LABEL: @test_vcpop_v_u16m8_mu( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vcpopv.mask.nxv32i16.i64( [[MASKEDOFF:%.*]], [[VS2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]], i64 1) // CHECK-NEXT: ret [[TMP0]] // -vuint16m8_t test_vcpopv_v_u16m8_mu(vbool2_t mask, vuint16m8_t maskedoff, vuint16m8_t vs2, size_t vl) { - return __riscv_vcpopv_v_u16m8_mu(mask, maskedoff, vs2, vl); +vuint16m8_t test_vcpop_v_u16m8_mu(vbool2_t mask, vuint16m8_t maskedoff, vuint16m8_t vs2, size_t vl) { + return __riscv_vcpop_v_u16m8_mu(mask, maskedoff, vs2, vl); } -// CHECK-LABEL: @test_vcpopv_v_u32mf2_mu( +// CHECK-LABEL: @test_vcpop_v_u32mf2_mu( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vcpopv.mask.nxv1i32.i64( [[MASKEDOFF:%.*]], [[VS2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]], i64 1) // CHECK-NEXT: ret [[TMP0]] // -vuint32mf2_t test_vcpopv_v_u32mf2_mu(vbool64_t mask, vuint32mf2_t maskedoff, vuint32mf2_t vs2, size_t vl) { - return __riscv_vcpopv_v_u32mf2_mu(mask, maskedoff, vs2, vl); +vuint32mf2_t test_vcpop_v_u32mf2_mu(vbool64_t mask, vuint32mf2_t maskedoff, vuint32mf2_t vs2, size_t vl) { + return __riscv_vcpop_v_u32mf2_mu(mask, maskedoff, vs2, vl); } -// CHECK-LABEL: @test_vcpopv_v_u32m1_mu( +// CHECK-LABEL: @test_vcpop_v_u32m1_mu( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vcpopv.mask.nxv2i32.i64( [[MASKEDOFF:%.*]], [[VS2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]], i64 1) // CHECK-NEXT: ret [[TMP0]] // -vuint32m1_t test_vcpopv_v_u32m1_mu(vbool32_t mask, vuint32m1_t maskedoff, vuint32m1_t vs2, size_t vl) { - return __riscv_vcpopv_v_u32m1_mu(mask, maskedoff, vs2, vl); +vuint32m1_t test_vcpop_v_u32m1_mu(vbool32_t mask, vuint32m1_t maskedoff, vuint32m1_t vs2, size_t vl) { + return __riscv_vcpop_v_u32m1_mu(mask, maskedoff, vs2, vl); } -// CHECK-LABEL: @test_vcpopv_v_u32m2_mu( +// CHECK-LABEL: @test_vcpop_v_u32m2_mu( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vcpopv.mask.nxv4i32.i64( [[MASKEDOFF:%.*]], [[VS2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]], i64 1) // CHECK-NEXT: ret [[TMP0]] // -vuint32m2_t test_vcpopv_v_u32m2_mu(vbool16_t mask, vuint32m2_t maskedoff, vuint32m2_t vs2, size_t vl) { - return __riscv_vcpopv_v_u32m2_mu(mask, maskedoff, vs2, vl); +vuint32m2_t test_vcpop_v_u32m2_mu(vbool16_t mask, vuint32m2_t maskedoff, vuint32m2_t vs2, size_t vl) { + return __riscv_vcpop_v_u32m2_mu(mask, maskedoff, vs2, vl); } -// CHECK-LABEL: @test_vcpopv_v_u32m4_mu( +// CHECK-LABEL: @test_vcpop_v_u32m4_mu( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vcpopv.mask.nxv8i32.i64( [[MASKEDOFF:%.*]], [[VS2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]], i64 1) // CHECK-NEXT: ret [[TMP0]] // -vuint32m4_t test_vcpopv_v_u32m4_mu(vbool8_t mask, vuint32m4_t maskedoff, vuint32m4_t vs2, size_t vl) { - return __riscv_vcpopv_v_u32m4_mu(mask, maskedoff, vs2, vl); +vuint32m4_t test_vcpop_v_u32m4_mu(vbool8_t mask, vuint32m4_t maskedoff, vuint32m4_t vs2, size_t vl) { + return __riscv_vcpop_v_u32m4_mu(mask, maskedoff, vs2, vl); } -// CHECK-LABEL: @test_vcpopv_v_u32m8_mu( +// CHECK-LABEL: @test_vcpop_v_u32m8_mu( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vcpopv.mask.nxv16i32.i64( [[MASKEDOFF:%.*]], [[VS2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]], i64 1) // CHECK-NEXT: ret [[TMP0]] // -vuint32m8_t test_vcpopv_v_u32m8_mu(vbool4_t mask, vuint32m8_t maskedoff, vuint32m8_t vs2, size_t vl) { - return __riscv_vcpopv_v_u32m8_mu(mask, maskedoff, vs2, vl); +vuint32m8_t test_vcpop_v_u32m8_mu(vbool4_t mask, vuint32m8_t maskedoff, vuint32m8_t vs2, size_t vl) { + return __riscv_vcpop_v_u32m8_mu(mask, maskedoff, vs2, vl); } -// CHECK-LABEL: @test_vcpopv_v_u64m1_mu( +// CHECK-LABEL: @test_vcpop_v_u64m1_mu( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vcpopv.mask.nxv1i64.i64( [[MASKEDOFF:%.*]], [[VS2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]], i64 1) // CHECK-NEXT: ret [[TMP0]] // -vuint64m1_t test_vcpopv_v_u64m1_mu(vbool64_t mask, vuint64m1_t maskedoff, vuint64m1_t vs2, size_t vl) { - return __riscv_vcpopv_v_u64m1_mu(mask, maskedoff, vs2, vl); +vuint64m1_t test_vcpop_v_u64m1_mu(vbool64_t mask, vuint64m1_t maskedoff, vuint64m1_t vs2, size_t vl) { + return __riscv_vcpop_v_u64m1_mu(mask, maskedoff, vs2, vl); } -// CHECK-LABEL: @test_vcpopv_v_u64m2_mu( +// CHECK-LABEL: @test_vcpop_v_u64m2_mu( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vcpopv.mask.nxv2i64.i64( [[MASKEDOFF:%.*]], [[VS2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]], i64 1) // CHECK-NEXT: ret [[TMP0]] // -vuint64m2_t test_vcpopv_v_u64m2_mu(vbool32_t mask, vuint64m2_t maskedoff, vuint64m2_t vs2, size_t vl) { - return __riscv_vcpopv_v_u64m2_mu(mask, maskedoff, vs2, vl); +vuint64m2_t test_vcpop_v_u64m2_mu(vbool32_t mask, vuint64m2_t maskedoff, vuint64m2_t vs2, size_t vl) { + return __riscv_vcpop_v_u64m2_mu(mask, maskedoff, vs2, vl); } -// CHECK-LABEL: @test_vcpopv_v_u64m4_mu( +// CHECK-LABEL: @test_vcpop_v_u64m4_mu( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vcpopv.mask.nxv4i64.i64( [[MASKEDOFF:%.*]], [[VS2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]], i64 1) // CHECK-NEXT: ret [[TMP0]] // -vuint64m4_t test_vcpopv_v_u64m4_mu(vbool16_t mask, vuint64m4_t maskedoff, vuint64m4_t vs2, size_t vl) { - return __riscv_vcpopv_v_u64m4_mu(mask, maskedoff, vs2, vl); +vuint64m4_t test_vcpop_v_u64m4_mu(vbool16_t mask, vuint64m4_t maskedoff, vuint64m4_t vs2, size_t vl) { + return __riscv_vcpop_v_u64m4_mu(mask, maskedoff, vs2, vl); } -// CHECK-LABEL: @test_vcpopv_v_u64m8_mu( +// CHECK-LABEL: @test_vcpop_v_u64m8_mu( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vcpopv.mask.nxv8i64.i64( [[MASKEDOFF:%.*]], [[VS2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]], i64 1) // CHECK-NEXT: ret [[TMP0]] // -vuint64m8_t test_vcpopv_v_u64m8_mu(vbool8_t mask, vuint64m8_t maskedoff, vuint64m8_t vs2, size_t vl) { - return __riscv_vcpopv_v_u64m8_mu(mask, maskedoff, vs2, vl); +vuint64m8_t test_vcpop_v_u64m8_mu(vbool8_t mask, vuint64m8_t maskedoff, vuint64m8_t vs2, size_t vl) { + return __riscv_vcpop_v_u64m8_mu(mask, maskedoff, vs2, vl); } diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vcpopv.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vcpopv.c index 02a499d4b67da54903b880f6a26efc0dfc7f17a5..953ccac133c382c5ae52147376d1923587bf9765 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vcpopv.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/vcpopv.c @@ -16,795 +16,795 @@ #include -// CHECK-LABEL: @test_vcpopv_v_u8mf8_tu( +// CHECK-LABEL: @test_vcpop_v_u8mf8_tu( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vcpopv.nxv1i8.i64( [[MASKEDOFF:%.*]], [[VS2:%.*]], i64 [[VL:%.*]]) // CHECK-NEXT: ret [[TMP0]] // -vuint8mf8_t test_vcpopv_v_u8mf8_tu(vuint8mf8_t maskedoff, vuint8mf8_t vs2, size_t vl) { - return __riscv_vcpopv_tu(maskedoff, vs2, vl); +vuint8mf8_t test_vcpop_v_u8mf8_tu(vuint8mf8_t maskedoff, vuint8mf8_t vs2, size_t vl) { + return __riscv_vcpop_tu(maskedoff, vs2, vl); } -// CHECK-LABEL: @test_vcpopv_v_u8mf4_tu( +// CHECK-LABEL: @test_vcpop_v_u8mf4_tu( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vcpopv.nxv2i8.i64( [[MASKEDOFF:%.*]], [[VS2:%.*]], i64 [[VL:%.*]]) // CHECK-NEXT: ret [[TMP0]] // -vuint8mf4_t test_vcpopv_v_u8mf4_tu(vuint8mf4_t maskedoff, vuint8mf4_t vs2, size_t vl) { - return __riscv_vcpopv_tu(maskedoff, vs2, vl); +vuint8mf4_t test_vcpop_v_u8mf4_tu(vuint8mf4_t maskedoff, vuint8mf4_t vs2, size_t vl) { + return __riscv_vcpop_tu(maskedoff, vs2, vl); } -// CHECK-LABEL: @test_vcpopv_v_u8mf2_tu( +// CHECK-LABEL: @test_vcpop_v_u8mf2_tu( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vcpopv.nxv4i8.i64( [[MASKEDOFF:%.*]], [[VS2:%.*]], i64 [[VL:%.*]]) // CHECK-NEXT: ret [[TMP0]] // -vuint8mf2_t test_vcpopv_v_u8mf2_tu(vuint8mf2_t maskedoff, vuint8mf2_t vs2, size_t vl) { - return __riscv_vcpopv_tu(maskedoff, vs2, vl); +vuint8mf2_t test_vcpop_v_u8mf2_tu(vuint8mf2_t maskedoff, vuint8mf2_t vs2, size_t vl) { + return __riscv_vcpop_tu(maskedoff, vs2, vl); } -// CHECK-LABEL: @test_vcpopv_v_u8m1_tu( +// CHECK-LABEL: @test_vcpop_v_u8m1_tu( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vcpopv.nxv8i8.i64( [[MASKEDOFF:%.*]], [[VS2:%.*]], i64 [[VL:%.*]]) // CHECK-NEXT: ret [[TMP0]] // -vuint8m1_t test_vcpopv_v_u8m1_tu(vuint8m1_t maskedoff, vuint8m1_t vs2, size_t vl) { - return __riscv_vcpopv_tu(maskedoff, vs2, vl); +vuint8m1_t test_vcpop_v_u8m1_tu(vuint8m1_t maskedoff, vuint8m1_t vs2, size_t vl) { + return __riscv_vcpop_tu(maskedoff, vs2, vl); } -// CHECK-LABEL: @test_vcpopv_v_u8m2_tu( +// CHECK-LABEL: @test_vcpop_v_u8m2_tu( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vcpopv.nxv16i8.i64( [[MASKEDOFF:%.*]], [[VS2:%.*]], i64 [[VL:%.*]]) // CHECK-NEXT: ret [[TMP0]] // -vuint8m2_t test_vcpopv_v_u8m2_tu(vuint8m2_t maskedoff, vuint8m2_t vs2, size_t vl) { - return __riscv_vcpopv_tu(maskedoff, vs2, vl); +vuint8m2_t test_vcpop_v_u8m2_tu(vuint8m2_t maskedoff, vuint8m2_t vs2, size_t vl) { + return __riscv_vcpop_tu(maskedoff, vs2, vl); } -// CHECK-LABEL: @test_vcpopv_v_u8m4_tu( +// CHECK-LABEL: @test_vcpop_v_u8m4_tu( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vcpopv.nxv32i8.i64( [[MASKEDOFF:%.*]], [[VS2:%.*]], i64 [[VL:%.*]]) // CHECK-NEXT: ret [[TMP0]] // -vuint8m4_t test_vcpopv_v_u8m4_tu(vuint8m4_t maskedoff, vuint8m4_t vs2, size_t vl) { - return __riscv_vcpopv_tu(maskedoff, vs2, vl); +vuint8m4_t test_vcpop_v_u8m4_tu(vuint8m4_t maskedoff, vuint8m4_t vs2, size_t vl) { + return __riscv_vcpop_tu(maskedoff, vs2, vl); } -// CHECK-LABEL: @test_vcpopv_v_u8m8_tu( +// CHECK-LABEL: @test_vcpop_v_u8m8_tu( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vcpopv.nxv64i8.i64( [[MASKEDOFF:%.*]], [[VS2:%.*]], i64 [[VL:%.*]]) // CHECK-NEXT: ret [[TMP0]] // -vuint8m8_t test_vcpopv_v_u8m8_tu(vuint8m8_t maskedoff, vuint8m8_t vs2, size_t vl) { - return __riscv_vcpopv_tu(maskedoff, vs2, vl); +vuint8m8_t test_vcpop_v_u8m8_tu(vuint8m8_t maskedoff, vuint8m8_t vs2, size_t vl) { + return __riscv_vcpop_tu(maskedoff, vs2, vl); } -// CHECK-LABEL: @test_vcpopv_v_u16mf4_tu( +// CHECK-LABEL: @test_vcpop_v_u16mf4_tu( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vcpopv.nxv1i16.i64( [[MASKEDOFF:%.*]], [[VS2:%.*]], i64 [[VL:%.*]]) // CHECK-NEXT: ret [[TMP0]] // -vuint16mf4_t test_vcpopv_v_u16mf4_tu(vuint16mf4_t maskedoff, vuint16mf4_t vs2, size_t vl) { - return __riscv_vcpopv_tu(maskedoff, vs2, vl); +vuint16mf4_t test_vcpop_v_u16mf4_tu(vuint16mf4_t maskedoff, vuint16mf4_t vs2, size_t vl) { + return __riscv_vcpop_tu(maskedoff, vs2, vl); } -// CHECK-LABEL: @test_vcpopv_v_u16mf2_tu( +// CHECK-LABEL: @test_vcpop_v_u16mf2_tu( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vcpopv.nxv2i16.i64( [[MASKEDOFF:%.*]], [[VS2:%.*]], i64 [[VL:%.*]]) // CHECK-NEXT: ret [[TMP0]] // -vuint16mf2_t test_vcpopv_v_u16mf2_tu(vuint16mf2_t maskedoff, vuint16mf2_t vs2, size_t vl) { - return __riscv_vcpopv_tu(maskedoff, vs2, vl); +vuint16mf2_t test_vcpop_v_u16mf2_tu(vuint16mf2_t maskedoff, vuint16mf2_t vs2, size_t vl) { + return __riscv_vcpop_tu(maskedoff, vs2, vl); } -// CHECK-LABEL: @test_vcpopv_v_u16m1_tu( +// CHECK-LABEL: @test_vcpop_v_u16m1_tu( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vcpopv.nxv4i16.i64( [[MASKEDOFF:%.*]], [[VS2:%.*]], i64 [[VL:%.*]]) // CHECK-NEXT: ret [[TMP0]] // -vuint16m1_t test_vcpopv_v_u16m1_tu(vuint16m1_t maskedoff, vuint16m1_t vs2, size_t vl) { - return __riscv_vcpopv_tu(maskedoff, vs2, vl); +vuint16m1_t test_vcpop_v_u16m1_tu(vuint16m1_t maskedoff, vuint16m1_t vs2, size_t vl) { + return __riscv_vcpop_tu(maskedoff, vs2, vl); } -// CHECK-LABEL: @test_vcpopv_v_u16m2_tu( +// CHECK-LABEL: @test_vcpop_v_u16m2_tu( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vcpopv.nxv8i16.i64( [[MASKEDOFF:%.*]], [[VS2:%.*]], i64 [[VL:%.*]]) // CHECK-NEXT: ret [[TMP0]] // -vuint16m2_t test_vcpopv_v_u16m2_tu(vuint16m2_t maskedoff, vuint16m2_t vs2, size_t vl) { - return __riscv_vcpopv_tu(maskedoff, vs2, vl); +vuint16m2_t test_vcpop_v_u16m2_tu(vuint16m2_t maskedoff, vuint16m2_t vs2, size_t vl) { + return __riscv_vcpop_tu(maskedoff, vs2, vl); } -// CHECK-LABEL: @test_vcpopv_v_u16m4_tu( +// CHECK-LABEL: @test_vcpop_v_u16m4_tu( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vcpopv.nxv16i16.i64( [[MASKEDOFF:%.*]], [[VS2:%.*]], i64 [[VL:%.*]]) // CHECK-NEXT: ret [[TMP0]] // -vuint16m4_t test_vcpopv_v_u16m4_tu(vuint16m4_t maskedoff, vuint16m4_t vs2, size_t vl) { - return __riscv_vcpopv_tu(maskedoff, vs2, vl); +vuint16m4_t test_vcpop_v_u16m4_tu(vuint16m4_t maskedoff, vuint16m4_t vs2, size_t vl) { + return __riscv_vcpop_tu(maskedoff, vs2, vl); } -// CHECK-LABEL: @test_vcpopv_v_u16m8_tu( +// CHECK-LABEL: @test_vcpop_v_u16m8_tu( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vcpopv.nxv32i16.i64( [[MASKEDOFF:%.*]], [[VS2:%.*]], i64 [[VL:%.*]]) // CHECK-NEXT: ret [[TMP0]] // -vuint16m8_t test_vcpopv_v_u16m8_tu(vuint16m8_t maskedoff, vuint16m8_t vs2, size_t vl) { - return __riscv_vcpopv_tu(maskedoff, vs2, vl); +vuint16m8_t test_vcpop_v_u16m8_tu(vuint16m8_t maskedoff, vuint16m8_t vs2, size_t vl) { + return __riscv_vcpop_tu(maskedoff, vs2, vl); } -// CHECK-LABEL: @test_vcpopv_v_u32mf2_tu( +// CHECK-LABEL: @test_vcpop_v_u32mf2_tu( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vcpopv.nxv1i32.i64( [[MASKEDOFF:%.*]], [[VS2:%.*]], i64 [[VL:%.*]]) // CHECK-NEXT: ret [[TMP0]] // -vuint32mf2_t test_vcpopv_v_u32mf2_tu(vuint32mf2_t maskedoff, vuint32mf2_t vs2, size_t vl) { - return __riscv_vcpopv_tu(maskedoff, vs2, vl); +vuint32mf2_t test_vcpop_v_u32mf2_tu(vuint32mf2_t maskedoff, vuint32mf2_t vs2, size_t vl) { + return __riscv_vcpop_tu(maskedoff, vs2, vl); } -// CHECK-LABEL: @test_vcpopv_v_u32m1_tu( +// CHECK-LABEL: @test_vcpop_v_u32m1_tu( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vcpopv.nxv2i32.i64( [[MASKEDOFF:%.*]], [[VS2:%.*]], i64 [[VL:%.*]]) // CHECK-NEXT: ret [[TMP0]] // -vuint32m1_t test_vcpopv_v_u32m1_tu(vuint32m1_t maskedoff, vuint32m1_t vs2, size_t vl) { - return __riscv_vcpopv_tu(maskedoff, vs2, vl); +vuint32m1_t test_vcpop_v_u32m1_tu(vuint32m1_t maskedoff, vuint32m1_t vs2, size_t vl) { + return __riscv_vcpop_tu(maskedoff, vs2, vl); } -// CHECK-LABEL: @test_vcpopv_v_u32m2_tu( +// CHECK-LABEL: @test_vcpop_v_u32m2_tu( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vcpopv.nxv4i32.i64( [[MASKEDOFF:%.*]], [[VS2:%.*]], i64 [[VL:%.*]]) // CHECK-NEXT: ret [[TMP0]] // -vuint32m2_t test_vcpopv_v_u32m2_tu(vuint32m2_t maskedoff, vuint32m2_t vs2, size_t vl) { - return __riscv_vcpopv_tu(maskedoff, vs2, vl); +vuint32m2_t test_vcpop_v_u32m2_tu(vuint32m2_t maskedoff, vuint32m2_t vs2, size_t vl) { + return __riscv_vcpop_tu(maskedoff, vs2, vl); } -// CHECK-LABEL: @test_vcpopv_v_u32m4_tu( +// CHECK-LABEL: @test_vcpop_v_u32m4_tu( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vcpopv.nxv8i32.i64( [[MASKEDOFF:%.*]], [[VS2:%.*]], i64 [[VL:%.*]]) // CHECK-NEXT: ret [[TMP0]] // -vuint32m4_t test_vcpopv_v_u32m4_tu(vuint32m4_t maskedoff, vuint32m4_t vs2, size_t vl) { - return __riscv_vcpopv_tu(maskedoff, vs2, vl); +vuint32m4_t test_vcpop_v_u32m4_tu(vuint32m4_t maskedoff, vuint32m4_t vs2, size_t vl) { + return __riscv_vcpop_tu(maskedoff, vs2, vl); } -// CHECK-LABEL: @test_vcpopv_v_u32m8_tu( +// CHECK-LABEL: @test_vcpop_v_u32m8_tu( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vcpopv.nxv16i32.i64( [[MASKEDOFF:%.*]], [[VS2:%.*]], i64 [[VL:%.*]]) // CHECK-NEXT: ret [[TMP0]] // -vuint32m8_t test_vcpopv_v_u32m8_tu(vuint32m8_t maskedoff, vuint32m8_t vs2, size_t vl) { - return __riscv_vcpopv_tu(maskedoff, vs2, vl); +vuint32m8_t test_vcpop_v_u32m8_tu(vuint32m8_t maskedoff, vuint32m8_t vs2, size_t vl) { + return __riscv_vcpop_tu(maskedoff, vs2, vl); } -// CHECK-LABEL: @test_vcpopv_v_u64m1_tu( +// CHECK-LABEL: @test_vcpop_v_u64m1_tu( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vcpopv.nxv1i64.i64( [[MASKEDOFF:%.*]], [[VS2:%.*]], i64 [[VL:%.*]]) // CHECK-NEXT: ret [[TMP0]] // -vuint64m1_t test_vcpopv_v_u64m1_tu(vuint64m1_t maskedoff, vuint64m1_t vs2, size_t vl) { - return __riscv_vcpopv_tu(maskedoff, vs2, vl); +vuint64m1_t test_vcpop_v_u64m1_tu(vuint64m1_t maskedoff, vuint64m1_t vs2, size_t vl) { + return __riscv_vcpop_tu(maskedoff, vs2, vl); } -// CHECK-LABEL: @test_vcpopv_v_u64m2_tu( +// CHECK-LABEL: @test_vcpop_v_u64m2_tu( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vcpopv.nxv2i64.i64( [[MASKEDOFF:%.*]], [[VS2:%.*]], i64 [[VL:%.*]]) // CHECK-NEXT: ret [[TMP0]] // -vuint64m2_t test_vcpopv_v_u64m2_tu(vuint64m2_t maskedoff, vuint64m2_t vs2, size_t vl) { - return __riscv_vcpopv_tu(maskedoff, vs2, vl); +vuint64m2_t test_vcpop_v_u64m2_tu(vuint64m2_t maskedoff, vuint64m2_t vs2, size_t vl) { + return __riscv_vcpop_tu(maskedoff, vs2, vl); } -// CHECK-LABEL: @test_vcpopv_v_u64m4_tu( +// CHECK-LABEL: @test_vcpop_v_u64m4_tu( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vcpopv.nxv4i64.i64( [[MASKEDOFF:%.*]], [[VS2:%.*]], i64 [[VL:%.*]]) // CHECK-NEXT: ret [[TMP0]] // -vuint64m4_t test_vcpopv_v_u64m4_tu(vuint64m4_t maskedoff, vuint64m4_t vs2, size_t vl) { - return __riscv_vcpopv_tu(maskedoff, vs2, vl); +vuint64m4_t test_vcpop_v_u64m4_tu(vuint64m4_t maskedoff, vuint64m4_t vs2, size_t vl) { + return __riscv_vcpop_tu(maskedoff, vs2, vl); } -// CHECK-LABEL: @test_vcpopv_v_u64m8_tu( +// CHECK-LABEL: @test_vcpop_v_u64m8_tu( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vcpopv.nxv8i64.i64( [[MASKEDOFF:%.*]], [[VS2:%.*]], i64 [[VL:%.*]]) // CHECK-NEXT: ret [[TMP0]] // -vuint64m8_t test_vcpopv_v_u64m8_tu(vuint64m8_t maskedoff, vuint64m8_t vs2, size_t vl) { - return __riscv_vcpopv_tu(maskedoff, vs2, vl); +vuint64m8_t test_vcpop_v_u64m8_tu(vuint64m8_t maskedoff, vuint64m8_t vs2, size_t vl) { + return __riscv_vcpop_tu(maskedoff, vs2, vl); } -// CHECK-LABEL: @test_vcpopv_v_u8mf8_tum( +// CHECK-LABEL: @test_vcpop_v_u8mf8_tum( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vcpopv.mask.nxv1i8.i64( [[MASKEDOFF:%.*]], [[VS2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]], i64 2) // CHECK-NEXT: ret [[TMP0]] // -vuint8mf8_t test_vcpopv_v_u8mf8_tum(vbool64_t mask, vuint8mf8_t maskedoff, vuint8mf8_t vs2, size_t vl) { - return __riscv_vcpopv_tum(mask, maskedoff, vs2, vl); +vuint8mf8_t test_vcpop_v_u8mf8_tum(vbool64_t mask, vuint8mf8_t maskedoff, vuint8mf8_t vs2, size_t vl) { + return __riscv_vcpop_tum(mask, maskedoff, vs2, vl); } -// CHECK-LABEL: @test_vcpopv_v_u8mf4_tum( +// CHECK-LABEL: @test_vcpop_v_u8mf4_tum( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vcpopv.mask.nxv2i8.i64( [[MASKEDOFF:%.*]], [[VS2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]], i64 2) // CHECK-NEXT: ret [[TMP0]] // -vuint8mf4_t test_vcpopv_v_u8mf4_tum(vbool32_t mask, vuint8mf4_t maskedoff, vuint8mf4_t vs2, size_t vl) { - return __riscv_vcpopv_tum(mask, maskedoff, vs2, vl); +vuint8mf4_t test_vcpop_v_u8mf4_tum(vbool32_t mask, vuint8mf4_t maskedoff, vuint8mf4_t vs2, size_t vl) { + return __riscv_vcpop_tum(mask, maskedoff, vs2, vl); } -// CHECK-LABEL: @test_vcpopv_v_u8mf2_tum( +// CHECK-LABEL: @test_vcpop_v_u8mf2_tum( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vcpopv.mask.nxv4i8.i64( [[MASKEDOFF:%.*]], [[VS2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]], i64 2) // CHECK-NEXT: ret [[TMP0]] // -vuint8mf2_t test_vcpopv_v_u8mf2_tum(vbool16_t mask, vuint8mf2_t maskedoff, vuint8mf2_t vs2, size_t vl) { - return __riscv_vcpopv_tum(mask, maskedoff, vs2, vl); +vuint8mf2_t test_vcpop_v_u8mf2_tum(vbool16_t mask, vuint8mf2_t maskedoff, vuint8mf2_t vs2, size_t vl) { + return __riscv_vcpop_tum(mask, maskedoff, vs2, vl); } -// CHECK-LABEL: @test_vcpopv_v_u8m1_tum( +// CHECK-LABEL: @test_vcpop_v_u8m1_tum( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vcpopv.mask.nxv8i8.i64( [[MASKEDOFF:%.*]], [[VS2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]], i64 2) // CHECK-NEXT: ret [[TMP0]] // -vuint8m1_t test_vcpopv_v_u8m1_tum(vbool8_t mask, vuint8m1_t maskedoff, vuint8m1_t vs2, size_t vl) { - return __riscv_vcpopv_tum(mask, maskedoff, vs2, vl); +vuint8m1_t test_vcpop_v_u8m1_tum(vbool8_t mask, vuint8m1_t maskedoff, vuint8m1_t vs2, size_t vl) { + return __riscv_vcpop_tum(mask, maskedoff, vs2, vl); } -// CHECK-LABEL: @test_vcpopv_v_u8m2_tum( +// CHECK-LABEL: @test_vcpop_v_u8m2_tum( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vcpopv.mask.nxv16i8.i64( [[MASKEDOFF:%.*]], [[VS2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]], i64 2) // CHECK-NEXT: ret [[TMP0]] // -vuint8m2_t test_vcpopv_v_u8m2_tum(vbool4_t mask, vuint8m2_t maskedoff, vuint8m2_t vs2, size_t vl) { - return __riscv_vcpopv_tum(mask, maskedoff, vs2, vl); +vuint8m2_t test_vcpop_v_u8m2_tum(vbool4_t mask, vuint8m2_t maskedoff, vuint8m2_t vs2, size_t vl) { + return __riscv_vcpop_tum(mask, maskedoff, vs2, vl); } -// CHECK-LABEL: @test_vcpopv_v_u8m4_tum( +// CHECK-LABEL: @test_vcpop_v_u8m4_tum( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vcpopv.mask.nxv32i8.i64( [[MASKEDOFF:%.*]], [[VS2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]], i64 2) // CHECK-NEXT: ret [[TMP0]] // -vuint8m4_t test_vcpopv_v_u8m4_tum(vbool2_t mask, vuint8m4_t maskedoff, vuint8m4_t vs2, size_t vl) { - return __riscv_vcpopv_tum(mask, maskedoff, vs2, vl); +vuint8m4_t test_vcpop_v_u8m4_tum(vbool2_t mask, vuint8m4_t maskedoff, vuint8m4_t vs2, size_t vl) { + return __riscv_vcpop_tum(mask, maskedoff, vs2, vl); } -// CHECK-LABEL: @test_vcpopv_v_u8m8_tum( +// CHECK-LABEL: @test_vcpop_v_u8m8_tum( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vcpopv.mask.nxv64i8.i64( [[MASKEDOFF:%.*]], [[VS2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]], i64 2) // CHECK-NEXT: ret [[TMP0]] // -vuint8m8_t test_vcpopv_v_u8m8_tum(vbool1_t mask, vuint8m8_t maskedoff, vuint8m8_t vs2, size_t vl) { - return __riscv_vcpopv_tum(mask, maskedoff, vs2, vl); +vuint8m8_t test_vcpop_v_u8m8_tum(vbool1_t mask, vuint8m8_t maskedoff, vuint8m8_t vs2, size_t vl) { + return __riscv_vcpop_tum(mask, maskedoff, vs2, vl); } -// CHECK-LABEL: @test_vcpopv_v_u16mf4_tum( +// CHECK-LABEL: @test_vcpop_v_u16mf4_tum( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vcpopv.mask.nxv1i16.i64( [[MASKEDOFF:%.*]], [[VS2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]], i64 2) // CHECK-NEXT: ret [[TMP0]] // -vuint16mf4_t test_vcpopv_v_u16mf4_tum(vbool64_t mask, vuint16mf4_t maskedoff, vuint16mf4_t vs2, size_t vl) { - return __riscv_vcpopv_tum(mask, maskedoff, vs2, vl); +vuint16mf4_t test_vcpop_v_u16mf4_tum(vbool64_t mask, vuint16mf4_t maskedoff, vuint16mf4_t vs2, size_t vl) { + return __riscv_vcpop_tum(mask, maskedoff, vs2, vl); } -// CHECK-LABEL: @test_vcpopv_v_u16mf2_tum( +// CHECK-LABEL: @test_vcpop_v_u16mf2_tum( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vcpopv.mask.nxv2i16.i64( [[MASKEDOFF:%.*]], [[VS2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]], i64 2) // CHECK-NEXT: ret [[TMP0]] // -vuint16mf2_t test_vcpopv_v_u16mf2_tum(vbool32_t mask, vuint16mf2_t maskedoff, vuint16mf2_t vs2, size_t vl) { - return __riscv_vcpopv_tum(mask, maskedoff, vs2, vl); +vuint16mf2_t test_vcpop_v_u16mf2_tum(vbool32_t mask, vuint16mf2_t maskedoff, vuint16mf2_t vs2, size_t vl) { + return __riscv_vcpop_tum(mask, maskedoff, vs2, vl); } -// CHECK-LABEL: @test_vcpopv_v_u16m1_tum( +// CHECK-LABEL: @test_vcpop_v_u16m1_tum( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vcpopv.mask.nxv4i16.i64( [[MASKEDOFF:%.*]], [[VS2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]], i64 2) // CHECK-NEXT: ret [[TMP0]] // -vuint16m1_t test_vcpopv_v_u16m1_tum(vbool16_t mask, vuint16m1_t maskedoff, vuint16m1_t vs2, size_t vl) { - return __riscv_vcpopv_tum(mask, maskedoff, vs2, vl); +vuint16m1_t test_vcpop_v_u16m1_tum(vbool16_t mask, vuint16m1_t maskedoff, vuint16m1_t vs2, size_t vl) { + return __riscv_vcpop_tum(mask, maskedoff, vs2, vl); } -// CHECK-LABEL: @test_vcpopv_v_u16m2_tum( +// CHECK-LABEL: @test_vcpop_v_u16m2_tum( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vcpopv.mask.nxv8i16.i64( [[MASKEDOFF:%.*]], [[VS2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]], i64 2) // CHECK-NEXT: ret [[TMP0]] // -vuint16m2_t test_vcpopv_v_u16m2_tum(vbool8_t mask, vuint16m2_t maskedoff, vuint16m2_t vs2, size_t vl) { - return __riscv_vcpopv_tum(mask, maskedoff, vs2, vl); +vuint16m2_t test_vcpop_v_u16m2_tum(vbool8_t mask, vuint16m2_t maskedoff, vuint16m2_t vs2, size_t vl) { + return __riscv_vcpop_tum(mask, maskedoff, vs2, vl); } -// CHECK-LABEL: @test_vcpopv_v_u16m4_tum( +// CHECK-LABEL: @test_vcpop_v_u16m4_tum( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vcpopv.mask.nxv16i16.i64( [[MASKEDOFF:%.*]], [[VS2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]], i64 2) // CHECK-NEXT: ret [[TMP0]] // -vuint16m4_t test_vcpopv_v_u16m4_tum(vbool4_t mask, vuint16m4_t maskedoff, vuint16m4_t vs2, size_t vl) { - return __riscv_vcpopv_tum(mask, maskedoff, vs2, vl); +vuint16m4_t test_vcpop_v_u16m4_tum(vbool4_t mask, vuint16m4_t maskedoff, vuint16m4_t vs2, size_t vl) { + return __riscv_vcpop_tum(mask, maskedoff, vs2, vl); } -// CHECK-LABEL: @test_vcpopv_v_u16m8_tum( +// CHECK-LABEL: @test_vcpop_v_u16m8_tum( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vcpopv.mask.nxv32i16.i64( [[MASKEDOFF:%.*]], [[VS2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]], i64 2) // CHECK-NEXT: ret [[TMP0]] // -vuint16m8_t test_vcpopv_v_u16m8_tum(vbool2_t mask, vuint16m8_t maskedoff, vuint16m8_t vs2, size_t vl) { - return __riscv_vcpopv_tum(mask, maskedoff, vs2, vl); +vuint16m8_t test_vcpop_v_u16m8_tum(vbool2_t mask, vuint16m8_t maskedoff, vuint16m8_t vs2, size_t vl) { + return __riscv_vcpop_tum(mask, maskedoff, vs2, vl); } -// CHECK-LABEL: @test_vcpopv_v_u32mf2_tum( +// CHECK-LABEL: @test_vcpop_v_u32mf2_tum( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vcpopv.mask.nxv1i32.i64( [[MASKEDOFF:%.*]], [[VS2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]], i64 2) // CHECK-NEXT: ret [[TMP0]] // -vuint32mf2_t test_vcpopv_v_u32mf2_tum(vbool64_t mask, vuint32mf2_t maskedoff, vuint32mf2_t vs2, size_t vl) { - return __riscv_vcpopv_tum(mask, maskedoff, vs2, vl); +vuint32mf2_t test_vcpop_v_u32mf2_tum(vbool64_t mask, vuint32mf2_t maskedoff, vuint32mf2_t vs2, size_t vl) { + return __riscv_vcpop_tum(mask, maskedoff, vs2, vl); } -// CHECK-LABEL: @test_vcpopv_v_u32m1_tum( +// CHECK-LABEL: @test_vcpop_v_u32m1_tum( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vcpopv.mask.nxv2i32.i64( [[MASKEDOFF:%.*]], [[VS2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]], i64 2) // CHECK-NEXT: ret [[TMP0]] // -vuint32m1_t test_vcpopv_v_u32m1_tum(vbool32_t mask, vuint32m1_t maskedoff, vuint32m1_t vs2, size_t vl) { - return __riscv_vcpopv_tum(mask, maskedoff, vs2, vl); +vuint32m1_t test_vcpop_v_u32m1_tum(vbool32_t mask, vuint32m1_t maskedoff, vuint32m1_t vs2, size_t vl) { + return __riscv_vcpop_tum(mask, maskedoff, vs2, vl); } -// CHECK-LABEL: @test_vcpopv_v_u32m2_tum( +// CHECK-LABEL: @test_vcpop_v_u32m2_tum( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vcpopv.mask.nxv4i32.i64( [[MASKEDOFF:%.*]], [[VS2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]], i64 2) // CHECK-NEXT: ret [[TMP0]] // -vuint32m2_t test_vcpopv_v_u32m2_tum(vbool16_t mask, vuint32m2_t maskedoff, vuint32m2_t vs2, size_t vl) { - return __riscv_vcpopv_tum(mask, maskedoff, vs2, vl); +vuint32m2_t test_vcpop_v_u32m2_tum(vbool16_t mask, vuint32m2_t maskedoff, vuint32m2_t vs2, size_t vl) { + return __riscv_vcpop_tum(mask, maskedoff, vs2, vl); } -// CHECK-LABEL: @test_vcpopv_v_u32m4_tum( +// CHECK-LABEL: @test_vcpop_v_u32m4_tum( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vcpopv.mask.nxv8i32.i64( [[MASKEDOFF:%.*]], [[VS2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]], i64 2) // CHECK-NEXT: ret [[TMP0]] // -vuint32m4_t test_vcpopv_v_u32m4_tum(vbool8_t mask, vuint32m4_t maskedoff, vuint32m4_t vs2, size_t vl) { - return __riscv_vcpopv_tum(mask, maskedoff, vs2, vl); +vuint32m4_t test_vcpop_v_u32m4_tum(vbool8_t mask, vuint32m4_t maskedoff, vuint32m4_t vs2, size_t vl) { + return __riscv_vcpop_tum(mask, maskedoff, vs2, vl); } -// CHECK-LABEL: @test_vcpopv_v_u32m8_tum( +// CHECK-LABEL: @test_vcpop_v_u32m8_tum( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vcpopv.mask.nxv16i32.i64( [[MASKEDOFF:%.*]], [[VS2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]], i64 2) // CHECK-NEXT: ret [[TMP0]] // -vuint32m8_t test_vcpopv_v_u32m8_tum(vbool4_t mask, vuint32m8_t maskedoff, vuint32m8_t vs2, size_t vl) { - return __riscv_vcpopv_tum(mask, maskedoff, vs2, vl); +vuint32m8_t test_vcpop_v_u32m8_tum(vbool4_t mask, vuint32m8_t maskedoff, vuint32m8_t vs2, size_t vl) { + return __riscv_vcpop_tum(mask, maskedoff, vs2, vl); } -// CHECK-LABEL: @test_vcpopv_v_u64m1_tum( +// CHECK-LABEL: @test_vcpop_v_u64m1_tum( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vcpopv.mask.nxv1i64.i64( [[MASKEDOFF:%.*]], [[VS2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]], i64 2) // CHECK-NEXT: ret [[TMP0]] // -vuint64m1_t test_vcpopv_v_u64m1_tum(vbool64_t mask, vuint64m1_t maskedoff, vuint64m1_t vs2, size_t vl) { - return __riscv_vcpopv_tum(mask, maskedoff, vs2, vl); +vuint64m1_t test_vcpop_v_u64m1_tum(vbool64_t mask, vuint64m1_t maskedoff, vuint64m1_t vs2, size_t vl) { + return __riscv_vcpop_tum(mask, maskedoff, vs2, vl); } -// CHECK-LABEL: @test_vcpopv_v_u64m2_tum( +// CHECK-LABEL: @test_vcpop_v_u64m2_tum( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vcpopv.mask.nxv2i64.i64( [[MASKEDOFF:%.*]], [[VS2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]], i64 2) // CHECK-NEXT: ret [[TMP0]] // -vuint64m2_t test_vcpopv_v_u64m2_tum(vbool32_t mask, vuint64m2_t maskedoff, vuint64m2_t vs2, size_t vl) { - return __riscv_vcpopv_tum(mask, maskedoff, vs2, vl); +vuint64m2_t test_vcpop_v_u64m2_tum(vbool32_t mask, vuint64m2_t maskedoff, vuint64m2_t vs2, size_t vl) { + return __riscv_vcpop_tum(mask, maskedoff, vs2, vl); } -// CHECK-LABEL: @test_vcpopv_v_u64m4_tum( +// CHECK-LABEL: @test_vcpop_v_u64m4_tum( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vcpopv.mask.nxv4i64.i64( [[MASKEDOFF:%.*]], [[VS2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]], i64 2) // CHECK-NEXT: ret [[TMP0]] // -vuint64m4_t test_vcpopv_v_u64m4_tum(vbool16_t mask, vuint64m4_t maskedoff, vuint64m4_t vs2, size_t vl) { - return __riscv_vcpopv_tum(mask, maskedoff, vs2, vl); +vuint64m4_t test_vcpop_v_u64m4_tum(vbool16_t mask, vuint64m4_t maskedoff, vuint64m4_t vs2, size_t vl) { + return __riscv_vcpop_tum(mask, maskedoff, vs2, vl); } -// CHECK-LABEL: @test_vcpopv_v_u64m8_tum( +// CHECK-LABEL: @test_vcpop_v_u64m8_tum( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vcpopv.mask.nxv8i64.i64( [[MASKEDOFF:%.*]], [[VS2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]], i64 2) // CHECK-NEXT: ret [[TMP0]] // -vuint64m8_t test_vcpopv_v_u64m8_tum(vbool8_t mask, vuint64m8_t maskedoff, vuint64m8_t vs2, size_t vl) { - return __riscv_vcpopv_tum(mask, maskedoff, vs2, vl); +vuint64m8_t test_vcpop_v_u64m8_tum(vbool8_t mask, vuint64m8_t maskedoff, vuint64m8_t vs2, size_t vl) { + return __riscv_vcpop_tum(mask, maskedoff, vs2, vl); } -// CHECK-LABEL: @test_vcpopv_v_u8mf8_tumu( +// CHECK-LABEL: @test_vcpop_v_u8mf8_tumu( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vcpopv.mask.nxv1i8.i64( [[MASKEDOFF:%.*]], [[VS2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]], i64 0) // CHECK-NEXT: ret [[TMP0]] // -vuint8mf8_t test_vcpopv_v_u8mf8_tumu(vbool64_t mask, vuint8mf8_t maskedoff, vuint8mf8_t vs2, size_t vl) { - return __riscv_vcpopv_tumu(mask, maskedoff, vs2, vl); +vuint8mf8_t test_vcpop_v_u8mf8_tumu(vbool64_t mask, vuint8mf8_t maskedoff, vuint8mf8_t vs2, size_t vl) { + return __riscv_vcpop_tumu(mask, maskedoff, vs2, vl); } -// CHECK-LABEL: @test_vcpopv_v_u8mf4_tumu( +// CHECK-LABEL: @test_vcpop_v_u8mf4_tumu( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vcpopv.mask.nxv2i8.i64( [[MASKEDOFF:%.*]], [[VS2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]], i64 0) // CHECK-NEXT: ret [[TMP0]] // -vuint8mf4_t test_vcpopv_v_u8mf4_tumu(vbool32_t mask, vuint8mf4_t maskedoff, vuint8mf4_t vs2, size_t vl) { - return __riscv_vcpopv_tumu(mask, maskedoff, vs2, vl); +vuint8mf4_t test_vcpop_v_u8mf4_tumu(vbool32_t mask, vuint8mf4_t maskedoff, vuint8mf4_t vs2, size_t vl) { + return __riscv_vcpop_tumu(mask, maskedoff, vs2, vl); } -// CHECK-LABEL: @test_vcpopv_v_u8mf2_tumu( +// CHECK-LABEL: @test_vcpop_v_u8mf2_tumu( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vcpopv.mask.nxv4i8.i64( [[MASKEDOFF:%.*]], [[VS2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]], i64 0) // CHECK-NEXT: ret [[TMP0]] // -vuint8mf2_t test_vcpopv_v_u8mf2_tumu(vbool16_t mask, vuint8mf2_t maskedoff, vuint8mf2_t vs2, size_t vl) { - return __riscv_vcpopv_tumu(mask, maskedoff, vs2, vl); +vuint8mf2_t test_vcpop_v_u8mf2_tumu(vbool16_t mask, vuint8mf2_t maskedoff, vuint8mf2_t vs2, size_t vl) { + return __riscv_vcpop_tumu(mask, maskedoff, vs2, vl); } -// CHECK-LABEL: @test_vcpopv_v_u8m1_tumu( +// CHECK-LABEL: @test_vcpop_v_u8m1_tumu( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vcpopv.mask.nxv8i8.i64( [[MASKEDOFF:%.*]], [[VS2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]], i64 0) // CHECK-NEXT: ret [[TMP0]] // -vuint8m1_t test_vcpopv_v_u8m1_tumu(vbool8_t mask, vuint8m1_t maskedoff, vuint8m1_t vs2, size_t vl) { - return __riscv_vcpopv_tumu(mask, maskedoff, vs2, vl); +vuint8m1_t test_vcpop_v_u8m1_tumu(vbool8_t mask, vuint8m1_t maskedoff, vuint8m1_t vs2, size_t vl) { + return __riscv_vcpop_tumu(mask, maskedoff, vs2, vl); } -// CHECK-LABEL: @test_vcpopv_v_u8m2_tumu( +// CHECK-LABEL: @test_vcpop_v_u8m2_tumu( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vcpopv.mask.nxv16i8.i64( [[MASKEDOFF:%.*]], [[VS2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]], i64 0) // CHECK-NEXT: ret [[TMP0]] // -vuint8m2_t test_vcpopv_v_u8m2_tumu(vbool4_t mask, vuint8m2_t maskedoff, vuint8m2_t vs2, size_t vl) { - return __riscv_vcpopv_tumu(mask, maskedoff, vs2, vl); +vuint8m2_t test_vcpop_v_u8m2_tumu(vbool4_t mask, vuint8m2_t maskedoff, vuint8m2_t vs2, size_t vl) { + return __riscv_vcpop_tumu(mask, maskedoff, vs2, vl); } -// CHECK-LABEL: @test_vcpopv_v_u8m4_tumu( +// CHECK-LABEL: @test_vcpop_v_u8m4_tumu( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vcpopv.mask.nxv32i8.i64( [[MASKEDOFF:%.*]], [[VS2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]], i64 0) // CHECK-NEXT: ret [[TMP0]] // -vuint8m4_t test_vcpopv_v_u8m4_tumu(vbool2_t mask, vuint8m4_t maskedoff, vuint8m4_t vs2, size_t vl) { - return __riscv_vcpopv_tumu(mask, maskedoff, vs2, vl); +vuint8m4_t test_vcpop_v_u8m4_tumu(vbool2_t mask, vuint8m4_t maskedoff, vuint8m4_t vs2, size_t vl) { + return __riscv_vcpop_tumu(mask, maskedoff, vs2, vl); } -// CHECK-LABEL: @test_vcpopv_v_u8m8_tumu( +// CHECK-LABEL: @test_vcpop_v_u8m8_tumu( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vcpopv.mask.nxv64i8.i64( [[MASKEDOFF:%.*]], [[VS2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]], i64 0) // CHECK-NEXT: ret [[TMP0]] // -vuint8m8_t test_vcpopv_v_u8m8_tumu(vbool1_t mask, vuint8m8_t maskedoff, vuint8m8_t vs2, size_t vl) { - return __riscv_vcpopv_tumu(mask, maskedoff, vs2, vl); +vuint8m8_t test_vcpop_v_u8m8_tumu(vbool1_t mask, vuint8m8_t maskedoff, vuint8m8_t vs2, size_t vl) { + return __riscv_vcpop_tumu(mask, maskedoff, vs2, vl); } -// CHECK-LABEL: @test_vcpopv_v_u16mf4_tumu( +// CHECK-LABEL: @test_vcpop_v_u16mf4_tumu( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vcpopv.mask.nxv1i16.i64( [[MASKEDOFF:%.*]], [[VS2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]], i64 0) // CHECK-NEXT: ret [[TMP0]] // -vuint16mf4_t test_vcpopv_v_u16mf4_tumu(vbool64_t mask, vuint16mf4_t maskedoff, vuint16mf4_t vs2, size_t vl) { - return __riscv_vcpopv_tumu(mask, maskedoff, vs2, vl); +vuint16mf4_t test_vcpop_v_u16mf4_tumu(vbool64_t mask, vuint16mf4_t maskedoff, vuint16mf4_t vs2, size_t vl) { + return __riscv_vcpop_tumu(mask, maskedoff, vs2, vl); } -// CHECK-LABEL: @test_vcpopv_v_u16mf2_tumu( +// CHECK-LABEL: @test_vcpop_v_u16mf2_tumu( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vcpopv.mask.nxv2i16.i64( [[MASKEDOFF:%.*]], [[VS2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]], i64 0) // CHECK-NEXT: ret [[TMP0]] // -vuint16mf2_t test_vcpopv_v_u16mf2_tumu(vbool32_t mask, vuint16mf2_t maskedoff, vuint16mf2_t vs2, size_t vl) { - return __riscv_vcpopv_tumu(mask, maskedoff, vs2, vl); +vuint16mf2_t test_vcpop_v_u16mf2_tumu(vbool32_t mask, vuint16mf2_t maskedoff, vuint16mf2_t vs2, size_t vl) { + return __riscv_vcpop_tumu(mask, maskedoff, vs2, vl); } -// CHECK-LABEL: @test_vcpopv_v_u16m1_tumu( +// CHECK-LABEL: @test_vcpop_v_u16m1_tumu( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vcpopv.mask.nxv4i16.i64( [[MASKEDOFF:%.*]], [[VS2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]], i64 0) // CHECK-NEXT: ret [[TMP0]] // -vuint16m1_t test_vcpopv_v_u16m1_tumu(vbool16_t mask, vuint16m1_t maskedoff, vuint16m1_t vs2, size_t vl) { - return __riscv_vcpopv_tumu(mask, maskedoff, vs2, vl); +vuint16m1_t test_vcpop_v_u16m1_tumu(vbool16_t mask, vuint16m1_t maskedoff, vuint16m1_t vs2, size_t vl) { + return __riscv_vcpop_tumu(mask, maskedoff, vs2, vl); } -// CHECK-LABEL: @test_vcpopv_v_u16m2_tumu( +// CHECK-LABEL: @test_vcpop_v_u16m2_tumu( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vcpopv.mask.nxv8i16.i64( [[MASKEDOFF:%.*]], [[VS2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]], i64 0) // CHECK-NEXT: ret [[TMP0]] // -vuint16m2_t test_vcpopv_v_u16m2_tumu(vbool8_t mask, vuint16m2_t maskedoff, vuint16m2_t vs2, size_t vl) { - return __riscv_vcpopv_tumu(mask, maskedoff, vs2, vl); +vuint16m2_t test_vcpop_v_u16m2_tumu(vbool8_t mask, vuint16m2_t maskedoff, vuint16m2_t vs2, size_t vl) { + return __riscv_vcpop_tumu(mask, maskedoff, vs2, vl); } -// CHECK-LABEL: @test_vcpopv_v_u16m4_tumu( +// CHECK-LABEL: @test_vcpop_v_u16m4_tumu( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vcpopv.mask.nxv16i16.i64( [[MASKEDOFF:%.*]], [[VS2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]], i64 0) // CHECK-NEXT: ret [[TMP0]] // -vuint16m4_t test_vcpopv_v_u16m4_tumu(vbool4_t mask, vuint16m4_t maskedoff, vuint16m4_t vs2, size_t vl) { - return __riscv_vcpopv_tumu(mask, maskedoff, vs2, vl); +vuint16m4_t test_vcpop_v_u16m4_tumu(vbool4_t mask, vuint16m4_t maskedoff, vuint16m4_t vs2, size_t vl) { + return __riscv_vcpop_tumu(mask, maskedoff, vs2, vl); } -// CHECK-LABEL: @test_vcpopv_v_u16m8_tumu( +// CHECK-LABEL: @test_vcpop_v_u16m8_tumu( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vcpopv.mask.nxv32i16.i64( [[MASKEDOFF:%.*]], [[VS2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]], i64 0) // CHECK-NEXT: ret [[TMP0]] // -vuint16m8_t test_vcpopv_v_u16m8_tumu(vbool2_t mask, vuint16m8_t maskedoff, vuint16m8_t vs2, size_t vl) { - return __riscv_vcpopv_tumu(mask, maskedoff, vs2, vl); +vuint16m8_t test_vcpop_v_u16m8_tumu(vbool2_t mask, vuint16m8_t maskedoff, vuint16m8_t vs2, size_t vl) { + return __riscv_vcpop_tumu(mask, maskedoff, vs2, vl); } -// CHECK-LABEL: @test_vcpopv_v_u32mf2_tumu( +// CHECK-LABEL: @test_vcpop_v_u32mf2_tumu( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vcpopv.mask.nxv1i32.i64( [[MASKEDOFF:%.*]], [[VS2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]], i64 0) // CHECK-NEXT: ret [[TMP0]] // -vuint32mf2_t test_vcpopv_v_u32mf2_tumu(vbool64_t mask, vuint32mf2_t maskedoff, vuint32mf2_t vs2, size_t vl) { - return __riscv_vcpopv_tumu(mask, maskedoff, vs2, vl); +vuint32mf2_t test_vcpop_v_u32mf2_tumu(vbool64_t mask, vuint32mf2_t maskedoff, vuint32mf2_t vs2, size_t vl) { + return __riscv_vcpop_tumu(mask, maskedoff, vs2, vl); } -// CHECK-LABEL: @test_vcpopv_v_u32m1_tumu( +// CHECK-LABEL: @test_vcpop_v_u32m1_tumu( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vcpopv.mask.nxv2i32.i64( [[MASKEDOFF:%.*]], [[VS2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]], i64 0) // CHECK-NEXT: ret [[TMP0]] // -vuint32m1_t test_vcpopv_v_u32m1_tumu(vbool32_t mask, vuint32m1_t maskedoff, vuint32m1_t vs2, size_t vl) { - return __riscv_vcpopv_tumu(mask, maskedoff, vs2, vl); +vuint32m1_t test_vcpop_v_u32m1_tumu(vbool32_t mask, vuint32m1_t maskedoff, vuint32m1_t vs2, size_t vl) { + return __riscv_vcpop_tumu(mask, maskedoff, vs2, vl); } -// CHECK-LABEL: @test_vcpopv_v_u32m2_tumu( +// CHECK-LABEL: @test_vcpop_v_u32m2_tumu( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vcpopv.mask.nxv4i32.i64( [[MASKEDOFF:%.*]], [[VS2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]], i64 0) // CHECK-NEXT: ret [[TMP0]] // -vuint32m2_t test_vcpopv_v_u32m2_tumu(vbool16_t mask, vuint32m2_t maskedoff, vuint32m2_t vs2, size_t vl) { - return __riscv_vcpopv_tumu(mask, maskedoff, vs2, vl); +vuint32m2_t test_vcpop_v_u32m2_tumu(vbool16_t mask, vuint32m2_t maskedoff, vuint32m2_t vs2, size_t vl) { + return __riscv_vcpop_tumu(mask, maskedoff, vs2, vl); } -// CHECK-LABEL: @test_vcpopv_v_u32m4_tumu( +// CHECK-LABEL: @test_vcpop_v_u32m4_tumu( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vcpopv.mask.nxv8i32.i64( [[MASKEDOFF:%.*]], [[VS2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]], i64 0) // CHECK-NEXT: ret [[TMP0]] // -vuint32m4_t test_vcpopv_v_u32m4_tumu(vbool8_t mask, vuint32m4_t maskedoff, vuint32m4_t vs2, size_t vl) { - return __riscv_vcpopv_tumu(mask, maskedoff, vs2, vl); +vuint32m4_t test_vcpop_v_u32m4_tumu(vbool8_t mask, vuint32m4_t maskedoff, vuint32m4_t vs2, size_t vl) { + return __riscv_vcpop_tumu(mask, maskedoff, vs2, vl); } -// CHECK-LABEL: @test_vcpopv_v_u32m8_tumu( +// CHECK-LABEL: @test_vcpop_v_u32m8_tumu( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vcpopv.mask.nxv16i32.i64( [[MASKEDOFF:%.*]], [[VS2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]], i64 0) // CHECK-NEXT: ret [[TMP0]] // -vuint32m8_t test_vcpopv_v_u32m8_tumu(vbool4_t mask, vuint32m8_t maskedoff, vuint32m8_t vs2, size_t vl) { - return __riscv_vcpopv_tumu(mask, maskedoff, vs2, vl); +vuint32m8_t test_vcpop_v_u32m8_tumu(vbool4_t mask, vuint32m8_t maskedoff, vuint32m8_t vs2, size_t vl) { + return __riscv_vcpop_tumu(mask, maskedoff, vs2, vl); } -// CHECK-LABEL: @test_vcpopv_v_u64m1_tumu( +// CHECK-LABEL: @test_vcpop_v_u64m1_tumu( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vcpopv.mask.nxv1i64.i64( [[MASKEDOFF:%.*]], [[VS2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]], i64 0) // CHECK-NEXT: ret [[TMP0]] // -vuint64m1_t test_vcpopv_v_u64m1_tumu(vbool64_t mask, vuint64m1_t maskedoff, vuint64m1_t vs2, size_t vl) { - return __riscv_vcpopv_tumu(mask, maskedoff, vs2, vl); +vuint64m1_t test_vcpop_v_u64m1_tumu(vbool64_t mask, vuint64m1_t maskedoff, vuint64m1_t vs2, size_t vl) { + return __riscv_vcpop_tumu(mask, maskedoff, vs2, vl); } -// CHECK-LABEL: @test_vcpopv_v_u64m2_tumu( +// CHECK-LABEL: @test_vcpop_v_u64m2_tumu( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vcpopv.mask.nxv2i64.i64( [[MASKEDOFF:%.*]], [[VS2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]], i64 0) // CHECK-NEXT: ret [[TMP0]] // -vuint64m2_t test_vcpopv_v_u64m2_tumu(vbool32_t mask, vuint64m2_t maskedoff, vuint64m2_t vs2, size_t vl) { - return __riscv_vcpopv_tumu(mask, maskedoff, vs2, vl); +vuint64m2_t test_vcpop_v_u64m2_tumu(vbool32_t mask, vuint64m2_t maskedoff, vuint64m2_t vs2, size_t vl) { + return __riscv_vcpop_tumu(mask, maskedoff, vs2, vl); } -// CHECK-LABEL: @test_vcpopv_v_u64m4_tumu( +// CHECK-LABEL: @test_vcpop_v_u64m4_tumu( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vcpopv.mask.nxv4i64.i64( [[MASKEDOFF:%.*]], [[VS2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]], i64 0) // CHECK-NEXT: ret [[TMP0]] // -vuint64m4_t test_vcpopv_v_u64m4_tumu(vbool16_t mask, vuint64m4_t maskedoff, vuint64m4_t vs2, size_t vl) { - return __riscv_vcpopv_tumu(mask, maskedoff, vs2, vl); +vuint64m4_t test_vcpop_v_u64m4_tumu(vbool16_t mask, vuint64m4_t maskedoff, vuint64m4_t vs2, size_t vl) { + return __riscv_vcpop_tumu(mask, maskedoff, vs2, vl); } -// CHECK-LABEL: @test_vcpopv_v_u64m8_tumu( +// CHECK-LABEL: @test_vcpop_v_u64m8_tumu( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vcpopv.mask.nxv8i64.i64( [[MASKEDOFF:%.*]], [[VS2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]], i64 0) // CHECK-NEXT: ret [[TMP0]] // -vuint64m8_t test_vcpopv_v_u64m8_tumu(vbool8_t mask, vuint64m8_t maskedoff, vuint64m8_t vs2, size_t vl) { - return __riscv_vcpopv_tumu(mask, maskedoff, vs2, vl); +vuint64m8_t test_vcpop_v_u64m8_tumu(vbool8_t mask, vuint64m8_t maskedoff, vuint64m8_t vs2, size_t vl) { + return __riscv_vcpop_tumu(mask, maskedoff, vs2, vl); } -// CHECK-LABEL: @test_vcpopv_v_u8mf8_mu( +// CHECK-LABEL: @test_vcpop_v_u8mf8_mu( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vcpopv.mask.nxv1i8.i64( [[MASKEDOFF:%.*]], [[VS2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]], i64 1) // CHECK-NEXT: ret [[TMP0]] // -vuint8mf8_t test_vcpopv_v_u8mf8_mu(vbool64_t mask, vuint8mf8_t maskedoff, vuint8mf8_t vs2, size_t vl) { - return __riscv_vcpopv_mu(mask, maskedoff, vs2, vl); +vuint8mf8_t test_vcpop_v_u8mf8_mu(vbool64_t mask, vuint8mf8_t maskedoff, vuint8mf8_t vs2, size_t vl) { + return __riscv_vcpop_mu(mask, maskedoff, vs2, vl); } -// CHECK-LABEL: @test_vcpopv_v_u8mf4_mu( +// CHECK-LABEL: @test_vcpop_v_u8mf4_mu( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vcpopv.mask.nxv2i8.i64( [[MASKEDOFF:%.*]], [[VS2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]], i64 1) // CHECK-NEXT: ret [[TMP0]] // -vuint8mf4_t test_vcpopv_v_u8mf4_mu(vbool32_t mask, vuint8mf4_t maskedoff, vuint8mf4_t vs2, size_t vl) { - return __riscv_vcpopv_mu(mask, maskedoff, vs2, vl); +vuint8mf4_t test_vcpop_v_u8mf4_mu(vbool32_t mask, vuint8mf4_t maskedoff, vuint8mf4_t vs2, size_t vl) { + return __riscv_vcpop_mu(mask, maskedoff, vs2, vl); } -// CHECK-LABEL: @test_vcpopv_v_u8mf2_mu( +// CHECK-LABEL: @test_vcpop_v_u8mf2_mu( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vcpopv.mask.nxv4i8.i64( [[MASKEDOFF:%.*]], [[VS2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]], i64 1) // CHECK-NEXT: ret [[TMP0]] // -vuint8mf2_t test_vcpopv_v_u8mf2_mu(vbool16_t mask, vuint8mf2_t maskedoff, vuint8mf2_t vs2, size_t vl) { - return __riscv_vcpopv_mu(mask, maskedoff, vs2, vl); +vuint8mf2_t test_vcpop_v_u8mf2_mu(vbool16_t mask, vuint8mf2_t maskedoff, vuint8mf2_t vs2, size_t vl) { + return __riscv_vcpop_mu(mask, maskedoff, vs2, vl); } -// CHECK-LABEL: @test_vcpopv_v_u8m1_mu( +// CHECK-LABEL: @test_vcpop_v_u8m1_mu( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vcpopv.mask.nxv8i8.i64( [[MASKEDOFF:%.*]], [[VS2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]], i64 1) // CHECK-NEXT: ret [[TMP0]] // -vuint8m1_t test_vcpopv_v_u8m1_mu(vbool8_t mask, vuint8m1_t maskedoff, vuint8m1_t vs2, size_t vl) { - return __riscv_vcpopv_mu(mask, maskedoff, vs2, vl); +vuint8m1_t test_vcpop_v_u8m1_mu(vbool8_t mask, vuint8m1_t maskedoff, vuint8m1_t vs2, size_t vl) { + return __riscv_vcpop_mu(mask, maskedoff, vs2, vl); } -// CHECK-LABEL: @test_vcpopv_v_u8m2_mu( +// CHECK-LABEL: @test_vcpop_v_u8m2_mu( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vcpopv.mask.nxv16i8.i64( [[MASKEDOFF:%.*]], [[VS2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]], i64 1) // CHECK-NEXT: ret [[TMP0]] // -vuint8m2_t test_vcpopv_v_u8m2_mu(vbool4_t mask, vuint8m2_t maskedoff, vuint8m2_t vs2, size_t vl) { - return __riscv_vcpopv_mu(mask, maskedoff, vs2, vl); +vuint8m2_t test_vcpop_v_u8m2_mu(vbool4_t mask, vuint8m2_t maskedoff, vuint8m2_t vs2, size_t vl) { + return __riscv_vcpop_mu(mask, maskedoff, vs2, vl); } -// CHECK-LABEL: @test_vcpopv_v_u8m4_mu( +// CHECK-LABEL: @test_vcpop_v_u8m4_mu( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vcpopv.mask.nxv32i8.i64( [[MASKEDOFF:%.*]], [[VS2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]], i64 1) // CHECK-NEXT: ret [[TMP0]] // -vuint8m4_t test_vcpopv_v_u8m4_mu(vbool2_t mask, vuint8m4_t maskedoff, vuint8m4_t vs2, size_t vl) { - return __riscv_vcpopv_mu(mask, maskedoff, vs2, vl); +vuint8m4_t test_vcpop_v_u8m4_mu(vbool2_t mask, vuint8m4_t maskedoff, vuint8m4_t vs2, size_t vl) { + return __riscv_vcpop_mu(mask, maskedoff, vs2, vl); } -// CHECK-LABEL: @test_vcpopv_v_u8m8_mu( +// CHECK-LABEL: @test_vcpop_v_u8m8_mu( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vcpopv.mask.nxv64i8.i64( [[MASKEDOFF:%.*]], [[VS2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]], i64 1) // CHECK-NEXT: ret [[TMP0]] // -vuint8m8_t test_vcpopv_v_u8m8_mu(vbool1_t mask, vuint8m8_t maskedoff, vuint8m8_t vs2, size_t vl) { - return __riscv_vcpopv_mu(mask, maskedoff, vs2, vl); +vuint8m8_t test_vcpop_v_u8m8_mu(vbool1_t mask, vuint8m8_t maskedoff, vuint8m8_t vs2, size_t vl) { + return __riscv_vcpop_mu(mask, maskedoff, vs2, vl); } -// CHECK-LABEL: @test_vcpopv_v_u16mf4_mu( +// CHECK-LABEL: @test_vcpop_v_u16mf4_mu( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vcpopv.mask.nxv1i16.i64( [[MASKEDOFF:%.*]], [[VS2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]], i64 1) // CHECK-NEXT: ret [[TMP0]] // -vuint16mf4_t test_vcpopv_v_u16mf4_mu(vbool64_t mask, vuint16mf4_t maskedoff, vuint16mf4_t vs2, size_t vl) { - return __riscv_vcpopv_mu(mask, maskedoff, vs2, vl); +vuint16mf4_t test_vcpop_v_u16mf4_mu(vbool64_t mask, vuint16mf4_t maskedoff, vuint16mf4_t vs2, size_t vl) { + return __riscv_vcpop_mu(mask, maskedoff, vs2, vl); } -// CHECK-LABEL: @test_vcpopv_v_u16mf2_mu( +// CHECK-LABEL: @test_vcpop_v_u16mf2_mu( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vcpopv.mask.nxv2i16.i64( [[MASKEDOFF:%.*]], [[VS2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]], i64 1) // CHECK-NEXT: ret [[TMP0]] // -vuint16mf2_t test_vcpopv_v_u16mf2_mu(vbool32_t mask, vuint16mf2_t maskedoff, vuint16mf2_t vs2, size_t vl) { - return __riscv_vcpopv_mu(mask, maskedoff, vs2, vl); +vuint16mf2_t test_vcpop_v_u16mf2_mu(vbool32_t mask, vuint16mf2_t maskedoff, vuint16mf2_t vs2, size_t vl) { + return __riscv_vcpop_mu(mask, maskedoff, vs2, vl); } -// CHECK-LABEL: @test_vcpopv_v_u16m1_mu( +// CHECK-LABEL: @test_vcpop_v_u16m1_mu( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vcpopv.mask.nxv4i16.i64( [[MASKEDOFF:%.*]], [[VS2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]], i64 1) // CHECK-NEXT: ret [[TMP0]] // -vuint16m1_t test_vcpopv_v_u16m1_mu(vbool16_t mask, vuint16m1_t maskedoff, vuint16m1_t vs2, size_t vl) { - return __riscv_vcpopv_mu(mask, maskedoff, vs2, vl); +vuint16m1_t test_vcpop_v_u16m1_mu(vbool16_t mask, vuint16m1_t maskedoff, vuint16m1_t vs2, size_t vl) { + return __riscv_vcpop_mu(mask, maskedoff, vs2, vl); } -// CHECK-LABEL: @test_vcpopv_v_u16m2_mu( +// CHECK-LABEL: @test_vcpop_v_u16m2_mu( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vcpopv.mask.nxv8i16.i64( [[MASKEDOFF:%.*]], [[VS2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]], i64 1) // CHECK-NEXT: ret [[TMP0]] // -vuint16m2_t test_vcpopv_v_u16m2_mu(vbool8_t mask, vuint16m2_t maskedoff, vuint16m2_t vs2, size_t vl) { - return __riscv_vcpopv_mu(mask, maskedoff, vs2, vl); +vuint16m2_t test_vcpop_v_u16m2_mu(vbool8_t mask, vuint16m2_t maskedoff, vuint16m2_t vs2, size_t vl) { + return __riscv_vcpop_mu(mask, maskedoff, vs2, vl); } -// CHECK-LABEL: @test_vcpopv_v_u16m4_mu( +// CHECK-LABEL: @test_vcpop_v_u16m4_mu( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vcpopv.mask.nxv16i16.i64( [[MASKEDOFF:%.*]], [[VS2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]], i64 1) // CHECK-NEXT: ret [[TMP0]] // -vuint16m4_t test_vcpopv_v_u16m4_mu(vbool4_t mask, vuint16m4_t maskedoff, vuint16m4_t vs2, size_t vl) { - return __riscv_vcpopv_mu(mask, maskedoff, vs2, vl); +vuint16m4_t test_vcpop_v_u16m4_mu(vbool4_t mask, vuint16m4_t maskedoff, vuint16m4_t vs2, size_t vl) { + return __riscv_vcpop_mu(mask, maskedoff, vs2, vl); } -// CHECK-LABEL: @test_vcpopv_v_u16m8_mu( +// CHECK-LABEL: @test_vcpop_v_u16m8_mu( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vcpopv.mask.nxv32i16.i64( [[MASKEDOFF:%.*]], [[VS2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]], i64 1) // CHECK-NEXT: ret [[TMP0]] // -vuint16m8_t test_vcpopv_v_u16m8_mu(vbool2_t mask, vuint16m8_t maskedoff, vuint16m8_t vs2, size_t vl) { - return __riscv_vcpopv_mu(mask, maskedoff, vs2, vl); +vuint16m8_t test_vcpop_v_u16m8_mu(vbool2_t mask, vuint16m8_t maskedoff, vuint16m8_t vs2, size_t vl) { + return __riscv_vcpop_mu(mask, maskedoff, vs2, vl); } -// CHECK-LABEL: @test_vcpopv_v_u32mf2_mu( +// CHECK-LABEL: @test_vcpop_v_u32mf2_mu( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vcpopv.mask.nxv1i32.i64( [[MASKEDOFF:%.*]], [[VS2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]], i64 1) // CHECK-NEXT: ret [[TMP0]] // -vuint32mf2_t test_vcpopv_v_u32mf2_mu(vbool64_t mask, vuint32mf2_t maskedoff, vuint32mf2_t vs2, size_t vl) { - return __riscv_vcpopv_mu(mask, maskedoff, vs2, vl); +vuint32mf2_t test_vcpop_v_u32mf2_mu(vbool64_t mask, vuint32mf2_t maskedoff, vuint32mf2_t vs2, size_t vl) { + return __riscv_vcpop_mu(mask, maskedoff, vs2, vl); } -// CHECK-LABEL: @test_vcpopv_v_u32m1_mu( +// CHECK-LABEL: @test_vcpop_v_u32m1_mu( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vcpopv.mask.nxv2i32.i64( [[MASKEDOFF:%.*]], [[VS2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]], i64 1) // CHECK-NEXT: ret [[TMP0]] // -vuint32m1_t test_vcpopv_v_u32m1_mu(vbool32_t mask, vuint32m1_t maskedoff, vuint32m1_t vs2, size_t vl) { - return __riscv_vcpopv_mu(mask, maskedoff, vs2, vl); +vuint32m1_t test_vcpop_v_u32m1_mu(vbool32_t mask, vuint32m1_t maskedoff, vuint32m1_t vs2, size_t vl) { + return __riscv_vcpop_mu(mask, maskedoff, vs2, vl); } -// CHECK-LABEL: @test_vcpopv_v_u32m2_mu( +// CHECK-LABEL: @test_vcpop_v_u32m2_mu( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vcpopv.mask.nxv4i32.i64( [[MASKEDOFF:%.*]], [[VS2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]], i64 1) // CHECK-NEXT: ret [[TMP0]] // -vuint32m2_t test_vcpopv_v_u32m2_mu(vbool16_t mask, vuint32m2_t maskedoff, vuint32m2_t vs2, size_t vl) { - return __riscv_vcpopv_mu(mask, maskedoff, vs2, vl); +vuint32m2_t test_vcpop_v_u32m2_mu(vbool16_t mask, vuint32m2_t maskedoff, vuint32m2_t vs2, size_t vl) { + return __riscv_vcpop_mu(mask, maskedoff, vs2, vl); } -// CHECK-LABEL: @test_vcpopv_v_u32m4_mu( +// CHECK-LABEL: @test_vcpop_v_u32m4_mu( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vcpopv.mask.nxv8i32.i64( [[MASKEDOFF:%.*]], [[VS2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]], i64 1) // CHECK-NEXT: ret [[TMP0]] // -vuint32m4_t test_vcpopv_v_u32m4_mu(vbool8_t mask, vuint32m4_t maskedoff, vuint32m4_t vs2, size_t vl) { - return __riscv_vcpopv_mu(mask, maskedoff, vs2, vl); +vuint32m4_t test_vcpop_v_u32m4_mu(vbool8_t mask, vuint32m4_t maskedoff, vuint32m4_t vs2, size_t vl) { + return __riscv_vcpop_mu(mask, maskedoff, vs2, vl); } -// CHECK-LABEL: @test_vcpopv_v_u32m8_mu( +// CHECK-LABEL: @test_vcpop_v_u32m8_mu( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vcpopv.mask.nxv16i32.i64( [[MASKEDOFF:%.*]], [[VS2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]], i64 1) // CHECK-NEXT: ret [[TMP0]] // -vuint32m8_t test_vcpopv_v_u32m8_mu(vbool4_t mask, vuint32m8_t maskedoff, vuint32m8_t vs2, size_t vl) { - return __riscv_vcpopv_mu(mask, maskedoff, vs2, vl); +vuint32m8_t test_vcpop_v_u32m8_mu(vbool4_t mask, vuint32m8_t maskedoff, vuint32m8_t vs2, size_t vl) { + return __riscv_vcpop_mu(mask, maskedoff, vs2, vl); } -// CHECK-LABEL: @test_vcpopv_v_u64m1_mu( +// CHECK-LABEL: @test_vcpop_v_u64m1_mu( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vcpopv.mask.nxv1i64.i64( [[MASKEDOFF:%.*]], [[VS2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]], i64 1) // CHECK-NEXT: ret [[TMP0]] // -vuint64m1_t test_vcpopv_v_u64m1_mu(vbool64_t mask, vuint64m1_t maskedoff, vuint64m1_t vs2, size_t vl) { - return __riscv_vcpopv_mu(mask, maskedoff, vs2, vl); +vuint64m1_t test_vcpop_v_u64m1_mu(vbool64_t mask, vuint64m1_t maskedoff, vuint64m1_t vs2, size_t vl) { + return __riscv_vcpop_mu(mask, maskedoff, vs2, vl); } -// CHECK-LABEL: @test_vcpopv_v_u64m2_mu( +// CHECK-LABEL: @test_vcpop_v_u64m2_mu( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vcpopv.mask.nxv2i64.i64( [[MASKEDOFF:%.*]], [[VS2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]], i64 1) // CHECK-NEXT: ret [[TMP0]] // -vuint64m2_t test_vcpopv_v_u64m2_mu(vbool32_t mask, vuint64m2_t maskedoff, vuint64m2_t vs2, size_t vl) { - return __riscv_vcpopv_mu(mask, maskedoff, vs2, vl); +vuint64m2_t test_vcpop_v_u64m2_mu(vbool32_t mask, vuint64m2_t maskedoff, vuint64m2_t vs2, size_t vl) { + return __riscv_vcpop_mu(mask, maskedoff, vs2, vl); } -// CHECK-LABEL: @test_vcpopv_v_u64m4_mu( +// CHECK-LABEL: @test_vcpop_v_u64m4_mu( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vcpopv.mask.nxv4i64.i64( [[MASKEDOFF:%.*]], [[VS2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]], i64 1) // CHECK-NEXT: ret [[TMP0]] // -vuint64m4_t test_vcpopv_v_u64m4_mu(vbool16_t mask, vuint64m4_t maskedoff, vuint64m4_t vs2, size_t vl) { - return __riscv_vcpopv_mu(mask, maskedoff, vs2, vl); +vuint64m4_t test_vcpop_v_u64m4_mu(vbool16_t mask, vuint64m4_t maskedoff, vuint64m4_t vs2, size_t vl) { + return __riscv_vcpop_mu(mask, maskedoff, vs2, vl); } -// CHECK-LABEL: @test_vcpopv_v_u64m8_mu( +// CHECK-LABEL: @test_vcpop_v_u64m8_mu( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vcpopv.mask.nxv8i64.i64( [[MASKEDOFF:%.*]], [[VS2:%.*]], [[MASK:%.*]], i64 [[VL:%.*]], i64 1) // CHECK-NEXT: ret [[TMP0]] // -vuint64m8_t test_vcpopv_v_u64m8_mu(vbool8_t mask, vuint64m8_t maskedoff, vuint64m8_t vs2, size_t vl) { - return __riscv_vcpopv_mu(mask, maskedoff, vs2, vl); +vuint64m8_t test_vcpop_v_u64m8_mu(vbool8_t mask, vuint64m8_t maskedoff, vuint64m8_t vs2, size_t vl) { + return __riscv_vcpop_mu(mask, maskedoff, vs2, vl); } diff --git a/clang/test/CodeGen/X86/math-builtins.c b/clang/test/CodeGen/X86/math-builtins.c index 093239b448260906c0ed0058e97921af3b40a1c2..1e0f129b986102691958fe63a0960f6b694a03c4 100644 --- a/clang/test/CodeGen/X86/math-builtins.c +++ b/clang/test/CodeGen/X86/math-builtins.c @@ -674,10 +674,10 @@ __builtin_sqrt(f); __builtin_sqrtf(f); __builtin_sqrtl(f); __builtin_ __builtin_tan(f); __builtin_tanf(f); __builtin_tanl(f); __builtin_tanf128(f); -// NO__ERRNO: declare double @tan(double noundef) [[READNONE]] -// NO__ERRNO: declare float @tanf(float noundef) [[READNONE]] -// NO__ERRNO: declare x86_fp80 @tanl(x86_fp80 noundef) [[READNONE]] -// NO__ERRNO: declare fp128 @tanf128(fp128 noundef) [[READNONE]] +// NO__ERRNO: declare double @llvm.tan.f64(double) [[READNONE_INTRINSIC]] +// NO__ERRNO: declare float @llvm.tan.f32(float) [[READNONE_INTRINSIC]] +// NO__ERRNO: declare x86_fp80 @llvm.tan.f80(x86_fp80) [[READNONE_INTRINSIC]] +// NO__ERRNO: declare fp128 @llvm.tan.f128(fp128) [[READNONE_INTRINSIC]] // HAS_ERRNO: declare double @tan(double noundef) [[NOT_READNONE]] // HAS_ERRNO: declare float @tanf(float noundef) [[NOT_READNONE]] // HAS_ERRNO: declare x86_fp80 @tanl(x86_fp80 noundef) [[NOT_READNONE]] diff --git a/clang/test/CodeGen/constrained-math-builtins.c b/clang/test/CodeGen/constrained-math-builtins.c index 2de832dd2b6cae116b65fc0565fdaf6415ba4d05..6cc3a10a1e7946f360dca81156c0b89f6d1e3b7d 100644 --- a/clang/test/CodeGen/constrained-math-builtins.c +++ b/clang/test/CodeGen/constrained-math-builtins.c @@ -183,6 +183,14 @@ void foo(double *d, float f, float *fp, long double *l, int *i, const char *c, _ // CHECK: call x86_fp80 @llvm.experimental.constrained.sqrt.f80(x86_fp80 %{{.*}}, metadata !"round.tonearest", metadata !"fpexcept.strict") // CHECK: call fp128 @llvm.experimental.constrained.sqrt.f128(fp128 %{{.*}}, metadata !"round.tonearest", metadata !"fpexcept.strict") + __builtin_tan(f); __builtin_tanf(f); __builtin_tanl(f); __builtin_tanf128(f); + +// CHECK: call double @llvm.experimental.constrained.tan.f64(double %{{.*}}, metadata !"round.tonearest", metadata !"fpexcept.strict") +// CHECK: call float @llvm.experimental.constrained.tan.f32(float %{{.*}}, metadata !"round.tonearest", metadata !"fpexcept.strict") +// CHECK: call x86_fp80 @llvm.experimental.constrained.tan.f80(x86_fp80 %{{.*}}, metadata !"round.tonearest", metadata !"fpexcept.strict") +// CHECK: call fp128 @llvm.experimental.constrained.tan.f128(fp128 %{{.*}}, metadata !"round.tonearest", metadata !"fpexcept.strict") + + __builtin_trunc(f); __builtin_truncf(f); __builtin_truncl(f); __builtin_truncf128(f); // CHECK: call double @llvm.experimental.constrained.trunc.f64(double %{{.*}}, metadata !"fpexcept.strict") @@ -315,6 +323,11 @@ void foo(double *d, float f, float *fp, long double *l, int *i, const char *c, _ // CHECK: declare x86_fp80 @llvm.experimental.constrained.sqrt.f80(x86_fp80, metadata, metadata) // CHECK: declare fp128 @llvm.experimental.constrained.sqrt.f128(fp128, metadata, metadata) +// CHECK: declare double @llvm.experimental.constrained.tan.f64(double, metadata, metadata) +// CHECK: declare float @llvm.experimental.constrained.tan.f32(float, metadata, metadata) +// CHECK: declare x86_fp80 @llvm.experimental.constrained.tan.f80(x86_fp80, metadata, metadata) +// CHECK: declare fp128 @llvm.experimental.constrained.tan.f128(fp128, metadata, metadata) + // CHECK: declare double @llvm.experimental.constrained.trunc.f64(double, metadata) // CHECK: declare float @llvm.experimental.constrained.trunc.f32(float, metadata) // CHECK: declare x86_fp80 @llvm.experimental.constrained.trunc.f80(x86_fp80, metadata) diff --git a/clang/test/CodeGen/debug-info-packed-struct.c b/clang/test/CodeGen/debug-info-packed-struct.c index 6441a740e3799f32b66bbb6804201894d25a4ab7..676cdb38b396f29cc00b0f9724c17bfb00b50932 100644 --- a/clang/test/CodeGen/debug-info-packed-struct.c +++ b/clang/test/CodeGen/debug-info-packed-struct.c @@ -59,7 +59,7 @@ struct layout2 { #pragma pack() // CHECK: l2_ofs0 // CHECK: !DIDerivedType(tag: DW_TAG_member, name: "l2_ofs1", -// CHECK-SAME: {{.*}}size: 64, offset: 8) +// CHECK-SAME: {{.*}}size: 64, align: 8, offset: 8) // CHECK: !DIDerivedType(tag: DW_TAG_member, name: "l2_ofs9", // CHECK-SAME: {{.*}}size: 1, offset: 72, flags: DIFlagBitField, extraData: i64 72) @@ -81,7 +81,7 @@ struct layout3 { #pragma pack() // CHECK: l3_ofs0 // CHECK: !DIDerivedType(tag: DW_TAG_member, name: "l3_ofs4", -// CHECK-SAME: {{.*}}size: 64, offset: 32) +// CHECK-SAME: {{.*}}size: 64, align: 32, offset: 32) // CHECK: !DIDerivedType(tag: DW_TAG_member, name: "l3_ofs12", // CHECK-SAME: {{.*}}size: 1, offset: 96, flags: DIFlagBitField, extraData: i64 96) diff --git a/clang/test/CodeGen/math-libcalls.c b/clang/test/CodeGen/math-libcalls.c index 29c312ba0ecac2d13534fa9fcb399be6d6903800..a249182692762d10bc7c98f3b3865c9e14617d77 100644 --- a/clang/test/CodeGen/math-libcalls.c +++ b/clang/test/CodeGen/math-libcalls.c @@ -662,15 +662,15 @@ void foo(double *d, float f, float *fp, long double *l, int *i, const char *c) { tan(f); tanf(f); tanl(f); -// NO__ERRNO: declare double @tan(double noundef) [[READNONE]] -// NO__ERRNO: declare float @tanf(float noundef) [[READNONE]] -// NO__ERRNO: declare x86_fp80 @tanl(x86_fp80 noundef) [[READNONE]] +// NO__ERRNO: declare double @llvm.tan.f64(double) [[READNONE_INTRINSIC]] +// NO__ERRNO: declare float @llvm.tan.f32(float) [[READNONE_INTRINSIC]] +// NO__ERRNO: declare x86_fp80 @llvm.tan.f80(x86_fp80) [[READNONE_INTRINSIC]] // HAS_ERRNO: declare double @tan(double noundef) [[NOT_READNONE]] // HAS_ERRNO: declare float @tanf(float noundef) [[NOT_READNONE]] // HAS_ERRNO: declare x86_fp80 @tanl(x86_fp80 noundef) [[NOT_READNONE]] -// HAS_MAYTRAP: declare double @tan(double noundef) [[NOT_READNONE]] -// HAS_MAYTRAP: declare float @tanf(float noundef) [[NOT_READNONE]] -// HAS_MAYTRAP: declare x86_fp80 @tanl(x86_fp80 noundef) [[NOT_READNONE]] +// HAS_MAYTRAP: declare double @llvm.experimental.constrained.tan.f64( +// HAS_MAYTRAP: declare float @llvm.experimental.constrained.tan.f32( +// HAS_MAYTRAP: declare x86_fp80 @llvm.experimental.constrained.tan.f80( tanh(f); tanhf(f); tanhl(f); diff --git a/clang/test/CodeGen/paren-list-agg-init.cpp b/clang/test/CodeGen/paren-list-agg-init.cpp index 94d42431d125d45141c1646ef2128a5c8acc9628..88b1834d42d879191941b8ab7acd34dd0c31cdf2 100644 --- a/clang/test/CodeGen/paren-list-agg-init.cpp +++ b/clang/test/CodeGen/paren-list-agg-init.cpp @@ -271,14 +271,13 @@ const int* foo10() { // CHECK-NEXT: [[ARR_2:%.*]] = alloca [4 x i32], align 16 // CHECK-NEXT: store i32 [[A:%.*]], ptr [[A_ADDR]], align 4 // CHECK-NEXT: store i32 [[B:%.*]], ptr [[B_ADDR]], align 4 -// CHECK-NEXT: [[ARRINIT_BEGIN:%.*]] = getelementptr inbounds [4 x i32], ptr [[ARR_2]], i64 0, i64 0 // CHECK-NEXT: [[TMP_0:%.*]] = load i32, ptr [[A_ADDR]], align 4 -// CHECK-NEXT: store i32 [[TMP_0]], ptr [[ARRINIT_BEGIN]], align 4 -// CHECK-NEXT: [[ARRINIT_ELEM:%.*]] = getelementptr inbounds i32, ptr [[ARRINIT_BEGIN]], i64 1 +// CHECK-NEXT: store i32 [[TMP_0]], ptr [[ARR_2]], align 4 +// CHECK-NEXT: [[ARRINIT_ELEM:%.*]] = getelementptr inbounds i32, ptr [[ARR_2]], i64 1 // CHECK-NEXT: [[TMP_1:%.*]] = load i32, ptr [[B_ADDR]], align 4 // CHECK-NEXT: store i32 [[TMP_1]], ptr [[ARRINIT_ELEM]], align 4 -// CHECK-NEXT: [[ARRINIT_START:%.*]] = getelementptr inbounds i32, ptr [[ARRINIT_ELEM]], i64 1 -// CHECK-NEXT: [[ARRINIT_END:%.*]] = getelementptr inbounds i32, ptr [[ARRINIT_BEGIN]], i64 4 +// CHECK-NEXT: [[ARRINIT_START:%.*]] = getelementptr inbounds i32, ptr [[ARR_2]], i64 2 +// CHECK-NEXT: [[ARRINIT_END:%.*]] = getelementptr inbounds i32, ptr [[ARR_2]], i64 4 // CHECK-NEXT: br label [[ARRINIT_BODY:%.*]] // CHECK: [[ARRINIT_CUR:%.*]] = phi ptr [ [[ARRINIT_START]], %entry ], [ [[ARRINIT_NEXT:%.*]], [[ARRINIT_BODY]] ] // CHECK-NEXT: store i32 0, ptr [[ARRINIT_CUR]], align 4 @@ -297,10 +296,9 @@ void foo11(int a, int b) { // CHECK-NEXT: [[ARR_3:%.*]] = alloca [2 x i32], align 4 // CHECK-NEXT: store i32 [[A:%.*]], ptr [[A_ADDR]], align 4 // CHECK-NEXT: store i32 [[B:%.*]], ptr [[B_ADDR]], align 4 -// CHECK-NEXT: [[ARRINIT_BEGIN:%.*]] = getelementptr inbounds [2 x i32], ptr [[ARR_3]], i64 0, i64 0 // CHECK-NEXT: [[TMP_0:%.*]] = load i32, ptr [[A_ADDR]], align 4 -// CHECK-NEXT: store i32 [[TMP_0]], ptr [[ARRINIT_BEGIN]], align 4 -// CHECK-NEXT: [[ARRINIT_ELEMENT:%.*]] = getelementptr inbounds i32, ptr [[ARRINIT_BEGIN]], i64 1 +// CHECK-NEXT: store i32 [[TMP_0]], ptr [[ARR_3]], align 4 +// CHECK-NEXT: [[ARRINIT_ELEMENT:%.*]] = getelementptr inbounds i32, ptr [[ARR_3]], i64 1 // CHECK-NEXT: [[TMP_1:%.*]] = load i32, ptr [[B_ADDR]], align 4 // CHECK-NEXT: store i32 [[TMP_1]], ptr [[ARRINIT_ELEMENT]], align 4 // CHECK-NEXT: ret void @@ -336,8 +334,7 @@ const int* foo15() { // CHECK-NEXT: entry: // CHECK-NEXT: [[ARR_6:%.*arr6.*]] = alloca ptr, align 8 // CHECK-NEXT: [[REF_TMP:%.*]] = alloca [1 x i32], align 4 -// CHECK-NEXT: [[ARRINIT_BEGIN:%.*]] = getelementptr inbounds [1 x i32], ptr [[REF_TMP]], i64 0, i64 0 -// CHECK-NEXT: store i32 3, ptr [[ARRINIT_BEGIN]], align 4 +// CHECK-NEXT: store i32 3, ptr [[REF_TMP]], align 4 // CHECK-NEXT: store ptr [[REF_TMP]], ptr [[ARR_6]], align 8 // CHECK-NEXT: ret void void foo16() { @@ -348,10 +345,9 @@ void foo16() { // CHECK-NEXT: entry: // CHECK-NEXT: [[ARR_7:%.*arr7.*]] = alloca ptr, align 8 // CHECK-NEXT: [[REF_TMP:%.*]] = alloca [2 x i32], align 4 -// CHECK-NEXT: [[ARRINIT_BEGIN:%.*]] = getelementptr inbounds [2 x i32], ptr [[REF_TMP]], i64 0, i64 0 -// CHECK-NEXT: store i32 4, ptr [[ARRINIT_BEGIN]], align 4 -// CHECK-NEXT: [[ARRINIT_START:%.*]] = getelementptr inbounds i32, ptr [[ARRINIT_BEGIN]], i64 1 -// CHECK-NEXT: [[ARRINIT_END:%.*]] = getelementptr inbounds i32, ptr [[ARRINIT_BEGIN]], i64 2 +// CHECK-NEXT: store i32 4, ptr [[REF_TMP]], align 4 +// CHECK-NEXT: [[ARRINIT_START:%.*]] = getelementptr inbounds i32, ptr [[REF_TMP]], i64 1 +// CHECK-NEXT: [[ARRINIT_END:%.*]] = getelementptr inbounds i32, ptr [[REF_TMP]], i64 2 // CHECK-NEXT: br label [[ARRINIT_BODY]] // CHECK: [[ARRINIT_CUR:%.*]] = phi ptr [ [[ARRINIT_START]], %entry ], [ [[ARRINIT_NEXT:%.*]], [[ARRINIT_BODY]] ] // CHECK-NEXT: store i32 0, ptr [[ARRINIT_CUR]], align 4 @@ -533,14 +529,12 @@ namespace gh68198 { // CHECK-NEXT: entry // CHECK-NEXT: [[ARR_10:%.*arr9.*]] = alloca ptr, align 8 // CHECK-NEXT: [[CALL_PTR]] = call noalias noundef nonnull ptr @_Znam(i64 noundef 16) - // CHECK-NEXT: [[ARRAYINIT_BEGIN:%.*]] = getelementptr inbounds [2 x i32], ptr [[CALL]], i64 0, i64 0 - // CHECK-NEXT: store i32 1, ptr [[ARRAYINIT_BEGIN]], align 4 - // CHECK-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds i32, ptr [[ARRAYINIT_BEGIN]], i64 1 + // CHECK-NEXT: store i32 1, ptr [[CALL]], align 4 + // CHECK-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds i32, ptr [[CALL]], i64 1 // CHECK-NEXT: store i32 2, ptr [[ARRAYINIT_ELEMENT]], align 4 // CHECK-NEXT: [[ARRAY_EXP_NEXT:%.*]] = getelementptr inbounds [2 x i32], ptr %call, i64 1 - // CHECK-NEXT: [[ARRAYINIT_BEGIN1:%.*]] = getelementptr inbounds [2 x i32], ptr [[ARRAY_EXP_NEXT]], i64 0, i64 0 - // CHECK-NEXT: store i32 3, ptr [[ARRAYINIT_BEGIN1]], align 4 - // CHECK-NEXT: [[ARRAYINIT_ELEMENT2:%.*]] = getelementptr inbounds i32, ptr [[ARRAYINIT_BEGIN1]], i64 1 + // CHECK-NEXT: store i32 3, ptr [[ARRAY_EXP_NEXT]], align 4 + // CHECK-NEXT: [[ARRAYINIT_ELEMENT2:%.*]] = getelementptr inbounds i32, ptr [[ARRAY_EXP_NEXT]], i64 1 // CHECK-NEXT: store i32 4, ptr [[ARRAYINIT_ELEMENT2]], align 4 // CHECK-NEXT: [[ARRAY_EXP_NEXT3:%.*]] = getelementptr inbounds [2 x i32], ptr [[ARRAY_EXP_NEXT]], i64 1 // CHECK-NEXT: store ptr [[CALL_PTR]], ptr [[ARR_10]], align 8 @@ -553,14 +547,12 @@ namespace gh68198 { // CHECK-NEXT: entry // CHECK-NEXT: [[ARR_10:%.*arr10.*]] = alloca ptr, align 8 // CHECK-NEXT: [[CALL_PTR]] = call noalias noundef nonnull ptr @_Znam(i64 noundef 32) - // CHECK-NEXT: [[ARRAYINIT_BEGIN:%.*]] = getelementptr inbounds [2 x i32], ptr [[CALL]], i64 0, i64 0 - // CHECK-NEXT: store i32 5, ptr [[ARRAYINIT_BEGIN]], align 4 - // CHECK-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds i32, ptr [[ARRAYINIT_BEGIN]], i64 1 + // CHECK-NEXT: store i32 5, ptr [[CALL]], align 4 + // CHECK-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds i32, ptr [[CALL]], i64 1 // CHECK-NEXT: store i32 6, ptr [[ARRAYINIT_ELEMENT]], align 4 // CHECK-NEXT: [[ARRAY_EXP_NEXT:%.*]] = getelementptr inbounds [2 x i32], ptr %call, i64 1 - // CHECK-NEXT: [[ARRAYINIT_BEGIN1:%.*]] = getelementptr inbounds [2 x i32], ptr [[ARRAY_EXP_NEXT]], i64 0, i64 0 - // CHECK-NEXT: store i32 7, ptr [[ARRAYINIT_BEGIN1]], align 4 - // CHECK-NEXT: [[ARRAYINIT_ELEMENT2:%.*]] = getelementptr inbounds i32, ptr [[ARRAYINIT_BEGIN1]], i64 1 + // CHECK-NEXT: store i32 7, ptr [[ARRAY_EXP_NEXT]], align 4 + // CHECK-NEXT: [[ARRAYINIT_ELEMENT2:%.*]] = getelementptr inbounds i32, ptr [[ARRAY_EXP_NEXT]], i64 1 // CHECK-NEXT: store i32 8, ptr [[ARRAYINIT_ELEMENT2]], align 4 // CHECK-NEXT: [[ARRAY_EXP_NEXT3:%.*]] = getelementptr inbounds [2 x i32], ptr [[ARRAY_EXP_NEXT]], i64 1 // CHECK-NEXT: call void @llvm.memset.p0.i64(ptr align 4 [[ARRAY_EXP_NEXT3]], i8 0, i64 16, i1 false) diff --git a/clang/test/CodeGen/sanitize-numerical-stability-attr.cpp b/clang/test/CodeGen/sanitize-numerical-stability-attr.cpp new file mode 100644 index 0000000000000000000000000000000000000000..f51fb79bda6afdb901493beb1bec4d0db9ad77c0 --- /dev/null +++ b/clang/test/CodeGen/sanitize-numerical-stability-attr.cpp @@ -0,0 +1,34 @@ +// RUN: %clang_cc1 -triple x86_64-apple-darwin -emit-llvm -o - %s | FileCheck -check-prefix=WITHOUT %s +// RUN: %clang_cc1 -triple x86_64-apple-darwin -emit-llvm -o - %s -fsanitize=numerical | FileCheck -check-prefix=NSAN %s +// RUN: echo "src:%s" | sed -e 's/\\/\\\\/g' > %t +// RUN: %clang_cc1 -triple x86_64-apple-darwin -emit-llvm -o - %s -fsanitize=numerical -fsanitize-ignorelist=%t | FileCheck -check-prefix=BL %s + +// WITHOUT: NoNSAN3{{.*}}) [[NOATTR:#[0-9]+]] +// BL: NoNSAN3{{.*}}) [[NOATTR:#[0-9]+]] +// NSAN: NoNSAN3{{.*}}) [[NOATTR:#[0-9]+]] +__attribute__((no_sanitize("numerical"))) +int NoNSAN3(int *a) { return *a; } + +// WITHOUT: NSANOk{{.*}}) [[NOATTR]] +// BL: NSANOk{{.*}}) [[NOATTR]] +// NSAN: NSANOk{{.*}}) [[WITH:#[0-9]+]] +int NSANOk(int *a) { return *a; } + +// WITHOUT: TemplateNSANOk{{.*}}) [[NOATTR]] +// BL: TemplateNSANOk{{.*}}) [[NOATTR]] +// NSAN: TemplateNSANOk{{.*}}) [[WITH]] +template +int TemplateNSANOk() { return i; } + +// WITHOUT: TemplateNoNSAN{{.*}}) [[NOATTR]] +// BL: TemplateNoNSAN{{.*}}) [[NOATTR]] +// NSAN: TemplateNoNSAN{{.*}}) [[NOATTR]] +template +__attribute__((no_sanitize("numerical"))) +int TemplateNoNSAN() { return i; } + +int force_instance = TemplateNSANOk<42>() + TemplateNoNSAN<42>(); + +// WITHOUT: attributes [[NOATTR]] = { mustprogress noinline nounwind{{.*}} } +// BL: attributes [[NOATTR]] = { mustprogress noinline nounwind{{.*}} } +// NSAN: attributes [[WITH]] = { mustprogress noinline nounwind optnone sanitize_numerical_stability{{.*}} } diff --git a/clang/test/CodeGen/target-data.c b/clang/test/CodeGen/target-data.c index 9d86880d6513e036d199ce5e48552fbc243c683b..7f7005d21b99a3bd9ef043f56d5dbc5e7a768bbf 100644 --- a/clang/test/CodeGen/target-data.c +++ b/clang/test/CodeGen/target-data.c @@ -268,3 +268,7 @@ // RUN: %clang_cc1 -triple ve -o - -emit-llvm %s | \ // RUN: FileCheck %s -check-prefix=VE // VE: target datalayout = "e-m:e-i64:64-n32:64-S128-v64:64:64-v128:64:64-v256:64:64-v512:64:64-v1024:64:64-v2048:64:64-v4096:64:64-v8192:64:64-v16384:64:64" + +// RUN: %clang_cc1 -triple spirv64-amd -o - -emit-llvm %s | \ +// RUN: FileCheck %s -check-prefix=SPIR64 +// AMDGPUSPIRV64: target datalayout = "e-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-G1-P4-A0" diff --git a/clang/test/CodeGen/voidptr-vaarg.c b/clang/test/CodeGen/voidptr-vaarg.c new file mode 100644 index 0000000000000000000000000000000000000000..d023ddf0fb5d2d2aa6fde6c06d9a29f5bc4a3f54 --- /dev/null +++ b/clang/test/CodeGen/voidptr-vaarg.c @@ -0,0 +1,478 @@ +// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py +// REQUIRES: webassembly-registered-target +// RUN: %clang_cc1 -triple wasm32-unknown-unknown -emit-llvm -o - %s | FileCheck %s + +// Multiple targets use emitVoidPtrVAArg to lower va_arg instructions in clang +// PPC is complicated, excluding from this case analysis +// ForceRightAdjust is false for all non-PPC targets +// AllowHigherAlign is only false for two Microsoft targets, both of which +// pass most things by reference. +// +// Address emitVoidPtrVAArg(CodeGenFunction &CGF, Address VAListAddr, +// QualType ValueTy, bool IsIndirect, +// TypeInfoChars ValueInfo, CharUnits SlotSizeAndAlign, +// bool AllowHigherAlign, bool ForceRightAdjust = +// false); +// +// Target IsIndirect SlotSize AllowHigher ForceRightAdjust +// ARC false four true false +// ARM varies four true false +// Mips false 4 or 8 true false +// RISCV varies register true false +// PPC elided +// LoongArch varies register true false +// NVPTX WIP +// AMDGPU WIP +// X86_32 false four true false +// X86_64 MS varies eight false false +// CSKY false four true false +// Webassembly varies four true false +// AArch64 false eight true false +// AArch64 MS false eight false false +// +// Webassembly passes indirectly iff it's an aggregate of multiple values +// Choosing this as a representative architecture to check IR generation +// partly because it has a relatively simple variadic calling convention. + +// Int, by itself and packed in structs +// CHECK-LABEL: @raw_int( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[LIST_ADDR:%.*]] = alloca ptr, align 4 +// CHECK-NEXT: store ptr [[LIST:%.*]], ptr [[LIST_ADDR]], align 4 +// CHECK-NEXT: [[ARGP_CUR:%.*]] = load ptr, ptr [[LIST_ADDR]], align 4 +// CHECK-NEXT: [[ARGP_NEXT:%.*]] = getelementptr inbounds i8, ptr [[ARGP_CUR]], i32 4 +// CHECK-NEXT: store ptr [[ARGP_NEXT]], ptr [[LIST_ADDR]], align 4 +// CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[ARGP_CUR]], align 4 +// CHECK-NEXT: ret i32 [[TMP0]] +// +int raw_int(__builtin_va_list list) { return __builtin_va_arg(list, int); } + +typedef struct { + int x; +} one_int_t; + +// CHECK-LABEL: @one_int( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[RETVAL:%.*]] = alloca [[STRUCT_ONE_INT_T:%.*]], align 4 +// CHECK-NEXT: [[LIST_ADDR:%.*]] = alloca ptr, align 4 +// CHECK-NEXT: store ptr [[LIST:%.*]], ptr [[LIST_ADDR]], align 4 +// CHECK-NEXT: [[ARGP_CUR:%.*]] = load ptr, ptr [[LIST_ADDR]], align 4 +// CHECK-NEXT: [[ARGP_NEXT:%.*]] = getelementptr inbounds i8, ptr [[ARGP_CUR]], i32 4 +// CHECK-NEXT: store ptr [[ARGP_NEXT]], ptr [[LIST_ADDR]], align 4 +// CHECK-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 4 [[RETVAL]], ptr align 4 [[ARGP_CUR]], i32 4, i1 false) +// CHECK-NEXT: [[COERCE_DIVE:%.*]] = getelementptr inbounds [[STRUCT_ONE_INT_T]], ptr [[RETVAL]], i32 0, i32 0 +// CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[COERCE_DIVE]], align 4 +// CHECK-NEXT: ret i32 [[TMP0]] +// +one_int_t one_int(__builtin_va_list list) { + return __builtin_va_arg(list, one_int_t); +} + +typedef struct { + int x; + int y; +} two_int_t; + +// CHECK-LABEL: @two_int( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[LIST_ADDR:%.*]] = alloca ptr, align 4 +// CHECK-NEXT: store ptr [[LIST:%.*]], ptr [[LIST_ADDR]], align 4 +// CHECK-NEXT: [[ARGP_CUR:%.*]] = load ptr, ptr [[LIST_ADDR]], align 4 +// CHECK-NEXT: [[ARGP_NEXT:%.*]] = getelementptr inbounds i8, ptr [[ARGP_CUR]], i32 4 +// CHECK-NEXT: store ptr [[ARGP_NEXT]], ptr [[LIST_ADDR]], align 4 +// CHECK-NEXT: [[TMP0:%.*]] = load ptr, ptr [[ARGP_CUR]], align 4 +// CHECK-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 4 [[AGG_RESULT:%.*]], ptr align 4 [[TMP0]], i32 8, i1 false) +// CHECK-NEXT: ret void +// +two_int_t two_int(__builtin_va_list list) { + return __builtin_va_arg(list, two_int_t); +} + +// Double, by itself and packed in structs +// CHECK-LABEL: @raw_double( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[LIST_ADDR:%.*]] = alloca ptr, align 4 +// CHECK-NEXT: store ptr [[LIST:%.*]], ptr [[LIST_ADDR]], align 4 +// CHECK-NEXT: [[ARGP_CUR:%.*]] = load ptr, ptr [[LIST_ADDR]], align 4 +// CHECK-NEXT: [[TMP0:%.*]] = getelementptr inbounds i8, ptr [[ARGP_CUR]], i32 7 +// CHECK-NEXT: [[ARGP_CUR_ALIGNED:%.*]] = call ptr @llvm.ptrmask.p0.i32(ptr [[TMP0]], i32 -8) +// CHECK-NEXT: [[ARGP_NEXT:%.*]] = getelementptr inbounds i8, ptr [[ARGP_CUR_ALIGNED]], i32 8 +// CHECK-NEXT: store ptr [[ARGP_NEXT]], ptr [[LIST_ADDR]], align 4 +// CHECK-NEXT: [[TMP1:%.*]] = load double, ptr [[ARGP_CUR_ALIGNED]], align 8 +// CHECK-NEXT: ret double [[TMP1]] +// +double raw_double(__builtin_va_list list) { + return __builtin_va_arg(list, double); +} + +typedef struct { + double x; +} one_double_t; + +// CHECK-LABEL: @one_double( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[RETVAL:%.*]] = alloca [[STRUCT_ONE_DOUBLE_T:%.*]], align 8 +// CHECK-NEXT: [[LIST_ADDR:%.*]] = alloca ptr, align 4 +// CHECK-NEXT: store ptr [[LIST:%.*]], ptr [[LIST_ADDR]], align 4 +// CHECK-NEXT: [[ARGP_CUR:%.*]] = load ptr, ptr [[LIST_ADDR]], align 4 +// CHECK-NEXT: [[TMP0:%.*]] = getelementptr inbounds i8, ptr [[ARGP_CUR]], i32 7 +// CHECK-NEXT: [[ARGP_CUR_ALIGNED:%.*]] = call ptr @llvm.ptrmask.p0.i32(ptr [[TMP0]], i32 -8) +// CHECK-NEXT: [[ARGP_NEXT:%.*]] = getelementptr inbounds i8, ptr [[ARGP_CUR_ALIGNED]], i32 8 +// CHECK-NEXT: store ptr [[ARGP_NEXT]], ptr [[LIST_ADDR]], align 4 +// CHECK-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 8 [[RETVAL]], ptr align 8 [[ARGP_CUR_ALIGNED]], i32 8, i1 false) +// CHECK-NEXT: [[COERCE_DIVE:%.*]] = getelementptr inbounds [[STRUCT_ONE_DOUBLE_T]], ptr [[RETVAL]], i32 0, i32 0 +// CHECK-NEXT: [[TMP1:%.*]] = load double, ptr [[COERCE_DIVE]], align 8 +// CHECK-NEXT: ret double [[TMP1]] +// +one_double_t one_double(__builtin_va_list list) { + return __builtin_va_arg(list, one_double_t); +} + +typedef struct { + double x; + double y; +} two_double_t; + +// CHECK-LABEL: @two_double( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[LIST_ADDR:%.*]] = alloca ptr, align 4 +// CHECK-NEXT: store ptr [[LIST:%.*]], ptr [[LIST_ADDR]], align 4 +// CHECK-NEXT: [[ARGP_CUR:%.*]] = load ptr, ptr [[LIST_ADDR]], align 4 +// CHECK-NEXT: [[ARGP_NEXT:%.*]] = getelementptr inbounds i8, ptr [[ARGP_CUR]], i32 4 +// CHECK-NEXT: store ptr [[ARGP_NEXT]], ptr [[LIST_ADDR]], align 4 +// CHECK-NEXT: [[TMP0:%.*]] = load ptr, ptr [[ARGP_CUR]], align 4 +// CHECK-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 8 [[AGG_RESULT:%.*]], ptr align 8 [[TMP0]], i32 16, i1 false) +// CHECK-NEXT: ret void +// +two_double_t two_double(__builtin_va_list list) { + return __builtin_va_arg(list, two_double_t); +} + +// Scalar smaller than the slot size (C would promote a short to int) +typedef struct { + char x; +} one_char_t; + +// CHECK-LABEL: @one_char( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[RETVAL:%.*]] = alloca [[STRUCT_ONE_CHAR_T:%.*]], align 1 +// CHECK-NEXT: [[LIST_ADDR:%.*]] = alloca ptr, align 4 +// CHECK-NEXT: store ptr [[LIST:%.*]], ptr [[LIST_ADDR]], align 4 +// CHECK-NEXT: [[ARGP_CUR:%.*]] = load ptr, ptr [[LIST_ADDR]], align 4 +// CHECK-NEXT: [[ARGP_NEXT:%.*]] = getelementptr inbounds i8, ptr [[ARGP_CUR]], i32 4 +// CHECK-NEXT: store ptr [[ARGP_NEXT]], ptr [[LIST_ADDR]], align 4 +// CHECK-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 1 [[RETVAL]], ptr align 4 [[ARGP_CUR]], i32 1, i1 false) +// CHECK-NEXT: [[COERCE_DIVE:%.*]] = getelementptr inbounds [[STRUCT_ONE_CHAR_T]], ptr [[RETVAL]], i32 0, i32 0 +// CHECK-NEXT: [[TMP0:%.*]] = load i8, ptr [[COERCE_DIVE]], align 1 +// CHECK-NEXT: ret i8 [[TMP0]] +// +one_char_t one_char(__builtin_va_list list) { + return __builtin_va_arg(list, one_char_t); +} + +typedef struct { + short x; +} one_short_t; + +// CHECK-LABEL: @one_short( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[RETVAL:%.*]] = alloca [[STRUCT_ONE_SHORT_T:%.*]], align 2 +// CHECK-NEXT: [[LIST_ADDR:%.*]] = alloca ptr, align 4 +// CHECK-NEXT: store ptr [[LIST:%.*]], ptr [[LIST_ADDR]], align 4 +// CHECK-NEXT: [[ARGP_CUR:%.*]] = load ptr, ptr [[LIST_ADDR]], align 4 +// CHECK-NEXT: [[ARGP_NEXT:%.*]] = getelementptr inbounds i8, ptr [[ARGP_CUR]], i32 4 +// CHECK-NEXT: store ptr [[ARGP_NEXT]], ptr [[LIST_ADDR]], align 4 +// CHECK-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 2 [[RETVAL]], ptr align 4 [[ARGP_CUR]], i32 2, i1 false) +// CHECK-NEXT: [[COERCE_DIVE:%.*]] = getelementptr inbounds [[STRUCT_ONE_SHORT_T]], ptr [[RETVAL]], i32 0, i32 0 +// CHECK-NEXT: [[TMP0:%.*]] = load i16, ptr [[COERCE_DIVE]], align 2 +// CHECK-NEXT: ret i16 [[TMP0]] +// +one_short_t one_short(__builtin_va_list list) { + return __builtin_va_arg(list, one_short_t); +} + +// Composite smaller than the slot size +typedef struct { + _Alignas(2) char x; + char y; +} char_pair_t; + +// CHECK-LABEL: @char_pair( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[LIST_ADDR:%.*]] = alloca ptr, align 4 +// CHECK-NEXT: store ptr [[LIST:%.*]], ptr [[LIST_ADDR]], align 4 +// CHECK-NEXT: [[ARGP_CUR:%.*]] = load ptr, ptr [[LIST_ADDR]], align 4 +// CHECK-NEXT: [[ARGP_NEXT:%.*]] = getelementptr inbounds i8, ptr [[ARGP_CUR]], i32 4 +// CHECK-NEXT: store ptr [[ARGP_NEXT]], ptr [[LIST_ADDR]], align 4 +// CHECK-NEXT: [[TMP0:%.*]] = load ptr, ptr [[ARGP_CUR]], align 4 +// CHECK-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 2 [[AGG_RESULT:%.*]], ptr align 2 [[TMP0]], i32 2, i1 false) +// CHECK-NEXT: ret void +// +char_pair_t char_pair(__builtin_va_list list) { + return __builtin_va_arg(list, char_pair_t); +} + +// Empty struct +typedef struct { +} empty_t; + +// CHECK-LABEL: @empty( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[RETVAL:%.*]] = alloca [[STRUCT_EMPTY_T:%.*]], align 1 +// CHECK-NEXT: [[LIST_ADDR:%.*]] = alloca ptr, align 4 +// CHECK-NEXT: store ptr [[LIST:%.*]], ptr [[LIST_ADDR]], align 4 +// CHECK-NEXT: [[ARGP_CUR:%.*]] = load ptr, ptr [[LIST_ADDR]], align 4 +// CHECK-NEXT: [[ARGP_NEXT:%.*]] = getelementptr inbounds i8, ptr [[ARGP_CUR]], i32 0 +// CHECK-NEXT: store ptr [[ARGP_NEXT]], ptr [[LIST_ADDR]], align 4 +// CHECK-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 1 [[RETVAL]], ptr align 4 [[ARGP_CUR]], i32 0, i1 false) +// CHECK-NEXT: ret void +// +empty_t empty(__builtin_va_list list) { + return __builtin_va_arg(list, empty_t); +} + +typedef struct { + empty_t x; + int y; +} empty_int_t; + +// CHECK-LABEL: @empty_int( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[RETVAL:%.*]] = alloca [[STRUCT_EMPTY_INT_T:%.*]], align 4 +// CHECK-NEXT: [[LIST_ADDR:%.*]] = alloca ptr, align 4 +// CHECK-NEXT: store ptr [[LIST:%.*]], ptr [[LIST_ADDR]], align 4 +// CHECK-NEXT: [[ARGP_CUR:%.*]] = load ptr, ptr [[LIST_ADDR]], align 4 +// CHECK-NEXT: [[ARGP_NEXT:%.*]] = getelementptr inbounds i8, ptr [[ARGP_CUR]], i32 4 +// CHECK-NEXT: store ptr [[ARGP_NEXT]], ptr [[LIST_ADDR]], align 4 +// CHECK-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 4 [[RETVAL]], ptr align 4 [[ARGP_CUR]], i32 4, i1 false) +// CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[RETVAL]], align 4 +// CHECK-NEXT: ret i32 [[TMP0]] +// +empty_int_t empty_int(__builtin_va_list list) { + return __builtin_va_arg(list, empty_int_t); +} + +typedef struct { + int x; + empty_t y; +} int_empty_t; + +// CHECK-LABEL: @int_empty( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[RETVAL:%.*]] = alloca [[STRUCT_INT_EMPTY_T:%.*]], align 4 +// CHECK-NEXT: [[LIST_ADDR:%.*]] = alloca ptr, align 4 +// CHECK-NEXT: store ptr [[LIST:%.*]], ptr [[LIST_ADDR]], align 4 +// CHECK-NEXT: [[ARGP_CUR:%.*]] = load ptr, ptr [[LIST_ADDR]], align 4 +// CHECK-NEXT: [[ARGP_NEXT:%.*]] = getelementptr inbounds i8, ptr [[ARGP_CUR]], i32 4 +// CHECK-NEXT: store ptr [[ARGP_NEXT]], ptr [[LIST_ADDR]], align 4 +// CHECK-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 4 [[RETVAL]], ptr align 4 [[ARGP_CUR]], i32 4, i1 false) +// CHECK-NEXT: [[COERCE_DIVE:%.*]] = getelementptr inbounds [[STRUCT_INT_EMPTY_T]], ptr [[RETVAL]], i32 0, i32 0 +// CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[COERCE_DIVE]], align 4 +// CHECK-NEXT: ret i32 [[TMP0]] +// +int_empty_t int_empty(__builtin_va_list list) { + return __builtin_va_arg(list, int_empty_t); +} + +// Need multiple va_arg instructions to check the postincrement +// Using types that are passed directly as the indirect handling +// is independent of the alignment handling in emitVoidPtrDirectVAArg. + +// CHECK-LABEL: @multiple_int( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[LIST_ADDR:%.*]] = alloca ptr, align 4 +// CHECK-NEXT: [[OUT0_ADDR:%.*]] = alloca ptr, align 4 +// CHECK-NEXT: [[OUT1_ADDR:%.*]] = alloca ptr, align 4 +// CHECK-NEXT: [[OUT2_ADDR:%.*]] = alloca ptr, align 4 +// CHECK-NEXT: store ptr [[LIST:%.*]], ptr [[LIST_ADDR]], align 4 +// CHECK-NEXT: store ptr [[OUT0:%.*]], ptr [[OUT0_ADDR]], align 4 +// CHECK-NEXT: store ptr [[OUT1:%.*]], ptr [[OUT1_ADDR]], align 4 +// CHECK-NEXT: store ptr [[OUT2:%.*]], ptr [[OUT2_ADDR]], align 4 +// CHECK-NEXT: [[ARGP_CUR:%.*]] = load ptr, ptr [[LIST_ADDR]], align 4 +// CHECK-NEXT: [[ARGP_NEXT:%.*]] = getelementptr inbounds i8, ptr [[ARGP_CUR]], i32 4 +// CHECK-NEXT: store ptr [[ARGP_NEXT]], ptr [[LIST_ADDR]], align 4 +// CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[ARGP_CUR]], align 4 +// CHECK-NEXT: [[TMP1:%.*]] = load ptr, ptr [[OUT0_ADDR]], align 4 +// CHECK-NEXT: store i32 [[TMP0]], ptr [[TMP1]], align 4 +// CHECK-NEXT: [[ARGP_CUR1:%.*]] = load ptr, ptr [[LIST_ADDR]], align 4 +// CHECK-NEXT: [[ARGP_NEXT2:%.*]] = getelementptr inbounds i8, ptr [[ARGP_CUR1]], i32 4 +// CHECK-NEXT: store ptr [[ARGP_NEXT2]], ptr [[LIST_ADDR]], align 4 +// CHECK-NEXT: [[TMP2:%.*]] = load i32, ptr [[ARGP_CUR1]], align 4 +// CHECK-NEXT: [[TMP3:%.*]] = load ptr, ptr [[OUT1_ADDR]], align 4 +// CHECK-NEXT: store i32 [[TMP2]], ptr [[TMP3]], align 4 +// CHECK-NEXT: [[ARGP_CUR3:%.*]] = load ptr, ptr [[LIST_ADDR]], align 4 +// CHECK-NEXT: [[ARGP_NEXT4:%.*]] = getelementptr inbounds i8, ptr [[ARGP_CUR3]], i32 4 +// CHECK-NEXT: store ptr [[ARGP_NEXT4]], ptr [[LIST_ADDR]], align 4 +// CHECK-NEXT: [[TMP4:%.*]] = load i32, ptr [[ARGP_CUR3]], align 4 +// CHECK-NEXT: [[TMP5:%.*]] = load ptr, ptr [[OUT2_ADDR]], align 4 +// CHECK-NEXT: store i32 [[TMP4]], ptr [[TMP5]], align 4 +// CHECK-NEXT: ret void +// +void multiple_int(__builtin_va_list list, int *out0, int *out1, int *out2) { + *out0 = __builtin_va_arg(list, int); + *out1 = __builtin_va_arg(list, int); + *out2 = __builtin_va_arg(list, int); +} + +// Scalars in structs are an easy way of specifying alignment from C +// CHECK-LABEL: @increasing_alignment( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[LIST_ADDR:%.*]] = alloca ptr, align 4 +// CHECK-NEXT: [[OUT0_ADDR:%.*]] = alloca ptr, align 4 +// CHECK-NEXT: [[OUT1_ADDR:%.*]] = alloca ptr, align 4 +// CHECK-NEXT: [[OUT2_ADDR:%.*]] = alloca ptr, align 4 +// CHECK-NEXT: [[OUT3_ADDR:%.*]] = alloca ptr, align 4 +// CHECK-NEXT: store ptr [[LIST:%.*]], ptr [[LIST_ADDR]], align 4 +// CHECK-NEXT: store ptr [[OUT0:%.*]], ptr [[OUT0_ADDR]], align 4 +// CHECK-NEXT: store ptr [[OUT1:%.*]], ptr [[OUT1_ADDR]], align 4 +// CHECK-NEXT: store ptr [[OUT2:%.*]], ptr [[OUT2_ADDR]], align 4 +// CHECK-NEXT: store ptr [[OUT3:%.*]], ptr [[OUT3_ADDR]], align 4 +// CHECK-NEXT: [[TMP0:%.*]] = load ptr, ptr [[OUT0_ADDR]], align 4 +// CHECK-NEXT: [[ARGP_CUR:%.*]] = load ptr, ptr [[LIST_ADDR]], align 4 +// CHECK-NEXT: [[ARGP_NEXT:%.*]] = getelementptr inbounds i8, ptr [[ARGP_CUR]], i32 4 +// CHECK-NEXT: store ptr [[ARGP_NEXT]], ptr [[LIST_ADDR]], align 4 +// CHECK-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 1 [[TMP0]], ptr align 4 [[ARGP_CUR]], i32 1, i1 false) +// CHECK-NEXT: [[TMP1:%.*]] = load ptr, ptr [[OUT1_ADDR]], align 4 +// CHECK-NEXT: [[ARGP_CUR1:%.*]] = load ptr, ptr [[LIST_ADDR]], align 4 +// CHECK-NEXT: [[ARGP_NEXT2:%.*]] = getelementptr inbounds i8, ptr [[ARGP_CUR1]], i32 4 +// CHECK-NEXT: store ptr [[ARGP_NEXT2]], ptr [[LIST_ADDR]], align 4 +// CHECK-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 2 [[TMP1]], ptr align 4 [[ARGP_CUR1]], i32 2, i1 false) +// CHECK-NEXT: [[ARGP_CUR3:%.*]] = load ptr, ptr [[LIST_ADDR]], align 4 +// CHECK-NEXT: [[ARGP_NEXT4:%.*]] = getelementptr inbounds i8, ptr [[ARGP_CUR3]], i32 4 +// CHECK-NEXT: store ptr [[ARGP_NEXT4]], ptr [[LIST_ADDR]], align 4 +// CHECK-NEXT: [[TMP2:%.*]] = load i32, ptr [[ARGP_CUR3]], align 4 +// CHECK-NEXT: [[TMP3:%.*]] = load ptr, ptr [[OUT2_ADDR]], align 4 +// CHECK-NEXT: store i32 [[TMP2]], ptr [[TMP3]], align 4 +// CHECK-NEXT: [[ARGP_CUR5:%.*]] = load ptr, ptr [[LIST_ADDR]], align 4 +// CHECK-NEXT: [[TMP4:%.*]] = getelementptr inbounds i8, ptr [[ARGP_CUR5]], i32 7 +// CHECK-NEXT: [[ARGP_CUR5_ALIGNED:%.*]] = call ptr @llvm.ptrmask.p0.i32(ptr [[TMP4]], i32 -8) +// CHECK-NEXT: [[ARGP_NEXT6:%.*]] = getelementptr inbounds i8, ptr [[ARGP_CUR5_ALIGNED]], i32 8 +// CHECK-NEXT: store ptr [[ARGP_NEXT6]], ptr [[LIST_ADDR]], align 4 +// CHECK-NEXT: [[TMP5:%.*]] = load double, ptr [[ARGP_CUR5_ALIGNED]], align 8 +// CHECK-NEXT: [[TMP6:%.*]] = load ptr, ptr [[OUT3_ADDR]], align 4 +// CHECK-NEXT: store double [[TMP5]], ptr [[TMP6]], align 8 +// CHECK-NEXT: ret void +// +void increasing_alignment(__builtin_va_list list, one_char_t *out0, + one_short_t *out1, int *out2, double *out3) { + *out0 = __builtin_va_arg(list, one_char_t); + *out1 = __builtin_va_arg(list, one_short_t); + *out2 = __builtin_va_arg(list, int); + *out3 = __builtin_va_arg(list, double); +} + +// CHECK-LABEL: @decreasing_alignment( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[LIST_ADDR:%.*]] = alloca ptr, align 4 +// CHECK-NEXT: [[OUT0_ADDR:%.*]] = alloca ptr, align 4 +// CHECK-NEXT: [[OUT1_ADDR:%.*]] = alloca ptr, align 4 +// CHECK-NEXT: [[OUT2_ADDR:%.*]] = alloca ptr, align 4 +// CHECK-NEXT: [[OUT3_ADDR:%.*]] = alloca ptr, align 4 +// CHECK-NEXT: store ptr [[LIST:%.*]], ptr [[LIST_ADDR]], align 4 +// CHECK-NEXT: store ptr [[OUT0:%.*]], ptr [[OUT0_ADDR]], align 4 +// CHECK-NEXT: store ptr [[OUT1:%.*]], ptr [[OUT1_ADDR]], align 4 +// CHECK-NEXT: store ptr [[OUT2:%.*]], ptr [[OUT2_ADDR]], align 4 +// CHECK-NEXT: store ptr [[OUT3:%.*]], ptr [[OUT3_ADDR]], align 4 +// CHECK-NEXT: [[ARGP_CUR:%.*]] = load ptr, ptr [[LIST_ADDR]], align 4 +// CHECK-NEXT: [[TMP0:%.*]] = getelementptr inbounds i8, ptr [[ARGP_CUR]], i32 7 +// CHECK-NEXT: [[ARGP_CUR_ALIGNED:%.*]] = call ptr @llvm.ptrmask.p0.i32(ptr [[TMP0]], i32 -8) +// CHECK-NEXT: [[ARGP_NEXT:%.*]] = getelementptr inbounds i8, ptr [[ARGP_CUR_ALIGNED]], i32 8 +// CHECK-NEXT: store ptr [[ARGP_NEXT]], ptr [[LIST_ADDR]], align 4 +// CHECK-NEXT: [[TMP1:%.*]] = load double, ptr [[ARGP_CUR_ALIGNED]], align 8 +// CHECK-NEXT: [[TMP2:%.*]] = load ptr, ptr [[OUT0_ADDR]], align 4 +// CHECK-NEXT: store double [[TMP1]], ptr [[TMP2]], align 8 +// CHECK-NEXT: [[ARGP_CUR1:%.*]] = load ptr, ptr [[LIST_ADDR]], align 4 +// CHECK-NEXT: [[ARGP_NEXT2:%.*]] = getelementptr inbounds i8, ptr [[ARGP_CUR1]], i32 4 +// CHECK-NEXT: store ptr [[ARGP_NEXT2]], ptr [[LIST_ADDR]], align 4 +// CHECK-NEXT: [[TMP3:%.*]] = load i32, ptr [[ARGP_CUR1]], align 4 +// CHECK-NEXT: [[TMP4:%.*]] = load ptr, ptr [[OUT1_ADDR]], align 4 +// CHECK-NEXT: store i32 [[TMP3]], ptr [[TMP4]], align 4 +// CHECK-NEXT: [[TMP5:%.*]] = load ptr, ptr [[OUT2_ADDR]], align 4 +// CHECK-NEXT: [[ARGP_CUR3:%.*]] = load ptr, ptr [[LIST_ADDR]], align 4 +// CHECK-NEXT: [[ARGP_NEXT4:%.*]] = getelementptr inbounds i8, ptr [[ARGP_CUR3]], i32 4 +// CHECK-NEXT: store ptr [[ARGP_NEXT4]], ptr [[LIST_ADDR]], align 4 +// CHECK-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 2 [[TMP5]], ptr align 4 [[ARGP_CUR3]], i32 2, i1 false) +// CHECK-NEXT: [[TMP6:%.*]] = load ptr, ptr [[OUT3_ADDR]], align 4 +// CHECK-NEXT: [[ARGP_CUR5:%.*]] = load ptr, ptr [[LIST_ADDR]], align 4 +// CHECK-NEXT: [[ARGP_NEXT6:%.*]] = getelementptr inbounds i8, ptr [[ARGP_CUR5]], i32 4 +// CHECK-NEXT: store ptr [[ARGP_NEXT6]], ptr [[LIST_ADDR]], align 4 +// CHECK-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 1 [[TMP6]], ptr align 4 [[ARGP_CUR5]], i32 1, i1 false) +// CHECK-NEXT: ret void +// +void decreasing_alignment(__builtin_va_list list, double *out0, int *out1, + one_short_t *out2, one_char_t *out3) { + *out0 = __builtin_va_arg(list, double); + *out1 = __builtin_va_arg(list, int); + *out2 = __builtin_va_arg(list, one_short_t); + *out3 = __builtin_va_arg(list, one_char_t); +} + +// Typical edge cases, none hit special handling in VAArg lowering. +typedef struct { + int x[16]; + double y[8]; +} large_value_t; + +// CHECK-LABEL: @large_value( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[LIST_ADDR:%.*]] = alloca ptr, align 4 +// CHECK-NEXT: [[OUT_ADDR:%.*]] = alloca ptr, align 4 +// CHECK-NEXT: store ptr [[LIST:%.*]], ptr [[LIST_ADDR]], align 4 +// CHECK-NEXT: store ptr [[OUT:%.*]], ptr [[OUT_ADDR]], align 4 +// CHECK-NEXT: [[TMP0:%.*]] = load ptr, ptr [[OUT_ADDR]], align 4 +// CHECK-NEXT: [[ARGP_CUR:%.*]] = load ptr, ptr [[LIST_ADDR]], align 4 +// CHECK-NEXT: [[ARGP_NEXT:%.*]] = getelementptr inbounds i8, ptr [[ARGP_CUR]], i32 4 +// CHECK-NEXT: store ptr [[ARGP_NEXT]], ptr [[LIST_ADDR]], align 4 +// CHECK-NEXT: [[TMP1:%.*]] = load ptr, ptr [[ARGP_CUR]], align 4 +// CHECK-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 8 [[TMP0]], ptr align 8 [[TMP1]], i32 128, i1 false) +// CHECK-NEXT: ret void +// +void large_value(__builtin_va_list list, large_value_t *out) { + *out = __builtin_va_arg(list, large_value_t); +} + +typedef int v128_t __attribute__((__vector_size__(16), __aligned__(16))); +// CHECK-LABEL: @vector( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[LIST_ADDR:%.*]] = alloca ptr, align 4 +// CHECK-NEXT: [[OUT_ADDR:%.*]] = alloca ptr, align 4 +// CHECK-NEXT: store ptr [[LIST:%.*]], ptr [[LIST_ADDR]], align 4 +// CHECK-NEXT: store ptr [[OUT:%.*]], ptr [[OUT_ADDR]], align 4 +// CHECK-NEXT: [[ARGP_CUR:%.*]] = load ptr, ptr [[LIST_ADDR]], align 4 +// CHECK-NEXT: [[TMP0:%.*]] = getelementptr inbounds i8, ptr [[ARGP_CUR]], i32 15 +// CHECK-NEXT: [[ARGP_CUR_ALIGNED:%.*]] = call ptr @llvm.ptrmask.p0.i32(ptr [[TMP0]], i32 -16) +// CHECK-NEXT: [[ARGP_NEXT:%.*]] = getelementptr inbounds i8, ptr [[ARGP_CUR_ALIGNED]], i32 16 +// CHECK-NEXT: store ptr [[ARGP_NEXT]], ptr [[LIST_ADDR]], align 4 +// CHECK-NEXT: [[TMP1:%.*]] = load <4 x i32>, ptr [[ARGP_CUR_ALIGNED]], align 16 +// CHECK-NEXT: [[TMP2:%.*]] = load ptr, ptr [[OUT_ADDR]], align 4 +// CHECK-NEXT: store <4 x i32> [[TMP1]], ptr [[TMP2]], align 16 +// CHECK-NEXT: ret void +// +void vector(__builtin_va_list list, v128_t *out) { + *out = __builtin_va_arg(list, v128_t); +} + +typedef struct BF { + float not_an_i32[2]; + int A : 1; + char B; + int C : 13; +} BF; + +// CHECK-LABEL: @bitfield( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[LIST_ADDR:%.*]] = alloca ptr, align 4 +// CHECK-NEXT: [[OUT_ADDR:%.*]] = alloca ptr, align 4 +// CHECK-NEXT: store ptr [[LIST:%.*]], ptr [[LIST_ADDR]], align 4 +// CHECK-NEXT: store ptr [[OUT:%.*]], ptr [[OUT_ADDR]], align 4 +// CHECK-NEXT: [[TMP0:%.*]] = load ptr, ptr [[OUT_ADDR]], align 4 +// CHECK-NEXT: [[ARGP_CUR:%.*]] = load ptr, ptr [[LIST_ADDR]], align 4 +// CHECK-NEXT: [[ARGP_NEXT:%.*]] = getelementptr inbounds i8, ptr [[ARGP_CUR]], i32 4 +// CHECK-NEXT: store ptr [[ARGP_NEXT]], ptr [[LIST_ADDR]], align 4 +// CHECK-NEXT: [[TMP1:%.*]] = load ptr, ptr [[ARGP_CUR]], align 4 +// CHECK-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 4 [[TMP0]], ptr align 4 [[TMP1]], i32 12, i1 false) +// CHECK-NEXT: ret void +// +void bitfield(__builtin_va_list list, BF *out) { + *out = __builtin_va_arg(list, BF); +} diff --git a/clang/test/CodeGenCUDA/builtins-spirv-amdgcn.cu b/clang/test/CodeGenCUDA/builtins-spirv-amdgcn.cu new file mode 100644 index 0000000000000000000000000000000000000000..8dbb8c538ddc16b9b583a8084bc761ccd45dd7c9 --- /dev/null +++ b/clang/test/CodeGenCUDA/builtins-spirv-amdgcn.cu @@ -0,0 +1,294 @@ +// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py +// RUN: %clang_cc1 -triple spirv64-amd-amdhsa -x hip \ +// RUN: -aux-triple x86_64-unknown-linux-gnu -fcuda-is-device -emit-llvm %s \ +// RUN: -o - | FileCheck %s + +// RUN: %clang_cc1 -triple spirv64-amd-amdhsa -x hip \ +// RUN: -aux-triple x86_64-pc-windows-msvc -fcuda-is-device -emit-llvm %s \ +// RUN: -o - | FileCheck %s + +#include "Inputs/cuda.h" + +// CHECK-LABEL: @_Z16use_dispatch_ptrPi( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[OUT:%.*]] = alloca ptr addrspace(4), align 8 +// CHECK-NEXT: [[OUT_ADDR:%.*]] = alloca ptr addrspace(4), align 8 +// CHECK-NEXT: [[DISPATCH_PTR:%.*]] = alloca ptr addrspace(4), align 8 +// CHECK-NEXT: [[OUT_ASCAST:%.*]] = addrspacecast ptr [[OUT]] to ptr addrspace(4) +// CHECK-NEXT: [[OUT_ADDR_ASCAST:%.*]] = addrspacecast ptr [[OUT_ADDR]] to ptr addrspace(4) +// CHECK-NEXT: [[DISPATCH_PTR_ASCAST:%.*]] = addrspacecast ptr [[DISPATCH_PTR]] to ptr addrspace(4) +// CHECK-NEXT: [[TMP0:%.*]] = addrspacecast ptr addrspace(1) [[OUT_COERCE:%.*]] to ptr addrspace(4) +// CHECK-NEXT: store ptr addrspace(4) [[TMP0]], ptr addrspace(4) [[OUT_ASCAST]], align 8 +// CHECK-NEXT: [[OUT1:%.*]] = load ptr addrspace(4), ptr addrspace(4) [[OUT_ASCAST]], align 8 +// CHECK-NEXT: store ptr addrspace(4) [[OUT1]], ptr addrspace(4) [[OUT_ADDR_ASCAST]], align 8 +// CHECK-NEXT: [[TMP1:%.*]] = call align 4 dereferenceable(64) addrspace(4) ptr addrspace(4) @llvm.amdgcn.dispatch.ptr() +// CHECK-NEXT: store ptr addrspace(4) [[TMP1]], ptr addrspace(4) [[DISPATCH_PTR_ASCAST]], align 8 +// CHECK-NEXT: [[TMP2:%.*]] = load ptr addrspace(4), ptr addrspace(4) [[DISPATCH_PTR_ASCAST]], align 8 +// CHECK-NEXT: [[TMP3:%.*]] = load i32, ptr addrspace(4) [[TMP2]], align 4 +// CHECK-NEXT: [[TMP4:%.*]] = load ptr addrspace(4), ptr addrspace(4) [[OUT_ADDR_ASCAST]], align 8 +// CHECK-NEXT: store i32 [[TMP3]], ptr addrspace(4) [[TMP4]], align 4 +// CHECK-NEXT: ret void +// +__global__ void use_dispatch_ptr(int* out) { + const int* dispatch_ptr = (const int*)__builtin_amdgcn_dispatch_ptr(); + *out = *dispatch_ptr; +} + +// CHECK-LABEL: @_Z13use_queue_ptrPi( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[OUT:%.*]] = alloca ptr addrspace(4), align 8 +// CHECK-NEXT: [[OUT_ADDR:%.*]] = alloca ptr addrspace(4), align 8 +// CHECK-NEXT: [[QUEUE_PTR:%.*]] = alloca ptr addrspace(4), align 8 +// CHECK-NEXT: [[OUT_ASCAST:%.*]] = addrspacecast ptr [[OUT]] to ptr addrspace(4) +// CHECK-NEXT: [[OUT_ADDR_ASCAST:%.*]] = addrspacecast ptr [[OUT_ADDR]] to ptr addrspace(4) +// CHECK-NEXT: [[QUEUE_PTR_ASCAST:%.*]] = addrspacecast ptr [[QUEUE_PTR]] to ptr addrspace(4) +// CHECK-NEXT: [[TMP0:%.*]] = addrspacecast ptr addrspace(1) [[OUT_COERCE:%.*]] to ptr addrspace(4) +// CHECK-NEXT: store ptr addrspace(4) [[TMP0]], ptr addrspace(4) [[OUT_ASCAST]], align 8 +// CHECK-NEXT: [[OUT1:%.*]] = load ptr addrspace(4), ptr addrspace(4) [[OUT_ASCAST]], align 8 +// CHECK-NEXT: store ptr addrspace(4) [[OUT1]], ptr addrspace(4) [[OUT_ADDR_ASCAST]], align 8 +// CHECK-NEXT: [[TMP1:%.*]] = call addrspace(4) ptr addrspace(4) @llvm.amdgcn.queue.ptr() +// CHECK-NEXT: store ptr addrspace(4) [[TMP1]], ptr addrspace(4) [[QUEUE_PTR_ASCAST]], align 8 +// CHECK-NEXT: [[TMP2:%.*]] = load ptr addrspace(4), ptr addrspace(4) [[QUEUE_PTR_ASCAST]], align 8 +// CHECK-NEXT: [[TMP3:%.*]] = load i32, ptr addrspace(4) [[TMP2]], align 4 +// CHECK-NEXT: [[TMP4:%.*]] = load ptr addrspace(4), ptr addrspace(4) [[OUT_ADDR_ASCAST]], align 8 +// CHECK-NEXT: store i32 [[TMP3]], ptr addrspace(4) [[TMP4]], align 4 +// CHECK-NEXT: ret void +// +__global__ void use_queue_ptr(int* out) { + const int* queue_ptr = (const int*)__builtin_amdgcn_queue_ptr(); + *out = *queue_ptr; +} + +// CHECK-LABEL: @_Z19use_implicitarg_ptrPi( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[OUT:%.*]] = alloca ptr addrspace(4), align 8 +// CHECK-NEXT: [[OUT_ADDR:%.*]] = alloca ptr addrspace(4), align 8 +// CHECK-NEXT: [[IMPLICITARG_PTR:%.*]] = alloca ptr addrspace(4), align 8 +// CHECK-NEXT: [[OUT_ASCAST:%.*]] = addrspacecast ptr [[OUT]] to ptr addrspace(4) +// CHECK-NEXT: [[OUT_ADDR_ASCAST:%.*]] = addrspacecast ptr [[OUT_ADDR]] to ptr addrspace(4) +// CHECK-NEXT: [[IMPLICITARG_PTR_ASCAST:%.*]] = addrspacecast ptr [[IMPLICITARG_PTR]] to ptr addrspace(4) +// CHECK-NEXT: [[TMP0:%.*]] = addrspacecast ptr addrspace(1) [[OUT_COERCE:%.*]] to ptr addrspace(4) +// CHECK-NEXT: store ptr addrspace(4) [[TMP0]], ptr addrspace(4) [[OUT_ASCAST]], align 8 +// CHECK-NEXT: [[OUT1:%.*]] = load ptr addrspace(4), ptr addrspace(4) [[OUT_ASCAST]], align 8 +// CHECK-NEXT: store ptr addrspace(4) [[OUT1]], ptr addrspace(4) [[OUT_ADDR_ASCAST]], align 8 +// CHECK-NEXT: [[TMP1:%.*]] = call addrspace(4) ptr addrspace(4) @llvm.amdgcn.implicitarg.ptr() +// CHECK-NEXT: store ptr addrspace(4) [[TMP1]], ptr addrspace(4) [[IMPLICITARG_PTR_ASCAST]], align 8 +// CHECK-NEXT: [[TMP2:%.*]] = load ptr addrspace(4), ptr addrspace(4) [[IMPLICITARG_PTR_ASCAST]], align 8 +// CHECK-NEXT: [[TMP3:%.*]] = load i32, ptr addrspace(4) [[TMP2]], align 4 +// CHECK-NEXT: [[TMP4:%.*]] = load ptr addrspace(4), ptr addrspace(4) [[OUT_ADDR_ASCAST]], align 8 +// CHECK-NEXT: store i32 [[TMP3]], ptr addrspace(4) [[TMP4]], align 4 +// CHECK-NEXT: ret void +// +__global__ void use_implicitarg_ptr(int* out) { + const int* implicitarg_ptr = (const int*)__builtin_amdgcn_implicitarg_ptr(); + *out = *implicitarg_ptr; +} + +__global__ + // + void +// CHECK-LABEL: @_Z12test_ds_fmaxf( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[SRC_ADDR:%.*]] = alloca float, align 4 +// CHECK-NEXT: [[X:%.*]] = alloca float, align 4 +// CHECK-NEXT: [[SRC_ADDR_ASCAST:%.*]] = addrspacecast ptr [[SRC_ADDR]] to ptr addrspace(4) +// CHECK-NEXT: [[X_ASCAST:%.*]] = addrspacecast ptr [[X]] to ptr addrspace(4) +// CHECK-NEXT: store float [[SRC:%.*]], ptr addrspace(4) [[SRC_ADDR_ASCAST]], align 4 +// CHECK-NEXT: [[TMP0:%.*]] = load float, ptr addrspace(4) [[SRC_ADDR_ASCAST]], align 4 +// CHECK-NEXT: [[TMP1:%.*]] = call contract addrspace(4) float @llvm.amdgcn.ds.fmax.f32(ptr addrspace(3) @_ZZ12test_ds_fmaxfE6shared, float [[TMP0]], i32 0, i32 0, i1 false) +// CHECK-NEXT: store volatile float [[TMP1]], ptr addrspace(4) [[X_ASCAST]], align 4 +// CHECK-NEXT: ret void +// + test_ds_fmax(float src) { + __shared__ float shared; + volatile float x = __builtin_amdgcn_ds_fmaxf(&shared, src, 0, 0, false); +} + +// CHECK-LABEL: @_Z12test_ds_faddf( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[SRC_ADDR:%.*]] = alloca float, align 4 +// CHECK-NEXT: [[X:%.*]] = alloca float, align 4 +// CHECK-NEXT: [[SRC_ADDR_ASCAST:%.*]] = addrspacecast ptr [[SRC_ADDR]] to ptr addrspace(4) +// CHECK-NEXT: [[X_ASCAST:%.*]] = addrspacecast ptr [[X]] to ptr addrspace(4) +// CHECK-NEXT: store float [[SRC:%.*]], ptr addrspace(4) [[SRC_ADDR_ASCAST]], align 4 +// CHECK-NEXT: [[TMP0:%.*]] = load float, ptr addrspace(4) [[SRC_ADDR_ASCAST]], align 4 +// CHECK-NEXT: [[TMP1:%.*]] = call contract addrspace(4) float @llvm.amdgcn.ds.fadd.f32(ptr addrspace(3) @_ZZ12test_ds_faddfE6shared, float [[TMP0]], i32 0, i32 0, i1 false) +// CHECK-NEXT: store volatile float [[TMP1]], ptr addrspace(4) [[X_ASCAST]], align 4 +// CHECK-NEXT: ret void +// +__global__ void test_ds_fadd(float src) { + __shared__ float shared; + volatile float x = __builtin_amdgcn_ds_faddf(&shared, src, 0, 0, false); +} + +// CHECK-LABEL: @_Z12test_ds_fminfPf( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[SHARED:%.*]] = alloca ptr addrspace(4), align 8 +// CHECK-NEXT: [[SRC_ADDR:%.*]] = alloca float, align 4 +// CHECK-NEXT: [[SHARED_ADDR:%.*]] = alloca ptr addrspace(4), align 8 +// CHECK-NEXT: [[X:%.*]] = alloca float, align 4 +// CHECK-NEXT: [[SHARED_ASCAST:%.*]] = addrspacecast ptr [[SHARED]] to ptr addrspace(4) +// CHECK-NEXT: [[SRC_ADDR_ASCAST:%.*]] = addrspacecast ptr [[SRC_ADDR]] to ptr addrspace(4) +// CHECK-NEXT: [[SHARED_ADDR_ASCAST:%.*]] = addrspacecast ptr [[SHARED_ADDR]] to ptr addrspace(4) +// CHECK-NEXT: [[X_ASCAST:%.*]] = addrspacecast ptr [[X]] to ptr addrspace(4) +// CHECK-NEXT: [[TMP0:%.*]] = addrspacecast ptr addrspace(1) [[SHARED_COERCE:%.*]] to ptr addrspace(4) +// CHECK-NEXT: store ptr addrspace(4) [[TMP0]], ptr addrspace(4) [[SHARED_ASCAST]], align 8 +// CHECK-NEXT: [[SHARED1:%.*]] = load ptr addrspace(4), ptr addrspace(4) [[SHARED_ASCAST]], align 8 +// CHECK-NEXT: store float [[SRC:%.*]], ptr addrspace(4) [[SRC_ADDR_ASCAST]], align 4 +// CHECK-NEXT: store ptr addrspace(4) [[SHARED1]], ptr addrspace(4) [[SHARED_ADDR_ASCAST]], align 8 +// CHECK-NEXT: [[TMP1:%.*]] = load ptr addrspace(4), ptr addrspace(4) [[SHARED_ADDR_ASCAST]], align 8 +// CHECK-NEXT: [[TMP2:%.*]] = addrspacecast ptr addrspace(4) [[TMP1]] to ptr addrspace(3) +// CHECK-NEXT: [[TMP3:%.*]] = load float, ptr addrspace(4) [[SRC_ADDR_ASCAST]], align 4 +// CHECK-NEXT: [[TMP4:%.*]] = call contract addrspace(4) float @llvm.amdgcn.ds.fmin.f32(ptr addrspace(3) [[TMP2]], float [[TMP3]], i32 0, i32 0, i1 false) +// CHECK-NEXT: store volatile float [[TMP4]], ptr addrspace(4) [[X_ASCAST]], align 4 +// CHECK-NEXT: ret void +// +__global__ void test_ds_fmin(float src, float *shared) { + volatile float x = __builtin_amdgcn_ds_fminf(shared, src, 0, 0, false); +} + +#if 0 // FIXME: returning a pointer to AS4 explicitly is wrong for AMDGPU SPIRV +// +__device__ void test_ret_builtin_nondef_addrspace() { + void *x = __builtin_amdgcn_dispatch_ptr(); +} +#endif + +// CHECK-LABEL: @_Z6endpgmv( +// CHECK-NEXT: entry: +// CHECK-NEXT: call addrspace(4) void @llvm.amdgcn.endpgm() +// CHECK-NEXT: ret void +// +__global__ void endpgm() { + __builtin_amdgcn_endpgm(); +} + +// Check the 64 bit argument is correctly passed to the intrinsic without truncation or assertion. + +// CHECK-LABEL: @_Z14test_uicmp_i64Pyyy( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[OUT:%.*]] = alloca ptr addrspace(4), align 8 +// CHECK-NEXT: [[OUT_ADDR:%.*]] = alloca ptr addrspace(4), align 8 +// CHECK-NEXT: [[A_ADDR:%.*]] = alloca i64, align 8 +// CHECK-NEXT: [[B_ADDR:%.*]] = alloca i64, align 8 +// CHECK-NEXT: [[OUT_ASCAST:%.*]] = addrspacecast ptr [[OUT]] to ptr addrspace(4) +// CHECK-NEXT: [[OUT_ADDR_ASCAST:%.*]] = addrspacecast ptr [[OUT_ADDR]] to ptr addrspace(4) +// CHECK-NEXT: [[A_ADDR_ASCAST:%.*]] = addrspacecast ptr [[A_ADDR]] to ptr addrspace(4) +// CHECK-NEXT: [[B_ADDR_ASCAST:%.*]] = addrspacecast ptr [[B_ADDR]] to ptr addrspace(4) +// CHECK-NEXT: [[TMP0:%.*]] = addrspacecast ptr addrspace(1) [[OUT_COERCE:%.*]] to ptr addrspace(4) +// CHECK-NEXT: store ptr addrspace(4) [[TMP0]], ptr addrspace(4) [[OUT_ASCAST]], align 8 +// CHECK-NEXT: [[OUT1:%.*]] = load ptr addrspace(4), ptr addrspace(4) [[OUT_ASCAST]], align 8 +// CHECK-NEXT: store ptr addrspace(4) [[OUT1]], ptr addrspace(4) [[OUT_ADDR_ASCAST]], align 8 +// CHECK-NEXT: store i64 [[A:%.*]], ptr addrspace(4) [[A_ADDR_ASCAST]], align 8 +// CHECK-NEXT: store i64 [[B:%.*]], ptr addrspace(4) [[B_ADDR_ASCAST]], align 8 +// CHECK-NEXT: [[TMP1:%.*]] = load i64, ptr addrspace(4) [[A_ADDR_ASCAST]], align 8 +// CHECK-NEXT: [[TMP2:%.*]] = load i64, ptr addrspace(4) [[B_ADDR_ASCAST]], align 8 +// CHECK-NEXT: [[TMP3:%.*]] = call addrspace(4) i64 @llvm.amdgcn.icmp.i64.i64(i64 [[TMP1]], i64 [[TMP2]], i32 35) +// CHECK-NEXT: [[TMP4:%.*]] = load ptr addrspace(4), ptr addrspace(4) [[OUT_ADDR_ASCAST]], align 8 +// CHECK-NEXT: store i64 [[TMP3]], ptr addrspace(4) [[TMP4]], align 8 +// CHECK-NEXT: ret void +// +__global__ void test_uicmp_i64(unsigned long long *out, unsigned long long a, unsigned long long b) +{ + *out = __builtin_amdgcn_uicmpl(a, b, 30+5); +} + +// Check the 64 bit return value is correctly returned without truncation or assertion. + +// CHECK-LABEL: @_Z14test_s_memtimePy( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[OUT:%.*]] = alloca ptr addrspace(4), align 8 +// CHECK-NEXT: [[OUT_ADDR:%.*]] = alloca ptr addrspace(4), align 8 +// CHECK-NEXT: [[OUT_ASCAST:%.*]] = addrspacecast ptr [[OUT]] to ptr addrspace(4) +// CHECK-NEXT: [[OUT_ADDR_ASCAST:%.*]] = addrspacecast ptr [[OUT_ADDR]] to ptr addrspace(4) +// CHECK-NEXT: [[TMP0:%.*]] = addrspacecast ptr addrspace(1) [[OUT_COERCE:%.*]] to ptr addrspace(4) +// CHECK-NEXT: store ptr addrspace(4) [[TMP0]], ptr addrspace(4) [[OUT_ASCAST]], align 8 +// CHECK-NEXT: [[OUT1:%.*]] = load ptr addrspace(4), ptr addrspace(4) [[OUT_ASCAST]], align 8 +// CHECK-NEXT: store ptr addrspace(4) [[OUT1]], ptr addrspace(4) [[OUT_ADDR_ASCAST]], align 8 +// CHECK-NEXT: [[TMP1:%.*]] = call addrspace(4) i64 @llvm.amdgcn.s.memtime() +// CHECK-NEXT: [[TMP2:%.*]] = load ptr addrspace(4), ptr addrspace(4) [[OUT_ADDR_ASCAST]], align 8 +// CHECK-NEXT: store i64 [[TMP1]], ptr addrspace(4) [[TMP2]], align 8 +// CHECK-NEXT: ret void +// +__global__ void test_s_memtime(unsigned long long* out) +{ + *out = __builtin_amdgcn_s_memtime(); +} + +// Check a generic pointer can be passed as a shared pointer and a generic pointer. +__device__ void func(float *x); + +// CHECK-LABEL: @_Z17test_ds_fmin_funcfPf( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[SHARED:%.*]] = alloca ptr addrspace(4), align 8 +// CHECK-NEXT: [[SRC_ADDR:%.*]] = alloca float, align 4 +// CHECK-NEXT: [[SHARED_ADDR:%.*]] = alloca ptr addrspace(4), align 8 +// CHECK-NEXT: [[X:%.*]] = alloca float, align 4 +// CHECK-NEXT: [[SHARED_ASCAST:%.*]] = addrspacecast ptr [[SHARED]] to ptr addrspace(4) +// CHECK-NEXT: [[SRC_ADDR_ASCAST:%.*]] = addrspacecast ptr [[SRC_ADDR]] to ptr addrspace(4) +// CHECK-NEXT: [[SHARED_ADDR_ASCAST:%.*]] = addrspacecast ptr [[SHARED_ADDR]] to ptr addrspace(4) +// CHECK-NEXT: [[X_ASCAST:%.*]] = addrspacecast ptr [[X]] to ptr addrspace(4) +// CHECK-NEXT: [[TMP0:%.*]] = addrspacecast ptr addrspace(1) [[SHARED_COERCE:%.*]] to ptr addrspace(4) +// CHECK-NEXT: store ptr addrspace(4) [[TMP0]], ptr addrspace(4) [[SHARED_ASCAST]], align 8 +// CHECK-NEXT: [[SHARED1:%.*]] = load ptr addrspace(4), ptr addrspace(4) [[SHARED_ASCAST]], align 8 +// CHECK-NEXT: store float [[SRC:%.*]], ptr addrspace(4) [[SRC_ADDR_ASCAST]], align 4 +// CHECK-NEXT: store ptr addrspace(4) [[SHARED1]], ptr addrspace(4) [[SHARED_ADDR_ASCAST]], align 8 +// CHECK-NEXT: [[TMP1:%.*]] = load ptr addrspace(4), ptr addrspace(4) [[SHARED_ADDR_ASCAST]], align 8 +// CHECK-NEXT: [[TMP2:%.*]] = addrspacecast ptr addrspace(4) [[TMP1]] to ptr addrspace(3) +// CHECK-NEXT: [[TMP3:%.*]] = load float, ptr addrspace(4) [[SRC_ADDR_ASCAST]], align 4 +// CHECK-NEXT: [[TMP4:%.*]] = call contract addrspace(4) float @llvm.amdgcn.ds.fmin.f32(ptr addrspace(3) [[TMP2]], float [[TMP3]], i32 0, i32 0, i1 false) +// CHECK-NEXT: store volatile float [[TMP4]], ptr addrspace(4) [[X_ASCAST]], align 4 +// CHECK-NEXT: [[TMP5:%.*]] = load ptr addrspace(4), ptr addrspace(4) [[SHARED_ADDR_ASCAST]], align 8 +// CHECK-NEXT: call spir_func addrspace(4) void @_Z4funcPf(ptr addrspace(4) noundef [[TMP5]]) #[[ATTR7:[0-9]+]] +// CHECK-NEXT: ret void +// +__global__ void test_ds_fmin_func(float src, float *__restrict shared) { + volatile float x = __builtin_amdgcn_ds_fminf(shared, src, 0, 0, false); + func(shared); +} + +// CHECK-LABEL: @_Z14test_is_sharedPf( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[X:%.*]] = alloca ptr addrspace(4), align 8 +// CHECK-NEXT: [[X_ADDR:%.*]] = alloca ptr addrspace(4), align 8 +// CHECK-NEXT: [[RET:%.*]] = alloca i8, align 1 +// CHECK-NEXT: [[X_ASCAST:%.*]] = addrspacecast ptr [[X]] to ptr addrspace(4) +// CHECK-NEXT: [[X_ADDR_ASCAST:%.*]] = addrspacecast ptr [[X_ADDR]] to ptr addrspace(4) +// CHECK-NEXT: [[RET_ASCAST:%.*]] = addrspacecast ptr [[RET]] to ptr addrspace(4) +// CHECK-NEXT: [[TMP0:%.*]] = addrspacecast ptr addrspace(1) [[X_COERCE:%.*]] to ptr addrspace(4) +// CHECK-NEXT: store ptr addrspace(4) [[TMP0]], ptr addrspace(4) [[X_ASCAST]], align 8 +// CHECK-NEXT: [[X1:%.*]] = load ptr addrspace(4), ptr addrspace(4) [[X_ASCAST]], align 8 +// CHECK-NEXT: store ptr addrspace(4) [[X1]], ptr addrspace(4) [[X_ADDR_ASCAST]], align 8 +// CHECK-NEXT: [[TMP1:%.*]] = load ptr addrspace(4), ptr addrspace(4) [[X_ADDR_ASCAST]], align 8 +// CHECK-NEXT: [[TMP2:%.*]] = addrspacecast ptr addrspace(4) [[TMP1]] to ptr +// CHECK-NEXT: [[TMP3:%.*]] = call addrspace(4) i1 @llvm.amdgcn.is.shared(ptr [[TMP2]]) +// CHECK-NEXT: [[FROMBOOL:%.*]] = zext i1 [[TMP3]] to i8 +// CHECK-NEXT: store i8 [[FROMBOOL]], ptr addrspace(4) [[RET_ASCAST]], align 1 +// CHECK-NEXT: ret void +// +__global__ void test_is_shared(float *x){ + bool ret = __builtin_amdgcn_is_shared(x); +} + +// CHECK-LABEL: @_Z15test_is_privatePi( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[X:%.*]] = alloca ptr addrspace(4), align 8 +// CHECK-NEXT: [[X_ADDR:%.*]] = alloca ptr addrspace(4), align 8 +// CHECK-NEXT: [[RET:%.*]] = alloca i8, align 1 +// CHECK-NEXT: [[X_ASCAST:%.*]] = addrspacecast ptr [[X]] to ptr addrspace(4) +// CHECK-NEXT: [[X_ADDR_ASCAST:%.*]] = addrspacecast ptr [[X_ADDR]] to ptr addrspace(4) +// CHECK-NEXT: [[RET_ASCAST:%.*]] = addrspacecast ptr [[RET]] to ptr addrspace(4) +// CHECK-NEXT: [[TMP0:%.*]] = addrspacecast ptr addrspace(1) [[X_COERCE:%.*]] to ptr addrspace(4) +// CHECK-NEXT: store ptr addrspace(4) [[TMP0]], ptr addrspace(4) [[X_ASCAST]], align 8 +// CHECK-NEXT: [[X1:%.*]] = load ptr addrspace(4), ptr addrspace(4) [[X_ASCAST]], align 8 +// CHECK-NEXT: store ptr addrspace(4) [[X1]], ptr addrspace(4) [[X_ADDR_ASCAST]], align 8 +// CHECK-NEXT: [[TMP1:%.*]] = load ptr addrspace(4), ptr addrspace(4) [[X_ADDR_ASCAST]], align 8 +// CHECK-NEXT: [[TMP2:%.*]] = addrspacecast ptr addrspace(4) [[TMP1]] to ptr +// CHECK-NEXT: [[TMP3:%.*]] = call addrspace(4) i1 @llvm.amdgcn.is.private(ptr [[TMP2]]) +// CHECK-NEXT: [[FROMBOOL:%.*]] = zext i1 [[TMP3]] to i8 +// CHECK-NEXT: store i8 [[FROMBOOL]], ptr addrspace(4) [[RET_ASCAST]], align 1 +// CHECK-NEXT: ret void +// +__global__ void test_is_private(int *x){ + bool ret = __builtin_amdgcn_is_private(x); +} diff --git a/clang/test/CodeGenCUDA/builtins-unsafe-atomics-spirv-amdgcn-gfx90a.cu b/clang/test/CodeGenCUDA/builtins-unsafe-atomics-spirv-amdgcn-gfx90a.cu new file mode 100644 index 0000000000000000000000000000000000000000..1ea1d5f454762dbab51ce4238dc0ac44954a0053 --- /dev/null +++ b/clang/test/CodeGenCUDA/builtins-unsafe-atomics-spirv-amdgcn-gfx90a.cu @@ -0,0 +1,31 @@ +// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 4 +// RUN: %clang_cc1 -triple spirv64-amd-amdhsa -x hip \ +// RUN: -aux-triple x86_64-unknown-linux-gnu -fcuda-is-device -emit-llvm %s \ +// RUN: -o - | FileCheck %s + +#define __device__ __attribute__((device)) +typedef __attribute__((address_space(3))) float *LP; + +// CHECK-LABEL: define spir_func void @_Z22test_ds_atomic_add_f32Pff( +// CHECK-SAME: ptr addrspace(4) noundef [[ADDR:%.*]], float noundef [[VAL:%.*]]) addrspace(4) #[[ATTR0:[0-9]+]] { +// CHECK-NEXT: entry: +// CHECK-NEXT: [[ADDR_ADDR:%.*]] = alloca ptr addrspace(4), align 8 +// CHECK-NEXT: [[VAL_ADDR:%.*]] = alloca float, align 4 +// CHECK-NEXT: [[RTN:%.*]] = alloca ptr addrspace(4), align 8 +// CHECK-NEXT: [[ADDR_ADDR_ASCAST:%.*]] = addrspacecast ptr [[ADDR_ADDR]] to ptr addrspace(4) +// CHECK-NEXT: [[VAL_ADDR_ASCAST:%.*]] = addrspacecast ptr [[VAL_ADDR]] to ptr addrspace(4) +// CHECK-NEXT: [[RTN_ASCAST:%.*]] = addrspacecast ptr [[RTN]] to ptr addrspace(4) +// CHECK-NEXT: store ptr addrspace(4) [[ADDR]], ptr addrspace(4) [[ADDR_ADDR_ASCAST]], align 8 +// CHECK-NEXT: store float [[VAL]], ptr addrspace(4) [[VAL_ADDR_ASCAST]], align 4 +// CHECK-NEXT: [[TMP0:%.*]] = load ptr addrspace(4), ptr addrspace(4) [[ADDR_ADDR_ASCAST]], align 8 +// CHECK-NEXT: [[TMP1:%.*]] = addrspacecast ptr addrspace(4) [[TMP0]] to ptr addrspace(3) +// CHECK-NEXT: [[TMP2:%.*]] = load float, ptr addrspace(4) [[VAL_ADDR_ASCAST]], align 4 +// CHECK-NEXT: [[TMP3:%.*]] = call contract addrspace(4) float @llvm.amdgcn.ds.fadd.f32(ptr addrspace(3) [[TMP1]], float [[TMP2]], i32 0, i32 0, i1 false) +// CHECK-NEXT: [[TMP4:%.*]] = load ptr addrspace(4), ptr addrspace(4) [[RTN_ASCAST]], align 8 +// CHECK-NEXT: store float [[TMP3]], ptr addrspace(4) [[TMP4]], align 4 +// CHECK-NEXT: ret void +// +__device__ void test_ds_atomic_add_f32(float *addr, float val) { + float *rtn; + *rtn = __builtin_amdgcn_ds_faddf((LP)addr, val, 0, 0, 0); +} diff --git a/clang/test/CodeGenCUDA/cuda-builtin-vars.cu b/clang/test/CodeGenCUDA/cuda-builtin-vars.cu index ba5e5f13ebe707f278faef55deda994f693c319b..7880a8036f8cd405c20f47b8748863c7dc549152 100644 --- a/clang/test/CodeGenCUDA/cuda-builtin-vars.cu +++ b/clang/test/CodeGenCUDA/cuda-builtin-vars.cu @@ -6,21 +6,21 @@ __attribute__((global)) void kernel(int *out) { int i = 0; - out[i++] = threadIdx.x; // CHECK: call noundef i32 @llvm.nvvm.read.ptx.sreg.tid.x() - out[i++] = threadIdx.y; // CHECK: call noundef i32 @llvm.nvvm.read.ptx.sreg.tid.y() - out[i++] = threadIdx.z; // CHECK: call noundef i32 @llvm.nvvm.read.ptx.sreg.tid.z() + out[i++] = threadIdx.x; // CHECK: call noundef{{.*}} i32 @llvm.nvvm.read.ptx.sreg.tid.x() + out[i++] = threadIdx.y; // CHECK: call noundef{{.*}} i32 @llvm.nvvm.read.ptx.sreg.tid.y() + out[i++] = threadIdx.z; // CHECK: call noundef{{.*}} i32 @llvm.nvvm.read.ptx.sreg.tid.z() - out[i++] = blockIdx.x; // CHECK: call noundef i32 @llvm.nvvm.read.ptx.sreg.ctaid.x() - out[i++] = blockIdx.y; // CHECK: call noundef i32 @llvm.nvvm.read.ptx.sreg.ctaid.y() - out[i++] = blockIdx.z; // CHECK: call noundef i32 @llvm.nvvm.read.ptx.sreg.ctaid.z() + out[i++] = blockIdx.x; // CHECK: call noundef{{.*}} i32 @llvm.nvvm.read.ptx.sreg.ctaid.x() + out[i++] = blockIdx.y; // CHECK: call noundef{{.*}} i32 @llvm.nvvm.read.ptx.sreg.ctaid.y() + out[i++] = blockIdx.z; // CHECK: call noundef{{.*}} i32 @llvm.nvvm.read.ptx.sreg.ctaid.z() - out[i++] = blockDim.x; // CHECK: call noundef i32 @llvm.nvvm.read.ptx.sreg.ntid.x() - out[i++] = blockDim.y; // CHECK: call noundef i32 @llvm.nvvm.read.ptx.sreg.ntid.y() - out[i++] = blockDim.z; // CHECK: call noundef i32 @llvm.nvvm.read.ptx.sreg.ntid.z() + out[i++] = blockDim.x; // CHECK: call noundef{{.*}} i32 @llvm.nvvm.read.ptx.sreg.ntid.x() + out[i++] = blockDim.y; // CHECK: call noundef{{.*}} i32 @llvm.nvvm.read.ptx.sreg.ntid.y() + out[i++] = blockDim.z; // CHECK: call noundef{{.*}} i32 @llvm.nvvm.read.ptx.sreg.ntid.z() - out[i++] = gridDim.x; // CHECK: call noundef i32 @llvm.nvvm.read.ptx.sreg.nctaid.x() - out[i++] = gridDim.y; // CHECK: call noundef i32 @llvm.nvvm.read.ptx.sreg.nctaid.y() - out[i++] = gridDim.z; // CHECK: call noundef i32 @llvm.nvvm.read.ptx.sreg.nctaid.z() + out[i++] = gridDim.x; // CHECK: call noundef{{.*}} i32 @llvm.nvvm.read.ptx.sreg.nctaid.x() + out[i++] = gridDim.y; // CHECK: call noundef{{.*}} i32 @llvm.nvvm.read.ptx.sreg.nctaid.y() + out[i++] = gridDim.z; // CHECK: call noundef{{.*}} i32 @llvm.nvvm.read.ptx.sreg.nctaid.z() out[i++] = warpSize; // CHECK: store i32 32, diff --git a/clang/test/CodeGenCUDA/long-double.cu b/clang/test/CodeGenCUDA/long-double.cu index d52de972ea3da4e9aaf4c2fed0e4423ae003ec0a..898afcac124b5f841f0d11f08eb301994387362a 100644 --- a/clang/test/CodeGenCUDA/long-double.cu +++ b/clang/test/CodeGenCUDA/long-double.cu @@ -2,6 +2,10 @@ // RUN: -aux-triple x86_64-unknown-gnu-linux -fcuda-is-device \ // RUN: -emit-llvm -o - -x hip %s 2>&1 | FileCheck %s +// RUN: %clang_cc1 -triple spirv64-amd-amdhsa \ +// RUN: -aux-triple x86_64-unknown-gnu-linux -fcuda-is-device \ +// RUN: -emit-llvm -o - -x hip %s 2>&1 | FileCheck %s + // RUN: %clang_cc1 -triple nvptx \ // RUN: -aux-triple x86_64-unknown-gnu-linux -fcuda-is-device \ // RUN: -emit-llvm -o - %s 2>&1 | FileCheck %s diff --git a/clang/test/CodeGenCUDA/spirv-amdgcn-bf16.cu b/clang/test/CodeGenCUDA/spirv-amdgcn-bf16.cu new file mode 100644 index 0000000000000000000000000000000000000000..2a0f84d1daa758d1b9ee105420f5068a6b0af2cb --- /dev/null +++ b/clang/test/CodeGenCUDA/spirv-amdgcn-bf16.cu @@ -0,0 +1,129 @@ +// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py +// REQUIRES: amdgpu-registered-target +// REQUIRES: x86-registered-target + +// RUN: %clang_cc1 "-aux-triple" "x86_64-unknown-linux-gnu" "-triple" "spirv64-amd-amdhsa" \ +// RUN: -fcuda-is-device "-aux-target-cpu" "x86-64" -emit-llvm -o - %s | FileCheck %s + +#include "Inputs/cuda.h" + +// CHECK-LABEL: @_Z8test_argPDF16bDF16b( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[OUT_ADDR:%.*]] = alloca ptr addrspace(4), align 8 +// CHECK-NEXT: [[IN_ADDR:%.*]] = alloca bfloat, align 2 +// CHECK-NEXT: [[BF16:%.*]] = alloca bfloat, align 2 +// CHECK-NEXT: [[OUT_ADDR_ASCAST:%.*]] = addrspacecast ptr [[OUT_ADDR]] to ptr addrspace(4) +// CHECK-NEXT: [[IN_ADDR_ASCAST:%.*]] = addrspacecast ptr [[IN_ADDR]] to ptr addrspace(4) +// CHECK-NEXT: [[BF16_ASCAST:%.*]] = addrspacecast ptr [[BF16]] to ptr addrspace(4) +// CHECK-NEXT: store ptr addrspace(4) [[OUT:%.*]], ptr addrspace(4) [[OUT_ADDR_ASCAST]], align 8 +// CHECK-NEXT: store bfloat [[IN:%.*]], ptr addrspace(4) [[IN_ADDR_ASCAST]], align 2 +// CHECK-NEXT: [[TMP0:%.*]] = load bfloat, ptr addrspace(4) [[IN_ADDR_ASCAST]], align 2 +// CHECK-NEXT: store bfloat [[TMP0]], ptr addrspace(4) [[BF16_ASCAST]], align 2 +// CHECK-NEXT: [[TMP1:%.*]] = load bfloat, ptr addrspace(4) [[BF16_ASCAST]], align 2 +// CHECK-NEXT: [[TMP2:%.*]] = load ptr addrspace(4), ptr addrspace(4) [[OUT_ADDR_ASCAST]], align 8 +// CHECK-NEXT: store bfloat [[TMP1]], ptr addrspace(4) [[TMP2]], align 2 +// CHECK-NEXT: ret void +// +__device__ void test_arg(__bf16 *out, __bf16 in) { + __bf16 bf16 = in; + *out = bf16; +} + +// CHECK-LABEL: @_Z9test_loadPDF16bS_( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[OUT_ADDR:%.*]] = alloca ptr addrspace(4), align 8 +// CHECK-NEXT: [[IN_ADDR:%.*]] = alloca ptr addrspace(4), align 8 +// CHECK-NEXT: [[BF16:%.*]] = alloca bfloat, align 2 +// CHECK-NEXT: [[OUT_ADDR_ASCAST:%.*]] = addrspacecast ptr [[OUT_ADDR]] to ptr addrspace(4) +// CHECK-NEXT: [[IN_ADDR_ASCAST:%.*]] = addrspacecast ptr [[IN_ADDR]] to ptr addrspace(4) +// CHECK-NEXT: [[BF16_ASCAST:%.*]] = addrspacecast ptr [[BF16]] to ptr addrspace(4) +// CHECK-NEXT: store ptr addrspace(4) [[OUT:%.*]], ptr addrspace(4) [[OUT_ADDR_ASCAST]], align 8 +// CHECK-NEXT: store ptr addrspace(4) [[IN:%.*]], ptr addrspace(4) [[IN_ADDR_ASCAST]], align 8 +// CHECK-NEXT: [[TMP0:%.*]] = load ptr addrspace(4), ptr addrspace(4) [[IN_ADDR_ASCAST]], align 8 +// CHECK-NEXT: [[TMP1:%.*]] = load bfloat, ptr addrspace(4) [[TMP0]], align 2 +// CHECK-NEXT: store bfloat [[TMP1]], ptr addrspace(4) [[BF16_ASCAST]], align 2 +// CHECK-NEXT: [[TMP2:%.*]] = load bfloat, ptr addrspace(4) [[BF16_ASCAST]], align 2 +// CHECK-NEXT: [[TMP3:%.*]] = load ptr addrspace(4), ptr addrspace(4) [[OUT_ADDR_ASCAST]], align 8 +// CHECK-NEXT: store bfloat [[TMP2]], ptr addrspace(4) [[TMP3]], align 2 +// CHECK-NEXT: ret void +// +__device__ void test_load(__bf16 *out, __bf16 *in) { + __bf16 bf16 = *in; + *out = bf16; +} + +// CHECK-LABEL: @_Z8test_retDF16b( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[RETVAL:%.*]] = alloca bfloat, align 2 +// CHECK-NEXT: [[IN_ADDR:%.*]] = alloca bfloat, align 2 +// CHECK-NEXT: [[RETVAL_ASCAST:%.*]] = addrspacecast ptr [[RETVAL]] to ptr addrspace(4) +// CHECK-NEXT: [[IN_ADDR_ASCAST:%.*]] = addrspacecast ptr [[IN_ADDR]] to ptr addrspace(4) +// CHECK-NEXT: store bfloat [[IN:%.*]], ptr addrspace(4) [[IN_ADDR_ASCAST]], align 2 +// CHECK-NEXT: [[TMP0:%.*]] = load bfloat, ptr addrspace(4) [[IN_ADDR_ASCAST]], align 2 +// CHECK-NEXT: ret bfloat [[TMP0]] +// +__device__ __bf16 test_ret( __bf16 in) { + return in; +} + +// CHECK-LABEL: @_Z9test_callDF16b( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[RETVAL:%.*]] = alloca bfloat, align 2 +// CHECK-NEXT: [[IN_ADDR:%.*]] = alloca bfloat, align 2 +// CHECK-NEXT: [[RETVAL_ASCAST:%.*]] = addrspacecast ptr [[RETVAL]] to ptr addrspace(4) +// CHECK-NEXT: [[IN_ADDR_ASCAST:%.*]] = addrspacecast ptr [[IN_ADDR]] to ptr addrspace(4) +// CHECK-NEXT: store bfloat [[IN:%.*]], ptr addrspace(4) [[IN_ADDR_ASCAST]], align 2 +// CHECK-NEXT: [[TMP0:%.*]] = load bfloat, ptr addrspace(4) [[IN_ADDR_ASCAST]], align 2 +// CHECK-NEXT: [[CALL:%.*]] = call contract spir_func noundef addrspace(4) bfloat @_Z8test_retDF16b(bfloat noundef [[TMP0]]) #[[ATTR1:[0-9]+]] +// CHECK-NEXT: ret bfloat [[CALL]] +// +__device__ __bf16 test_call( __bf16 in) { + return test_ret(in); +} + + +// CHECK-LABEL: @_Z15test_vec_assignv( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[VEC2_A:%.*]] = alloca <2 x bfloat>, align 4 +// CHECK-NEXT: [[VEC2_B:%.*]] = alloca <2 x bfloat>, align 4 +// CHECK-NEXT: [[VEC4_A:%.*]] = alloca <4 x bfloat>, align 8 +// CHECK-NEXT: [[VEC4_B:%.*]] = alloca <4 x bfloat>, align 8 +// CHECK-NEXT: [[VEC8_A:%.*]] = alloca <8 x bfloat>, align 16 +// CHECK-NEXT: [[VEC8_B:%.*]] = alloca <8 x bfloat>, align 16 +// CHECK-NEXT: [[VEC16_A:%.*]] = alloca <16 x bfloat>, align 32 +// CHECK-NEXT: [[VEC16_B:%.*]] = alloca <16 x bfloat>, align 32 +// CHECK-NEXT: [[VEC2_A_ASCAST:%.*]] = addrspacecast ptr [[VEC2_A]] to ptr addrspace(4) +// CHECK-NEXT: [[VEC2_B_ASCAST:%.*]] = addrspacecast ptr [[VEC2_B]] to ptr addrspace(4) +// CHECK-NEXT: [[VEC4_A_ASCAST:%.*]] = addrspacecast ptr [[VEC4_A]] to ptr addrspace(4) +// CHECK-NEXT: [[VEC4_B_ASCAST:%.*]] = addrspacecast ptr [[VEC4_B]] to ptr addrspace(4) +// CHECK-NEXT: [[VEC8_A_ASCAST:%.*]] = addrspacecast ptr [[VEC8_A]] to ptr addrspace(4) +// CHECK-NEXT: [[VEC8_B_ASCAST:%.*]] = addrspacecast ptr [[VEC8_B]] to ptr addrspace(4) +// CHECK-NEXT: [[VEC16_A_ASCAST:%.*]] = addrspacecast ptr [[VEC16_A]] to ptr addrspace(4) +// CHECK-NEXT: [[VEC16_B_ASCAST:%.*]] = addrspacecast ptr [[VEC16_B]] to ptr addrspace(4) +// CHECK-NEXT: [[TMP0:%.*]] = load <2 x bfloat>, ptr addrspace(4) [[VEC2_B_ASCAST]], align 4 +// CHECK-NEXT: store <2 x bfloat> [[TMP0]], ptr addrspace(4) [[VEC2_A_ASCAST]], align 4 +// CHECK-NEXT: [[TMP1:%.*]] = load <4 x bfloat>, ptr addrspace(4) [[VEC4_B_ASCAST]], align 8 +// CHECK-NEXT: store <4 x bfloat> [[TMP1]], ptr addrspace(4) [[VEC4_A_ASCAST]], align 8 +// CHECK-NEXT: [[TMP2:%.*]] = load <8 x bfloat>, ptr addrspace(4) [[VEC8_B_ASCAST]], align 16 +// CHECK-NEXT: store <8 x bfloat> [[TMP2]], ptr addrspace(4) [[VEC8_A_ASCAST]], align 16 +// CHECK-NEXT: [[TMP3:%.*]] = load <16 x bfloat>, ptr addrspace(4) [[VEC16_B_ASCAST]], align 32 +// CHECK-NEXT: store <16 x bfloat> [[TMP3]], ptr addrspace(4) [[VEC16_A_ASCAST]], align 32 +// CHECK-NEXT: ret void +// +__device__ void test_vec_assign() { + typedef __attribute__((ext_vector_type(2))) __bf16 bf16_x2; + bf16_x2 vec2_a, vec2_b; + vec2_a = vec2_b; + + typedef __attribute__((ext_vector_type(4))) __bf16 bf16_x4; + bf16_x4 vec4_a, vec4_b; + vec4_a = vec4_b; + + typedef __attribute__((ext_vector_type(8))) __bf16 bf16_x8; + bf16_x8 vec8_a, vec8_b; + vec8_a = vec8_b; + + typedef __attribute__((ext_vector_type(16))) __bf16 bf16_x16; + bf16_x16 vec16_a, vec16_b; + vec16_a = vec16_b; +} diff --git a/clang/test/CodeGenCXX/control-flow-in-stmt-expr.cpp b/clang/test/CodeGenCXX/control-flow-in-stmt-expr.cpp index ac466ee5bba40b0dd2d24aa0159e115611669898..4eafa720e0cb41b0248835a9475ae2cbb08399a5 100644 --- a/clang/test/CodeGenCXX/control-flow-in-stmt-expr.cpp +++ b/clang/test/CodeGenCXX/control-flow-in-stmt-expr.cpp @@ -158,16 +158,15 @@ void ArrayInit() { // CHECK-LABEL: define dso_local void @_Z9ArrayInitv() // CHECK: %arrayinit.endOfInit = alloca ptr, align 8 // CHECK: %cleanup.dest.slot = alloca i32, align 4 - // CHECK: %arrayinit.begin = getelementptr inbounds [4 x %struct.Printy], ptr %arr, i64 0, i64 0 - // CHECK: store ptr %arrayinit.begin, ptr %arrayinit.endOfInit, align 8 + // CHECK: store ptr %arr, ptr %arrayinit.endOfInit, align 8 Printy arr[4] = { Printy("a"), - // CHECK: call void @_ZN6PrintyC1EPKc(ptr noundef nonnull align 8 dereferenceable(8) %arrayinit.begin, ptr noundef @.str) - // CHECK: [[ARRAYINIT_ELEMENT1:%.+]] = getelementptr inbounds %struct.Printy, ptr %arrayinit.begin, i64 1 + // CHECK: call void @_ZN6PrintyC1EPKc(ptr noundef nonnull align 8 dereferenceable(8) %arr, ptr noundef @.str) + // CHECK: [[ARRAYINIT_ELEMENT1:%.+]] = getelementptr inbounds %struct.Printy, ptr %arr, i64 1 // CHECK: store ptr [[ARRAYINIT_ELEMENT1]], ptr %arrayinit.endOfInit, align 8 Printy("b"), // CHECK: call void @_ZN6PrintyC1EPKc(ptr noundef nonnull align 8 dereferenceable(8) [[ARRAYINIT_ELEMENT1]], ptr noundef @.str.1) - // CHECK: [[ARRAYINIT_ELEMENT2:%.+]] = getelementptr inbounds %struct.Printy, ptr [[ARRAYINIT_ELEMENT1]], i64 1 + // CHECK: [[ARRAYINIT_ELEMENT2:%.+]] = getelementptr inbounds %struct.Printy, ptr %arr, i64 2 // CHECK: store ptr [[ARRAYINIT_ELEMENT2]], ptr %arrayinit.endOfInit, align 8 ({ // CHECK: br i1 {{.*}}, label %if.then, label %if.end @@ -180,7 +179,7 @@ void ArrayInit() { // CHECK: if.end: Printy("c"); // CHECK-NEXT: call void @_ZN6PrintyC1EPKc - // CHECK-NEXT: %arrayinit.element2 = getelementptr inbounds %struct.Printy, ptr %arrayinit.element1, i64 1 + // CHECK-NEXT: %arrayinit.element2 = getelementptr inbounds %struct.Printy, ptr %arr, i64 3 // CHECK-NEXT: store ptr %arrayinit.element2, ptr %arrayinit.endOfInit, align 8 }), ({ @@ -212,14 +211,14 @@ void ArrayInit() { // CHECK: cleanup: // CHECK-NEXT: %1 = load ptr, ptr %arrayinit.endOfInit, align 8 - // CHECK-NEXT: %arraydestroy.isempty = icmp eq ptr %arrayinit.begin, %1 + // CHECK-NEXT: %arraydestroy.isempty = icmp eq ptr %arr, %1 // CHECK-NEXT: br i1 %arraydestroy.isempty, label %[[ARRAY_DESTROY_DONE2:.+]], label %[[ARRAY_DESTROY_BODY2:.+]] // CHECK: [[ARRAY_DESTROY_BODY2]]: // CHECK-NEXT: %arraydestroy.elementPast = phi ptr [ %1, %cleanup ], [ %arraydestroy.element, %[[ARRAY_DESTROY_BODY2]] ] // CHECK-NEXT: %arraydestroy.element = getelementptr inbounds %struct.Printy, ptr %arraydestroy.elementPast, i64 -1 // CHECK-NEXT: call void @_ZN6PrintyD1Ev(ptr noundef nonnull align 8 dereferenceable(8) %arraydestroy.element) - // CHECK-NEXT: %arraydestroy.done = icmp eq ptr %arraydestroy.element, %arrayinit.begin + // CHECK-NEXT: %arraydestroy.done = icmp eq ptr %arraydestroy.element, %arr // CHECK-NEXT: br i1 %arraydestroy.done, label %[[ARRAY_DESTROY_DONE2]], label %[[ARRAY_DESTROY_BODY2]] // CHECK: [[ARRAY_DESTROY_DONE2]]: @@ -238,8 +237,7 @@ void ArraySubobjects() { // CHECK: call void @_ZN6PrintyC1EPKc // CHECK: call void @_ZN6PrintyC1EPKc {Printy("a"), - // CHECK: [[ARRAYINIT_BEGIN:%.+]] = getelementptr inbounds [2 x %struct.Printy] - // CHECK: store ptr [[ARRAYINIT_BEGIN]], ptr %arrayinit.endOfInit, align 8 + // CHECK: store ptr %arr2, ptr %arrayinit.endOfInit, align 8 // CHECK: call void @_ZN6PrintyC1EPKc // CHECK: [[ARRAYINIT_ELEMENT:%.+]] = getelementptr inbounds %struct.Printy // CHECK: store ptr [[ARRAYINIT_ELEMENT]], ptr %arrayinit.endOfInit, align 8 @@ -248,7 +246,7 @@ void ArraySubobjects() { return; // CHECK: if.then: // CHECK-NEXT: [[V0:%.+]] = load ptr, ptr %arrayinit.endOfInit, align 8 - // CHECK-NEXT: %arraydestroy.isempty = icmp eq ptr [[ARRAYINIT_BEGIN]], [[V0]] + // CHECK-NEXT: %arraydestroy.isempty = icmp eq ptr %arr2, [[V0]] // CHECK-NEXT: br i1 %arraydestroy.isempty, label %[[ARRAY_DESTROY_DONE:.+]], label %[[ARRAY_DESTROY_BODY:.+]] } Printy("b"); @@ -268,7 +266,7 @@ void ArraySubobjects() { // CHECK-NEXT: %arraydestroy.elementPast = phi ptr [ %0, %if.then ], [ %arraydestroy.element, %[[ARRAY_DESTROY_BODY]] ] // CHECK-NEXT: %arraydestroy.element = getelementptr inbounds %struct.Printy, ptr %arraydestroy.elementPast, i64 -1 // CHECK-NEXT: call void @_ZN6PrintyD1Ev(ptr noundef nonnull align 8 dereferenceable(8) %arraydestroy.element) - // CHECK-NEXT: %arraydestroy.done = icmp eq ptr %arraydestroy.element, [[ARRAYINIT_BEGIN]] + // CHECK-NEXT: %arraydestroy.done = icmp eq ptr %arraydestroy.element, %arr2 // CHECK-NEXT: br i1 %arraydestroy.done, label %[[ARRAY_DESTROY_DONE]], label %[[ARRAY_DESTROY_BODY]] // CHECK: [[ARRAY_DESTROY_DONE]] @@ -277,11 +275,11 @@ void ArraySubobjects() { // CHECK-NEXT: br label %[[ARRAY_DESTROY_BODY2:.+]] // CHECK: [[ARRAY_DESTROY_BODY2]]: - // CHECK-NEXT: %arraydestroy.elementPast5 = phi ptr [ %1, %[[ARRAY_DESTROY_DONE]] ], [ %arraydestroy.element6, %[[ARRAY_DESTROY_BODY2]] ] - // CHECK-NEXT: %arraydestroy.element6 = getelementptr inbounds %struct.Printy, ptr %arraydestroy.elementPast5, i64 -1 - // CHECK-NEXT: call void @_ZN6PrintyD1Ev(ptr noundef nonnull align 8 dereferenceable(8) %arraydestroy.element6) - // CHECK-NEXT: %arraydestroy.done7 = icmp eq ptr %arraydestroy.element6, [[ARRAY_BEGIN]] - // CHECK-NEXT: br i1 %arraydestroy.done7, label %[[ARRAY_DESTROY_DONE2:.+]], label %[[ARRAY_DESTROY_BODY2]] + // CHECK-NEXT: %arraydestroy.elementPast4 = phi ptr [ %1, %[[ARRAY_DESTROY_DONE]] ], [ %arraydestroy.element5, %[[ARRAY_DESTROY_BODY2]] ] + // CHECK-NEXT: %arraydestroy.element5 = getelementptr inbounds %struct.Printy, ptr %arraydestroy.elementPast4, i64 -1 + // CHECK-NEXT: call void @_ZN6PrintyD1Ev(ptr noundef nonnull align 8 dereferenceable(8) %arraydestroy.element5) + // CHECK-NEXT: %arraydestroy.done6 = icmp eq ptr %arraydestroy.element5, [[ARRAY_BEGIN]] + // CHECK-NEXT: br i1 %arraydestroy.done6, label %[[ARRAY_DESTROY_DONE2:.+]], label %[[ARRAY_DESTROY_BODY2]] // CHECK: [[ARRAY_DESTROY_DONE2]]: diff --git a/clang/test/CodeGenCXX/cxx0x-initializer-references.cpp b/clang/test/CodeGenCXX/cxx0x-initializer-references.cpp index b19ca1d861b11c7e1e5283d56614386c0c7ed3d3..419525d0544d52e736e8e33ba32516d9088f9aaf 100644 --- a/clang/test/CodeGenCXX/cxx0x-initializer-references.cpp +++ b/clang/test/CodeGenCXX/cxx0x-initializer-references.cpp @@ -52,11 +52,10 @@ namespace reference { // CHECK-NEXT: store ptr %{{.*}}, ptr %{{.*}}, align const A &ra1{1, i}; - // CHECK-NEXT: getelementptr inbounds [3 x i32], ptr %{{.*}}, i{{32|64}} 0, i{{32|64}} 0 // CHECK-NEXT: store i32 1 // CHECK-NEXT: getelementptr inbounds i32, ptr %{{.*}}, i{{32|64}} 1 // CHECK-NEXT: store i32 2 - // CHECK-NEXT: getelementptr inbounds i32, ptr %{{.*}}, i{{32|64}} 1 + // CHECK-NEXT: getelementptr inbounds i32, ptr %{{.*}}, i{{32|64}} 2 // CHECK-NEXT: %[[I2:.*]] = load i32, ptr // CHECK-NEXT: store i32 %[[I2]] // CHECK-NEXT: store ptr %{{.*}}, ptr %{{.*}}, align diff --git a/clang/test/CodeGenCXX/cxx0x-initializer-stdinitializerlist-startend.cpp b/clang/test/CodeGenCXX/cxx0x-initializer-stdinitializerlist-startend.cpp index d9e4c5d5403c25143f8b454e84a2afc6903f8849..e2d566121331fdc7b57354669c2f4dfb48ae91c3 100644 --- a/clang/test/CodeGenCXX/cxx0x-initializer-stdinitializerlist-startend.cpp +++ b/clang/test/CodeGenCXX/cxx0x-initializer-stdinitializerlist-startend.cpp @@ -40,8 +40,7 @@ void fn1(int i) { // CHECK-LABEL: define{{.*}} void @_Z3fn1i // temporary array // CHECK: [[array:%[^ ]+]] = alloca [3 x i32] - // CHECK: getelementptr inbounds [3 x i32], ptr [[array]], i{{32|64}} 0 - // CHECK-NEXT: store i32 1, ptr + // CHECK: store i32 1, ptr // CHECK-NEXT: getelementptr // CHECK-NEXT: store // CHECK-NEXT: getelementptr diff --git a/clang/test/CodeGenCXX/cxx0x-initializer-stdinitializerlist.cpp b/clang/test/CodeGenCXX/cxx0x-initializer-stdinitializerlist.cpp index aa2f078a5fb0ca61e602a2cb8d7cbc3ecd889e22..3d0cf968bfd54cbaadef1a18fd66e732e99cea99 100644 --- a/clang/test/CodeGenCXX/cxx0x-initializer-stdinitializerlist.cpp +++ b/clang/test/CodeGenCXX/cxx0x-initializer-stdinitializerlist.cpp @@ -122,8 +122,7 @@ void fn1(int i) { // X86: [[array:%[^ ]+]] = alloca [3 x i32] // AMDGCN: [[alloca:%[^ ]+]] = alloca [3 x i32], align 4, addrspace(5) // AMDGCN: [[array:%[^ ]+]] ={{.*}} addrspacecast ptr addrspace(5) [[alloca]] to ptr - // CHECK: getelementptr inbounds [3 x i32], ptr [[array]], i{{32|64}} 0 - // CHECK-NEXT: store i32 1, ptr + // CHECK: store i32 1, ptr // CHECK-NEXT: getelementptr // CHECK-NEXT: store // CHECK-NEXT: getelementptr diff --git a/clang/test/CodeGenCXX/cxx11-initializer-array-new.cpp b/clang/test/CodeGenCXX/cxx11-initializer-array-new.cpp index 48ee019a55f555aff3da0890eee613ec5e26700d..d86c712372cd89cc2ead093b586e36b1d086eec1 100644 --- a/clang/test/CodeGenCXX/cxx11-initializer-array-new.cpp +++ b/clang/test/CodeGenCXX/cxx11-initializer-array-new.cpp @@ -16,22 +16,20 @@ void *p = new S[2][3]{ { 1, 2, 3 }, { 4, 5, 6 } }; // { 1, 2, 3 } // // -// CHECK: %[[S_0_0:.*]] = getelementptr inbounds [3 x %[[S:.*]]], ptr %[[START_AS_i8]], i64 0, i64 0 -// CHECK: call void @_ZN1SC1Ei(ptr {{[^,]*}} %[[S_0_0]], i32 noundef 1) -// CHECK: %[[S_0_1:.*]] = getelementptr inbounds %[[S]], ptr %[[S_0_0]], i64 1 +// CHECK: call void @_ZN1SC1Ei(ptr {{[^,]*}} %[[START_AS_i8]], i32 noundef 1) +// CHECK: %[[S_0_1:.*]] = getelementptr inbounds %[[S:.+]], ptr %[[START_AS_i8]], i64 1 // CHECK: call void @_ZN1SC1Ei(ptr {{[^,]*}} %[[S_0_1]], i32 noundef 2) -// CHECK: %[[S_0_2:.*]] = getelementptr inbounds %[[S]], ptr %[[S_0_1]], i64 1 +// CHECK: %[[S_0_2:.*]] = getelementptr inbounds %[[S]], ptr %[[START_AS_i8]], i64 2 // CHECK: call void @_ZN1SC1Ei(ptr {{[^,]*}} %[[S_0_2]], i32 noundef 3) // // { 4, 5, 6 } // // CHECK: %[[S_1:.*]] = getelementptr inbounds [3 x %[[S]]], ptr %[[START_AS_i8]], i64 1 // -// CHECK: %[[S_1_0:.*]] = getelementptr inbounds [3 x %[[S]]], ptr %[[S_1]], i64 0, i64 0 -// CHECK: call void @_ZN1SC1Ei(ptr {{[^,]*}} %[[S_1_0]], i32 noundef 4) -// CHECK: %[[S_1_1:.*]] = getelementptr inbounds %[[S]], ptr %[[S_1_0]], i64 1 +// CHECK: call void @_ZN1SC1Ei(ptr {{[^,]*}} %[[S_1]], i32 noundef 4) +// CHECK: %[[S_1_1:.*]] = getelementptr inbounds %[[S]], ptr %[[S_1]], i64 1 // CHECK: call void @_ZN1SC1Ei(ptr {{[^,]*}} %[[S_1_1]], i32 noundef 5) -// CHECK: %[[S_1_2:.*]] = getelementptr inbounds %[[S]], ptr %[[S_1_1]], i64 1 +// CHECK: %[[S_1_2:.*]] = getelementptr inbounds %[[S]], ptr %[[S_1]], i64 2 // CHECK: call void @_ZN1SC1Ei(ptr {{[^,]*}} %[[S_1_2]], i32 noundef 6) // // CHECK-NOT: br i1 @@ -57,22 +55,20 @@ void *q = new S[n][3]{ { 1, 2, 3 }, { 4, 5, 6 } }; // { 1, 2, 3 } // // -// CHECK: %[[S_0_0:.*]] = getelementptr inbounds [3 x %[[S]]], ptr %[[START_AS_i8]], i64 0, i64 0 -// CHECK: call void @_ZN1SC1Ei(ptr {{[^,]*}} %[[S_0_0]], i32 noundef 1) -// CHECK: %[[S_0_1:.*]] = getelementptr inbounds %[[S]], ptr %[[S_0_0]], i64 1 +// CHECK: call void @_ZN1SC1Ei(ptr {{[^,]*}} %[[START_AS_i8]], i32 noundef 1) +// CHECK: %[[S_0_1:.*]] = getelementptr inbounds %[[S]], ptr %[[START_AS_i8]], i64 1 // CHECK: call void @_ZN1SC1Ei(ptr {{[^,]*}} %[[S_0_1]], i32 noundef 2) -// CHECK: %[[S_0_2:.*]] = getelementptr inbounds %[[S]], ptr %[[S_0_1]], i64 1 +// CHECK: %[[S_0_2:.*]] = getelementptr inbounds %[[S]], ptr %[[START_AS_i8]], i64 2 // CHECK: call void @_ZN1SC1Ei(ptr {{[^,]*}} %[[S_0_2]], i32 noundef 3) // // { 4, 5, 6 } // // CHECK: %[[S_1:.*]] = getelementptr inbounds [3 x %[[S]]], ptr %[[START_AS_i8]], i64 1 // -// CHECK: %[[S_1_0:.*]] = getelementptr inbounds [3 x %[[S]]], ptr %[[S_1]], i64 0, i64 0 -// CHECK: call void @_ZN1SC1Ei(ptr {{[^,]*}} %[[S_1_0]], i32 noundef 4) -// CHECK: %[[S_1_1:.*]] = getelementptr inbounds %[[S]], ptr %[[S_1_0]], i64 1 +// CHECK: call void @_ZN1SC1Ei(ptr {{[^,]*}} %[[S_1]], i32 noundef 4) +// CHECK: %[[S_1_1:.*]] = getelementptr inbounds %[[S]], ptr %[[S_1]], i64 1 // CHECK: call void @_ZN1SC1Ei(ptr {{[^,]*}} %[[S_1_1]], i32 noundef 5) -// CHECK: %[[S_1_2:.*]] = getelementptr inbounds %[[S]], ptr %[[S_1_1]], i64 1 +// CHECK: %[[S_1_2:.*]] = getelementptr inbounds %[[S]], ptr %[[S_1]], i64 2 // CHECK: call void @_ZN1SC1Ei(ptr {{[^,]*}} %[[S_1_2]], i32 noundef 6) // // And the rest. @@ -114,13 +110,12 @@ void *r = new T[n][3]{ { 1, 2, 3 }, { 4, 5, 6 } }; // { 1, 2, 3 } // // -// CHECK: %[[T_0_0:.*]] = getelementptr inbounds [3 x %[[T:.*]]], ptr %[[ALLOC]], i64 0, i64 0 -// CHECK: %[[T_0_0_0:.*]] = getelementptr inbounds %[[T]], ptr %[[T_0_0]], i32 0, i32 0 +// CHECK: %[[T_0_0_0:.*]] = getelementptr inbounds %[[T:.+]], ptr %[[ALLOC]], i32 0, i32 0 // CHECK: store i32 1, ptr %[[T_0_0_0]] -// CHECK: %[[T_0_1:.*]] = getelementptr inbounds %[[T]], ptr %[[T_0_0]], i64 1 +// CHECK: %[[T_0_1:.*]] = getelementptr inbounds %[[T]], ptr %[[ALLOC]], i64 1 // CHECK: %[[T_0_1_0:.*]] = getelementptr inbounds %[[T]], ptr %[[T_0_1]], i32 0, i32 0 // CHECK: store i32 2, ptr %[[T_0_1_0]] -// CHECK: %[[T_0_2:.*]] = getelementptr inbounds %[[T]], ptr %[[T_0_1]], i64 1 +// CHECK: %[[T_0_2:.*]] = getelementptr inbounds %[[T]], ptr %[[ALLOC]], i64 2 // CHECK: %[[T_0_2_0:.*]] = getelementptr inbounds %[[T]], ptr %[[T_0_2]], i32 0, i32 0 // CHECK: store i32 3, ptr %[[T_0_2_0]] // @@ -128,13 +123,12 @@ void *r = new T[n][3]{ { 1, 2, 3 }, { 4, 5, 6 } }; // // CHECK: %[[T_1:.*]] = getelementptr inbounds [3 x %[[T]]], ptr %[[ALLOC]], i64 1 // -// CHECK: %[[T_1_0:.*]] = getelementptr inbounds [3 x %[[T]]], ptr %[[T_1]], i64 0, i64 0 -// CHECK: %[[T_1_0_0:.*]] = getelementptr inbounds %[[T]], ptr %[[T_1_0]], i32 0, i32 0 +// CHECK: %[[T_1_0_0:.*]] = getelementptr inbounds %[[T]], ptr %[[T_1]], i32 0, i32 0 // CHECK: store i32 4, ptr %[[T_1_0_0]] -// CHECK: %[[T_1_1:.*]] = getelementptr inbounds %[[T]], ptr %[[T_1_0]], i64 1 +// CHECK: %[[T_1_1:.*]] = getelementptr inbounds %[[T]], ptr %[[T_1]], i64 1 // CHECK: %[[T_1_1_0:.*]] = getelementptr inbounds %[[T]], ptr %[[T_1_1]], i32 0, i32 0 // CHECK: store i32 5, ptr %[[T_1_1_0]] -// CHECK: %[[T_1_2:.*]] = getelementptr inbounds %[[T]], ptr %[[T_1_1]], i64 1 +// CHECK: %[[T_1_2:.*]] = getelementptr inbounds %[[T]], ptr %[[T_1]], i64 2 // CHECK: %[[T_1_2_0:.*]] = getelementptr inbounds %[[T]], ptr %[[T_1_2]], i32 0, i32 0 // CHECK: store i32 6, ptr %[[T_1_2_0]] // diff --git a/clang/test/CodeGenCXX/cxx2b-deducing-this.cpp b/clang/test/CodeGenCXX/cxx2b-deducing-this.cpp index 649fe2afbf4e91a08661c33eefd1d4fe2fed0ae3..f9f9fbd7397f8547de51a268ea37df725baf9744 100644 --- a/clang/test/CodeGenCXX/cxx2b-deducing-this.cpp +++ b/clang/test/CodeGenCXX/cxx2b-deducing-this.cpp @@ -245,3 +245,23 @@ void f() { d(); } } + + +namespace P2797 { +struct C { + void c(this const C&); // #first + void c() &; // #second + static void c(int = 0); // #third + + void d() { + (&C::c)(C{}); + (&C::c)(); + } +}; +void test() { + (void)C{}.d(); +} +// CHECK-LABEL: {{.*}} @_ZN5P27971C1dEv +// CHECK: call void @_ZNH5P27971C1cERKS0_ +// CHECK: call void @_ZN5P27971C1cEi +} diff --git a/clang/test/CodeGenCXX/debug-info-struct-align.cpp b/clang/test/CodeGenCXX/debug-info-struct-align.cpp index 1269cbce83ef0a03894eb0ee83450f6d6f8f8c4e..cd91f4c302ddc6a191639c88725899abfdc4164b 100644 --- a/clang/test/CodeGenCXX/debug-info-struct-align.cpp +++ b/clang/test/CodeGenCXX/debug-info-struct-align.cpp @@ -25,3 +25,11 @@ struct MyType2 { MyType2 mt2; static_assert(alignof(MyType2) == 1, "alignof MyType2 is wrong"); + +#pragma pack(1) +struct MyType3 { + int m; +}; +MyType3 mt3; + +static_assert(alignof(MyType3) == 1, "alignof MyType3 is wrong"); diff --git a/clang/test/CodeGenCXX/inline-then-fold-variadics.cpp b/clang/test/CodeGenCXX/inline-then-fold-variadics.cpp new file mode 100644 index 0000000000000000000000000000000000000000..a0673b96626d15e9173d0490c5ff1f55d584c1a6 --- /dev/null +++ b/clang/test/CodeGenCXX/inline-then-fold-variadics.cpp @@ -0,0 +1,181 @@ +// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --function-signature +// REQUIRES: webassembly-registered-target + +// Simple calls to known variadic functions that are completely elided when +// optimisations are on This is a functional check that the expand-variadic pass +// is consistent with clang's va_arg handling + +// When expand-variadics is added to the default pipeline, clang -O1 will +// suffice here -Wno-varargs avoids warning second argument to 'va_start' is not +// the last named parameter + +// RUN: %clang_cc1 %s -triple wasm32-unknown-unknown -Wno-varargs -O1 -emit-llvm -o - | opt - -S --passes='module(expand-variadics,default)' --expand-variadics-override=optimize -o - | FileCheck %s + +#include +#include + +template static X first(...) { + va_list va; + __builtin_va_start(va, 0); + X r = va_arg(va, X); + va_end(va); + return r; +} + +template static Y second(...) { + va_list va; + __builtin_va_start(va, 0); + va_arg(va, X); + Y r = va_arg(va, Y); + va_end(va); + return r; +} + +extern "C" { + +// CHECK-LABEL: define {{[^@]+}}@first_pair_i32 +// CHECK-SAME: (i32 noundef returned [[X:%.*]], i32 noundef [[Y:%.*]]) +// CHECK-NEXT: entry: +// CHECK-NEXT: ret i32 [[X]] +// +int first_pair_i32(int x, int y) { return first(x, y); } + +// CHECK-LABEL: define {{[^@]+}}@second_pair_i32 +// CHECK-SAME: (i32 noundef [[X:%.*]], i32 noundef returned [[Y:%.*]]) +// CHECK-NEXT: entry: +// CHECK-NEXT: ret i32 [[Y]] +// +int second_pair_i32(int x, int y) { return second(x, y); } + +// CHECK-LABEL: define {{[^@]+}}@first_pair_f64 +// CHECK-SAME: (double noundef returned [[X:%.*]], double noundef [[Y:%.*]]) +// CHECK-NEXT: entry: +// CHECK-NEXT: ret double [[X]] +// +double first_pair_f64(double x, double y) { + return first(x, y); +} + +// CHECK-LABEL: define {{[^@]+}}@second_pair_f64 +// CHECK-SAME: (double noundef [[X:%.*]], double noundef returned [[Y:%.*]]) +// CHECK-NEXT: entry: +// CHECK-NEXT: ret double [[Y]] +// +double second_pair_f64(double x, double y) { + return second(x, y); +} +} + +extern "C" { + +// CHECK-LABEL: define {{[^@]+}}@first_i32_f64 +// CHECK-SAME: (i32 noundef returned [[X:%.*]], double noundef [[Y:%.*]]) +// CHECK-NEXT: entry: +// CHECK-NEXT: ret i32 [[X]] +// +int first_i32_f64(int x, double y) { return first(x, y); } + +// CHECK-LABEL: define {{[^@]+}}@second_i32_f64 +// CHECK-SAME: (i32 noundef [[X:%.*]], double noundef returned [[Y:%.*]]) +// CHECK-NEXT: entry: +// CHECK-NEXT: ret double [[Y]] +// +double second_i32_f64(int x, double y) { return second(x, y); } + +// CHECK-LABEL: define {{[^@]+}}@first_f64_i32 +// CHECK-SAME: (double noundef returned [[X:%.*]], i32 noundef [[Y:%.*]]) +// CHECK-NEXT: entry: +// CHECK-NEXT: ret double [[X]] +// +double first_f64_i32(double x, int y) { return first(x, y); } + +// CHECK-LABEL: define {{[^@]+}}@second_f64_i32 +// CHECK-SAME: (double noundef [[X:%.*]], i32 noundef returned [[Y:%.*]]) +// CHECK-NEXT: entry: +// CHECK-NEXT: ret i32 [[Y]] +// +int second_f64_i32(double x, int y) { return second(x, y); } +} + +extern "C" { +typedef uint64_t ulong2 __attribute__((__vector_size__(16), __aligned__(16))); + +// CHECK-LABEL: define {{[^@]+}}@first_i32_ulong2 +// CHECK-SAME: (i32 noundef returned [[X:%.*]], ptr nocapture noundef readonly [[Y:%.*]]) +// CHECK-NEXT: entry: +// CHECK-NEXT: ret i32 [[X]] +// +int first_i32_ulong2(int x, ulong2 *y) { return first(x, *y); } + +// CHECK-LABEL: define {{[^@]+}}@second_i32_ulong2 +// CHECK-SAME: (i32 noundef [[X:%.*]], ptr nocapture noundef readonly [[Y:%.*]], ptr nocapture noundef writeonly [[R:%.*]]) local_unnamed_addr #[[ATTR1:[0-9]+]] { +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = load <2 x i64>, ptr [[Y]], align 16, !tbaa [[TBAA2:![0-9]+]] +// CHECK-NEXT: store <2 x i64> [[TMP0]], ptr [[R]], align 16, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void +// +void second_i32_ulong2(int x, ulong2 *y, ulong2 *r) { + *r = second(x, *y); +} + +// CHECK-LABEL: define {{[^@]+}}@first_ulong2_i32 +// CHECK-SAME: (ptr nocapture noundef readonly [[X:%.*]], i32 noundef [[Y:%.*]], ptr nocapture noundef writeonly [[R:%.*]]) local_unnamed_addr #[[ATTR1]] { +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = load <2 x i64>, ptr [[X]], align 16, !tbaa [[TBAA2]] +// CHECK-NEXT: store <2 x i64> [[TMP0]], ptr [[R]], align 16, !tbaa [[TBAA2]] +// CHECK-NEXT: ret void +// +void first_ulong2_i32(ulong2 *x, int y, ulong2 *r) { + *r = first(*x, y); +} + +// CHECK-LABEL: define {{[^@]+}}@second_ulong2_i32 +// CHECK-SAME: (ptr nocapture noundef readonly [[X:%.*]], i32 noundef returned [[Y:%.*]]) +// CHECK-NEXT: entry: +// CHECK-NEXT: ret i32 [[Y]] +// +int second_ulong2_i32(ulong2 *x, int y) { return second(*x, y); } +} + +// ascending alignment +typedef struct { + char c; + short s; + int i; + long l; + float f; + double d; +} asc; + +extern "C" { + +// CHECK-LABEL: define {{[^@]+}}@first_i32_asc +// CHECK-SAME: (i32 noundef returned [[X:%.*]], ptr nocapture noundef readonly [[Y:%.*]]) +// CHECK-NEXT: entry: +// CHECK-NEXT: ret i32 [[X]] +// +int first_i32_asc(int x, asc *y) { return first(x, *y); } + +// CHECK-LABEL: define {{[^@]+}}@second_i32_asc +// CHECK-SAME: (i32 noundef [[X:%.*]], ptr nocapture noundef readonly [[Y:%.*]], ptr nocapture noundef writeonly [[R:%.*]]) local_unnamed_addr #[[ATTR1]] { +// CHECK-NEXT: entry: +// CHECK-NEXT: tail call void @llvm.memmove.p0.p0.i32(ptr noundef nonnull align 8 dereferenceable(24) [[R]], ptr noundef nonnull align 1 dereferenceable(24) [[Y]], i32 24, i1 false) +// CHECK-NEXT: ret void +// +void second_i32_asc(int x, asc *y, asc *r) { *r = second(x, *y); } + +// CHECK-LABEL: define {{[^@]+}}@first_asc_i32 +// CHECK-SAME: (ptr nocapture noundef readonly [[X:%.*]], i32 noundef [[Y:%.*]], ptr nocapture noundef writeonly [[R:%.*]]) local_unnamed_addr #[[ATTR1]] { +// CHECK-NEXT: entry: +// CHECK-NEXT: tail call void @llvm.memmove.p0.p0.i32(ptr noundef nonnull align 8 dereferenceable(24) [[R]], ptr noundef nonnull align 1 dereferenceable(24) [[X]], i32 24, i1 false) +// CHECK-NEXT: ret void +// +void first_asc_i32(asc *x, int y, asc *r) { *r = first(*x, y); } + +// CHECK-LABEL: define {{[^@]+}}@second_asc_i32 +// CHECK-SAME: (ptr nocapture noundef readonly [[X:%.*]], i32 noundef returned [[Y:%.*]]) +// CHECK-NEXT: entry: +// CHECK-NEXT: ret i32 [[Y]] +// +int second_asc_i32(asc *x, int y) { return second(*x, y); } +} diff --git a/clang/test/CodeGenCXX/partial-destruction.cpp b/clang/test/CodeGenCXX/partial-destruction.cpp index 840e43880293b9fa0a7478b115b3ceb9376042c5..8ceb4b9bbedeaaea29ee9f654e22d18eef0281f0 100644 --- a/clang/test/CodeGenCXX/partial-destruction.cpp +++ b/clang/test/CodeGenCXX/partial-destruction.cpp @@ -20,15 +20,14 @@ namespace test0 { // CHECK-NEXT: [[SEL:%.*]] = alloca i32 // Initialize. - // CHECK-NEXT: [[E_BEGIN:%.*]] = getelementptr inbounds [10 x [[A]]], ptr [[AS]], i64 0, i64 0 - // CHECK-NEXT: store ptr [[E_BEGIN]], ptr [[ENDVAR]] - // CHECK-NEXT: invoke void @_ZN5test01AC1Ei(ptr {{[^,]*}} [[E_BEGIN]], i32 noundef 5) - // CHECK: [[E1:%.*]] = getelementptr inbounds [[A]], ptr [[E_BEGIN]], i64 1 + // CHECK-NEXT: store ptr [[AS]], ptr [[ENDVAR]] + // CHECK-NEXT: invoke void @_ZN5test01AC1Ei(ptr {{[^,]*}} [[AS]], i32 noundef 5) + // CHECK: [[E1:%.*]] = getelementptr inbounds [[A]], ptr [[AS]], i64 1 // CHECK-NEXT: store ptr [[E1]], ptr [[ENDVAR]] // CHECK-NEXT: invoke void @_ZN5test01AC1Ei(ptr {{[^,]*}} [[E1]], i32 noundef 7) - // CHECK: [[E2:%.*]] = getelementptr inbounds [[A]], ptr [[E1]], i64 1 + // CHECK: [[E2:%.*]] = getelementptr inbounds [[A]], ptr [[AS]], i64 2 // CHECK-NEXT: store ptr [[E2]], ptr [[ENDVAR]] - // CHECK-NEXT: [[E_END:%.*]] = getelementptr inbounds [[A]], ptr [[E_BEGIN]], i64 10 + // CHECK-NEXT: [[E_END:%.*]] = getelementptr inbounds [[A]], ptr [[AS]], i64 10 // CHECK-NEXT: br label // CHECK: [[E_CUR:%.*]] = phi ptr [ [[E2]], {{%.*}} ], [ [[E_NEXT:%.*]], {{%.*}} ] // CHECK-NEXT: invoke void @_ZN5test01AC1Ev(ptr {{[^,]*}} [[E_CUR]]) @@ -56,13 +55,13 @@ namespace test0 { // CHECK: landingpad { ptr, i32 } // CHECK-NEXT: cleanup // CHECK: [[PARTIAL_END:%.*]] = load ptr, ptr [[ENDVAR]] - // CHECK-NEXT: [[T0:%.*]] = icmp eq ptr [[E_BEGIN]], [[PARTIAL_END]] + // CHECK-NEXT: [[T0:%.*]] = icmp eq ptr [[AS]], [[PARTIAL_END]] // CHECK-NEXT: br i1 [[T0]], // CHECK: [[E_AFTER:%.*]] = phi ptr [ [[PARTIAL_END]], {{%.*}} ], [ [[E_CUR:%.*]], {{%.*}} ] // CHECK-NEXT: [[E_CUR]] = getelementptr inbounds [[A]], ptr [[E_AFTER]], i64 -1 // CHECKv03-NEXT: invoke void @_ZN5test01AD1Ev(ptr {{[^,]*}} [[E_CUR]]) // CHECKv11-NEXT: call void @_ZN5test01AD1Ev(ptr {{[^,]*}} [[E_CUR]]) - // CHECK: [[T0:%.*]] = icmp eq ptr [[E_CUR]], [[E_BEGIN]] + // CHECK: [[T0:%.*]] = icmp eq ptr [[E_CUR]], [[AS]] // CHECK-NEXT: br i1 [[T0]], // Primary EH destructor. @@ -189,25 +188,22 @@ namespace test4 { } // CHECK-LABEL: define{{.*}} void @_ZN5test44testEv() // CHECK: [[ARRAY:%.*]] = alloca [2 x [3 x [[A:%.*]]]], align -// CHECK: [[A0:%.*]] = getelementptr inbounds [2 x [3 x [[A]]]], ptr [[ARRAY]], i64 0, i64 0 -// CHECK-NEXT: store ptr [[A0]], -// CHECK-NEXT: [[A00:%.*]] = getelementptr inbounds [3 x [[A]]], ptr [[A0]], i64 0, i64 0 -// CHECK-NEXT: store ptr [[A00]], -// CHECK-NEXT: invoke void @_ZN5test41AC1Ej(ptr {{[^,]*}} [[A00]], i32 noundef 0) -// CHECK: [[A01:%.*]] = getelementptr inbounds [[A]], ptr [[A00]], i64 1 +// CHECK: store ptr [[ARRAY]], +// CHECK-NEXT: store ptr [[ARRAY]], +// CHECK-NEXT: invoke void @_ZN5test41AC1Ej(ptr {{[^,]*}} [[ARRAY]], i32 noundef 0) +// CHECK: [[A01:%.*]] = getelementptr inbounds [[A]], ptr [[ARRAY]], i64 1 // CHECK-NEXT: store ptr [[A01]], // CHECK-NEXT: invoke void @_ZN5test41AC1Ej(ptr {{[^,]*}} [[A01]], i32 noundef 1) -// CHECK: [[A02:%.*]] = getelementptr inbounds [[A]], ptr [[A01]], i64 1 +// CHECK: [[A02:%.*]] = getelementptr inbounds [[A]], ptr [[ARRAY]], i64 2 // CHECK-NEXT: store ptr [[A02]], // CHECK-NEXT: invoke void @_ZN5test41AC1Ej(ptr {{[^,]*}} [[A02]], i32 noundef 2) -// CHECK: [[A1:%.*]] = getelementptr inbounds [3 x [[A]]], ptr [[A0]], i64 1 +// CHECK: [[A1:%.*]] = getelementptr inbounds [3 x [[A]]], ptr [[ARRAY]], i64 1 // CHECK-NEXT: store ptr [[A1]], -// CHECK-NEXT: [[A10:%.*]] = getelementptr inbounds [3 x [[A]]], ptr [[A1]], i64 0, i64 0 -// CHECK-NEXT: store ptr [[A10]], -// CHECK-NEXT: invoke void @_ZN5test41AC1Ej(ptr {{[^,]*}} [[A10]], i32 noundef 3) -// CHECK: [[A11:%.*]] = getelementptr inbounds [[A]], ptr [[A10]], i64 1 +// CHECK-NEXT: store ptr [[A1]], +// CHECK-NEXT: invoke void @_ZN5test41AC1Ej(ptr {{[^,]*}} [[A1]], i32 noundef 3) +// CHECK: [[A11:%.*]] = getelementptr inbounds [[A]], ptr [[A1]], i64 1 // CHECK-NEXT: store ptr [[A11]], // CHECK-NEXT: invoke void @_ZN5test41AC1Ej(ptr {{[^,]*}} [[A11]], i32 noundef 4) -// CHECK: [[A12:%.*]] = getelementptr inbounds [[A]], ptr [[A11]], i64 1 +// CHECK: [[A12:%.*]] = getelementptr inbounds [[A]], ptr [[A1]], i64 2 // CHECK-NEXT: store ptr [[A12]], // CHECK-NEXT: invoke void @_ZN5test41AC1Ej(ptr {{[^,]*}} [[A12]], i32 noundef 5) diff --git a/clang/test/CodeGenCXX/pointers-to-data-members.cpp b/clang/test/CodeGenCXX/pointers-to-data-members.cpp index 29f1c3f48e3ac04308fa8ef13d6c6cd483f84257..cf1d6c018409d2a64470d9f118d225505594e743 100644 --- a/clang/test/CodeGenCXX/pointers-to-data-members.cpp +++ b/clang/test/CodeGenCXX/pointers-to-data-members.cpp @@ -1,4 +1,5 @@ // RUN: %clang_cc1 %s -emit-llvm -o %t.ll -triple=x86_64-apple-darwin10 +// RUN: %clang_cc1 %s -emit-llvm -o %t.ll -triple=x86_64-apple-darwin10 -fexperimental-new-constant-interpreter // RUN: FileCheck %s < %t.ll // RUN: FileCheck -check-prefix=CHECK-GLOBAL %s < %t.ll diff --git a/clang/test/CodeGenCXX/spirv-amdgcn-float16.cpp b/clang/test/CodeGenCXX/spirv-amdgcn-float16.cpp new file mode 100644 index 0000000000000000000000000000000000000000..2487e0fcd4343a2aac8ebfa547a6104cb0dd43ca --- /dev/null +++ b/clang/test/CodeGenCXX/spirv-amdgcn-float16.cpp @@ -0,0 +1,38 @@ +// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 4 +// RUN: %clang_cc1 -triple spirv64-amd-amdhsa -emit-llvm -o - %s | FileCheck %s + +// CHECK-LABEL: define spir_func void @_Z1fv( +// CHECK-SAME: ) addrspace(4) #[[ATTR0:[0-9]+]] { +// CHECK-NEXT: entry: +// CHECK-NEXT: [[X:%.*]] = alloca half, align 2 +// CHECK-NEXT: [[Y:%.*]] = alloca half, align 2 +// CHECK-NEXT: [[Z:%.*]] = alloca half, align 2 +// CHECK-NEXT: [[TMP0:%.*]] = load half, ptr [[X]], align 2 +// CHECK-NEXT: [[TMP1:%.*]] = load half, ptr [[Y]], align 2 +// CHECK-NEXT: [[ADD:%.*]] = fadd half [[TMP0]], [[TMP1]] +// CHECK-NEXT: store half [[ADD]], ptr [[Z]], align 2 +// CHECK-NEXT: [[TMP2:%.*]] = load half, ptr [[X]], align 2 +// CHECK-NEXT: [[TMP3:%.*]] = load half, ptr [[Y]], align 2 +// CHECK-NEXT: [[SUB:%.*]] = fsub half [[TMP2]], [[TMP3]] +// CHECK-NEXT: store half [[SUB]], ptr [[Z]], align 2 +// CHECK-NEXT: [[TMP4:%.*]] = load half, ptr [[X]], align 2 +// CHECK-NEXT: [[TMP5:%.*]] = load half, ptr [[Y]], align 2 +// CHECK-NEXT: [[MUL:%.*]] = fmul half [[TMP4]], [[TMP5]] +// CHECK-NEXT: store half [[MUL]], ptr [[Z]], align 2 +// CHECK-NEXT: [[TMP6:%.*]] = load half, ptr [[X]], align 2 +// CHECK-NEXT: [[TMP7:%.*]] = load half, ptr [[Y]], align 2 +// CHECK-NEXT: [[DIV:%.*]] = fdiv half [[TMP6]], [[TMP7]] +// CHECK-NEXT: store half [[DIV]], ptr [[Z]], align 2 +// CHECK-NEXT: ret void +// +void f() { + _Float16 x, y, z; + + z = x + y; + + z = x - y; + + z = x * y; + + z = x / y; +} diff --git a/clang/test/CodeGenCXX/template-param-objects-linkage.cpp b/clang/test/CodeGenCXX/template-param-objects-linkage.cpp index 63e7d8c6468695d981742db0ba3f26674097dee5..9c148ed83753d86de958fbebde2a9060efa537f6 100644 --- a/clang/test/CodeGenCXX/template-param-objects-linkage.cpp +++ b/clang/test/CodeGenCXX/template-param-objects-linkage.cpp @@ -1,4 +1,5 @@ // RUN: %clang_cc1 -triple x86_64-linux-gnu -std=c++20 %s -emit-llvm -o - | FileCheck %s +// RUN: %clang_cc1 -triple x86_64-linux-gnu -std=c++20 %s -emit-llvm -o - -fexperimental-new-constant-interpreter | FileCheck %s struct S { char buf[32]; }; template constexpr const char* f() { return s.buf; } diff --git a/clang/test/CodeGenCXX/temporaries.cpp b/clang/test/CodeGenCXX/temporaries.cpp index 9f29d3b7327839515c3aebd40127cab921434482..186f4934873fa94814c6686a729d000b3e602758 100644 --- a/clang/test/CodeGenCXX/temporaries.cpp +++ b/clang/test/CodeGenCXX/temporaries.cpp @@ -477,9 +477,8 @@ namespace Elision { // CHECK-NEXT: call void @_ZN7Elision1AC1Ev(ptr {{[^,]*}} [[X]]) A x; - // CHECK-NEXT: [[XS0:%.*]] = getelementptr inbounds [2 x [[A]]], ptr [[XS]], i64 0, i64 0 - // CHECK-NEXT: call void @_ZN7Elision1AC1Ev(ptr {{[^,]*}} [[XS0]]) - // CHECK-NEXT: [[XS1:%.*]] = getelementptr inbounds [[A]], ptr [[XS0]], i64 1 + // CHECK-NEXT: call void @_ZN7Elision1AC1Ev(ptr {{[^,]*}} [[XS]]) + // CHECK-NEXT: [[XS1:%.*]] = getelementptr inbounds [[A]], ptr [[XS]], i64 1 // CHECK-NEXT: call void @_ZN7Elision1AC1ERKS0_(ptr {{[^,]*}} [[XS1]], ptr noundef {{(nonnull )?}}align {{[0-9]+}} dereferenceable({{[0-9]+}}) [[X]]) A xs[] = { A(), x }; diff --git a/clang/test/CodeGenCXX/value-init.cpp b/clang/test/CodeGenCXX/value-init.cpp index 42181be92ace9e1c80f285e5955e91a0b4ca3692..9e72769d87f696a894f4690f3f34db81dd339311 100644 --- a/clang/test/CodeGenCXX/value-init.cpp +++ b/clang/test/CodeGenCXX/value-init.cpp @@ -205,11 +205,9 @@ namespace test6 { // CHECK-LABEL: define{{.*}} void @_ZN5test64testEv() // CHECK: [[ARR:%.*]] = alloca [10 x [20 x [[A:%.*]]]], - // CHECK-NEXT: [[INNER:%.*]] = getelementptr inbounds [10 x [20 x [[A]]]], ptr [[ARR]], i64 0, i64 0 - // CHECK-NEXT: [[T0:%.*]] = getelementptr inbounds [20 x [[A]]], ptr [[INNER]], i64 0, i64 0 - // CHECK-NEXT: call void @_ZN5test61AC1Ei(ptr {{[^,]*}} [[T0]], i32 noundef 5) - // CHECK-NEXT: [[BEGIN:%.*]] = getelementptr inbounds [[A]], ptr [[T0]], i64 1 - // CHECK-NEXT: [[END:%.*]] = getelementptr inbounds [[A]], ptr [[T0]], i64 20 + // CHECK-NEXT: call void @_ZN5test61AC1Ei(ptr {{[^,]*}} [[ARR]], i32 noundef 5) + // CHECK-NEXT: [[BEGIN:%.*]] = getelementptr inbounds [[A]], ptr [[ARR]], i64 1 + // CHECK-NEXT: [[END:%.*]] = getelementptr inbounds [[A]], ptr [[ARR]], i64 20 // CHECK-NEXT: br label // CHECK: [[CUR:%.*]] = phi ptr [ [[BEGIN]], {{%.*}} ], [ [[NEXT:%.*]], {{%.*}} ] // CHECK-NEXT: call void @_ZN5test61AC1Ev(ptr {{[^,]*}} [[CUR]]) @@ -217,13 +215,15 @@ namespace test6 { // CHECK-NEXT: [[T0:%.*]] = icmp eq ptr [[NEXT]], [[END]] // CHECK-NEXT: br i1 - // CHECK: [[BEGIN:%.*]] = getelementptr inbounds [20 x [[A]]], ptr [[INNER]], i64 1 - // CHECK-NEXT: [[END:%.*]] = getelementptr inbounds [20 x [[A]]], ptr [[INNER]], i64 10 + // CHECK: [[BEGIN:%.*]] = getelementptr inbounds [20 x [[A]]], ptr [[ARR]], i64 1 + // CHECK-NEXT: [[END:%.*]] = getelementptr inbounds [20 x [[A]]], ptr [[ARR]], i64 10 // CHECK-NEXT: br label - // CHECK: [[CUR:%.*]] = phi ptr [ [[BEGIN]], {{%.*}} ], [ [[NEXT:%.*]], {{%.*}} ] - // Inner loop. - // CHECK-NEXT: [[IBEGIN:%.*]] = getelementptr inbounds [20 x [[A]]], ptr [[CUR]], i{{32|64}} 0, i{{32|64}} 0 + // CHECK-CXX98: [[CUR:%.*]] = phi ptr [ [[BEGIN]], {{%.*}} ], [ [[NEXT:%.*]], {{%.*}} ] + + // CHECK-CXX98: [[IBEGIN:%.*]] = getelementptr inbounds [20 x [[A]]], ptr [[CUR]], i{{32|64}} 0, i{{32|64}} 0 + // CHECK-CXX17: [[IBEGIN:%.*]] = phi ptr [ [[BEGIN]], {{%.*}} ], [ [[NEXT:%.*]], {{%.*}} ] + // CHECK-NEXT: [[IEND:%.*]] = getelementptr inbounds [[A]], ptr [[IBEGIN]], i64 20 // CHECK-NEXT: br label // CHECK: [[ICUR:%.*]] = phi ptr [ [[IBEGIN]], {{%.*}} ], [ [[INEXT:%.*]], {{%.*}} ] @@ -232,7 +232,8 @@ namespace test6 { // CHECK-NEXT: [[T0:%.*]] = icmp eq ptr [[INEXT]], [[IEND]] // CHECK-NEXT: br i1 [[T0]], - // CHECK: [[NEXT]] = getelementptr inbounds [20 x [[A]]], ptr [[CUR]], i64 1 + // CHECK-CXX98: [[NEXT]] = getelementptr inbounds [20 x [[A]]], ptr [[CUR]], i64 1 + // CHECK-CXX17: [[NEXT]] = getelementptr inbounds [20 x [[A]]], ptr [[IBEGIN]], i64 1 // CHECK-NEXT: [[T0:%.*]] = icmp eq ptr [[NEXT]], [[END]] // CHECK-NEXT: br i1 [[T0]] // CHECK: ret void diff --git a/clang/test/CodeGenCXX/windows-instantiate-dllexport-template-specialization.cpp b/clang/test/CodeGenCXX/windows-instantiate-dllexport-template-specialization.cpp new file mode 100644 index 0000000000000000000000000000000000000000..97f341ba1f909eb95fe7b7d03dc2bf62b5859663 --- /dev/null +++ b/clang/test/CodeGenCXX/windows-instantiate-dllexport-template-specialization.cpp @@ -0,0 +1,18 @@ +// RUN: %clang_cc1 -triple i686-windows -fdeclspec -emit-llvm %s -o - | FileCheck %s -check-prefix CHECK-MS +// RUN: %clang_cc1 -triple i686-windows-itanium -fdeclspec -emit-llvm %s -o - | FileCheck %s +// RUN: %clang_cc1 -triple x86_64-scei-ps4 -fdeclspec -emit-llvm %s -o - | FileCheck %s +// RUN: %clang_cc1 -triple x86_64-sie-ps5 -fdeclspec -emit-llvm %s -o - | FileCheck %s + +struct s { + template static bool f(); +}; + +template bool template_using_f(T) { return s::f(); } + +bool use_template_using_f() { return template_using_f(0); } + +template<> +bool __declspec(dllexport) s::f() { return true; } + +// CHECK-MS: dllexport {{.*}} @"??$f@$00@s@@SA_NXZ" +// CHECK: dllexport {{.*}} @_ZN1s1fILb1EEEbv diff --git a/clang/test/CodeGenCoroutines/coro-suspend-cleanups.cpp b/clang/test/CodeGenCoroutines/coro-suspend-cleanups.cpp index 06cc2069dbe9aed686fbb8e6295ca38ae8990bb8..d71c2c558996a7adb7ab107228a51a24767a9ad1 100644 --- a/clang/test/CodeGenCoroutines/coro-suspend-cleanups.cpp +++ b/clang/test/CodeGenCoroutines/coro-suspend-cleanups.cpp @@ -43,14 +43,11 @@ coroutine ArrayInitCoro() { // CHECK: %cleanup.isactive = alloca i1, align 1 Printy arr[2] = { Printy("a"), - // CHECK: %arrayinit.begin = getelementptr inbounds [2 x %struct.Printy], ptr %arr.reload.addr, i64 0, i64 0 - // CHECK-NEXT: %arrayinit.begin.spill.addr = getelementptr inbounds %_Z13ArrayInitCorov.Frame, ptr %0, i32 0, i32 10 - // CHECK-NEXT: store ptr %arrayinit.begin, ptr %arrayinit.begin.spill.addr, align 8 - // CHECK-NEXT: store i1 true, ptr %cleanup.isactive.reload.addr, align 1 - // CHECK-NEXT: store ptr %arrayinit.begin, ptr %arrayinit.endOfInit.reload.addr, align 8 - // CHECK-NEXT: call void @_ZN6PrintyC1EPKc(ptr noundef nonnull align 8 dereferenceable(8) %arrayinit.begin, ptr noundef @.str) - // CHECK-NEXT: %arrayinit.element = getelementptr inbounds %struct.Printy, ptr %arrayinit.begin, i64 1 - // CHECK-NEXT: %arrayinit.element.spill.addr = getelementptr inbounds %_Z13ArrayInitCorov.Frame, ptr %0, i32 0, i32 11 + // CHECK: store i1 true, ptr %cleanup.isactive.reload.addr, align 1 + // CHECK-NEXT: store ptr %arr.reload.addr, ptr %arrayinit.endOfInit.reload.addr, align 8 + // CHECK-NEXT: call void @_ZN6PrintyC1EPKc(ptr noundef nonnull align 8 dereferenceable(8) %arr.reload.addr, ptr noundef @.str) + // CHECK-NEXT: %arrayinit.element = getelementptr inbounds %struct.Printy, ptr %arr.reload.addr, i64 1 + // CHECK-NEXT: %arrayinit.element.spill.addr = getelementptr inbounds %_Z13ArrayInitCorov.Frame, ptr %0, i32 0, i32 10 // CHECK-NEXT: store ptr %arrayinit.element, ptr %arrayinit.element.spill.addr, align 8 // CHECK-NEXT: store ptr %arrayinit.element, ptr %arrayinit.endOfInit.reload.addr, align 8 co_await Awaiter{} @@ -64,7 +61,7 @@ coroutine ArrayInitCoro() { // CHECK: br label %cleanup{{.*}} // CHECK: await.ready: - // CHECK-NEXT: %arrayinit.element.reload.addr = getelementptr inbounds %_Z13ArrayInitCorov.Frame, ptr %0, i32 0, i32 11 + // CHECK-NEXT: %arrayinit.element.reload.addr = getelementptr inbounds %_Z13ArrayInitCorov.Frame, ptr %0, i32 0, i32 10 // CHECK-NEXT: %arrayinit.element.reload = load ptr, ptr %arrayinit.element.reload.addr, align 8 // CHECK-NEXT: call void @_ZN7Awaiter12await_resumeEv // CHECK-NEXT: store i1 false, ptr %cleanup.isactive.reload.addr, align 1 @@ -75,7 +72,7 @@ coroutine ArrayInitCoro() { // CHECK-NEXT: br i1 %cleanup.is_active, label %cleanup.action, label %cleanup.done // CHECK: cleanup.action: - // CHECK: %arraydestroy.isempty = icmp eq ptr %arrayinit.begin.reload{{.*}}, %{{.*}} + // CHECK: %arraydestroy.isempty = icmp eq ptr %arr.reload.addr, %{{.*}} // CHECK-NEXT: br i1 %arraydestroy.isempty, label %arraydestroy.done{{.*}}, label %arraydestroy.body.from.cleanup.action // Ignore rest of the array cleanup. } diff --git a/clang/test/CodeGenHIP/hipspv-addr-spaces.cpp b/clang/test/CodeGenHIP/hipspv-addr-spaces.cpp index 9fcdc460482e7e26f0c0d265054f91b96586d122..c575f49ff697165513756f217f867f49687b0888 100644 --- a/clang/test/CodeGenHIP/hipspv-addr-spaces.cpp +++ b/clang/test/CodeGenHIP/hipspv-addr-spaces.cpp @@ -1,5 +1,7 @@ // RUN: %clang_cc1 -triple spirv64 -x hip -emit-llvm -fcuda-is-device \ // RUN: -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple spirv64-amd-amdhsa -x hip -emit-llvm -fcuda-is-device \ +// RUN: -o - %s | FileCheck %s #define __device__ __attribute__((device)) #define __shared__ __attribute__((shared)) diff --git a/clang/test/CodeGenHIP/spirv-amdgcn-ballot.cpp b/clang/test/CodeGenHIP/spirv-amdgcn-ballot.cpp new file mode 100644 index 0000000000000000000000000000000000000000..8226a109d8b8d9bc035ea25e33e812bf9c06961b --- /dev/null +++ b/clang/test/CodeGenHIP/spirv-amdgcn-ballot.cpp @@ -0,0 +1,27 @@ +// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 4 +// RUN: %clang_cc1 -triple spirv64-amd-amdhsa -aux-triple x86_64-pc-windows-msvc -x hip -emit-llvm -fcuda-is-device -o - %s | FileCheck %s + +// Unlike OpenCL, HIP depends on the C++ interpration of "unsigned long", which +// is 64 bits long on Linux and 32 bits long on Windows. The return type of the +// ballot intrinsic needs to be a 64 bit integer on both platforms. This test +// cross-compiles to Windows to confirm that the return type is indeed 64 bits +// on Windows. + +#define __device__ __attribute__((device)) + +// CHECK-LABEL: define spir_func noundef i64 @_Z3fooi( +// CHECK-SAME: i32 noundef [[P:%.*]]) addrspace(4) #[[ATTR0:[0-9]+]] { +// CHECK-NEXT: entry: +// CHECK-NEXT: [[RETVAL:%.*]] = alloca i64, align 8 +// CHECK-NEXT: [[P_ADDR:%.*]] = alloca i32, align 4 +// CHECK-NEXT: [[RETVAL_ASCAST:%.*]] = addrspacecast ptr [[RETVAL]] to ptr addrspace(4) +// CHECK-NEXT: [[P_ADDR_ASCAST:%.*]] = addrspacecast ptr [[P_ADDR]] to ptr addrspace(4) +// CHECK-NEXT: store i32 [[P]], ptr addrspace(4) [[P_ADDR_ASCAST]], align 4 +// CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr addrspace(4) [[P_ADDR_ASCAST]], align 4 +// CHECK-NEXT: [[TOBOOL:%.*]] = icmp ne i32 [[TMP0]], 0 +// CHECK-NEXT: [[TMP1:%.*]] = call addrspace(4) i64 @llvm.amdgcn.ballot.i64(i1 [[TOBOOL]]) +// CHECK-NEXT: ret i64 [[TMP1]] +// +__device__ unsigned long long foo(int p) { + return __builtin_amdgcn_ballot_w64(p); +} diff --git a/clang/test/CodeGenHIP/spirv-amdgcn-dpp-const-fold.hip b/clang/test/CodeGenHIP/spirv-amdgcn-dpp-const-fold.hip new file mode 100644 index 0000000000000000000000000000000000000000..2b785200e8eeab97a92589886857f3cc6818ad73 --- /dev/null +++ b/clang/test/CodeGenHIP/spirv-amdgcn-dpp-const-fold.hip @@ -0,0 +1,46 @@ +// RUN: %clang_cc1 -triple spirv64-amd-amdhsa -x hip -fcuda-is-device -emit-llvm %s \ +// RUN: -o - | FileCheck %s + +constexpr static int OpCtrl() +{ + return 15 + 1; +} + +constexpr static int RowMask() +{ + return 3 + 1; +} + +constexpr static int BankMask() +{ + return 2 + 1; +} + +constexpr static bool BountCtrl() +{ + return true & false; +} + +// CHECK: call{{.*}} i32 @llvm.amdgcn.update.dpp.i32(i32 %1, i32 %2, i32 16, i32 0, i32 0, i1 false) +__attribute__((global)) void test_update_dpp_const_fold_imm_operand_2(int* out, int a, int b) +{ + *out = __builtin_amdgcn_update_dpp(a, b, OpCtrl(), 0, 0, false); +} + +// CHECK: call{{.*}} i32 @llvm.amdgcn.update.dpp.i32(i32 %1, i32 %2, i32 0, i32 4, i32 0, i1 false) +__attribute__((global)) void test_update_dpp_const_fold_imm_operand_3(int* out, int a, int b) +{ + *out = __builtin_amdgcn_update_dpp(a, b, 0, RowMask(), 0, false); +} + +// CHECK: call{{.*}} i32 @llvm.amdgcn.update.dpp.i32(i32 %1, i32 %2, i32 0, i32 0, i32 3, i1 false) +__attribute__((global)) void test_update_dpp_const_fold_imm_operand_4(int* out, int a, int b) +{ + *out = __builtin_amdgcn_update_dpp(a, b, 0, 0, BankMask(), false); +} + +// CHECK: call{{.*}} i32 @llvm.amdgcn.update.dpp.i32(i32 %1, i32 %2, i32 0, i32 0, i32 0, i1 false) +__attribute__((global)) void test_update_dpp_const_fold_imm_operand_5(int* out, int a, int b) +{ + *out = __builtin_amdgcn_update_dpp(a, b, 0, 0, 0, BountCtrl()); +} diff --git a/clang/test/CodeGenHIP/spirv-amdgcn-half.hip b/clang/test/CodeGenHIP/spirv-amdgcn-half.hip new file mode 100644 index 0000000000000000000000000000000000000000..2caf766d943b11cbb6f0bfd45e74a8467ee3b8fd --- /dev/null +++ b/clang/test/CodeGenHIP/spirv-amdgcn-half.hip @@ -0,0 +1,15 @@ +// RUN: %clang_cc1 -triple spirv64-amd-amdhsa -x hip -emit-llvm -fcuda-is-device -o - %s | FileCheck %s + +#define __device__ __attribute__((device)) + +// CHECK-LABEL: @_Z2d0DF16_ +// CHECK: fpext +__device__ float d0(_Float16 x) { + return x; +} + +// CHECK-LABEL: @_Z2d1f +// CHECK: fptrunc +__device__ _Float16 d1(float x) { + return x; +} diff --git a/clang/test/CodeGenObjC/arc-ternary-op.m b/clang/test/CodeGenObjC/arc-ternary-op.m index 87167d911ea8ef1bec8d3022174ce35809b288cc..d633851ac76174e76e2e1431beb2efe6437cdeeb 100644 --- a/clang/test/CodeGenObjC/arc-ternary-op.m +++ b/clang/test/CodeGenObjC/arc-ternary-op.m @@ -153,22 +153,20 @@ void test3(int cond) { // CHECK: %[[_COMPOUNDLITERAL1:.*]] = alloca [2 x ptr], align 8 // CHECK: %[[CLEANUP_COND4:.*]] = alloca i1, align 1 - // CHECK: %[[ARRAYINIT_BEGIN:.*]] = getelementptr inbounds [2 x ptr], ptr %[[_COMPOUNDLITERAL]], i64 0, i64 0 // CHECK: %[[V2:.*]] = load ptr, ptr @g0, align 8 // CHECK: %[[V3:.*]] = call ptr @llvm.objc.retain(ptr %[[V2]]) - // CHECK: store ptr %[[V3]], ptr %[[ARRAYINIT_BEGIN]], align 8 - // CHECK: %[[ARRAYINIT_ELEMENT:.*]] = getelementptr inbounds ptr, ptr %[[ARRAYINIT_BEGIN]], i64 1 + // CHECK: store ptr %[[V3]], ptr %[[_COMPOUNDLITERAL]], align 8 + // CHECK: %[[ARRAYINIT_ELEMENT:.*]] = getelementptr inbounds ptr, ptr %[[_COMPOUNDLITERAL]], i64 1 // CHECK: %[[V4:.*]] = load ptr, ptr @g1, align 8 // CHECK: %[[V5:.*]] = call ptr @llvm.objc.retain(ptr %[[V4]]) // CHECK: store ptr %[[V5]], ptr %[[ARRAYINIT_ELEMENT]], align 8 // CHECK: store i1 true, ptr %[[CLEANUP_COND]], align 1 // CHECK: %[[ARRAYDECAY:.*]] = getelementptr inbounds [2 x ptr], ptr %[[_COMPOUNDLITERAL]], i64 0, i64 0 - // CHECK: %[[ARRAYINIT_BEGIN2:.*]] = getelementptr inbounds [2 x ptr], ptr %[[_COMPOUNDLITERAL1]], i64 0, i64 0 // CHECK: %[[V6:.*]] = load ptr, ptr @g1, align 8 // CHECK: %[[V7:.*]] = call ptr @llvm.objc.retain(ptr %[[V6]]) - // CHECK: store ptr %[[V7]], ptr %[[ARRAYINIT_BEGIN2]], align 8 - // CHECK: %[[ARRAYINIT_ELEMENT3:.*]] = getelementptr inbounds ptr, ptr %[[ARRAYINIT_BEGIN2]], i64 1 + // CHECK: store ptr %[[V7]], ptr %[[_COMPOUNDLITERAL1]], align 8 + // CHECK: %[[ARRAYINIT_ELEMENT3:.*]] = getelementptr inbounds ptr, ptr %[[_COMPOUNDLITERAL1]], i64 1 // CHECK: %[[V8:.*]] = load ptr, ptr @g0, align 8 // CHECK: %[[V9:.*]] = call ptr @llvm.objc.retain(ptr %[[V8]]) // CHECK: store ptr %[[V9]], ptr %[[ARRAYINIT_ELEMENT3]], align 8 diff --git a/clang/test/CodeGenObjC/arc.m b/clang/test/CodeGenObjC/arc.m index aeead58f8131d70402af5f48fb7c2a92326aa42f..48ca14af3b2abd91a6e9268dfb72e4f6b59c3ff8 100644 --- a/clang/test/CodeGenObjC/arc.m +++ b/clang/test/CodeGenObjC/arc.m @@ -1377,11 +1377,10 @@ void test71(void) { // CHECK: %[[T:.*]] = alloca [2 x ptr], align 16 // CHECK: %[[V0:.*]] = call ptr @llvm.objc.retain(ptr %[[A]]) // CHECK: %[[V1:.*]] = call ptr @llvm.objc.retain(ptr %[[B]]) #2 -// CHECK: %[[ARRAYINIT_BEGIN:.*]] = getelementptr inbounds [2 x ptr], ptr %[[T]], i64 0, i64 0 // CHECK: %[[V3:.*]] = load ptr, ptr %[[A_ADDR]], align 8, !tbaa !7 // CHECK: %[[V4:.*]] = call ptr @llvm.objc.retain(ptr %[[V3]]) #2 -// CHECK: store ptr %[[V4]], ptr %[[ARRAYINIT_BEGIN]], align 8, !tbaa !7 -// CHECK: %[[ARRAYINIT_ELEMENT:.*]] = getelementptr inbounds ptr, ptr %[[ARRAYINIT_BEGIN]], i64 1 +// CHECK: store ptr %[[V4]], ptr %[[T]], align 8, !tbaa !7 +// CHECK: %[[ARRAYINIT_ELEMENT:.*]] = getelementptr inbounds ptr, ptr %[[T]], i64 1 // CHECK: %[[V5:.*]] = load ptr, ptr %[[B_ADDR]], align 8, !tbaa !7 // CHECK: %[[V6:.*]] = call ptr @llvm.objc.retain(ptr %[[V5]]) #2 // CHECK: store ptr %[[V6]], ptr %[[ARRAYINIT_ELEMENT]], align 8, !tbaa !7 diff --git a/clang/test/CodeGenObjCXX/arc-exceptions.mm b/clang/test/CodeGenObjCXX/arc-exceptions.mm index 709afa32ac7d81f833ccefa27a18f4cfef8beebd..3efe566a6a8b51a24bce981145074f376313bd3c 100644 --- a/clang/test/CodeGenObjCXX/arc-exceptions.mm +++ b/clang/test/CodeGenObjCXX/arc-exceptions.mm @@ -115,23 +115,20 @@ void test5(void) { } // CHECK-LABEL: define{{.*}} void @_Z5test5v() // CHECK: [[ARRAY:%.*]] = alloca [2 x [2 x ptr]], align -// CHECK: [[A0:%.*]] = getelementptr inbounds [2 x [2 x ptr]], ptr [[ARRAY]], i64 0, i64 0 -// CHECK-NEXT: store ptr [[A0]], -// CHECK-NEXT: [[A00:%.*]] = getelementptr inbounds [2 x ptr], ptr [[A0]], i64 0, i64 0 -// CHECK-NEXT: store ptr [[A00]], +// CHECK: store ptr [[ARRAY]], +// CHECK-NEXT: store ptr [[ARRAY]], // CHECK-NEXT: [[T0:%.*]] = invoke noundef ptr @_Z12test5_helperj(i32 noundef 0) -// CHECK: store ptr [[T0]], ptr [[A00]], align -// CHECK-NEXT: [[A01:%.*]] = getelementptr inbounds ptr, ptr [[A00]], i64 1 +// CHECK: store ptr [[T0]], ptr [[ARRAY]], align +// CHECK-NEXT: [[A01:%.*]] = getelementptr inbounds ptr, ptr [[ARRAY]], i64 1 // CHECK-NEXT: store ptr [[A01]], // CHECK-NEXT: [[T0:%.*]] = invoke noundef ptr @_Z12test5_helperj(i32 noundef 1) // CHECK: store ptr [[T0]], ptr [[A01]], align -// CHECK-NEXT: [[A1:%.*]] = getelementptr inbounds [2 x ptr], ptr [[A0]], i64 1 +// CHECK-NEXT: [[A1:%.*]] = getelementptr inbounds [2 x ptr], ptr [[ARRAY]], i64 1 +// CHECK-NEXT: store ptr [[A1]], // CHECK-NEXT: store ptr [[A1]], -// CHECK-NEXT: [[A10:%.*]] = getelementptr inbounds [2 x ptr], ptr [[A1]], i64 0, i64 0 -// CHECK-NEXT: store ptr [[A10]], // CHECK-NEXT: [[T0:%.*]] = invoke noundef ptr @_Z12test5_helperj(i32 noundef 2) -// CHECK: store ptr [[T0]], ptr [[A10]], align -// CHECK-NEXT: [[A11:%.*]] = getelementptr inbounds ptr, ptr [[A10]], i64 1 +// CHECK: store ptr [[T0]], ptr [[A1]], align +// CHECK-NEXT: [[A11:%.*]] = getelementptr inbounds ptr, ptr [[A1]], i64 1 // CHECK-NEXT: store ptr [[A11]], // CHECK-NEXT: [[T0:%.*]] = invoke noundef ptr @_Z12test5_helperj(i32 noundef 3) // CHECK: store ptr [[T0]], ptr [[A11]], align diff --git a/clang/test/CodeGenOpenCL/amdgcn-flat-scratch-name.cl b/clang/test/CodeGenOpenCL/amdgcn-flat-scratch-name.cl index 619a9a99568e203730124a453ea92d5599b0939a..40a523f0aa0bfd49db9d72d5eb58c3100774d6aa 100644 --- a/clang/test/CodeGenOpenCL/amdgcn-flat-scratch-name.cl +++ b/clang/test/CodeGenOpenCL/amdgcn-flat-scratch-name.cl @@ -1,15 +1,16 @@ // REQUIRES: amdgpu-registered-target // RUN: %clang_cc1 -triple amdgcn-unknown-unknown -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple spirv64-amd-amdhsa -emit-llvm -o - %s | FileCheck %s // CHECK-LABEL: @use_flat_scratch_name kernel void use_flat_scratch_name() { -// CHECK: tail call void asm sideeffect "s_mov_b64 flat_scratch, 0", "~{flat_scratch}"() +// CHECK: tail call{{.*}} void asm sideeffect "s_mov_b64 flat_scratch, 0", "~{flat_scratch}"() __asm__ volatile("s_mov_b64 flat_scratch, 0" : : : "flat_scratch"); -// CHECK: tail call void asm sideeffect "s_mov_b32 flat_scratch_lo, 0", "~{flat_scratch_lo}"() +// CHECK: tail call{{.*}} void asm sideeffect "s_mov_b32 flat_scratch_lo, 0", "~{flat_scratch_lo}"() __asm__ volatile("s_mov_b32 flat_scratch_lo, 0" : : : "flat_scratch_lo"); -// CHECK: tail call void asm sideeffect "s_mov_b32 flat_scratch_hi, 0", "~{flat_scratch_hi}"() +// CHECK: tail call{{.*}} void asm sideeffect "s_mov_b32 flat_scratch_hi, 0", "~{flat_scratch_hi}"() __asm__ volatile("s_mov_b32 flat_scratch_hi, 0" : : : "flat_scratch_hi"); } diff --git a/clang/test/CodeGenOpenCL/amdgpu-features.cl b/clang/test/CodeGenOpenCL/amdgpu-features.cl index 2fda52dcd2dc6bf00dd7bfc87461a1bed866d5e0..854ab39791f1643fc650e95603574279deb09dd2 100644 --- a/clang/test/CodeGenOpenCL/amdgpu-features.cl +++ b/clang/test/CodeGenOpenCL/amdgpu-features.cl @@ -49,6 +49,7 @@ // RUN: %clang_cc1 -triple amdgcn -target-cpu gfx1103 -emit-llvm -o - %s | FileCheck --check-prefix=GFX1103 %s // RUN: %clang_cc1 -triple amdgcn -target-cpu gfx1150 -emit-llvm -o - %s | FileCheck --check-prefix=GFX1150 %s // RUN: %clang_cc1 -triple amdgcn -target-cpu gfx1151 -emit-llvm -o - %s | FileCheck --check-prefix=GFX1151 %s +// RUN: %clang_cc1 -triple amdgcn -target-cpu gfx1152 -emit-llvm -o - %s | FileCheck --check-prefix=GFX1152 %s // RUN: %clang_cc1 -triple amdgcn -target-cpu gfx1200 -emit-llvm -o - %s | FileCheck --check-prefix=GFX1200 %s // RUN: %clang_cc1 -triple amdgcn -target-cpu gfx1201 -emit-llvm -o - %s | FileCheck --check-prefix=GFX1201 %s @@ -100,6 +101,7 @@ // GFX1103: "target-features"="+16-bit-insts,+atomic-fadd-rtn-insts,+ci-insts,+dl-insts,+dot10-insts,+dot5-insts,+dot7-insts,+dot8-insts,+dot9-insts,+dpp,+gfx10-3-insts,+gfx10-insts,+gfx11-insts,+gfx8-insts,+gfx9-insts,+wavefrontsize32" // GFX1150: "target-features"="+16-bit-insts,+atomic-fadd-rtn-insts,+ci-insts,+dl-insts,+dot10-insts,+dot5-insts,+dot7-insts,+dot8-insts,+dot9-insts,+dpp,+gfx10-3-insts,+gfx10-insts,+gfx11-insts,+gfx8-insts,+gfx9-insts,+wavefrontsize32" // GFX1151: "target-features"="+16-bit-insts,+atomic-fadd-rtn-insts,+ci-insts,+dl-insts,+dot10-insts,+dot5-insts,+dot7-insts,+dot8-insts,+dot9-insts,+dpp,+gfx10-3-insts,+gfx10-insts,+gfx11-insts,+gfx8-insts,+gfx9-insts,+wavefrontsize32" +// GFX1152: "target-features"="+16-bit-insts,+atomic-fadd-rtn-insts,+ci-insts,+dl-insts,+dot10-insts,+dot5-insts,+dot7-insts,+dot8-insts,+dot9-insts,+dpp,+gfx10-3-insts,+gfx10-insts,+gfx11-insts,+gfx8-insts,+gfx9-insts,+wavefrontsize32" // GFX1200: "target-features"="+16-bit-insts,+atomic-buffer-global-pk-add-f16-insts,+atomic-ds-pk-add-16-insts,+atomic-fadd-rtn-insts,+atomic-flat-pk-add-16-insts,+atomic-global-pk-add-bf16-inst,+ci-insts,+dl-insts,+dot10-insts,+dot11-insts,+dot7-insts,+dot8-insts,+dot9-insts,+dpp,+fp8-conversion-insts,+gfx10-3-insts,+gfx10-insts,+gfx11-insts,+gfx12-insts,+gfx8-insts,+gfx9-insts,+wavefrontsize32" // GFX1201: "target-features"="+16-bit-insts,+atomic-buffer-global-pk-add-f16-insts,+atomic-ds-pk-add-16-insts,+atomic-fadd-rtn-insts,+atomic-flat-pk-add-16-insts,+atomic-global-pk-add-bf16-inst,+ci-insts,+dl-insts,+dot10-insts,+dot11-insts,+dot7-insts,+dot8-insts,+dot9-insts,+dpp,+fp8-conversion-insts,+gfx10-3-insts,+gfx10-insts,+gfx11-insts,+gfx12-insts,+gfx8-insts,+gfx9-insts,+wavefrontsize32" diff --git a/clang/test/CodeGenOpenCL/builtins-amdgcn-gfx10.cl b/clang/test/CodeGenOpenCL/builtins-amdgcn-gfx10.cl index 3c40370e7f107656387de9a44acf1aa6b8b5dd9b..f30776a8bb85b9d7fa814aed7ae9c933caa21c4f 100644 --- a/clang/test/CodeGenOpenCL/builtins-amdgcn-gfx10.cl +++ b/clang/test/CodeGenOpenCL/builtins-amdgcn-gfx10.cl @@ -2,44 +2,45 @@ // RUN: %clang_cc1 -triple amdgcn-unknown-unknown -target-cpu gfx1010 -emit-llvm -o - %s | FileCheck %s // RUN: %clang_cc1 -triple amdgcn-unknown-unknown -target-cpu gfx1011 -emit-llvm -o - %s | FileCheck %s // RUN: %clang_cc1 -triple amdgcn-unknown-unknown -target-cpu gfx1012 -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple spirv64-amd-amdhsa -emit-llvm -o - %s | FileCheck %s typedef unsigned int uint; typedef unsigned long ulong; // CHECK-LABEL: @test_permlane16( -// CHECK: call i32 @llvm.amdgcn.permlane16(i32 %a, i32 %b, i32 %c, i32 %d, i1 false, i1 false) +// CHECK: {{.*}}call{{.*}} i32 @llvm.amdgcn.permlane16(i32 %a, i32 %b, i32 %c, i32 %d, i1 false, i1 false) void test_permlane16(global uint* out, uint a, uint b, uint c, uint d) { *out = __builtin_amdgcn_permlane16(a, b, c, d, 0, 0); } // CHECK-LABEL: @test_permlanex16( -// CHECK: call i32 @llvm.amdgcn.permlanex16(i32 %a, i32 %b, i32 %c, i32 %d, i1 false, i1 false) +// CHECK: {{.*}}call{{.*}} i32 @llvm.amdgcn.permlanex16(i32 %a, i32 %b, i32 %c, i32 %d, i1 false, i1 false) void test_permlanex16(global uint* out, uint a, uint b, uint c, uint d) { *out = __builtin_amdgcn_permlanex16(a, b, c, d, 0, 0); } // CHECK-LABEL: @test_mov_dpp8( -// CHECK: call i32 @llvm.amdgcn.mov.dpp8.i32(i32 %a, i32 1) +// CHECK: {{.*}}call{{.*}} i32 @llvm.amdgcn.mov.dpp8.i32(i32 %a, i32 1) void test_mov_dpp8(global uint* out, uint a) { *out = __builtin_amdgcn_mov_dpp8(a, 1); } // CHECK-LABEL: @test_s_memtime -// CHECK: call i64 @llvm.amdgcn.s.memtime() +// CHECK: {{.*}}call{{.*}} i64 @llvm.amdgcn.s.memtime() void test_s_memtime(global ulong* out) { *out = __builtin_amdgcn_s_memtime(); } // CHECK-LABEL: @test_groupstaticsize -// CHECK: call i32 @llvm.amdgcn.groupstaticsize() +// CHECK: {{.*}}call{{.*}} i32 @llvm.amdgcn.groupstaticsize() void test_groupstaticsize(global uint* out) { *out = __builtin_amdgcn_groupstaticsize(); } // CHECK-LABEL: @test_ballot_wave32( -// CHECK: call i32 @llvm.amdgcn.ballot.i32(i1 %{{.+}}) +// CHECK: {{.*}}call{{.*}} i32 @llvm.amdgcn.ballot.i32(i1 %{{.+}}) void test_ballot_wave32(global uint* out, int a, int b) { *out = __builtin_amdgcn_ballot_w32(a == b); diff --git a/clang/test/CodeGenOpenCL/builtins-amdgcn-gfx11.cl b/clang/test/CodeGenOpenCL/builtins-amdgcn-gfx11.cl index d17ff81e5d43ca04397f0fc316f943453ed0dd37..868b5bed0c9522df71a689cd6844f441d1a3e507 100644 --- a/clang/test/CodeGenOpenCL/builtins-amdgcn-gfx11.cl +++ b/clang/test/CodeGenOpenCL/builtins-amdgcn-gfx11.cl @@ -5,6 +5,8 @@ // RUN: %clang_cc1 -triple amdgcn-unknown-unknown -target-cpu gfx1103 -emit-llvm -o - %s | FileCheck %s // RUN: %clang_cc1 -triple amdgcn-unknown-unknown -target-cpu gfx1150 -emit-llvm -o - %s | FileCheck %s // RUN: %clang_cc1 -triple amdgcn-unknown-unknown -target-cpu gfx1151 -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple amdgcn-unknown-unknown -target-cpu gfx1152 -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple spirv64-amd-amdhsa -emit-llvm -o - %s | FileCheck %s typedef unsigned int uint; typedef unsigned long ulong; @@ -12,19 +14,19 @@ typedef uint uint2 __attribute__((ext_vector_type(2))); typedef uint uint4 __attribute__((ext_vector_type(4))); // CHECK-LABEL: @test_s_sendmsg_rtn( -// CHECK: call i32 @llvm.amdgcn.s.sendmsg.rtn.i32(i32 0) +// CHECK: {{.*}}call{{.*}} i32 @llvm.amdgcn.s.sendmsg.rtn.i32(i32 0) void test_s_sendmsg_rtn(global uint* out) { *out = __builtin_amdgcn_s_sendmsg_rtn(0); } // CHECK-LABEL: @test_s_sendmsg_rtnl( -// CHECK: call i64 @llvm.amdgcn.s.sendmsg.rtn.i64(i32 0) +// CHECK: {{.*}}call{{.*}} i64 @llvm.amdgcn.s.sendmsg.rtn.i64(i32 0) void test_s_sendmsg_rtnl(global ulong* out) { *out = __builtin_amdgcn_s_sendmsg_rtnl(0); } // CHECK-LABEL: @test_ds_bvh_stack_rtn( -// CHECK: %0 = tail call { i32, i32 } @llvm.amdgcn.ds.bvh.stack.rtn(i32 %addr, i32 %data, <4 x i32> %data1, i32 128) +// CHECK: %0 = tail call{{.*}} { i32, i32 } @llvm.amdgcn.ds.bvh.stack.rtn(i32 %addr, i32 %data, <4 x i32> %data1, i32 128) // CHECK: %1 = extractvalue { i32, i32 } %0, 0 // CHECK: %2 = extractvalue { i32, i32 } %0, 1 // CHECK: %3 = insertelement <2 x i32> poison, i32 %1, i64 0 @@ -35,19 +37,19 @@ void test_ds_bvh_stack_rtn(global uint2* out, uint addr, uint data, uint4 data1) } // CHECK-LABEL: @test_permlane64( -// CHECK: call i32 @llvm.amdgcn.permlane64(i32 %a) +// CHECK: {{.*}}call{{.*}} i32 @llvm.amdgcn.permlane64(i32 %a) void test_permlane64(global uint* out, uint a) { *out = __builtin_amdgcn_permlane64(a); } // CHECK-LABEL: @test_s_wait_event_export_ready -// CHECK: call void @llvm.amdgcn.s.wait.event.export.ready +// CHECK: {{.*}}call{{.*}} void @llvm.amdgcn.s.wait.event.export.ready void test_s_wait_event_export_ready() { __builtin_amdgcn_s_wait_event_export_ready(); } // CHECK-LABEL: @test_global_add_f32 -// CHECK: call float @llvm.amdgcn.global.atomic.fadd.f32.p1.f32(ptr addrspace(1) %{{.*}}, float %{{.*}}) +// CHECK: {{.*}}call{{.*}} float @llvm.amdgcn.global.atomic.fadd.f32.p1.f32(ptr addrspace(1) %{{.*}}, float %{{.*}}) void test_global_add_f32(float *rtn, global float *addr, float x) { *rtn = __builtin_amdgcn_global_atomic_fadd_f32(addr, x); } diff --git a/clang/test/CodeGenOpenCL/builtins-amdgcn-vi.cl b/clang/test/CodeGenOpenCL/builtins-amdgcn-vi.cl index d135d33d7dec6ea21a74e398aa3505c316e7eb53..ea2aedf8d44a5243049b5399804d5581939ff35b 100644 --- a/clang/test/CodeGenOpenCL/builtins-amdgcn-vi.cl +++ b/clang/test/CodeGenOpenCL/builtins-amdgcn-vi.cl @@ -3,6 +3,7 @@ // RUN: %clang_cc1 -triple amdgcn-unknown-unknown -target-cpu gfx900 -emit-llvm -o - %s | FileCheck %s // RUN: %clang_cc1 -triple amdgcn-unknown-unknown -target-cpu gfx1010 -emit-llvm -o - %s | FileCheck %s // RUN: %clang_cc1 -triple amdgcn-unknown-unknown -target-cpu gfx1012 -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple spirv64-amd-amdhsa -emit-llvm -o - %s | FileCheck %s #pragma OPENCL EXTENSION cl_khr_fp16 : enable @@ -10,42 +11,42 @@ typedef unsigned long ulong; typedef unsigned int uint; // CHECK-LABEL: @test_div_fixup_f16 -// CHECK: call half @llvm.amdgcn.div.fixup.f16 +// CHECK: {{.*}}call{{.*}} half @llvm.amdgcn.div.fixup.f16 void test_div_fixup_f16(global half* out, half a, half b, half c) { *out = __builtin_amdgcn_div_fixuph(a, b, c); } // CHECK-LABEL: @test_rcp_f16 -// CHECK: call half @llvm.amdgcn.rcp.f16 +// CHECK: {{.*}}call{{.*}} half @llvm.amdgcn.rcp.f16 void test_rcp_f16(global half* out, half a) { *out = __builtin_amdgcn_rcph(a); } // CHECK-LABEL: @test_sqrt_f16 -// CHECK: call half @llvm.sqrt.f16 +// CHECK: {{.*}}call{{.*}} half @llvm.{{((amdgcn.){0,1})}}sqrt.f16 void test_sqrt_f16(global half* out, half a) { *out = __builtin_amdgcn_sqrth(a); } // CHECK-LABEL: @test_rsq_f16 -// CHECK: call half @llvm.amdgcn.rsq.f16 +// CHECK: {{.*}}call{{.*}} half @llvm.amdgcn.rsq.f16 void test_rsq_f16(global half* out, half a) { *out = __builtin_amdgcn_rsqh(a); } // CHECK-LABEL: @test_sin_f16 -// CHECK: call half @llvm.amdgcn.sin.f16 +// CHECK: {{.*}}call{{.*}} half @llvm.amdgcn.sin.f16 void test_sin_f16(global half* out, half a) { *out = __builtin_amdgcn_sinh(a); } // CHECK-LABEL: @test_cos_f16 -// CHECK: call half @llvm.amdgcn.cos.f16 +// CHECK: {{.*}}call{{.*}} half @llvm.amdgcn.cos.f16 void test_cos_f16(global half* out, half a) { *out = __builtin_amdgcn_cosh(a); @@ -53,102 +54,114 @@ void test_cos_f16(global half* out, half a) // CHECK-LABEL: @test_ldexp_f16 // CHECK: [[TRUNC:%[0-9a-z]+]] = trunc i32 -// CHECK: call half @llvm.ldexp.f16.i16(half %a, i16 [[TRUNC]]) +// CHECK: {{.*}}call{{.*}} half @llvm.ldexp.f16.i16(half %a, i16 [[TRUNC]]) void test_ldexp_f16(global half* out, half a, int b) { *out = __builtin_amdgcn_ldexph(a, b); } // CHECK-LABEL: @test_frexp_mant_f16 -// CHECK: call half @llvm.amdgcn.frexp.mant.f16 +// CHECK: {{.*}}call{{.*}} half @llvm.amdgcn.frexp.mant.f16 void test_frexp_mant_f16(global half* out, half a) { *out = __builtin_amdgcn_frexp_manth(a); } // CHECK-LABEL: @test_frexp_exp_f16 -// CHECK: call i16 @llvm.amdgcn.frexp.exp.i16.f16 +// CHECK: {{.*}}call{{.*}} i16 @llvm.amdgcn.frexp.exp.i16.f16 void test_frexp_exp_f16(global short* out, half a) { *out = __builtin_amdgcn_frexp_exph(a); } // CHECK-LABEL: @test_fract_f16 -// CHECK: call half @llvm.amdgcn.fract.f16 +// CHECK: {{.*}}call{{.*}} half @llvm.amdgcn.fract.f16 void test_fract_f16(global half* out, half a) { *out = __builtin_amdgcn_fracth(a); } // CHECK-LABEL: @test_class_f16 -// CHECK: call i1 @llvm.amdgcn.class.f16 +// CHECK: {{.*}}call{{.*}} i1 @llvm.amdgcn.class.f16 void test_class_f16(global half* out, half a, int b) { *out = __builtin_amdgcn_classh(a, b); } // CHECK-LABEL: @test_s_memrealtime -// CHECK: call i64 @llvm.amdgcn.s.memrealtime() +// CHECK: {{.*}}call{{.*}} i64 @llvm.amdgcn.s.memrealtime() void test_s_memrealtime(global ulong* out) { *out = __builtin_amdgcn_s_memrealtime(); } // CHECK-LABEL: @test_s_dcache_wb() -// CHECK: call void @llvm.amdgcn.s.dcache.wb() +// CHECK: {{.*}}call{{.*}} void @llvm.amdgcn.s.dcache.wb() void test_s_dcache_wb() { __builtin_amdgcn_s_dcache_wb(); } // CHECK-LABEL: @test_mov_dpp -// CHECK: call i32 @llvm.amdgcn.update.dpp.i32(i32 poison, i32 %src, i32 0, i32 0, i32 0, i1 false) +// CHECK: {{.*}}call{{.*}} i32 @llvm.amdgcn.update.dpp.i32(i32 poison, i32 %src, i32 0, i32 0, i32 0, i1 false) void test_mov_dpp(global int* out, int src) { *out = __builtin_amdgcn_mov_dpp(src, 0, 0, 0, false); } // CHECK-LABEL: @test_update_dpp -// CHECK: call i32 @llvm.amdgcn.update.dpp.i32(i32 %arg1, i32 %arg2, i32 0, i32 0, i32 0, i1 false) +// CHECK: {{.*}}call{{.*}} i32 @llvm.amdgcn.update.dpp.i32(i32 %arg1, i32 %arg2, i32 0, i32 0, i32 0, i1 false) void test_update_dpp(global int* out, int arg1, int arg2) { *out = __builtin_amdgcn_update_dpp(arg1, arg2, 0, 0, 0, false); } // CHECK-LABEL: @test_ds_fadd -// CHECK: call float @llvm.amdgcn.ds.fadd.f32(ptr addrspace(3) %out, float %src, i32 0, i32 0, i1 false) +// CHECK: {{.*}}call{{.*}} float @llvm.amdgcn.ds.fadd.f32(ptr addrspace(3) %out, float %src, i32 0, i32 0, i1 false) +#if !defined(__SPIRV__) void test_ds_faddf(local float *out, float src) { +#else +void test_ds_faddf(__attribute__((address_space(3))) float *out, float src) { +#endif *out = __builtin_amdgcn_ds_faddf(out, src, 0, 0, false); } // CHECK-LABEL: @test_ds_fmin -// CHECK: call float @llvm.amdgcn.ds.fmin.f32(ptr addrspace(3) %out, float %src, i32 0, i32 0, i1 false) +// CHECK: {{.*}}call{{.*}} float @llvm.amdgcn.ds.fmin.f32(ptr addrspace(3) %out, float %src, i32 0, i32 0, i1 false) +#if !defined(__SPIRV__) void test_ds_fminf(local float *out, float src) { +#else +void test_ds_fminf(__attribute__((address_space(3))) float *out, float src) { +#endif *out = __builtin_amdgcn_ds_fminf(out, src, 0, 0, false); } // CHECK-LABEL: @test_ds_fmax -// CHECK: call float @llvm.amdgcn.ds.fmax.f32(ptr addrspace(3) %out, float %src, i32 0, i32 0, i1 false) +// CHECK: {{.*}}call{{.*}} float @llvm.amdgcn.ds.fmax.f32(ptr addrspace(3) %out, float %src, i32 0, i32 0, i1 false) +#if !defined(__SPIRV__) void test_ds_fmaxf(local float *out, float src) { +#else +void test_ds_fmaxf(__attribute__((address_space(3))) float *out, float src) { +#endif *out = __builtin_amdgcn_ds_fmaxf(out, src, 0, 0, false); } // CHECK-LABEL: @test_s_memtime -// CHECK: call i64 @llvm.amdgcn.s.memtime() +// CHECK: {{.*}}call{{.*}} i64 @llvm.amdgcn.s.memtime() void test_s_memtime(global ulong* out) { *out = __builtin_amdgcn_s_memtime(); } // CHECK-LABEL: @test_perm -// CHECK: call i32 @llvm.amdgcn.perm(i32 %a, i32 %b, i32 %s) +// CHECK: {{.*}}call{{.*}} i32 @llvm.amdgcn.perm(i32 %a, i32 %b, i32 %s) void test_perm(global uint* out, uint a, uint b, uint s) { *out = __builtin_amdgcn_perm(a, b, s); } // CHECK-LABEL: @test_groupstaticsize -// CHECK: call i32 @llvm.amdgcn.groupstaticsize() +// CHECK: {{.*}}call{{.*}} i32 @llvm.amdgcn.groupstaticsize() void test_groupstaticsize(global uint* out) { *out = __builtin_amdgcn_groupstaticsize(); diff --git a/clang/test/CodeGenOpenCL/builtins-amdgcn.cl b/clang/test/CodeGenOpenCL/builtins-amdgcn.cl index c2ef9ea947e93c7d87103f5d81053cecfa26feec..ffc190b76db98b6c8b282ecee431ae025e04b11f 100644 --- a/clang/test/CodeGenOpenCL/builtins-amdgcn.cl +++ b/clang/test/CodeGenOpenCL/builtins-amdgcn.cl @@ -1,5 +1,7 @@ // REQUIRES: amdgpu-registered-target -// RUN: %clang_cc1 -cl-std=CL2.0 -triple amdgcn-unknown-unknown -target-cpu tahiti -emit-llvm -o - %s | FileCheck -enable-var-scope %s +// RUN: %clang_cc1 -cl-std=CL2.0 -triple amdgcn-unknown-unknown -target-cpu tahiti -emit-llvm -o - %s | FileCheck -enable-var-scope --check-prefixes=CHECK-AMDGCN,CHECK %s +// RUN: %clang_cc1 -cl-std=CL2.0 -triple spirv64-amd-amdhsa -emit-llvm -o - %s | FileCheck -enable-var-scope --check-prefix=CHECK %s + #pragma OPENCL EXTENSION cl_khr_fp64 : enable @@ -12,7 +14,7 @@ typedef ushort __attribute__((ext_vector_type(2))) ushort2; typedef uint __attribute__((ext_vector_type(4))) uint4; // CHECK-LABEL: @test_div_scale_f64 -// CHECK: call { double, i1 } @llvm.amdgcn.div.scale.f64(double %a, double %b, i1 true) +// CHECK: {{.*}}call{{.*}} { double, i1 } @llvm.amdgcn.div.scale.f64(double %a, double %b, i1 true) // CHECK-DAG: [[FLAG:%.+]] = extractvalue { double, i1 } %{{.+}}, 1 // CHECK-DAG: [[VAL:%.+]] = extractvalue { double, i1 } %{{.+}}, 0 // CHECK: [[FLAGEXT:%.+]] = zext i1 [[FLAG]] to i32 @@ -25,7 +27,7 @@ void test_div_scale_f64(global double* out, global int* flagout, double a, doubl } // CHECK-LABEL: @test_div_scale_f32( -// CHECK: call { float, i1 } @llvm.amdgcn.div.scale.f32(float %a, float %b, i1 true) +// CHECK: {{.*}}call{{.*}} { float, i1 } @llvm.amdgcn.div.scale.f32(float %a, float %b, i1 true) // CHECK-DAG: [[FLAG:%.+]] = extractvalue { float, i1 } %{{.+}}, 1 // CHECK-DAG: [[VAL:%.+]] = extractvalue { float, i1 } %{{.+}}, 0 // CHECK: [[FLAGEXT:%.+]] = zext i1 [[FLAG]] to i8 @@ -38,7 +40,7 @@ void test_div_scale_f32(global float* out, global bool* flagout, float a, float } // CHECK-LABEL: @test_div_scale_f32_global_ptr( -// CHECK: call { float, i1 } @llvm.amdgcn.div.scale.f32(float %a, float %b, i1 true) +// CHECK: {{.*}}call{{.*}} { float, i1 } @llvm.amdgcn.div.scale.f32(float %a, float %b, i1 true) // CHECK-DAG: [[FLAG:%.+]] = extractvalue { float, i1 } %{{.+}}, 1 // CHECK-DAG: [[VAL:%.+]] = extractvalue { float, i1 } %{{.+}}, 0 // CHECK: [[FLAGEXT:%.+]] = zext i1 [[FLAG]] to i8 @@ -49,7 +51,7 @@ void test_div_scale_f32_global_ptr(global float* out, global int* flagout, float } // CHECK-LABEL: @test_div_scale_f32_generic_ptr( -// CHECK: call { float, i1 } @llvm.amdgcn.div.scale.f32(float %a, float %b, i1 true) +// CHECK: {{.*}}call{{.*}} { float, i1 } @llvm.amdgcn.div.scale.f32(float %a, float %b, i1 true) // CHECK-DAG: [[FLAG:%.+]] = extractvalue { float, i1 } %{{.+}}, 1 // CHECK-DAG: [[VAL:%.+]] = extractvalue { float, i1 } %{{.+}}, 0 // CHECK: [[FLAGEXT:%.+]] = zext i1 [[FLAG]] to i8 @@ -61,360 +63,360 @@ void test_div_scale_f32_generic_ptr(global float* out, global int* flagout, floa } // CHECK-LABEL: @test_div_fmas_f32 -// CHECK: call float @llvm.amdgcn.div.fmas.f32 +// CHECK: {{.*}}call{{.*}} float @llvm.amdgcn.div.fmas.f32 void test_div_fmas_f32(global float* out, float a, float b, float c, int d) { *out = __builtin_amdgcn_div_fmasf(a, b, c, d); } // CHECK-LABEL: @test_div_fmas_f64 -// CHECK: call double @llvm.amdgcn.div.fmas.f64 +// CHECK: {{.*}}call{{.*}} double @llvm.amdgcn.div.fmas.f64 void test_div_fmas_f64(global double* out, double a, double b, double c, int d) { *out = __builtin_amdgcn_div_fmas(a, b, c, d); } // CHECK-LABEL: @test_div_fixup_f32 -// CHECK: call float @llvm.amdgcn.div.fixup.f32 +// CHECK: {{.*}}call{{.*}} float @llvm.amdgcn.div.fixup.f32 void test_div_fixup_f32(global float* out, float a, float b, float c) { *out = __builtin_amdgcn_div_fixupf(a, b, c); } // CHECK-LABEL: @test_div_fixup_f64 -// CHECK: call double @llvm.amdgcn.div.fixup.f64 +// CHECK: {{.*}}call{{.*}} double @llvm.amdgcn.div.fixup.f64 void test_div_fixup_f64(global double* out, double a, double b, double c) { *out = __builtin_amdgcn_div_fixup(a, b, c); } // CHECK-LABEL: @test_trig_preop_f32 -// CHECK: call float @llvm.amdgcn.trig.preop.f32 +// CHECK: {{.*}}call{{.*}} float @llvm.amdgcn.trig.preop.f32 void test_trig_preop_f32(global float* out, float a, int b) { *out = __builtin_amdgcn_trig_preopf(a, b); } // CHECK-LABEL: @test_trig_preop_f64 -// CHECK: call double @llvm.amdgcn.trig.preop.f64 +// CHECK: {{.*}}call{{.*}} double @llvm.amdgcn.trig.preop.f64 void test_trig_preop_f64(global double* out, double a, int b) { *out = __builtin_amdgcn_trig_preop(a, b); } // CHECK-LABEL: @test_rcp_f32 -// CHECK: call float @llvm.amdgcn.rcp.f32 +// CHECK: {{.*}}call{{.*}} float @llvm.amdgcn.rcp.f32 void test_rcp_f32(global float* out, float a) { *out = __builtin_amdgcn_rcpf(a); } // CHECK-LABEL: @test_rcp_f64 -// CHECK: call double @llvm.amdgcn.rcp.f64 +// CHECK: {{.*}}call{{.*}} double @llvm.amdgcn.rcp.f64 void test_rcp_f64(global double* out, double a) { *out = __builtin_amdgcn_rcp(a); } // CHECK-LABEL: @test_sqrt_f32 -// CHECK: call float @llvm.amdgcn.sqrt.f32 +// CHECK: {{.*}}call{{.*}} float @llvm.{{((amdgcn.){0,1})}}sqrt.f32 void test_sqrt_f32(global float* out, float a) { *out = __builtin_amdgcn_sqrtf(a); } // CHECK-LABEL: @test_sqrt_f64 -// CHECK: call double @llvm.amdgcn.sqrt.f64 +// CHECK: {{.*}}call{{.*}} double @llvm.amdgcn.sqrt.f64 void test_sqrt_f64(global double* out, double a) { *out = __builtin_amdgcn_sqrt(a); } // CHECK-LABEL: @test_rsq_f32 -// CHECK: call float @llvm.amdgcn.rsq.f32 +// CHECK: {{.*}}call{{.*}} float @llvm.amdgcn.rsq.f32 void test_rsq_f32(global float* out, float a) { *out = __builtin_amdgcn_rsqf(a); } // CHECK-LABEL: @test_rsq_f64 -// CHECK: call double @llvm.amdgcn.rsq.f64 +// CHECK: {{.*}}call{{.*}} double @llvm.amdgcn.rsq.f64 void test_rsq_f64(global double* out, double a) { *out = __builtin_amdgcn_rsq(a); } // CHECK-LABEL: @test_rsq_clamp_f32 -// CHECK: call float @llvm.amdgcn.rsq.clamp.f32 +// CHECK: {{.*}}call{{.*}} float @llvm.amdgcn.rsq.clamp.f32 void test_rsq_clamp_f32(global float* out, float a) { *out = __builtin_amdgcn_rsq_clampf(a); } // CHECK-LABEL: @test_rsq_clamp_f64 -// CHECK: call double @llvm.amdgcn.rsq.clamp.f64 +// CHECK: {{.*}}call{{.*}} double @llvm.amdgcn.rsq.clamp.f64 void test_rsq_clamp_f64(global double* out, double a) { *out = __builtin_amdgcn_rsq_clamp(a); } // CHECK-LABEL: @test_sin_f32 -// CHECK: call float @llvm.amdgcn.sin.f32 +// CHECK: {{.*}}call{{.*}} float @llvm.amdgcn.sin.f32 void test_sin_f32(global float* out, float a) { *out = __builtin_amdgcn_sinf(a); } // CHECK-LABEL: @test_cos_f32 -// CHECK: call float @llvm.amdgcn.cos.f32 +// CHECK: {{.*}}call{{.*}} float @llvm.amdgcn.cos.f32 void test_cos_f32(global float* out, float a) { *out = __builtin_amdgcn_cosf(a); } // CHECK-LABEL: @test_log_f32 -// CHECK: call float @llvm.amdgcn.log.f32 +// CHECK: {{.*}}call{{.*}} float @llvm.amdgcn.log.f32 void test_log_f32(global float* out, float a) { *out = __builtin_amdgcn_logf(a); } // CHECK-LABEL: @test_exp2_f32 -// CHECK: call float @llvm.amdgcn.exp2.f32 +// CHECK: {{.*}}call{{.*}} float @llvm.amdgcn.exp2.f32 void test_exp2_f32(global float* out, float a) { *out = __builtin_amdgcn_exp2f(a); } // CHECK-LABEL: @test_log_clamp_f32 -// CHECK: call float @llvm.amdgcn.log.clamp.f32 +// CHECK: {{.*}}call{{.*}} float @llvm.amdgcn.log.clamp.f32 void test_log_clamp_f32(global float* out, float a) { *out = __builtin_amdgcn_log_clampf(a); } // CHECK-LABEL: @test_ldexp_f32 -// CHECK: call float @llvm.ldexp.f32.i32 +// CHECK: {{.*}}call{{.*}} float @llvm.ldexp.f32.i32 void test_ldexp_f32(global float* out, float a, int b) { *out = __builtin_amdgcn_ldexpf(a, b); } // CHECK-LABEL: @test_ldexp_f64 -// CHECK: call double @llvm.ldexp.f64.i32 +// CHECK: {{.*}}call{{.*}} double @llvm.ldexp.f64.i32 void test_ldexp_f64(global double* out, double a, int b) { *out = __builtin_amdgcn_ldexp(a, b); } // CHECK-LABEL: @test_frexp_mant_f32 -// CHECK: call float @llvm.amdgcn.frexp.mant.f32 +// CHECK: {{.*}}call{{.*}} float @llvm.amdgcn.frexp.mant.f32 void test_frexp_mant_f32(global float* out, float a) { *out = __builtin_amdgcn_frexp_mantf(a); } // CHECK-LABEL: @test_frexp_mant_f64 -// CHECK: call double @llvm.amdgcn.frexp.mant.f64 +// CHECK: {{.*}}call{{.*}} double @llvm.amdgcn.frexp.mant.f64 void test_frexp_mant_f64(global double* out, double a) { *out = __builtin_amdgcn_frexp_mant(a); } // CHECK-LABEL: @test_frexp_exp_f32 -// CHECK: call i32 @llvm.amdgcn.frexp.exp.i32.f32 +// CHECK: {{.*}}call{{.*}} i32 @llvm.amdgcn.frexp.exp.i32.f32 void test_frexp_exp_f32(global int* out, float a) { *out = __builtin_amdgcn_frexp_expf(a); } // CHECK-LABEL: @test_frexp_exp_f64 -// CHECK: call i32 @llvm.amdgcn.frexp.exp.i32.f64 +// CHECK: {{.*}}call{{.*}} i32 @llvm.amdgcn.frexp.exp.i32.f64 void test_frexp_exp_f64(global int* out, double a) { *out = __builtin_amdgcn_frexp_exp(a); } // CHECK-LABEL: @test_fract_f32 -// CHECK: call float @llvm.amdgcn.fract.f32 +// CHECK: {{.*}}call{{.*}} float @llvm.amdgcn.fract.f32 void test_fract_f32(global int* out, float a) { *out = __builtin_amdgcn_fractf(a); } // CHECK-LABEL: @test_fract_f64 -// CHECK: call double @llvm.amdgcn.fract.f64 +// CHECK: {{.*}}call{{.*}} double @llvm.amdgcn.fract.f64 void test_fract_f64(global int* out, double a) { *out = __builtin_amdgcn_fract(a); } // CHECK-LABEL: @test_lerp -// CHECK: call i32 @llvm.amdgcn.lerp +// CHECK: {{.*}}call{{.*}} i32 @llvm.amdgcn.lerp void test_lerp(global int* out, int a, int b, int c) { *out = __builtin_amdgcn_lerp(a, b, c); } // CHECK-LABEL: @test_sicmp_i32 -// CHECK: call i64 @llvm.amdgcn.icmp.i64.i32(i32 %a, i32 %b, i32 32) +// CHECK: {{.*}}call{{.*}} i64 @llvm.amdgcn.icmp.i64.i32(i32 %a, i32 %b, i32 32) void test_sicmp_i32(global ulong* out, int a, int b) { *out = __builtin_amdgcn_sicmp(a, b, 32); } // CHECK-LABEL: @test_uicmp_i32 -// CHECK: call i64 @llvm.amdgcn.icmp.i64.i32(i32 %a, i32 %b, i32 32) +// CHECK: {{.*}}call{{.*}} i64 @llvm.amdgcn.icmp.i64.i32(i32 %a, i32 %b, i32 32) void test_uicmp_i32(global ulong* out, uint a, uint b) { *out = __builtin_amdgcn_uicmp(a, b, 32); } // CHECK-LABEL: @test_sicmp_i64 -// CHECK: call i64 @llvm.amdgcn.icmp.i64.i64(i64 %a, i64 %b, i32 38) +// CHECK: {{.*}}call{{.*}} i64 @llvm.amdgcn.icmp.i64.i64(i64 %a, i64 %b, i32 38) void test_sicmp_i64(global ulong* out, long a, long b) { *out = __builtin_amdgcn_sicmpl(a, b, 39-1); } // CHECK-LABEL: @test_uicmp_i64 -// CHECK: call i64 @llvm.amdgcn.icmp.i64.i64(i64 %a, i64 %b, i32 35) +// CHECK: {{.*}}call{{.*}} i64 @llvm.amdgcn.icmp.i64.i64(i64 %a, i64 %b, i32 35) void test_uicmp_i64(global ulong* out, ulong a, ulong b) { *out = __builtin_amdgcn_uicmpl(a, b, 30+5); } // CHECK-LABEL: @test_ds_swizzle -// CHECK: call i32 @llvm.amdgcn.ds.swizzle(i32 %a, i32 32) +// CHECK: {{.*}}call{{.*}} i32 @llvm.amdgcn.ds.swizzle(i32 %a, i32 32) void test_ds_swizzle(global int* out, int a) { *out = __builtin_amdgcn_ds_swizzle(a, 32); } // CHECK-LABEL: @test_ds_permute -// CHECK: call i32 @llvm.amdgcn.ds.permute(i32 %a, i32 %b) +// CHECK: {{.*}}call{{.*}} i32 @llvm.amdgcn.ds.permute(i32 %a, i32 %b) void test_ds_permute(global int* out, int a, int b) { out[0] = __builtin_amdgcn_ds_permute(a, b); } // CHECK-LABEL: @test_ds_bpermute -// CHECK: call i32 @llvm.amdgcn.ds.bpermute(i32 %a, i32 %b) +// CHECK: {{.*}}call{{.*}} i32 @llvm.amdgcn.ds.bpermute(i32 %a, i32 %b) void test_ds_bpermute(global int* out, int a, int b) { *out = __builtin_amdgcn_ds_bpermute(a, b); } // CHECK-LABEL: @test_readfirstlane -// CHECK: call i32 @llvm.amdgcn.readfirstlane(i32 %a) +// CHECK: {{.*}}call{{.*}} i32 @llvm.amdgcn.readfirstlane(i32 %a) void test_readfirstlane(global int* out, int a) { *out = __builtin_amdgcn_readfirstlane(a); } // CHECK-LABEL: @test_readlane -// CHECK: call i32 @llvm.amdgcn.readlane(i32 %a, i32 %b) +// CHECK: {{.*}}call{{.*}} i32 @llvm.amdgcn.readlane(i32 %a, i32 %b) void test_readlane(global int* out, int a, int b) { *out = __builtin_amdgcn_readlane(a, b); } // CHECK-LABEL: @test_fcmp_f32 -// CHECK: call i64 @llvm.amdgcn.fcmp.i64.f32(float %a, float %b, i32 5) +// CHECK: {{.*}}call{{.*}} i64 @llvm.amdgcn.fcmp.i64.f32(float %a, float %b, i32 5) void test_fcmp_f32(global ulong* out, float a, float b) { *out = __builtin_amdgcn_fcmpf(a, b, 5); } // CHECK-LABEL: @test_fcmp_f64 -// CHECK: call i64 @llvm.amdgcn.fcmp.i64.f64(double %a, double %b, i32 6) +// CHECK: {{.*}}call{{.*}} i64 @llvm.amdgcn.fcmp.i64.f64(double %a, double %b, i32 6) void test_fcmp_f64(global ulong* out, double a, double b) { *out = __builtin_amdgcn_fcmp(a, b, 3+3); } // CHECK-LABEL: @test_class_f32 -// CHECK: call i1 @llvm.amdgcn.class.f32 +// CHECK: {{.*}}call{{.*}} i1 @llvm.amdgcn.class.f32 void test_class_f32(global float* out, float a, int b) { *out = __builtin_amdgcn_classf(a, b); } // CHECK-LABEL: @test_class_f64 -// CHECK: call i1 @llvm.amdgcn.class.f64 +// CHECK: {{.*}}call{{.*}} i1 @llvm.amdgcn.class.f64 void test_class_f64(global double* out, double a, int b) { *out = __builtin_amdgcn_class(a, b); } // CHECK-LABEL: @test_buffer_wbinvl1 -// CHECK: call void @llvm.amdgcn.buffer.wbinvl1( +// CHECK: {{.*}}call{{.*}} void @llvm.amdgcn.buffer.wbinvl1( void test_buffer_wbinvl1() { __builtin_amdgcn_buffer_wbinvl1(); } // CHECK-LABEL: @test_s_dcache_inv -// CHECK: call void @llvm.amdgcn.s.dcache.inv( +// CHECK: {{.*}}call{{.*}} void @llvm.amdgcn.s.dcache.inv( void test_s_dcache_inv() { __builtin_amdgcn_s_dcache_inv(); } // CHECK-LABEL: @test_s_waitcnt -// CHECK: call void @llvm.amdgcn.s.waitcnt( +// CHECK: {{.*}}call{{.*}} void @llvm.amdgcn.s.waitcnt( void test_s_waitcnt() { __builtin_amdgcn_s_waitcnt(0); } // CHECK-LABEL: @test_s_sendmsg -// CHECK: call void @llvm.amdgcn.s.sendmsg( +// CHECK: {{.*}}call{{.*}} void @llvm.amdgcn.s.sendmsg( void test_s_sendmsg() { __builtin_amdgcn_s_sendmsg(1, 0); } // CHECK-LABEL: @test_s_sendmsg_var -// CHECK: call void @llvm.amdgcn.s.sendmsg( +// CHECK: {{.*}}call{{.*}} void @llvm.amdgcn.s.sendmsg( void test_s_sendmsg_var(int in) { __builtin_amdgcn_s_sendmsg(1, in); } // CHECK-LABEL: @test_s_sendmsghalt -// CHECK: call void @llvm.amdgcn.s.sendmsghalt( +// CHECK: {{.*}}call{{.*}} void @llvm.amdgcn.s.sendmsghalt( void test_s_sendmsghalt() { __builtin_amdgcn_s_sendmsghalt(1, 0); } // CHECK-LABEL: @test_s_sendmsghalt -// CHECK: call void @llvm.amdgcn.s.sendmsghalt( +// CHECK: {{.*}}call{{.*}} void @llvm.amdgcn.s.sendmsghalt( void test_s_sendmsghalt_var(int in) { __builtin_amdgcn_s_sendmsghalt(1, in); } // CHECK-LABEL: @test_s_barrier -// CHECK: call void @llvm.amdgcn.s.barrier( +// CHECK: {{.*}}call{{.*}} void @llvm.amdgcn.s.barrier( void test_s_barrier() { __builtin_amdgcn_s_barrier(); } // CHECK-LABEL: @test_wave_barrier -// CHECK: call void @llvm.amdgcn.wave.barrier( +// CHECK: {{.*}}call{{.*}} void @llvm.amdgcn.wave.barrier( void test_wave_barrier() { __builtin_amdgcn_wave_barrier(); } // CHECK-LABEL: @test_sched_barrier -// CHECK: call void @llvm.amdgcn.sched.barrier(i32 0) -// CHECK: call void @llvm.amdgcn.sched.barrier(i32 1) -// CHECK: call void @llvm.amdgcn.sched.barrier(i32 4) -// CHECK: call void @llvm.amdgcn.sched.barrier(i32 15) +// CHECK: {{.*}}call{{.*}} void @llvm.amdgcn.sched.barrier(i32 0) +// CHECK: {{.*}}call{{.*}} void @llvm.amdgcn.sched.barrier(i32 1) +// CHECK: {{.*}}call{{.*}} void @llvm.amdgcn.sched.barrier(i32 4) +// CHECK: {{.*}}call{{.*}} void @llvm.amdgcn.sched.barrier(i32 15) void test_sched_barrier() { __builtin_amdgcn_sched_barrier(0); @@ -424,10 +426,10 @@ void test_sched_barrier() } // CHECK-LABEL: @test_sched_group_barrier -// CHECK: call void @llvm.amdgcn.sched.group.barrier(i32 0, i32 1, i32 2) -// CHECK: call void @llvm.amdgcn.sched.group.barrier(i32 1, i32 2, i32 4) -// CHECK: call void @llvm.amdgcn.sched.group.barrier(i32 4, i32 8, i32 16) -// CHECK: call void @llvm.amdgcn.sched.group.barrier(i32 15, i32 10000, i32 -1) +// CHECK: {{.*}}call{{.*}} void @llvm.amdgcn.sched.group.barrier(i32 0, i32 1, i32 2) +// CHECK: {{.*}}call{{.*}} void @llvm.amdgcn.sched.group.barrier(i32 1, i32 2, i32 4) +// CHECK: {{.*}}call{{.*}} void @llvm.amdgcn.sched.group.barrier(i32 4, i32 8, i32 16) +// CHECK: {{.*}}call{{.*}} void @llvm.amdgcn.sched.group.barrier(i32 15, i32 10000, i32 -1) void test_sched_group_barrier() { __builtin_amdgcn_sched_group_barrier(0, 1, 2); @@ -437,10 +439,10 @@ void test_sched_group_barrier() } // CHECK-LABEL: @test_iglp_opt -// CHECK: call void @llvm.amdgcn.iglp.opt(i32 0) -// CHECK: call void @llvm.amdgcn.iglp.opt(i32 1) -// CHECK: call void @llvm.amdgcn.iglp.opt(i32 4) -// CHECK: call void @llvm.amdgcn.iglp.opt(i32 15) +// CHECK: {{.*}}call{{.*}} void @llvm.amdgcn.iglp.opt(i32 0) +// CHECK: {{.*}}call{{.*}} void @llvm.amdgcn.iglp.opt(i32 1) +// CHECK: {{.*}}call{{.*}} void @llvm.amdgcn.iglp.opt(i32 4) +// CHECK: {{.*}}call{{.*}} void @llvm.amdgcn.iglp.opt(i32 15) void test_iglp_opt() { __builtin_amdgcn_iglp_opt(0); @@ -450,8 +452,8 @@ void test_iglp_opt() } // CHECK-LABEL: @test_s_sleep -// CHECK: call void @llvm.amdgcn.s.sleep(i32 1) -// CHECK: call void @llvm.amdgcn.s.sleep(i32 15) +// CHECK: {{.*}}call{{.*}} void @llvm.amdgcn.s.sleep(i32 1) +// CHECK: {{.*}}call{{.*}} void @llvm.amdgcn.s.sleep(i32 15) void test_s_sleep() { __builtin_amdgcn_s_sleep(1); @@ -459,8 +461,8 @@ void test_s_sleep() } // CHECK-LABEL: @test_s_incperflevel -// CHECK: call void @llvm.amdgcn.s.incperflevel(i32 1) -// CHECK: call void @llvm.amdgcn.s.incperflevel(i32 15) +// CHECK: {{.*}}call{{.*}} void @llvm.amdgcn.s.incperflevel(i32 1) +// CHECK: {{.*}}call{{.*}} void @llvm.amdgcn.s.incperflevel(i32 15) void test_s_incperflevel() { __builtin_amdgcn_s_incperflevel(1); @@ -468,8 +470,8 @@ void test_s_incperflevel() } // CHECK-LABEL: @test_s_decperflevel -// CHECK: call void @llvm.amdgcn.s.decperflevel(i32 1) -// CHECK: call void @llvm.amdgcn.s.decperflevel(i32 15) +// CHECK: {{.*}}call{{.*}} void @llvm.amdgcn.s.decperflevel(i32 1) +// CHECK: {{.*}}call{{.*}} void @llvm.amdgcn.s.decperflevel(i32 15) void test_s_decperflevel() { __builtin_amdgcn_s_decperflevel(1); @@ -477,8 +479,8 @@ void test_s_decperflevel() } // CHECK-LABEL: @test_s_setprio -// CHECK: call void @llvm.amdgcn.s.setprio(i16 0) -// CHECK: call void @llvm.amdgcn.s.setprio(i16 3) +// CHECK: {{.*}}call{{.*}} void @llvm.amdgcn.s.setprio(i16 0) +// CHECK: {{.*}}call{{.*}} void @llvm.amdgcn.s.setprio(i16 3) void test_s_setprio() { __builtin_amdgcn_s_setprio(0); @@ -486,47 +488,47 @@ void test_s_setprio() } // CHECK-LABEL: @test_cubeid( -// CHECK: call float @llvm.amdgcn.cubeid(float %a, float %b, float %c) +// CHECK: {{.*}}call{{.*}} float @llvm.amdgcn.cubeid(float %a, float %b, float %c) void test_cubeid(global float* out, float a, float b, float c) { *out = __builtin_amdgcn_cubeid(a, b, c); } // CHECK-LABEL: @test_cubesc( -// CHECK: call float @llvm.amdgcn.cubesc(float %a, float %b, float %c) +// CHECK: {{.*}}call{{.*}} float @llvm.amdgcn.cubesc(float %a, float %b, float %c) void test_cubesc(global float* out, float a, float b, float c) { *out = __builtin_amdgcn_cubesc(a, b, c); } // CHECK-LABEL: @test_cubetc( -// CHECK: call float @llvm.amdgcn.cubetc(float %a, float %b, float %c) +// CHECK: {{.*}}call{{.*}} float @llvm.amdgcn.cubetc(float %a, float %b, float %c) void test_cubetc(global float* out, float a, float b, float c) { *out = __builtin_amdgcn_cubetc(a, b, c); } // CHECK-LABEL: @test_cubema( -// CHECK: call float @llvm.amdgcn.cubema(float %a, float %b, float %c) +// CHECK: {{.*}}call{{.*}} float @llvm.amdgcn.cubema(float %a, float %b, float %c) void test_cubema(global float* out, float a, float b, float c) { *out = __builtin_amdgcn_cubema(a, b, c); } // CHECK-LABEL: @test_read_exec( -// CHECK: call i64 @llvm.amdgcn.ballot.i64(i1 true) +// CHECK: {{.*}}call{{.*}} i64 @llvm.amdgcn.ballot.i64(i1 true) void test_read_exec(global ulong* out) { *out = __builtin_amdgcn_read_exec(); } -// CHECK: declare i64 @llvm.amdgcn.ballot.i64(i1) #[[$NOUNWIND_READONLY:[0-9]+]] +// CHECK: declare i64 @llvm.amdgcn.ballot.i64(i1){{.*}} #[[$NOUNWIND_READONLY:[0-9]+]] // CHECK-LABEL: @test_read_exec_lo( -// CHECK: call i32 @llvm.amdgcn.ballot.i32(i1 true) +// CHECK: {{.*}}call{{.*}} i32 @llvm.amdgcn.ballot.i32(i1 true) void test_read_exec_lo(global uint* out) { *out = __builtin_amdgcn_read_exec_lo(); } -// CHECK: declare i32 @llvm.amdgcn.ballot.i32(i1) #[[$NOUNWIND_READONLY:[0-9]+]] +// CHECK: declare i32 @llvm.amdgcn.ballot.i32(i1){{.*}} #[[$NOUNWIND_READONLY:[0-9]+]] // CHECK-LABEL: @test_read_exec_hi( -// CHECK: call i64 @llvm.amdgcn.ballot.i64(i1 true) +// CHECK: {{.*}}call{{.*}} i64 @llvm.amdgcn.ballot.i64(i1 true) // CHECK: lshr i64 [[A:%.*]], 32 // CHECK: trunc nuw i64 [[B:%.*]] to i32 void test_read_exec_hi(global uint* out) { @@ -534,37 +536,53 @@ void test_read_exec_hi(global uint* out) { } // CHECK-LABEL: @test_dispatch_ptr -// CHECK: call align 4 dereferenceable(64) ptr addrspace(4) @llvm.amdgcn.dispatch.ptr() +// CHECK: {{.*}}call align 4 dereferenceable(64){{.*}} ptr addrspace(4) @llvm.amdgcn.dispatch.ptr() +#if !defined(__SPIRV__) void test_dispatch_ptr(__constant unsigned char ** out) +#else +void test_dispatch_ptr(__attribute__((address_space(4))) unsigned char ** out) +#endif { *out = __builtin_amdgcn_dispatch_ptr(); } // CHECK-LABEL: @test_queue_ptr -// CHECK: call ptr addrspace(4) @llvm.amdgcn.queue.ptr() +// CHECK: {{.*}}call{{.*}} ptr addrspace(4) @llvm.amdgcn.queue.ptr() +#if !defined(__SPIRV__) void test_queue_ptr(__constant unsigned char ** out) +#else +void test_queue_ptr(__attribute__((address_space(4))) unsigned char ** out) +#endif { *out = __builtin_amdgcn_queue_ptr(); } // CHECK-LABEL: @test_kernarg_segment_ptr -// CHECK: call ptr addrspace(4) @llvm.amdgcn.kernarg.segment.ptr() +// CHECK: {{.*}}call{{.*}} ptr addrspace(4) @llvm.amdgcn.kernarg.segment.ptr() +#if !defined(__SPIRV__) void test_kernarg_segment_ptr(__constant unsigned char ** out) +#else +void test_kernarg_segment_ptr(__attribute__((address_space(4))) unsigned char ** out) +#endif { *out = __builtin_amdgcn_kernarg_segment_ptr(); } // CHECK-LABEL: @test_implicitarg_ptr -// CHECK: call ptr addrspace(4) @llvm.amdgcn.implicitarg.ptr() +// CHECK: {{.*}}call{{.*}} ptr addrspace(4) @llvm.amdgcn.implicitarg.ptr() +#if !defined(__SPIRV__) void test_implicitarg_ptr(__constant unsigned char ** out) +#else +void test_implicitarg_ptr(__attribute__((address_space(4))) unsigned char ** out) +#endif { *out = __builtin_amdgcn_implicitarg_ptr(); } // CHECK-LABEL: @test_get_group_id( -// CHECK: tail call i32 @llvm.amdgcn.workgroup.id.x() -// CHECK: tail call i32 @llvm.amdgcn.workgroup.id.y() -// CHECK: tail call i32 @llvm.amdgcn.workgroup.id.z() +// CHECK: tail call{{.*}} i32 @llvm.amdgcn.workgroup.id.x() +// CHECK: tail call{{.*}} i32 @llvm.amdgcn.workgroup.id.y() +// CHECK: tail call{{.*}} i32 @llvm.amdgcn.workgroup.id.z() void test_get_group_id(int d, global int *out) { switch (d) { @@ -576,9 +594,9 @@ void test_get_group_id(int d, global int *out) } // CHECK-LABEL: @test_s_getreg( -// CHECK: tail call i32 @llvm.amdgcn.s.getreg(i32 0) -// CHECK: tail call i32 @llvm.amdgcn.s.getreg(i32 1) -// CHECK: tail call i32 @llvm.amdgcn.s.getreg(i32 65535) +// CHECK: tail call{{.*}} i32 @llvm.amdgcn.s.getreg(i32 0) +// CHECK: tail call{{.*}} i32 @llvm.amdgcn.s.getreg(i32 1) +// CHECK: tail call{{.*}} i32 @llvm.amdgcn.s.getreg(i32 65535) void test_s_getreg(volatile global uint *out) { *out = __builtin_amdgcn_s_getreg(0); @@ -587,9 +605,9 @@ void test_s_getreg(volatile global uint *out) } // CHECK-LABEL: @test_get_local_id( -// CHECK: tail call i32 @llvm.amdgcn.workitem.id.x(), !range [[$WI_RANGE:![0-9]*]], !noundef -// CHECK: tail call i32 @llvm.amdgcn.workitem.id.y(), !range [[$WI_RANGE]], !noundef -// CHECK: tail call i32 @llvm.amdgcn.workitem.id.z(), !range [[$WI_RANGE]], !noundef +// CHECK: tail call{{.*}} i32 @llvm.amdgcn.workitem.id.x(), !range [[$WI_RANGE:![0-9]*]], !noundef +// CHECK: tail call{{.*}} i32 @llvm.amdgcn.workitem.id.y(), !range [[$WI_RANGE]], !noundef +// CHECK: tail call{{.*}} i32 @llvm.amdgcn.workitem.id.z(), !range [[$WI_RANGE]], !noundef void test_get_local_id(int d, global int *out) { switch (d) { @@ -601,7 +619,7 @@ void test_get_local_id(int d, global int *out) } // CHECK-LABEL: @test_get_workgroup_size( -// CHECK: call align 8 dereferenceable(256) ptr addrspace(4) @llvm.amdgcn.implicitarg.ptr() +// CHECK: {{.*}}call align 8 dereferenceable(256){{.*}} ptr addrspace(4) @llvm.amdgcn.implicitarg.ptr() // CHECK: getelementptr inbounds i8, ptr addrspace(4) %{{.*}}, i64 12 // CHECK: load i16, ptr addrspace(4) %{{.*}}, align 4, !range [[$WS_RANGE:![0-9]*]], !invariant.load{{.*}}, !noundef // CHECK: getelementptr inbounds i8, ptr addrspace(4) %{{.*}}, i64 14 @@ -619,7 +637,7 @@ void test_get_workgroup_size(int d, global int *out) } // CHECK-LABEL: @test_get_grid_size( -// CHECK: call align 4 dereferenceable(64) ptr addrspace(4) @llvm.amdgcn.dispatch.ptr() +// CHECK: {{.*}}call align 4 dereferenceable(64){{.*}} ptr addrspace(4) @llvm.amdgcn.dispatch.ptr() // CHECK: getelementptr inbounds i8, ptr addrspace(4) %{{.*}}, i64 12 // CHECK: load i32, ptr addrspace(4) %{{.*}}, align 4, !invariant.load // CHECK: getelementptr inbounds i8, ptr addrspace(4) %{{.*}}, i64 16 @@ -637,177 +655,185 @@ void test_get_grid_size(int d, global int *out) } // CHECK-LABEL: @test_fmed3_f32 -// CHECK: call float @llvm.amdgcn.fmed3.f32( +// CHECK: {{.*}}call{{.*}} float @llvm.amdgcn.fmed3.f32( void test_fmed3_f32(global float* out, float a, float b, float c) { *out = __builtin_amdgcn_fmed3f(a, b, c); } // CHECK-LABEL: @test_s_getpc -// CHECK: call i64 @llvm.amdgcn.s.getpc() +// CHECK: {{.*}}call{{.*}} i64 @llvm.amdgcn.s.getpc() void test_s_getpc(global ulong* out) { *out = __builtin_amdgcn_s_getpc(); } // CHECK-LABEL: @test_ds_append_lds( -// CHECK: call i32 @llvm.amdgcn.ds.append.p3(ptr addrspace(3) %ptr, i1 false) +// CHECK: {{.*}}call{{.*}} i32 @llvm.amdgcn.ds.append.p3(ptr addrspace(3) %ptr, i1 false) kernel void test_ds_append_lds(global int* out, local int* ptr) { +#if !defined(__SPIRV__) *out = __builtin_amdgcn_ds_append(ptr); +#else + *out = __builtin_amdgcn_ds_append((__attribute__((address_space(3))) int*)(int*)ptr); +#endif } // CHECK-LABEL: @test_ds_consume_lds( -// CHECK: call i32 @llvm.amdgcn.ds.consume.p3(ptr addrspace(3) %ptr, i1 false) +// CHECK: {{.*}}call{{.*}} i32 @llvm.amdgcn.ds.consume.p3(ptr addrspace(3) %ptr, i1 false) kernel void test_ds_consume_lds(global int* out, local int* ptr) { +#if !defined(__SPIRV__) *out = __builtin_amdgcn_ds_consume(ptr); +#else + *out = __builtin_amdgcn_ds_consume((__attribute__((address_space(3))) int*)(int*)ptr); +#endif } // CHECK-LABEL: @test_gws_init( -// CHECK: call void @llvm.amdgcn.ds.gws.init(i32 %value, i32 %id) +// CHECK: {{.*}}call{{.*}} void @llvm.amdgcn.ds.gws.init(i32 %value, i32 %id) kernel void test_gws_init(uint value, uint id) { __builtin_amdgcn_ds_gws_init(value, id); } // CHECK-LABEL: @test_gws_barrier( -// CHECK: call void @llvm.amdgcn.ds.gws.barrier(i32 %value, i32 %id) +// CHECK: {{.*}}call{{.*}} void @llvm.amdgcn.ds.gws.barrier(i32 %value, i32 %id) kernel void test_gws_barrier(uint value, uint id) { __builtin_amdgcn_ds_gws_barrier(value, id); } // CHECK-LABEL: @test_gws_sema_v( -// CHECK: call void @llvm.amdgcn.ds.gws.sema.v(i32 %id) +// CHECK: {{.*}}call{{.*}} void @llvm.amdgcn.ds.gws.sema.v(i32 %id) kernel void test_gws_sema_v(uint id) { __builtin_amdgcn_ds_gws_sema_v(id); } // CHECK-LABEL: @test_gws_sema_br( -// CHECK: call void @llvm.amdgcn.ds.gws.sema.br(i32 %value, i32 %id) +// CHECK: {{.*}}call{{.*}} void @llvm.amdgcn.ds.gws.sema.br(i32 %value, i32 %id) kernel void test_gws_sema_br(uint value, uint id) { __builtin_amdgcn_ds_gws_sema_br(value, id); } // CHECK-LABEL: @test_gws_sema_p( -// CHECK: call void @llvm.amdgcn.ds.gws.sema.p(i32 %id) +// CHECK: {{.*}}call{{.*}} void @llvm.amdgcn.ds.gws.sema.p(i32 %id) kernel void test_gws_sema_p(uint id) { __builtin_amdgcn_ds_gws_sema_p(id); } // CHECK-LABEL: @test_mbcnt_lo( -// CHECK: call i32 @llvm.amdgcn.mbcnt.lo(i32 %src0, i32 %src1) +// CHECK: {{.*}}call{{.*}} i32 @llvm.amdgcn.mbcnt.lo(i32 %src0, i32 %src1) kernel void test_mbcnt_lo(global uint* out, uint src0, uint src1) { *out = __builtin_amdgcn_mbcnt_lo(src0, src1); } // CHECK-LABEL: @test_mbcnt_hi( -// CHECK: call i32 @llvm.amdgcn.mbcnt.hi(i32 %src0, i32 %src1) +// CHECK: {{.*}}call{{.*}} i32 @llvm.amdgcn.mbcnt.hi(i32 %src0, i32 %src1) kernel void test_mbcnt_hi(global uint* out, uint src0, uint src1) { *out = __builtin_amdgcn_mbcnt_hi(src0, src1); } // CHECK-LABEL: @test_alignbit( -// CHECK: tail call i32 @llvm.fshr.i32(i32 %src0, i32 %src1, i32 %src2) +// CHECK: tail call{{.*}} i32 @llvm.fshr.i32(i32 %src0, i32 %src1, i32 %src2) kernel void test_alignbit(global uint* out, uint src0, uint src1, uint src2) { *out = __builtin_amdgcn_alignbit(src0, src1, src2); } // CHECK-LABEL: @test_alignbyte( -// CHECK: tail call i32 @llvm.amdgcn.alignbyte(i32 %src0, i32 %src1, i32 %src2) +// CHECK: tail call{{.*}} i32 @llvm.amdgcn.alignbyte(i32 %src0, i32 %src1, i32 %src2) kernel void test_alignbyte(global uint* out, uint src0, uint src1, uint src2) { *out = __builtin_amdgcn_alignbyte(src0, src1, src2); } // CHECK-LABEL: @test_ubfe( -// CHECK: tail call i32 @llvm.amdgcn.ubfe.i32(i32 %src0, i32 %src1, i32 %src2) +// CHECK: tail call{{.*}} i32 @llvm.amdgcn.ubfe.i32(i32 %src0, i32 %src1, i32 %src2) kernel void test_ubfe(global uint* out, uint src0, uint src1, uint src2) { *out = __builtin_amdgcn_ubfe(src0, src1, src2); } // CHECK-LABEL: @test_sbfe( -// CHECK: tail call i32 @llvm.amdgcn.sbfe.i32(i32 %src0, i32 %src1, i32 %src2) +// CHECK: tail call{{.*}} i32 @llvm.amdgcn.sbfe.i32(i32 %src0, i32 %src1, i32 %src2) kernel void test_sbfe(global uint* out, uint src0, uint src1, uint src2) { *out = __builtin_amdgcn_sbfe(src0, src1, src2); } // CHECK-LABEL: @test_cvt_pkrtz( -// CHECK: tail call <2 x half> @llvm.amdgcn.cvt.pkrtz(float %src0, float %src1) +// CHECK: tail call{{.*}} <2 x half> @llvm.amdgcn.cvt.pkrtz(float %src0, float %src1) kernel void test_cvt_pkrtz(global half2* out, float src0, float src1) { *out = __builtin_amdgcn_cvt_pkrtz(src0, src1); } // CHECK-LABEL: @test_cvt_pknorm_i16( -// CHECK: tail call <2 x i16> @llvm.amdgcn.cvt.pknorm.i16(float %src0, float %src1) +// CHECK: tail call{{.*}} <2 x i16> @llvm.amdgcn.cvt.pknorm.i16(float %src0, float %src1) kernel void test_cvt_pknorm_i16(global short2* out, float src0, float src1) { *out = __builtin_amdgcn_cvt_pknorm_i16(src0, src1); } // CHECK-LABEL: @test_cvt_pknorm_u16( -// CHECK: tail call <2 x i16> @llvm.amdgcn.cvt.pknorm.u16(float %src0, float %src1) +// CHECK: tail call{{.*}} <2 x i16> @llvm.amdgcn.cvt.pknorm.u16(float %src0, float %src1) kernel void test_cvt_pknorm_u16(global ushort2* out, float src0, float src1) { *out = __builtin_amdgcn_cvt_pknorm_u16(src0, src1); } // CHECK-LABEL: @test_cvt_pk_i16( -// CHECK: tail call <2 x i16> @llvm.amdgcn.cvt.pk.i16(i32 %src0, i32 %src1) +// CHECK: tail call{{.*}} <2 x i16> @llvm.amdgcn.cvt.pk.i16(i32 %src0, i32 %src1) kernel void test_cvt_pk_i16(global short2* out, int src0, int src1) { *out = __builtin_amdgcn_cvt_pk_i16(src0, src1); } // CHECK-LABEL: @test_cvt_pk_u16( -// CHECK: tail call <2 x i16> @llvm.amdgcn.cvt.pk.u16(i32 %src0, i32 %src1) +// CHECK: tail call{{.*}} <2 x i16> @llvm.amdgcn.cvt.pk.u16(i32 %src0, i32 %src1) kernel void test_cvt_pk_u16(global ushort2* out, uint src0, uint src1) { *out = __builtin_amdgcn_cvt_pk_u16(src0, src1); } // CHECK-LABEL: @test_cvt_pk_u8_f32 -// CHECK: tail call i32 @llvm.amdgcn.cvt.pk.u8.f32(float %src0, i32 %src1, i32 %src2) +// CHECK: tail call{{.*}} i32 @llvm.amdgcn.cvt.pk.u8.f32(float %src0, i32 %src1, i32 %src2) kernel void test_cvt_pk_u8_f32(global uint* out, float src0, uint src1, uint src2) { *out = __builtin_amdgcn_cvt_pk_u8_f32(src0, src1, src2); } // CHECK-LABEL: @test_sad_u8( -// CHECK: tail call i32 @llvm.amdgcn.sad.u8(i32 %src0, i32 %src1, i32 %src2) +// CHECK: tail call{{.*}} i32 @llvm.amdgcn.sad.u8(i32 %src0, i32 %src1, i32 %src2) kernel void test_sad_u8(global uint* out, uint src0, uint src1, uint src2) { *out = __builtin_amdgcn_sad_u8(src0, src1, src2); } // CHECK-LABEL: test_msad_u8( -// CHECK: call i32 @llvm.amdgcn.msad.u8(i32 %src0, i32 %src1, i32 %src2) +// CHECK: {{.*}}call{{.*}} i32 @llvm.amdgcn.msad.u8(i32 %src0, i32 %src1, i32 %src2) kernel void test_msad_u8(global uint* out, uint src0, uint src1, uint src2) { *out = __builtin_amdgcn_msad_u8(src0, src1, src2); } // CHECK-LABEL: test_sad_hi_u8( -// CHECK: call i32 @llvm.amdgcn.sad.hi.u8(i32 %src0, i32 %src1, i32 %src2) +// CHECK: {{.*}}call{{.*}} i32 @llvm.amdgcn.sad.hi.u8(i32 %src0, i32 %src1, i32 %src2) kernel void test_sad_hi_u8(global uint* out, uint src0, uint src1, uint src2) { *out = __builtin_amdgcn_sad_hi_u8(src0, src1, src2); } // CHECK-LABEL: @test_sad_u16( -// CHECK: call i32 @llvm.amdgcn.sad.u16(i32 %src0, i32 %src1, i32 %src2) +// CHECK: {{.*}}call{{.*}} i32 @llvm.amdgcn.sad.u16(i32 %src0, i32 %src1, i32 %src2) kernel void test_sad_u16(global uint* out, uint src0, uint src1, uint src2) { *out = __builtin_amdgcn_sad_u16(src0, src1, src2); } // CHECK-LABEL: @test_qsad_pk_u16_u8( -// CHECK: call i64 @llvm.amdgcn.qsad.pk.u16.u8(i64 %src0, i32 %src1, i64 %src2) +// CHECK: {{.*}}call{{.*}} i64 @llvm.amdgcn.qsad.pk.u16.u8(i64 %src0, i32 %src1, i64 %src2) kernel void test_qsad_pk_u16_u8(global ulong* out, ulong src0, uint src1, ulong src2) { *out = __builtin_amdgcn_qsad_pk_u16_u8(src0, src1, src2); } // CHECK-LABEL: @test_mqsad_pk_u16_u8( -// CHECK: call i64 @llvm.amdgcn.mqsad.pk.u16.u8(i64 %src0, i32 %src1, i64 %src2) +// CHECK: {{.*}}call{{.*}} i64 @llvm.amdgcn.mqsad.pk.u16.u8(i64 %src0, i32 %src1, i64 %src2) kernel void test_mqsad_pk_u16_u8(global ulong* out, ulong src0, uint src1, ulong src2) { *out = __builtin_amdgcn_mqsad_pk_u16_u8(src0, src1, src2); } // CHECK-LABEL: test_mqsad_u32_u8( -// CHECK: call <4 x i32> @llvm.amdgcn.mqsad.u32.u8(i64 %src0, i32 %src1, <4 x i32> %src2) +// CHECK: {{.*}}call{{.*}} <4 x i32> @llvm.amdgcn.mqsad.u32.u8(i64 %src0, i32 %src1, <4 x i32> %src2) kernel void test_mqsad_u32_u8(global uint4* out, ulong src0, uint src1, uint4 src2) { *out = __builtin_amdgcn_mqsad_u32_u8(src0, src1, src2); } // CHECK-LABEL: test_s_setreg( -// CHECK: call void @llvm.amdgcn.s.setreg(i32 8193, i32 %val) +// CHECK: {{.*}}call{{.*}} void @llvm.amdgcn.s.setreg(i32 8193, i32 %val) kernel void test_s_setreg(uint val) { __builtin_amdgcn_s_setreg(8193, val); } @@ -835,31 +861,33 @@ void test_atomic_inc_dec(local uint *lptr, global uint *gptr, uint val) { // CHECK-LABEL test_wavefrontsize( unsigned test_wavefrontsize() { - // CHECK: call i32 @llvm.amdgcn.wavefrontsize() + // CHECK: {{.*}}call{{.*}} i32 @llvm.amdgcn.wavefrontsize() return __builtin_amdgcn_wavefrontsize(); } // CHECK-LABEL test_flt_rounds( unsigned test_flt_rounds() { - // CHECK: call i32 @llvm.get.rounding() + // CHECK: {{.*}}call{{.*}} i32 @llvm.get.rounding() unsigned mode = __builtin_flt_rounds(); - // CHECK: call void @llvm.set.rounding(i32 %0) +#if !defined(__SPIRV__) + // CHECK-AMDGCN: call void @llvm.set.rounding(i32 %0) __builtin_set_flt_rounds(mode); +#endif return mode; } // CHECK-LABEL test_get_fpenv( unsigned long test_get_fpenv() { - // CHECK: call i64 @llvm.get.fpenv.i64() + // CHECK: {{.*}}call{{.*}} i64 @llvm.get.fpenv.i64() return __builtin_amdgcn_get_fpenv(); } // CHECK-LABEL test_set_fpenv( void test_set_fpenv(unsigned long env) { - // CHECK: call void @llvm.set.fpenv.i64(i64 %[[ENV:.+]]) + // CHECK: {{.*}}call{{.*}} void @llvm.set.fpenv.i64(i64 %[[ENV:.+]]) __builtin_amdgcn_set_fpenv(env); } diff --git a/clang/test/CodeGenOpenCL/builtins-f16.cl b/clang/test/CodeGenOpenCL/builtins-f16.cl index adf7cdde154f51367aa4f9395f30c4beb50f28ec..d7bffdad5c548f372a125ae345143d824f6d285d 100644 --- a/clang/test/CodeGenOpenCL/builtins-f16.cl +++ b/clang/test/CodeGenOpenCL/builtins-f16.cl @@ -66,6 +66,9 @@ void test_half_builtins(half h0, half h1, half h2, int i0) { // CHECK: call half @llvm.sqrt.f16(half %h0) res = __builtin_sqrtf16(h0); + // CHECK: call half @llvm.tan.f16(half %h0) + res = __builtin_tanf16(h0); + // CHECK: call half @llvm.trunc.f16(half %h0) res = __builtin_truncf16(h0); diff --git a/clang/test/CodeGenOpenCL/inline-asm-amdgcn.cl b/clang/test/CodeGenOpenCL/inline-asm-amdgcn.cl index 259c12384f2c8d33a41c08d9b2b6040347f9082b..5ebb0ea0c33c3e1742aed92d8eafe7a8577109a5 100644 --- a/clang/test/CodeGenOpenCL/inline-asm-amdgcn.cl +++ b/clang/test/CodeGenOpenCL/inline-asm-amdgcn.cl @@ -1,11 +1,12 @@ // REQUIRES: amdgpu-registered-target // RUN: %clang_cc1 -emit-llvm -O0 -o - -triple amdgcn %s | FileCheck %s +// RUN: %clang_cc1 -emit-llvm -O0 -o - -triple spirv64-amd-amdhsa %s | FileCheck %s typedef float float32 __attribute__((ext_vector_type(32))); kernel void test_long(int arg0) { long v15_16; - // CHECK: call i64 asm sideeffect "v_lshlrev_b64 v[15:16], 0, $0", "={v[15:16]},v" + // CHECK: call{{.*}} i64 asm sideeffect "v_lshlrev_b64 v[15:16], 0, $0", "={v[15:16]},v" __asm volatile("v_lshlrev_b64 v[15:16], 0, %0" : "={v[15:16]}"(v15_16) : "v"(arg0)); } @@ -14,7 +15,7 @@ kernel void test_agpr() { float reg_a; float reg_b; float32 reg_c; - // CHECK: call <32 x float> asm "v_mfma_f32_32x32x1f32 $0, $1, $2, $3", "=a,v,v,a,~{a0},~{a1},~{a2},~{a3},~{a4},~{a5},~{a6},~{a7},~{a8},~{a9},~{a10},~{a11},~{a12},~{a13},~{a14},~{a15},~{a16},~{a17},~{a18},~{a19},~{a20},~{a21},~{a22},~{a23},~{a24},~{a25},~{a26},~{a27},~{a28},~{a29},~{a30},~{a31}" + // CHECK: call{{.*}} <32 x float> asm "v_mfma_f32_32x32x1f32 $0, $1, $2, $3", "=a,v,v,a,~{a0},~{a1},~{a2},~{a3},~{a4},~{a5},~{a6},~{a7},~{a8},~{a9},~{a10},~{a11},~{a12},~{a13},~{a14},~{a15},~{a16},~{a17},~{a18},~{a19},~{a20},~{a21},~{a22},~{a23},~{a24},~{a25},~{a26},~{a27},~{a28},~{a29},~{a30},~{a31}" __asm ("v_mfma_f32_32x32x1f32 %0, %1, %2, %3" : "=a"(acc_c) : "v"(reg_a), "v"(reg_b), "a"(reg_c) @@ -23,12 +24,12 @@ kernel void test_agpr() { "a16", "a17", "a18", "a19", "a20", "a21", "a22", "a23", "a24", "a25", "a26", "a27", "a28", "a29", "a30", "a31"); - // CHECK: call <32 x float> asm sideeffect "v_mfma_f32_32x32x1f32 a[0:31], $0, $1, a[0:31]", "={a[0:31]},v,v,{a[0:31]}" + // CHECK: call{{.*}} <32 x float> asm sideeffect "v_mfma_f32_32x32x1f32 a[0:31], $0, $1, a[0:31]", "={a[0:31]},v,v,{a[0:31]}" __asm volatile("v_mfma_f32_32x32x1f32 a[0:31], %0, %1, a[0:31]" : "={a[0:31]}"(acc_c) : "v"(reg_a),"v"(reg_b), "{a[0:31]}"(reg_c)); - // CHECK: call float asm "v_accvgpr_read_b32 $0, $1", "={a1},{a1}" + // CHECK: call{{.*}} float asm "v_accvgpr_read_b32 $0, $1", "={a1},{a1}" __asm ("v_accvgpr_read_b32 %0, %1" : "={a1}"(reg_a) : "{a1}"(reg_b)); @@ -37,13 +38,13 @@ kernel void test_agpr() { kernel void test_constraint_DA() { const long x = 0x200000001; int res; - // CHECK: call i32 asm sideeffect "v_mov_b32 $0, $1 & 0xFFFFFFFF", "=v,^DA"(i64 8589934593) + // CHECK: call{{.*}} i32 asm sideeffect "v_mov_b32 $0, $1 & 0xFFFFFFFF", "=v,^DA"(i64 8589934593) __asm volatile("v_mov_b32 %0, %1 & 0xFFFFFFFF" : "=v"(res) : "DA"(x)); } kernel void test_constraint_DB() { const long x = 0x200000001; int res; - // CHECK: call i32 asm sideeffect "v_mov_b32 $0, $1 & 0xFFFFFFFF", "=v,^DB"(i64 8589934593) + // CHECK: call{{.*}} i32 asm sideeffect "v_mov_b32 $0, $1 & 0xFFFFFFFF", "=v,^DB"(i64 8589934593) __asm volatile("v_mov_b32 %0, %1 & 0xFFFFFFFF" : "=v"(res) : "DB"(x)); } diff --git a/clang/test/Driver/aarch64-mac-cpus.c b/clang/test/Driver/aarch64-mac-cpus.c index 51797312689506d5d01d6150dfea6cf69c5f5f0a..488298cfd2d245f723b9c9966043d63853d9f1e5 100644 --- a/clang/test/Driver/aarch64-mac-cpus.c +++ b/clang/test/Driver/aarch64-mac-cpus.c @@ -16,7 +16,7 @@ // RUN: %clang --target=arm64-apple-macos -mcpu=apple-m1 -### -c %s 2>&1 | FileCheck --check-prefix=EXPLICIT-M1 %s // CHECK: "-cc1"{{.*}} "-triple" "arm64{{.*}}" "-target-cpu" "apple-m1" -// CHECK-SAME: "-target-feature" "+v8.5a" +// CHECK-SAME: "-target-feature" "+v8.4a" // EXPLICIT-A11: "-cc1"{{.*}} "-triple" "arm64{{.*}}" "-target-cpu" "apple-a11" // EXPLICIT-A7: "-cc1"{{.*}} "-triple" "arm64{{.*}}" "-target-cpu" "apple-a7" diff --git a/clang/test/Driver/aarch64-oryon-1.c b/clang/test/Driver/aarch64-oryon-1.c new file mode 100644 index 0000000000000000000000000000000000000000..952ba5df74bafe7a29da6735926d7711022d215f --- /dev/null +++ b/clang/test/Driver/aarch64-oryon-1.c @@ -0,0 +1,19 @@ +// RUN: %clang -target aarch64 -mcpu=oryon-1 -### -c %s 2>&1 | FileCheck -check-prefix=Phoenix %s +// RUN: %clang -target aarch64 -mlittle-endian -mcpu=oryon-1 -### -c %s 2>&1 | FileCheck -check-prefix=Phoenix %s +// RUN: %clang -target aarch64_be -mlittle-endian -mcpu=oryon-1 -### -c %s 2>&1 | FileCheck -check-prefix=Phoenix %s +// RUN: %clang -target aarch64 -mtune=oryon-1 -### -c %s 2>&1 | FileCheck -check-prefix=Phoenix-TUNE %s +// RUN: %clang -target aarch64 -mlittle-endian -mtune=oryon-1 -### -c %s 2>&1 | FileCheck -check-prefix=Phoenix-TUNE %s +// RUN: %clang -target aarch64_be -mlittle-endian -mtune=oryon-1 -### -c %s 2>&1 | FileCheck -check-prefix=Phoenix-TUNE %s +// Phoenix: "-cc1"{{.*}} "-triple" "aarch64{{(--)?}}"{{.*}} "-target-cpu" "oryon-1" "-target-feature" "+v8.6a" +// Phoenix-TUNE: "-cc1"{{.*}} "-triple" "aarch64{{(--)?}}"{{.*}} "-target-cpu" "generic" + +// RUN: %clang -target arm64 -mcpu=oryon-1 -### -c %s 2>&1 | FileCheck -check-prefix=ARM64-Phoenix %s +// RUN: %clang -target arm64 -mlittle-endian -mcpu=oryon-1 -### -c %s 2>&1 | FileCheck -check-prefix=ARM64-Phoenix %s +// RUN: %clang -target arm64 -mtune=oryon-1 -### -c %s 2>&1 | FileCheck -check-prefix=ARM64-Phoenix-TUNE %s +// RUN: %clang -target arm64 -mlittle-endian -mtune=oryon-1 -### -c %s 2>&1 | FileCheck -check-prefix=ARM64-Phoenix-TUNE %s +// ARM64-Phoenix: "-cc1"{{.*}} "-triple" "arm64{{.*}}" "-target-cpu" "oryon-1" "-target-feature" "+v8.6a" +// ARM64-Phoenix-TUNE: "-cc1"{{.*}} "-triple" "arm64{{.*}}" "-target-cpu" "generic" + +// RUN: %clang -target aarch64 -mcpu=oryon-1 -mtune=cortex-a53 -### -c %s 2>&1 | FileCheck -check-prefix=MCPU-MTUNE-Phoenix %s +// RUN: %clang -target aarch64 -mtune=cortex-a53 -mcpu=oryon-1 -### -c %s 2>&1 | FileCheck -check-prefix=MCPU-MTUNE-Phoenix %s +// MCPU-MTUNE-Phoenix: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-cpu" "oryon-1" diff --git a/clang/test/Driver/amdgpu-macros.cl b/clang/test/Driver/amdgpu-macros.cl index a878a7decee95e5e4ddd0b4a71a03cb95fa12e62..3e4a570671babed9797f37d7f27693b5af03c0c5 100644 --- a/clang/test/Driver/amdgpu-macros.cl +++ b/clang/test/Driver/amdgpu-macros.cl @@ -127,6 +127,7 @@ // RUN: %clang -E -dM -target amdgcn -mcpu=gfx1103 %s 2>&1 | FileCheck --check-prefixes=ARCH-GCN,FAST_FMAF %s -DWAVEFRONT_SIZE=32 -DCPU=gfx1103 -DFAMILY=GFX11 // RUN: %clang -E -dM -target amdgcn -mcpu=gfx1150 %s 2>&1 | FileCheck --check-prefixes=ARCH-GCN,FAST_FMAF %s -DWAVEFRONT_SIZE=32 -DCPU=gfx1150 -DFAMILY=GFX11 // RUN: %clang -E -dM -target amdgcn -mcpu=gfx1151 %s 2>&1 | FileCheck --check-prefixes=ARCH-GCN,FAST_FMAF %s -DWAVEFRONT_SIZE=32 -DCPU=gfx1151 -DFAMILY=GFX11 +// RUN: %clang -E -dM -target amdgcn -mcpu=gfx1152 %s 2>&1 | FileCheck --check-prefixes=ARCH-GCN,FAST_FMAF %s -DWAVEFRONT_SIZE=32 -DCPU=gfx1152 -DFAMILY=GFX11 // RUN: %clang -E -dM -target amdgcn -mcpu=gfx1200 %s 2>&1 | FileCheck --check-prefixes=ARCH-GCN,FAST_FMAF %s -DWAVEFRONT_SIZE=32 -DCPU=gfx1200 -DFAMILY=GFX12 // RUN: %clang -E -dM -target amdgcn -mcpu=gfx1201 %s 2>&1 | FileCheck --check-prefixes=ARCH-GCN,FAST_FMAF %s -DWAVEFRONT_SIZE=32 -DCPU=gfx1201 -DFAMILY=GFX12 diff --git a/clang/test/Driver/amdgpu-mcpu.cl b/clang/test/Driver/amdgpu-mcpu.cl index 5b6a22016f043b3d0f3e8a4033175f039f28507a..4b0ef92b682a501d95eb92cfe5a166ca31afd6b1 100644 --- a/clang/test/Driver/amdgpu-mcpu.cl +++ b/clang/test/Driver/amdgpu-mcpu.cl @@ -112,6 +112,7 @@ // RUN: %clang -### -target amdgcn -mcpu=gfx1103 %s 2>&1 | FileCheck --check-prefix=GFX1103 %s // RUN: %clang -### -target amdgcn -mcpu=gfx1150 %s 2>&1 | FileCheck --check-prefix=GFX1150 %s // RUN: %clang -### -target amdgcn -mcpu=gfx1151 %s 2>&1 | FileCheck --check-prefix=GFX1151 %s +// RUN: %clang -### -target amdgcn -mcpu=gfx1152 %s 2>&1 | FileCheck --check-prefix=GFX1152 %s // RUN: %clang -### -target amdgcn -mcpu=gfx1200 %s 2>&1 | FileCheck --check-prefix=GFX1200 %s // RUN: %clang -### -target amdgcn -mcpu=gfx1201 %s 2>&1 | FileCheck --check-prefix=GFX1201 %s @@ -164,6 +165,7 @@ // GFX1103: "-target-cpu" "gfx1103" // GFX1150: "-target-cpu" "gfx1150" // GFX1151: "-target-cpu" "gfx1151" +// GFX1152: "-target-cpu" "gfx1152" // GFX1200: "-target-cpu" "gfx1200" // GFX1201: "-target-cpu" "gfx1201" diff --git a/clang/test/Driver/amdgpu-openmp-toolchain.c b/clang/test/Driver/amdgpu-openmp-toolchain.c index ef58c2c4e3f3ae24fb8105e5d4135432fd3dfcd0..49af04acc46397b48c6646c9241c6e185d26f18e 100644 --- a/clang/test/Driver/amdgpu-openmp-toolchain.c +++ b/clang/test/Driver/amdgpu-openmp-toolchain.c @@ -7,7 +7,7 @@ // verify the tools invocations // CHECK: "-cc1" "-triple" "x86_64-unknown-linux-gnu"{{.*}}"-emit-llvm-bc"{{.*}}"-x" "c" -// CHECK: "-cc1" "-triple" "amdgcn-amd-amdhsa" "-aux-triple" "x86_64-unknown-linux-gnu"{{.*}}"-target-cpu" "gfx906"{{.*}}"-fcuda-is-device"{{.*}} +// CHECK: "-cc1" "-triple" "amdgcn-amd-amdhsa" "-aux-triple" "x86_64-unknown-linux-gnu"{{.*}}"-fcuda-is-device"{{.*}}"-target-cpu" "gfx906" // CHECK: "-cc1" "-triple" "x86_64-unknown-linux-gnu"{{.*}}"-emit-obj" // CHECK: clang-linker-wrapper{{.*}} "-o" "a.out" @@ -63,6 +63,7 @@ // RUN: %clang -### -target x86_64-pc-linux-gnu -fopenmp --offload-arch=gfx90a:sramecc-:xnack+ \ // RUN: -nogpulib %s 2>&1 | FileCheck %s --check-prefix=CHECK-TARGET-ID +// CHECK-TARGET-ID: "-cc1" "-triple" "amdgcn-amd-amdhsa" {{.*}} "-target-cpu" "gfx90a" "-target-feature" "-sramecc" "-target-feature" "+xnack" // CHECK-TARGET-ID: clang-offload-packager{{.*}}arch=gfx90a:sramecc-:xnack+,kind=openmp,feature=-sramecc,feature=+xnack // RUN: not %clang -### -target x86_64-pc-linux-gnu -fopenmp --offload-arch=gfx90a,gfx90a:xnack+ \ diff --git a/clang/test/Driver/apple-os-triples.c b/clang/test/Driver/apple-os-triples.c new file mode 100644 index 0000000000000000000000000000000000000000..7664d3bc19fca269211294fd04199bb8136a7ee4 --- /dev/null +++ b/clang/test/Driver/apple-os-triples.c @@ -0,0 +1,31 @@ +// Test triple manipulations. + +// RUN: %clang -### -c %s \ +// RUN: --target=i386-apple-darwin10 -mappletvsimulator-version-min=9.0 -arch x86_64 2>&1 | \ +// RUN: FileCheck %s -DARCH=x86_64 -DOS=tvos9.0.0-simulator +// RUN: %clang -### -c %s \ +// RUN: --target=armv7s-apple-darwin10 -mappletvos-version-min=9.0 -arch arm64 2>&1 | \ +// RUN: FileCheck %s -DARCH=arm64 -DOS=tvos9.0.0 +// RUN: env TVOS_DEPLOYMENT_TARGET=9.0 %clang -### -c %s \ +// RUN: -isysroot SDKs/MacOSX10.9.sdk -target i386-apple-darwin10 -arch x86_64 2>&1 | \ +// RUN: FileCheck %s -DARCH=x86_64 -DOS=tvos9.0.0 + +// RUN: %clang -### -c %s \ +// RUN: --target=x86_64-apple-driverkit19.0 2>&1 | \ +// RUN: FileCheck %s -DARCH=x86_64 -DOS=driverkit19.0.0 + +// RUN: %clang -### -c %s \ +// RUN: --target=i386-apple-darwin10 -miphonesimulator-version-min=7.0 -arch i386 2>&1 | \ +// RUN: FileCheck %s -DARCH=i386 -DOS=ios7.0.0-simulator +// RUN: %clang -### -c %s \ +// RUN: --target=armv7s-apple-darwin10 -miphoneos-version-min=7.0 -arch armv7s 2>&1 | \ +// RUN: FileCheck %s -DARCH=thumbv7s -DOS=ios7.0.0 + +// RUN: %clang -### -c %s \ +// RUN: --target=i386-apple-darwin10 -mwatchsimulator-version-min=2.0 -arch i386 2>&1 | \ +// RUN: FileCheck %s -DARCH=i386 -DOS=watchos2.0.0-simulator +// RUN: %clang -### -c %s \ +// RUN: --target=armv7s-apple-darwin10 -mwatchos-version-min=2.0 -arch armv7k 2>&1 | \ +// RUN: FileCheck %s -DARCH=thumbv7k -DOS=watchos2.0.0 + +// CHECK: "-cc1" "-triple" "[[ARCH]]-apple-[[OS]]" diff --git a/clang/test/Driver/appletvos-version-min.c b/clang/test/Driver/appletvos-version-min.c deleted file mode 100644 index 7cbb2001a3ec215a5c30d56a5876f74cd15bc923..0000000000000000000000000000000000000000 --- a/clang/test/Driver/appletvos-version-min.c +++ /dev/null @@ -1,8 +0,0 @@ -// REQUIRES: x86-registered-target -// REQUIRES: aarch64-registered-target -// RUN: %clang -target i386-apple-darwin10 -mappletvsimulator-version-min=9.0 -arch x86_64 -S -o - %s | FileCheck %s -// RUN: %clang -target armv7s-apple-darwin10 -mappletvos-version-min=9.0 -arch arm64 -S -o - %s | FileCheck %s -// RUN: env TVOS_DEPLOYMENT_TARGET=9.0 %clang -isysroot SDKs/MacOSX10.9.sdk -target i386-apple-darwin10 -arch x86_64 -S -o - %s | FileCheck %s - -int main() { return 0; } -// CHECK: .tvos_version_min 9, 0 diff --git a/clang/test/Driver/baremetal-ld.c b/clang/test/Driver/baremetal-ld.c new file mode 100644 index 0000000000000000000000000000000000000000..ec61b42b6f4875e6f75ca8c5e9707bb8e4582efc --- /dev/null +++ b/clang/test/Driver/baremetal-ld.c @@ -0,0 +1,6 @@ +// RUN: %clang -### --target=armv7-unknown-none-eabi -mcpu=cortex-m4 --sysroot= -fuse-ld=ld %s 2>&1 | FileCheck --check-prefix=NOLTO %s +// NOLTO: {{".*ld.*"}} {{.*}} +// NOLTO-NOT: "-plugin-opt=mcpu" + +// RUN: %clang -### --target=armv7-unknown-none-eabi -mcpu=cortex-m4 --sysroot= -fuse-ld=ld -flto -O3 %s 2>&1 | FileCheck --check-prefix=LTO %s +// LTO: {{".*ld.*"}} {{.*}} "-plugin-opt=mcpu=cortex-m4" "-plugin-opt=O3" diff --git a/clang/test/Driver/driverkit-version-min.c b/clang/test/Driver/driverkit-version-min.c deleted file mode 100644 index 9966152f11ce822013917fdeac7b63c5cccf7e30..0000000000000000000000000000000000000000 --- a/clang/test/Driver/driverkit-version-min.c +++ /dev/null @@ -1,5 +0,0 @@ -// REQUIRES: x86-registered-target -// RUN: %clang -target x86_64-apple-driverkit19.0 -S -o - %s | FileCheck %s - -int main() { return 0; } -// CHECK: .build_version driverkit, 19, 0 diff --git a/clang/test/Driver/fsanitize.c b/clang/test/Driver/fsanitize.c index 571f79a6e7f70dd7f19bea02f7c097f7af9cd2df..ba64b3dcb11aa539bb4a18680d999870acbccc02 100644 --- a/clang/test/Driver/fsanitize.c +++ b/clang/test/Driver/fsanitize.c @@ -459,6 +459,21 @@ // CHECK-TSAN-MSAN-MSAN-DARWIN: unsupported option '-fsanitize=memory' for target 'x86_64-apple-darwin10' // CHECK-TSAN-MSAN-MSAN-DARWIN-NOT: unsupported option +// RUN: %clang --target=x86_64-linux-gnu -fsanitize=numerical %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-NSAN-X86-64-LINUX +// CHECK-NSAN-X86-64-LINUX: "-fsanitize=numerical" + +// RUN: %clang --target=aarch64-unknown-linux-gnu -fsanitize=numerical %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-NSAN-AARCH64-LINUX +// CHECK-NSAN-AARCH64-LINUX: "-fsanitize=numerical" + +// RUN: not %clang --target=mips-unknown-linux -fsanitize=numerical %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-NSAN-MIPS-LINUX +// CHECK-NSAN-MIPS-LINUX: error: unsupported option '-fsanitize=numerical' for target 'mips-unknown-linux' + +// RUN: %clang --target=x86_64-apple-macos -fsanitize=numerical %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-NSAN-X86-64-MACOS +// CHECK-NSAN-X86-64-MACOS: "-fsanitize=numerical" + +// RUN: %clang --target=arm64-apple-macos -fsanitize=numerical %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-NSAN-ARM64-MACOS +// CHECK-NSAN-ARM64-MACOS: "-fsanitize=numerical" + // RUN: %clang --target=x86_64-apple-darwin -fsanitize=thread %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-TSAN-X86-64-DARWIN // CHECK-TSAN-X86-64-DARWIN-NOT: unsupported option // RUN: %clang --target=x86_64-apple-macos -fsanitize=thread %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-TSAN-X86-64-MACOS diff --git a/clang/test/Driver/gcc-param.c b/clang/test/Driver/gcc-param.c index 4672e1156ce7bb76682a54433c852525e3967810..7ae084784bf91d5867907b9ea7af05c70ebe3cd4 100644 --- a/clang/test/Driver/gcc-param.c +++ b/clang/test/Driver/gcc-param.c @@ -1,2 +1,2 @@ // RUN: touch %t.o -// RUN: %clang -Werror --param ssp-buffer-size=1 %t.o -### +// RUN: %clang -Werror -Wno-msvc-not-found --param ssp-buffer-size=1 %t.o -### diff --git a/clang/test/Driver/ios-version-min.c b/clang/test/Driver/ios-version-min.c deleted file mode 100644 index aa536cf7827b36a9bb70976db366e19aa2e18a8b..0000000000000000000000000000000000000000 --- a/clang/test/Driver/ios-version-min.c +++ /dev/null @@ -1,7 +0,0 @@ -// REQUIRES: x86-registered-target -// REQUIRES: arm-registered-target -// RUN: %clang -target i386-apple-darwin10 -miphonesimulator-version-min=7.0 -arch i386 -S -o - %s | FileCheck %s -// RUN: %clang -target armv7s-apple-darwin10 -miphoneos-version-min=7.0 -arch armv7s -S -o - %s | FileCheck %s - -int main() { return 0; } -// CHECK: .ios_version_min 7, 0 diff --git a/clang/test/Driver/loongarch-default-features.c b/clang/test/Driver/loongarch-features.c similarity index 100% rename from clang/test/Driver/loongarch-default-features.c rename to clang/test/Driver/loongarch-features.c diff --git a/clang/test/Driver/riscv-arch.c b/clang/test/Driver/riscv-arch.c index ddf617bbb623723a489215dad11f86d08495df3e..ffd92e1f398c4575e308b7882bc05edab0700ae7 100644 --- a/clang/test/Driver/riscv-arch.c +++ b/clang/test/Driver/riscv-arch.c @@ -231,11 +231,6 @@ // RV32-STD: error: invalid arch name 'rv32imqc', // RV32-STD: unsupported standard user-level extension 'q' -// RUN: not %clang --target=riscv32-unknown-elf -march=rv32ib -### %s \ -// RUN: -fsyntax-only 2>&1 | FileCheck -check-prefix=RV32-B %s -// RV32-B: error: invalid arch name 'rv32ib', -// RV32-B: unsupported standard user-level extension 'b' - // RUN: not %clang --target=riscv32-unknown-elf -march=rv32xabc -### %s \ // RUN: -fsyntax-only 2>&1 | FileCheck -check-prefix=RV32X %s // RV32X: error: invalid arch name 'rv32xabc', diff --git a/clang/test/Driver/watchos-version-min.c b/clang/test/Driver/watchos-version-min.c deleted file mode 100644 index 8f12285d4e4737d8fb5ddd6df0071d3e2743a9e7..0000000000000000000000000000000000000000 --- a/clang/test/Driver/watchos-version-min.c +++ /dev/null @@ -1,7 +0,0 @@ -// REQUIRES: x86-registered-target -// REQUIRES: arm-registered-target -// RUN: %clang -target i386-apple-darwin10 -mwatchsimulator-version-min=2.0 -arch i386 -S -o - %s | FileCheck %s -// RUN: %clang -target armv7s-apple-darwin10 -mwatchos-version-min=2.0 -arch armv7k -S -o - %s | FileCheck %s - -int main() { return 0; } -// CHECK: .watchos_version_min 2, 0 diff --git a/clang/test/Index/comment-to-html-xml-conversion.cpp b/clang/test/Index/comment-to-html-xml-conversion.cpp index d9eefb909653c7f14891d95ee7a0b95dd0143242..e0a7cff5a9a3dbae624de8eafbb20b729e3d3aab 100644 --- a/clang/test/Index/comment-to-html-xml-conversion.cpp +++ b/clang/test/Index/comment-to-html-xml-conversion.cpp @@ -1046,82 +1046,101 @@ void comment_to_xml_conversion_todo_4(); /// Aaa. /// \throws Bbb. void comment_to_xml_conversion_exceptions_1(); -// CHECK: comment-to-html-xml-conversion.cpp:[[@LINE-1]]:6: FunctionDecl=comment_to_xml_conversion_exceptions_1:{{.*}} FullCommentAsXML=[comment_to_xml_conversion_exceptions_1c:@F@comment_to_xml_conversion_exceptions_1#void comment_to_xml_conversion_exceptions_1() Aaa. Bbb.] +// CHECK: comment-to-html-xml-conversion.cpp:[[@LINE-1]]:6: FunctionDecl=comment_to_xml_conversion_exceptions_1:{{.*}} FullCommentAsXML=[comment_to_xml_conversion_exceptions_1c:@F@comment_to_xml_conversion_exceptions_1#void comment_to_xml_conversion_exceptions_1() Aaa. Bbb. ] // CHECK-NEXT: CommentAST=[ // CHECK-NEXT: (CXComment_FullComment // CHECK-NEXT: (CXComment_Paragraph // CHECK-NEXT: (CXComment_Text Text=[ Aaa.] HasTrailingNewline) // CHECK-NEXT: (CXComment_Text Text=[ ] IsWhitespace)) -// CHECK-NEXT: (CXComment_BlockCommand CommandName=[throws] -// CHECK-NEXT: (CXComment_Paragraph -// CHECK-NEXT: (CXComment_Text Text=[ Bbb.]))))] +// CHECK-NEXT: (CXComment_BlockCommand CommandName=[throws] Arg[0]=Bbb. +// CHECK-NEXT: (CXComment_Paragraph IsWhitespace)))] /// Aaa. /// \throw Bbb. void comment_to_xml_conversion_exceptions_2(); -// CHECK: comment-to-html-xml-conversion.cpp:[[@LINE-1]]:6: FunctionDecl=comment_to_xml_conversion_exceptions_2:{{.*}} FullCommentAsXML=[comment_to_xml_conversion_exceptions_2c:@F@comment_to_xml_conversion_exceptions_2#void comment_to_xml_conversion_exceptions_2() Aaa. Bbb.] +// CHECK: comment-to-html-xml-conversion.cpp:[[@LINE-1]]:6: FunctionDecl=comment_to_xml_conversion_exceptions_2:{{.*}} FullCommentAsXML=[comment_to_xml_conversion_exceptions_2c:@F@comment_to_xml_conversion_exceptions_2#void comment_to_xml_conversion_exceptions_2() Aaa. Bbb. ] // CHECK-NEXT: CommentAST=[ // CHECK-NEXT: (CXComment_FullComment // CHECK-NEXT: (CXComment_Paragraph // CHECK-NEXT: (CXComment_Text Text=[ Aaa.] HasTrailingNewline) // CHECK-NEXT: (CXComment_Text Text=[ ] IsWhitespace)) -// CHECK-NEXT: (CXComment_BlockCommand CommandName=[throw] -// CHECK-NEXT: (CXComment_Paragraph -// CHECK-NEXT: (CXComment_Text Text=[ Bbb.]))))] +// CHECK-NEXT: (CXComment_BlockCommand CommandName=[throw] Arg[0]=Bbb. +// CHECK-NEXT: (CXComment_Paragraph IsWhitespace)))] /// Aaa. /// \exception Bbb. void comment_to_xml_conversion_exceptions_3(); -// CHECK: comment-to-html-xml-conversion.cpp:[[@LINE-1]]:6: FunctionDecl=comment_to_xml_conversion_exceptions_3:{{.*}} FullCommentAsXML=[comment_to_xml_conversion_exceptions_3c:@F@comment_to_xml_conversion_exceptions_3#void comment_to_xml_conversion_exceptions_3() Aaa. Bbb.] +// CHECK: comment-to-html-xml-conversion.cpp:[[@LINE-1]]:6: FunctionDecl=comment_to_xml_conversion_exceptions_3:{{.*}} FullCommentAsXML=[comment_to_xml_conversion_exceptions_3c:@F@comment_to_xml_conversion_exceptions_3#void comment_to_xml_conversion_exceptions_3() Aaa. Bbb. ] // CHECK-NEXT: CommentAST=[ // CHECK-NEXT: (CXComment_FullComment // CHECK-NEXT: (CXComment_Paragraph // CHECK-NEXT: (CXComment_Text Text=[ Aaa.] HasTrailingNewline) // CHECK-NEXT: (CXComment_Text Text=[ ] IsWhitespace)) -// CHECK-NEXT: (CXComment_BlockCommand CommandName=[exception] -// CHECK-NEXT: (CXComment_Paragraph -// CHECK-NEXT: (CXComment_Text Text=[ Bbb.]))))] +// CHECK-NEXT: (CXComment_BlockCommand CommandName=[exception] Arg[0]=Bbb. +// CHECK-NEXT: (CXComment_Paragraph IsWhitespace)))] /// Aaa. /// \throws Bbb. /// \throws Ccc. /// \throws Ddd. void comment_to_xml_conversion_exceptions_4(); -// CHECK: comment-to-html-xml-conversion.cpp:[[@LINE-1]]:6: FunctionDecl=comment_to_xml_conversion_exceptions_4:{{.*}} FullCommentAsXML=[comment_to_xml_conversion_exceptions_4c:@F@comment_to_xml_conversion_exceptions_4#void comment_to_xml_conversion_exceptions_4() Aaa. Bbb. Ccc. Ddd.] +// CHECK: comment-to-html-xml-conversion.cpp:[[@LINE-1]]:6: FunctionDecl=comment_to_xml_conversion_exceptions_4:{{.*}} FullCommentAsXML=[comment_to_xml_conversion_exceptions_4c:@F@comment_to_xml_conversion_exceptions_4#void comment_to_xml_conversion_exceptions_4() Aaa. Bbb. Ccc. Ddd. ] // CHECK-NEXT: CommentAST=[ // CHECK-NEXT: (CXComment_FullComment // CHECK-NEXT: (CXComment_Paragraph // CHECK-NEXT: (CXComment_Text Text=[ Aaa.] HasTrailingNewline) // CHECK-NEXT: (CXComment_Text Text=[ ] IsWhitespace)) -// CHECK-NEXT: (CXComment_BlockCommand CommandName=[throws] -// CHECK-NEXT: (CXComment_Paragraph -// CHECK-NEXT: (CXComment_Text Text=[ Bbb.] HasTrailingNewline) -// CHECK-NEXT: (CXComment_Text Text=[ ] IsWhitespace))) -// CHECK-NEXT: (CXComment_BlockCommand CommandName=[throws] -// CHECK-NEXT: (CXComment_Paragraph -// CHECK-NEXT: (CXComment_Text Text=[ Ccc.] HasTrailingNewline) -// CHECK-NEXT: (CXComment_Text Text=[ ] IsWhitespace))) -// CHECK-NEXT: (CXComment_BlockCommand CommandName=[throws] -// CHECK-NEXT: (CXComment_Paragraph -// CHECK-NEXT: (CXComment_Text Text=[ Ddd.]))))] +// CHECK-NEXT: (CXComment_BlockCommand CommandName=[throws] Arg[0]=Bbb. +// CHECK-NEXT: (CXComment_Paragraph IsWhitespace)) +// CHECK-NEXT: (CXComment_BlockCommand CommandName=[throws] Arg[0]=Ccc. +// CHECK-NEXT: (CXComment_Paragraph IsWhitespace)) +// CHECK-NEXT: (CXComment_BlockCommand CommandName=[throws] Arg[0]=Ddd. +// CHECK-NEXT: (CXComment_Paragraph IsWhitespace)))] /// Aaa. /// \throws Bbb. /// \throw Ccc. void comment_to_xml_conversion_exceptions_5(); -// CHECK: comment-to-html-xml-conversion.cpp:[[@LINE-1]]:6: FunctionDecl=comment_to_xml_conversion_exceptions_5:{{.*}} FullCommentAsXML=[comment_to_xml_conversion_exceptions_5c:@F@comment_to_xml_conversion_exceptions_5#void comment_to_xml_conversion_exceptions_5() Aaa. Bbb. Ccc.] +// CHECK: comment-to-html-xml-conversion.cpp:[[@LINE-1]]:6: FunctionDecl=comment_to_xml_conversion_exceptions_5:{{.*}} FullCommentAsXML=[comment_to_xml_conversion_exceptions_5c:@F@comment_to_xml_conversion_exceptions_5#void comment_to_xml_conversion_exceptions_5() Aaa. Bbb. Ccc. ] +// CHECK-NEXT: CommentAST=[ +// CHECK-NEXT: (CXComment_FullComment +// CHECK-NEXT: (CXComment_Paragraph +// CHECK-NEXT: (CXComment_Text Text=[ Aaa.] HasTrailingNewline) +// CHECK-NEXT: (CXComment_Text Text=[ ] IsWhitespace)) +// CHECK-NEXT: (CXComment_BlockCommand CommandName=[throws] Arg[0]=Bbb. +// CHECK-NEXT: (CXComment_Paragraph IsWhitespace)) +// CHECK-NEXT: (CXComment_BlockCommand CommandName=[throw] Arg[0]=Ccc. +// CHECK-NEXT: (CXComment_Paragraph IsWhitespace)))] + +/// Aaa. +/// \throws Bbb subsequent arg text +void comment_to_xml_conversion_exceptions_6(); +// CHECK: comment-to-html-xml-conversion.cpp:[[@LINE-1]]:6: FunctionDecl=comment_to_xml_conversion_exceptions_6:{{.*}} FullCommentAsXML=[comment_to_xml_conversion_exceptions_6c:@F@comment_to_xml_conversion_exceptions_6#void comment_to_xml_conversion_exceptions_6() Aaa. Bbb subsequent arg text] // CHECK-NEXT: CommentAST=[ // CHECK-NEXT: (CXComment_FullComment // CHECK-NEXT: (CXComment_Paragraph // CHECK-NEXT: (CXComment_Text Text=[ Aaa.] HasTrailingNewline) // CHECK-NEXT: (CXComment_Text Text=[ ] IsWhitespace)) -// CHECK-NEXT: (CXComment_BlockCommand CommandName=[throws] +// CHECK-NEXT: (CXComment_BlockCommand CommandName=[throws] Arg[0]=Bbb // CHECK-NEXT: (CXComment_Paragraph -// CHECK-NEXT: (CXComment_Text Text=[ Bbb.] HasTrailingNewline) +// CHECK-NEXT: (CXComment_Text Text=[subsequent arg text]))))] + +/// Aaa. +/// \throws Bbb subsequent arg text +/// \throw Ccc subsequent arg text +void comment_to_xml_conversion_exceptions_7(); +// CHECK: comment-to-html-xml-conversion.cpp:[[@LINE-1]]:6: FunctionDecl=comment_to_xml_conversion_exceptions_7:{{.*}} FullCommentAsXML=[comment_to_xml_conversion_exceptions_7c:@F@comment_to_xml_conversion_exceptions_7#void comment_to_xml_conversion_exceptions_7() Aaa. Bbb subsequent arg text Ccc subsequent arg text] +// CHECK-NEXT: CommentAST=[ +// CHECK-NEXT: (CXComment_FullComment +// CHECK-NEXT: (CXComment_Paragraph +// CHECK-NEXT: (CXComment_Text Text=[ Aaa.] HasTrailingNewline) +// CHECK-NEXT: (CXComment_Text Text=[ ] IsWhitespace)) +// CHECK-NEXT: (CXComment_BlockCommand CommandName=[throws] Arg[0]=Bbb +// CHECK-NEXT: (CXComment_Paragraph +// CHECK-NEXT: (CXComment_Text Text=[subsequent arg text] HasTrailingNewline) // CHECK-NEXT: (CXComment_Text Text=[ ] IsWhitespace))) -// CHECK-NEXT: (CXComment_BlockCommand CommandName=[throw] +// CHECK-NEXT: (CXComment_BlockCommand CommandName=[throw] Arg[0]=Ccc // CHECK-NEXT: (CXComment_Paragraph -// CHECK-NEXT: (CXComment_Text Text=[ Ccc.]))))] +// CHECK-NEXT: (CXComment_Text Text=[subsequent arg text]))))] #endif - diff --git a/clang/test/Interpreter/pretty-print.c b/clang/test/Interpreter/pretty-print.c new file mode 100644 index 0000000000000000000000000000000000000000..d21749a649e1c0631a9e91492df66c72ce373ed1 --- /dev/null +++ b/clang/test/Interpreter/pretty-print.c @@ -0,0 +1,11 @@ +// REQUIRES: host-supports-jit +// UNSUPPORTED: system-aix +// RUN: cat %s | clang-repl -Xcc -xc | FileCheck %s +// RUN: cat %s | clang-repl -Xcc -std=c++11 | FileCheck %s + +// Fails with `Symbols not found: [ __clang_Interpreter_SetValueNoAlloc ]`. +// UNSUPPORTED: hwasan + +const char* c_str = "Hello, world!"; c_str + +// CHECK: Not implement yet. diff --git a/clang/test/Lexer/has_feature_numerical_stability_sanitizer.cpp b/clang/test/Lexer/has_feature_numerical_stability_sanitizer.cpp new file mode 100644 index 0000000000000000000000000000000000000000..78884977322b8e5c8434ba88ad1512a62aee3a5c --- /dev/null +++ b/clang/test/Lexer/has_feature_numerical_stability_sanitizer.cpp @@ -0,0 +1,11 @@ +// RUN: %clang_cc1 -E -fsanitize=numerical %s -o - | FileCheck --check-prefix=CHECK-NSAN %s +// RUN: %clang_cc1 -E %s -o - | FileCheck --check-prefix=CHECK-NO-NSAN %s + +#if __has_feature(numerical_stability_sanitizer) +int NumericalStabilitySanitizerEnabled(); +#else +int NumericalStabilitySanitizerDisabled(); +#endif + +// CHECK-NSAN: NumericalStabilitySanitizerEnabled +// CHECK-NO-NSAN: NumericalStabilitySanitizerDisabled diff --git a/clang/test/Misc/target-invalid-cpu-note.c b/clang/test/Misc/target-invalid-cpu-note.c index 6558fd753d1d125fab38152c0bde153ab6823531..2439025609b9f9ca6b4975b0c579bab667064e0b 100644 --- a/clang/test/Misc/target-invalid-cpu-note.c +++ b/clang/test/Misc/target-invalid-cpu-note.c @@ -1,15 +1,15 @@ // Use CHECK-NEXT instead of multiple CHECK-SAME to ensure we will fail if there is anything extra in the output. // RUN: not %clang_cc1 -triple armv5--- -target-cpu not-a-cpu -fsyntax-only %s 2>&1 | FileCheck %s --check-prefix ARM // ARM: error: unknown target CPU 'not-a-cpu' -// ARM-NEXT: note: valid target CPU values are: arm8, arm810, strongarm, strongarm110, strongarm1100, strongarm1110, arm7tdmi, arm7tdmi-s, arm710t, arm720t, arm9, arm9tdmi, arm920, arm920t, arm922t, arm940t, ep9312, arm10tdmi, arm1020t, arm9e, arm946e-s, arm966e-s, arm968e-s, arm10e, arm1020e, arm1022e, arm926ej-s, arm1136j-s, arm1136jf-s, mpcore, mpcorenovfp, arm1176jz-s, arm1176jzf-s, arm1156t2-s, arm1156t2f-s, cortex-m0, cortex-m0plus, cortex-m1, sc000, cortex-a5, cortex-a7, cortex-a8, cortex-a9, cortex-a12, cortex-a15, cortex-a17, krait, cortex-r4, cortex-r4f, cortex-r5, cortex-r7, cortex-r8, cortex-r52, sc300, cortex-m3, cortex-m4, cortex-m7, cortex-m23, cortex-m33, cortex-m35p, cortex-m55, cortex-m85, cortex-m52, cortex-a32, cortex-a35, cortex-a53, cortex-a55, cortex-a57, cortex-a72, cortex-a73, cortex-a75, cortex-a76, cortex-a76ae, cortex-a77, cortex-a78, cortex-a78ae, cortex-a78c, cortex-a710, cortex-x1, cortex-x1c, neoverse-n1, neoverse-n2, neoverse-v1, cyclone, exynos-m3, exynos-m4, exynos-m5, kryo, iwmmxt, xscale, swift{{$}} +// ARM-NEXT: note: valid target CPU values are: arm8, arm810, strongarm, strongarm110, strongarm1100, strongarm1110, arm7tdmi, arm7tdmi-s, arm710t, arm720t, arm9, arm9tdmi, arm920, arm920t, arm922t, arm940t, ep9312, arm10tdmi, arm1020t, arm9e, arm946e-s, arm966e-s, arm968e-s, arm10e, arm1020e, arm1022e, arm926ej-s, arm1136j-s, arm1136jf-s, mpcore, mpcorenovfp, arm1176jz-s, arm1176jzf-s, arm1156t2-s, arm1156t2f-s, cortex-m0, cortex-m0plus, cortex-m1, sc000, cortex-a5, cortex-a7, cortex-a8, cortex-a9, cortex-a12, cortex-a15, cortex-a17, krait, cortex-r4, cortex-r4f, cortex-r5, cortex-r7, cortex-r8, cortex-r52, cortex-r52plus, sc300, cortex-m3, cortex-m4, cortex-m7, cortex-m23, cortex-m33, cortex-m35p, cortex-m55, cortex-m85, cortex-m52, cortex-a32, cortex-a35, cortex-a53, cortex-a55, cortex-a57, cortex-a72, cortex-a73, cortex-a75, cortex-a76, cortex-a76ae, cortex-a77, cortex-a78, cortex-a78ae, cortex-a78c, cortex-a710, cortex-x1, cortex-x1c, neoverse-n1, neoverse-n2, neoverse-v1, cyclone, exynos-m3, exynos-m4, exynos-m5, kryo, iwmmxt, xscale, swift{{$}} // RUN: not %clang_cc1 -triple arm64--- -target-cpu not-a-cpu -fsyntax-only %s 2>&1 | FileCheck %s --check-prefix AARCH64 // AARCH64: error: unknown target CPU 'not-a-cpu' -// AARCH64-NEXT: note: valid target CPU values are: cortex-a34, cortex-a35, cortex-a53, cortex-a55, cortex-a510, cortex-a520, cortex-a520ae, cortex-a57, cortex-a65, cortex-a65ae, cortex-a72, cortex-a73, cortex-a75, cortex-a76, cortex-a76ae, cortex-a77, cortex-a78, cortex-a78ae, cortex-a78c, cortex-a710, cortex-a715, cortex-a720, cortex-a720ae, cortex-r82, cortex-r82ae, cortex-x1, cortex-x1c, cortex-x2, cortex-x3, cortex-x4, neoverse-e1, neoverse-n1, neoverse-n2, neoverse-n3, neoverse-512tvb, neoverse-v1, neoverse-v2, neoverse-v3, neoverse-v3ae, cyclone, apple-a7, apple-a8, apple-a9, apple-a10, apple-a11, apple-a12, apple-a13, apple-a14, apple-a15, apple-a16, apple-a17, apple-m1, apple-m2, apple-m3, apple-s4, apple-s5, exynos-m3, exynos-m4, exynos-m5, falkor, saphira, kryo, thunderx2t99, thunderx3t110, thunderx, thunderxt88, thunderxt81, thunderxt83, tsv110, a64fx, carmel, ampere1, ampere1a, ampere1b, cobalt-100, grace{{$}} +// AARCH64-NEXT: note: valid target CPU values are: cortex-a34, cortex-a35, cortex-a53, cortex-a55, cortex-a510, cortex-a520, cortex-a520ae, cortex-a57, cortex-a65, cortex-a65ae, cortex-a72, cortex-a73, cortex-a75, cortex-a76, cortex-a76ae, cortex-a77, cortex-a78, cortex-a78ae, cortex-a78c, cortex-a710, cortex-a715, cortex-a720, cortex-a720ae, cortex-r82, cortex-r82ae, cortex-x1, cortex-x1c, cortex-x2, cortex-x3, cortex-x4, neoverse-e1, neoverse-n1, neoverse-n2, neoverse-n3, neoverse-512tvb, neoverse-v1, neoverse-v2, neoverse-v3, neoverse-v3ae, cyclone, apple-a7, apple-a8, apple-a9, apple-a10, apple-a11, apple-a12, apple-a13, apple-a14, apple-a15, apple-a16, apple-a17, apple-m1, apple-m2, apple-m3, apple-s4, apple-s5, exynos-m3, exynos-m4, exynos-m5, falkor, saphira, kryo, thunderx2t99, thunderx3t110, thunderx, thunderxt88, thunderxt81, thunderxt83, tsv110, a64fx, carmel, ampere1, ampere1a, ampere1b, oryon-1, cobalt-100, grace{{$}} // RUN: not %clang_cc1 -triple arm64--- -tune-cpu not-a-cpu -fsyntax-only %s 2>&1 | FileCheck %s --check-prefix TUNE_AARCH64 // TUNE_AARCH64: error: unknown target CPU 'not-a-cpu' -// TUNE_AARCH64-NEXT: note: valid target CPU values are: cortex-a34, cortex-a35, cortex-a53, cortex-a55, cortex-a510, cortex-a520, cortex-a520ae, cortex-a57, cortex-a65, cortex-a65ae, cortex-a72, cortex-a73, cortex-a75, cortex-a76, cortex-a76ae, cortex-a77, cortex-a78, cortex-a78ae, cortex-a78c, cortex-a710, cortex-a715, cortex-a720, cortex-a720ae, cortex-r82, cortex-r82ae, cortex-x1, cortex-x1c, cortex-x2, cortex-x3, cortex-x4, neoverse-e1, neoverse-n1, neoverse-n2, neoverse-n3, neoverse-512tvb, neoverse-v1, neoverse-v2, neoverse-v3, neoverse-v3ae, cyclone, apple-a7, apple-a8, apple-a9, apple-a10, apple-a11, apple-a12, apple-a13, apple-a14, apple-a15, apple-a16, apple-a17, apple-m1, apple-m2, apple-m3, apple-s4, apple-s5, exynos-m3, exynos-m4, exynos-m5, falkor, saphira, kryo, thunderx2t99, thunderx3t110, thunderx, thunderxt88, thunderxt81, thunderxt83, tsv110, a64fx, carmel, ampere1, ampere1a, ampere1b, cobalt-100, grace{{$}} +// TUNE_AARCH64-NEXT: note: valid target CPU values are: cortex-a34, cortex-a35, cortex-a53, cortex-a55, cortex-a510, cortex-a520, cortex-a520ae, cortex-a57, cortex-a65, cortex-a65ae, cortex-a72, cortex-a73, cortex-a75, cortex-a76, cortex-a76ae, cortex-a77, cortex-a78, cortex-a78ae, cortex-a78c, cortex-a710, cortex-a715, cortex-a720, cortex-a720ae, cortex-r82, cortex-r82ae, cortex-x1, cortex-x1c, cortex-x2, cortex-x3, cortex-x4, neoverse-e1, neoverse-n1, neoverse-n2, neoverse-n3, neoverse-512tvb, neoverse-v1, neoverse-v2, neoverse-v3, neoverse-v3ae, cyclone, apple-a7, apple-a8, apple-a9, apple-a10, apple-a11, apple-a12, apple-a13, apple-a14, apple-a15, apple-a16, apple-a17, apple-m1, apple-m2, apple-m3, apple-s4, apple-s5, exynos-m3, exynos-m4, exynos-m5, falkor, saphira, kryo, thunderx2t99, thunderx3t110, thunderx, thunderxt88, thunderxt81, thunderxt83, tsv110, a64fx, carmel, ampere1, ampere1a, ampere1b, oryon-1, cobalt-100, grace{{$}} // RUN: not %clang_cc1 -triple i386--- -target-cpu not-a-cpu -fsyntax-only %s 2>&1 | FileCheck %s --check-prefix X86 // X86: error: unknown target CPU 'not-a-cpu' @@ -29,7 +29,7 @@ // RUN: not %clang_cc1 -triple nvptx--- -target-cpu not-a-cpu -fsyntax-only %s 2>&1 | FileCheck %s --check-prefix NVPTX // NVPTX: error: unknown target CPU 'not-a-cpu' -// NVPTX-NEXT: note: valid target CPU values are: sm_20, sm_21, sm_30, sm_32, sm_35, sm_37, sm_50, sm_52, sm_53, sm_60, sm_61, sm_62, sm_70, sm_72, sm_75, sm_80, sm_86, sm_87, sm_89, sm_90, sm_90a, gfx600, gfx601, gfx602, gfx700, gfx701, gfx702, gfx703, gfx704, gfx705, gfx801, gfx802, gfx803, gfx805, gfx810, gfx900, gfx902, gfx904, gfx906, gfx908, gfx909, gfx90a, gfx90c, gfx940, gfx941, gfx942, gfx1010, gfx1011, gfx1012, gfx1013, gfx1030, gfx1031, gfx1032, gfx1033, gfx1034, gfx1035, gfx1036, gfx1100, gfx1101, gfx1102, gfx1103, gfx1150, gfx1151, gfx1200, gfx1201{{$}} +// NVPTX-NEXT: note: valid target CPU values are: sm_20, sm_21, sm_30, sm_32, sm_35, sm_37, sm_50, sm_52, sm_53, sm_60, sm_61, sm_62, sm_70, sm_72, sm_75, sm_80, sm_86, sm_87, sm_89, sm_90, sm_90a, gfx600, gfx601, gfx602, gfx700, gfx701, gfx702, gfx703, gfx704, gfx705, gfx801, gfx802, gfx803, gfx805, gfx810, gfx9-generic, gfx900, gfx902, gfx904, gfx906, gfx908, gfx909, gfx90a, gfx90c, gfx940, gfx941, gfx942, gfx10-1-generic, gfx1010, gfx1011, gfx1012, gfx1013, gfx10-3-generic, gfx1030, gfx1031, gfx1032, gfx1033, gfx1034, gfx1035, gfx1036, gfx11-generic, gfx1100, gfx1101, gfx1102, gfx1103, gfx1150, gfx1151, gfx1152, gfx12-generic, gfx1200, gfx1201{{$}} // RUN: not %clang_cc1 -triple r600--- -target-cpu not-a-cpu -fsyntax-only %s 2>&1 | FileCheck %s --check-prefix R600 // R600: error: unknown target CPU 'not-a-cpu' @@ -37,7 +37,7 @@ // RUN: not %clang_cc1 -triple amdgcn--- -target-cpu not-a-cpu -fsyntax-only %s 2>&1 | FileCheck %s --check-prefix AMDGCN // AMDGCN: error: unknown target CPU 'not-a-cpu' -// AMDGCN-NEXT: note: valid target CPU values are: gfx600, tahiti, gfx601, pitcairn, verde, gfx602, hainan, oland, gfx700, kaveri, gfx701, hawaii, gfx702, gfx703, kabini, mullins, gfx704, bonaire, gfx705, gfx801, carrizo, gfx802, iceland, tonga, gfx803, fiji, polaris10, polaris11, gfx805, tongapro, gfx810, stoney, gfx900, gfx902, gfx904, gfx906, gfx908, gfx909, gfx90a, gfx90c, gfx940, gfx941, gfx942, gfx1010, gfx1011, gfx1012, gfx1013, gfx1030, gfx1031, gfx1032, gfx1033, gfx1034, gfx1035, gfx1036, gfx1100, gfx1101, gfx1102, gfx1103, gfx1150, gfx1151, gfx1200, gfx1201, gfx9-generic, gfx10-1-generic, gfx10-3-generic, gfx11-generic, gfx12-generic{{$}} +// AMDGCN-NEXT: note: valid target CPU values are: gfx600, tahiti, gfx601, pitcairn, verde, gfx602, hainan, oland, gfx700, kaveri, gfx701, hawaii, gfx702, gfx703, kabini, mullins, gfx704, bonaire, gfx705, gfx801, carrizo, gfx802, iceland, tonga, gfx803, fiji, polaris10, polaris11, gfx805, tongapro, gfx810, stoney, gfx900, gfx902, gfx904, gfx906, gfx908, gfx909, gfx90a, gfx90c, gfx940, gfx941, gfx942, gfx1010, gfx1011, gfx1012, gfx1013, gfx1030, gfx1031, gfx1032, gfx1033, gfx1034, gfx1035, gfx1036, gfx1100, gfx1101, gfx1102, gfx1103, gfx1150, gfx1151, gfx1152, gfx1200, gfx1201, gfx9-generic, gfx10-1-generic, gfx10-3-generic, gfx11-generic, gfx12-generic{{$}} // RUN: not %clang_cc1 -triple wasm64--- -target-cpu not-a-cpu -fsyntax-only %s 2>&1 | FileCheck %s --check-prefix WEBASM // WEBASM: error: unknown target CPU 'not-a-cpu' diff --git a/clang/test/Modules/no-transitive-decls-change.cppm b/clang/test/Modules/no-transitive-decls-change.cppm new file mode 100644 index 0000000000000000000000000000000000000000..42ac061bc90b3f188a129025b97fb2d74ad5ee8b --- /dev/null +++ b/clang/test/Modules/no-transitive-decls-change.cppm @@ -0,0 +1,112 @@ +// Testing that changing a declaration in an unused module file won't change +// the BMI of the current module file. +// +// RUN: rm -rf %t +// RUN: split-file %s %t +// +// RUN: %clang_cc1 -std=c++20 %t/m-partA.cppm -emit-reduced-module-interface -o %t/m-partA.pcm +// RUN: %clang_cc1 -std=c++20 %t/m-partA.v1.cppm -emit-reduced-module-interface -o \ +// RUN: %t/m-partA.v1.pcm +// RUN: %clang_cc1 -std=c++20 %t/m-partB.cppm -emit-reduced-module-interface -o %t/m-partB.pcm +// RUN: %clang_cc1 -std=c++20 %t/m.cppm -emit-reduced-module-interface -o %t/m.pcm \ +// RUN: -fmodule-file=m:partA=%t/m-partA.pcm -fmodule-file=m:partB=%t/m-partB.pcm +// RUN: %clang_cc1 -std=c++20 %t/m.cppm -emit-reduced-module-interface -o %t/m.v1.pcm \ +// RUN: -fmodule-file=m:partA=%t/m-partA.v1.pcm -fmodule-file=m:partB=%t/m-partB.pcm +// +// RUN: %clang_cc1 -std=c++20 %t/useBOnly.cppm -emit-reduced-module-interface -o %t/useBOnly.pcm \ +// RUN: -fmodule-file=m=%t/m.pcm -fmodule-file=m:partA=%t/m-partA.pcm \ +// RUN: -fmodule-file=m:partB=%t/m-partB.pcm +// RUN: %clang_cc1 -std=c++20 %t/useBOnly.cppm -emit-reduced-module-interface -o %t/useBOnly.v1.pcm \ +// RUN: -fmodule-file=m=%t/m.v1.pcm -fmodule-file=m:partA=%t/m-partA.v1.pcm \ +// RUN: -fmodule-file=m:partB=%t/m-partB.pcm +// Since useBOnly only uses partB from module M, the change in partA shouldn't affect +// useBOnly. +// RUN: diff %t/useBOnly.pcm %t/useBOnly.v1.pcm &> /dev/null + +//--- m-partA.cppm +export module m:partA; + +namespace A_Impl { + inline int getAImpl() { + return 43; + } + + inline int getA2Impl() { + return 43; + } +} + +namespace A { + using A_Impl::getAImpl; +} + +export inline int getA() { + return 43; +} + +export inline int getA2(int) { + return 88; +} + +//--- m-partA.v1.cppm +export module m:partA; + +namespace A_Impl { + inline int getAImpl() { + return 43; + } + + inline int getA2Impl() { + return 43; + } +} + +namespace A { + using A_Impl::getAImpl; + // Adding a new declaration without introducing a new declaration name. + using A_Impl::getA2Impl; +} + +inline int getA() { + return 43; +} + +inline int getA2(int) { + return 88; +} + +// Now we add a new declaration without introducing new identifier and new types. +// The consuming module which didn't use m:partA completely is expected to be +// not changed. +inline int getA(int) { + return 88; +} + +//--- m-partB.cppm +export module m:partB; + +export inline int getB() { + return 430; +} + +//--- m.cppm +export module m; +export import :partA; +export import :partB; + +//--- useBOnly.cppm +export module useBOnly; +import m; + +export inline int get() { + return getB(); +} + +//--- useAOnly.cppm +export module useAOnly; +import m; + +export inline int get() { + A a; + return a.getValue(); +} diff --git a/clang/test/OpenMP/distribute_firstprivate_codegen.cpp b/clang/test/OpenMP/distribute_firstprivate_codegen.cpp index 567d12119db2187842c67a6a9782230825918aad..6a15cae307623153f29bacc117ed8d6bfcec98cd 100644 --- a/clang/test/OpenMP/distribute_firstprivate_codegen.cpp +++ b/clang/test/OpenMP/distribute_firstprivate_codegen.cpp @@ -493,9 +493,8 @@ int main() { // CHECK9-NEXT: call void @_ZN1SIfEC1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[TEST]]) // CHECK9-NEXT: store i32 0, ptr [[T_VAR]], align 4 // CHECK9-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 4 [[VEC]], ptr align 4 @__const.main.vec, i64 8, i1 false) -// CHECK9-NEXT: [[ARRAYINIT_BEGIN:%.*]] = getelementptr inbounds [2 x %struct.S], ptr [[S_ARR]], i64 0, i64 0 -// CHECK9-NEXT: call void @_ZN1SIfEC1Ef(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_BEGIN]], float noundef 1.000000e+00) -// CHECK9-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[ARRAYINIT_BEGIN]], i64 1 +// CHECK9-NEXT: call void @_ZN1SIfEC1Ef(ptr noundef nonnull align 4 dereferenceable(4) [[S_ARR]], float noundef 1.000000e+00) +// CHECK9-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[S_ARR]], i64 1 // CHECK9-NEXT: call void @_ZN1SIfEC1Ef(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_ELEMENT]], float noundef 2.000000e+00) // CHECK9-NEXT: store ptr [[TEST]], ptr [[VAR]], align 8 // CHECK9-NEXT: [[TMP0:%.*]] = load ptr, ptr [[VAR]], align 8 @@ -798,9 +797,8 @@ int main() { // CHECK9-NEXT: call void @_ZN1SIiEC1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[TEST]]) // CHECK9-NEXT: store i32 0, ptr [[T_VAR]], align 4 // CHECK9-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 4 [[VEC]], ptr align 4 @__const._Z5tmainIiET_v.vec, i64 8, i1 false) -// CHECK9-NEXT: [[ARRAYINIT_BEGIN:%.*]] = getelementptr inbounds [2 x %struct.S.0], ptr [[S_ARR]], i64 0, i64 0 -// CHECK9-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_BEGIN]], i32 noundef signext 1) -// CHECK9-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[ARRAYINIT_BEGIN]], i64 1 +// CHECK9-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[S_ARR]], i32 noundef signext 1) +// CHECK9-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[S_ARR]], i64 1 // CHECK9-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_ELEMENT]], i32 noundef signext 2) // CHECK9-NEXT: store ptr [[TEST]], ptr [[VAR]], align 8 // CHECK9-NEXT: [[TMP0:%.*]] = load ptr, ptr [[VAR]], align 8 @@ -1158,9 +1156,8 @@ int main() { // CHECK11-NEXT: call void @_ZN1SIfEC1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[TEST]]) // CHECK11-NEXT: store i32 0, ptr [[T_VAR]], align 4 // CHECK11-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 4 [[VEC]], ptr align 4 @__const.main.vec, i32 8, i1 false) -// CHECK11-NEXT: [[ARRAYINIT_BEGIN:%.*]] = getelementptr inbounds [2 x %struct.S], ptr [[S_ARR]], i32 0, i32 0 -// CHECK11-NEXT: call void @_ZN1SIfEC1Ef(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_BEGIN]], float noundef 1.000000e+00) -// CHECK11-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[ARRAYINIT_BEGIN]], i32 1 +// CHECK11-NEXT: call void @_ZN1SIfEC1Ef(ptr noundef nonnull align 4 dereferenceable(4) [[S_ARR]], float noundef 1.000000e+00) +// CHECK11-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[S_ARR]], i32 1 // CHECK11-NEXT: call void @_ZN1SIfEC1Ef(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_ELEMENT]], float noundef 2.000000e+00) // CHECK11-NEXT: store ptr [[TEST]], ptr [[VAR]], align 4 // CHECK11-NEXT: [[TMP0:%.*]] = load ptr, ptr [[VAR]], align 4 @@ -1461,9 +1458,8 @@ int main() { // CHECK11-NEXT: call void @_ZN1SIiEC1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[TEST]]) // CHECK11-NEXT: store i32 0, ptr [[T_VAR]], align 4 // CHECK11-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 4 [[VEC]], ptr align 4 @__const._Z5tmainIiET_v.vec, i32 8, i1 false) -// CHECK11-NEXT: [[ARRAYINIT_BEGIN:%.*]] = getelementptr inbounds [2 x %struct.S.0], ptr [[S_ARR]], i32 0, i32 0 -// CHECK11-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_BEGIN]], i32 noundef 1) -// CHECK11-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[ARRAYINIT_BEGIN]], i32 1 +// CHECK11-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[S_ARR]], i32 noundef 1) +// CHECK11-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[S_ARR]], i32 1 // CHECK11-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_ELEMENT]], i32 noundef 2) // CHECK11-NEXT: store ptr [[TEST]], ptr [[VAR]], align 4 // CHECK11-NEXT: [[TMP0:%.*]] = load ptr, ptr [[VAR]], align 4 diff --git a/clang/test/OpenMP/distribute_lastprivate_codegen.cpp b/clang/test/OpenMP/distribute_lastprivate_codegen.cpp index 5d1a12d27145e03786acae6a0b5a0787d6ad374f..510c5d4d88efc24740581d4439ecc6936e60e940 100644 --- a/clang/test/OpenMP/distribute_lastprivate_codegen.cpp +++ b/clang/test/OpenMP/distribute_lastprivate_codegen.cpp @@ -478,9 +478,8 @@ int main() { // CHECK9-NEXT: call void @_ZN1SIfEC1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[TEST]]) // CHECK9-NEXT: store i32 0, ptr [[T_VAR]], align 4 // CHECK9-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 4 [[VEC]], ptr align 4 @__const.main.vec, i64 8, i1 false) -// CHECK9-NEXT: [[ARRAYINIT_BEGIN:%.*]] = getelementptr inbounds [2 x %struct.S], ptr [[S_ARR]], i64 0, i64 0 -// CHECK9-NEXT: call void @_ZN1SIfEC1Ef(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_BEGIN]], float noundef 1.000000e+00) -// CHECK9-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[ARRAYINIT_BEGIN]], i64 1 +// CHECK9-NEXT: call void @_ZN1SIfEC1Ef(ptr noundef nonnull align 4 dereferenceable(4) [[S_ARR]], float noundef 1.000000e+00) +// CHECK9-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[S_ARR]], i64 1 // CHECK9-NEXT: call void @_ZN1SIfEC1Ef(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_ELEMENT]], float noundef 2.000000e+00) // CHECK9-NEXT: store ptr [[TEST]], ptr [[VAR]], align 8 // CHECK9-NEXT: [[TMP0:%.*]] = load ptr, ptr [[VAR]], align 8 @@ -801,9 +800,8 @@ int main() { // CHECK9-NEXT: call void @_ZN1SIiEC1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[TEST]]) // CHECK9-NEXT: store i32 0, ptr [[T_VAR]], align 4 // CHECK9-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 4 [[VEC]], ptr align 4 @__const._Z5tmainIiET_v.vec, i64 8, i1 false) -// CHECK9-NEXT: [[ARRAYINIT_BEGIN:%.*]] = getelementptr inbounds [2 x %struct.S.0], ptr [[S_ARR]], i64 0, i64 0 -// CHECK9-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_BEGIN]], i32 noundef signext 1) -// CHECK9-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[ARRAYINIT_BEGIN]], i64 1 +// CHECK9-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[S_ARR]], i32 noundef signext 1) +// CHECK9-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[S_ARR]], i64 1 // CHECK9-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_ELEMENT]], i32 noundef signext 2) // CHECK9-NEXT: store ptr [[TEST]], ptr [[VAR]], align 8 // CHECK9-NEXT: [[TMP0:%.*]] = load ptr, ptr [[VAR]], align 8 @@ -1180,9 +1178,8 @@ int main() { // CHECK11-NEXT: call void @_ZN1SIfEC1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[TEST]]) // CHECK11-NEXT: store i32 0, ptr [[T_VAR]], align 4 // CHECK11-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 4 [[VEC]], ptr align 4 @__const.main.vec, i32 8, i1 false) -// CHECK11-NEXT: [[ARRAYINIT_BEGIN:%.*]] = getelementptr inbounds [2 x %struct.S], ptr [[S_ARR]], i32 0, i32 0 -// CHECK11-NEXT: call void @_ZN1SIfEC1Ef(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_BEGIN]], float noundef 1.000000e+00) -// CHECK11-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[ARRAYINIT_BEGIN]], i32 1 +// CHECK11-NEXT: call void @_ZN1SIfEC1Ef(ptr noundef nonnull align 4 dereferenceable(4) [[S_ARR]], float noundef 1.000000e+00) +// CHECK11-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[S_ARR]], i32 1 // CHECK11-NEXT: call void @_ZN1SIfEC1Ef(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_ELEMENT]], float noundef 2.000000e+00) // CHECK11-NEXT: store ptr [[TEST]], ptr [[VAR]], align 4 // CHECK11-NEXT: [[TMP0:%.*]] = load ptr, ptr [[VAR]], align 4 @@ -1501,9 +1498,8 @@ int main() { // CHECK11-NEXT: call void @_ZN1SIiEC1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[TEST]]) // CHECK11-NEXT: store i32 0, ptr [[T_VAR]], align 4 // CHECK11-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 4 [[VEC]], ptr align 4 @__const._Z5tmainIiET_v.vec, i32 8, i1 false) -// CHECK11-NEXT: [[ARRAYINIT_BEGIN:%.*]] = getelementptr inbounds [2 x %struct.S.0], ptr [[S_ARR]], i32 0, i32 0 -// CHECK11-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_BEGIN]], i32 noundef 1) -// CHECK11-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[ARRAYINIT_BEGIN]], i32 1 +// CHECK11-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[S_ARR]], i32 noundef 1) +// CHECK11-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[S_ARR]], i32 1 // CHECK11-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_ELEMENT]], i32 noundef 2) // CHECK11-NEXT: store ptr [[TEST]], ptr [[VAR]], align 4 // CHECK11-NEXT: [[TMP0:%.*]] = load ptr, ptr [[VAR]], align 4 diff --git a/clang/test/OpenMP/distribute_parallel_for_firstprivate_codegen.cpp b/clang/test/OpenMP/distribute_parallel_for_firstprivate_codegen.cpp index faae599bb32afe7adc1f015792b3e4be42275035..11b18e871551eb6a9c31c83f2bcfb1ec9e365c65 100644 --- a/clang/test/OpenMP/distribute_parallel_for_firstprivate_codegen.cpp +++ b/clang/test/OpenMP/distribute_parallel_for_firstprivate_codegen.cpp @@ -776,9 +776,8 @@ int main() { // CHECK8-NEXT: call void @_ZN1SIfEC1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[TEST]]) // CHECK8-NEXT: store i32 0, ptr [[T_VAR]], align 4 // CHECK8-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 4 [[VEC]], ptr align 4 @__const.main.vec, i64 8, i1 false) -// CHECK8-NEXT: [[ARRAYINIT_BEGIN:%.*]] = getelementptr inbounds [2 x %struct.S], ptr [[S_ARR]], i64 0, i64 0 -// CHECK8-NEXT: call void @_ZN1SIfEC1Ef(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_BEGIN]], float noundef 1.000000e+00) -// CHECK8-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[ARRAYINIT_BEGIN]], i64 1 +// CHECK8-NEXT: call void @_ZN1SIfEC1Ef(ptr noundef nonnull align 4 dereferenceable(4) [[S_ARR]], float noundef 1.000000e+00) +// CHECK8-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[S_ARR]], i64 1 // CHECK8-NEXT: call void @_ZN1SIfEC1Ef(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_ELEMENT]], float noundef 2.000000e+00) // CHECK8-NEXT: store ptr [[TEST]], ptr [[VAR]], align 8 // CHECK8-NEXT: [[TMP0:%.*]] = load ptr, ptr [[VAR]], align 8 @@ -1211,9 +1210,8 @@ int main() { // CHECK8-NEXT: call void @_ZN1SIiEC1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[TEST]]) // CHECK8-NEXT: store i32 0, ptr [[T_VAR]], align 4 // CHECK8-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 4 [[VEC]], ptr align 4 @__const._Z5tmainIiET_v.vec, i64 8, i1 false) -// CHECK8-NEXT: [[ARRAYINIT_BEGIN:%.*]] = getelementptr inbounds [2 x %struct.S.0], ptr [[S_ARR]], i64 0, i64 0 -// CHECK8-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_BEGIN]], i32 noundef signext 1) -// CHECK8-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[ARRAYINIT_BEGIN]], i64 1 +// CHECK8-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[S_ARR]], i32 noundef signext 1) +// CHECK8-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[S_ARR]], i64 1 // CHECK8-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_ELEMENT]], i32 noundef signext 2) // CHECK8-NEXT: store ptr [[TEST]], ptr [[VAR]], align 8 // CHECK8-NEXT: [[TMP0:%.*]] = load ptr, ptr [[VAR]], align 8 @@ -1695,9 +1693,8 @@ int main() { // CHECK10-NEXT: call void @_ZN1SIfEC1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[TEST]]) // CHECK10-NEXT: store i32 0, ptr [[T_VAR]], align 4 // CHECK10-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 4 [[VEC]], ptr align 4 @__const.main.vec, i32 8, i1 false) -// CHECK10-NEXT: [[ARRAYINIT_BEGIN:%.*]] = getelementptr inbounds [2 x %struct.S], ptr [[S_ARR]], i32 0, i32 0 -// CHECK10-NEXT: call void @_ZN1SIfEC1Ef(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_BEGIN]], float noundef 1.000000e+00) -// CHECK10-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[ARRAYINIT_BEGIN]], i32 1 +// CHECK10-NEXT: call void @_ZN1SIfEC1Ef(ptr noundef nonnull align 4 dereferenceable(4) [[S_ARR]], float noundef 1.000000e+00) +// CHECK10-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[S_ARR]], i32 1 // CHECK10-NEXT: call void @_ZN1SIfEC1Ef(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_ELEMENT]], float noundef 2.000000e+00) // CHECK10-NEXT: store ptr [[TEST]], ptr [[VAR]], align 4 // CHECK10-NEXT: [[TMP0:%.*]] = load ptr, ptr [[VAR]], align 4 @@ -2124,9 +2121,8 @@ int main() { // CHECK10-NEXT: call void @_ZN1SIiEC1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[TEST]]) // CHECK10-NEXT: store i32 0, ptr [[T_VAR]], align 4 // CHECK10-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 4 [[VEC]], ptr align 4 @__const._Z5tmainIiET_v.vec, i32 8, i1 false) -// CHECK10-NEXT: [[ARRAYINIT_BEGIN:%.*]] = getelementptr inbounds [2 x %struct.S.0], ptr [[S_ARR]], i32 0, i32 0 -// CHECK10-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_BEGIN]], i32 noundef 1) -// CHECK10-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[ARRAYINIT_BEGIN]], i32 1 +// CHECK10-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[S_ARR]], i32 noundef 1) +// CHECK10-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[S_ARR]], i32 1 // CHECK10-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_ELEMENT]], i32 noundef 2) // CHECK10-NEXT: store ptr [[TEST]], ptr [[VAR]], align 4 // CHECK10-NEXT: [[TMP0:%.*]] = load ptr, ptr [[VAR]], align 4 diff --git a/clang/test/OpenMP/distribute_parallel_for_lastprivate_codegen.cpp b/clang/test/OpenMP/distribute_parallel_for_lastprivate_codegen.cpp index 18a86c5e5666399e8779fccaede3c0038f597693..29e1a35e90e0251194d93bd6d03f98cba659335f 100644 --- a/clang/test/OpenMP/distribute_parallel_for_lastprivate_codegen.cpp +++ b/clang/test/OpenMP/distribute_parallel_for_lastprivate_codegen.cpp @@ -752,9 +752,8 @@ int main() { // CHECK9-NEXT: call void @_ZN1SIfEC1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[TEST]]) // CHECK9-NEXT: store i32 0, ptr [[T_VAR]], align 4 // CHECK9-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 4 [[VEC]], ptr align 4 @__const.main.vec, i64 8, i1 false) -// CHECK9-NEXT: [[ARRAYINIT_BEGIN:%.*]] = getelementptr inbounds [2 x %struct.S], ptr [[S_ARR]], i64 0, i64 0 -// CHECK9-NEXT: call void @_ZN1SIfEC1Ef(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_BEGIN]], float noundef 1.000000e+00) -// CHECK9-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[ARRAYINIT_BEGIN]], i64 1 +// CHECK9-NEXT: call void @_ZN1SIfEC1Ef(ptr noundef nonnull align 4 dereferenceable(4) [[S_ARR]], float noundef 1.000000e+00) +// CHECK9-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[S_ARR]], i64 1 // CHECK9-NEXT: call void @_ZN1SIfEC1Ef(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_ELEMENT]], float noundef 2.000000e+00) // CHECK9-NEXT: store ptr [[TEST]], ptr [[VAR]], align 8 // CHECK9-NEXT: [[TMP0:%.*]] = load ptr, ptr [[VAR]], align 8 @@ -1223,9 +1222,8 @@ int main() { // CHECK9-NEXT: call void @_ZN1SIiEC1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[TEST]]) // CHECK9-NEXT: store i32 0, ptr [[T_VAR]], align 4 // CHECK9-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 4 [[VEC]], ptr align 4 @__const._Z5tmainIiET_v.vec, i64 8, i1 false) -// CHECK9-NEXT: [[ARRAYINIT_BEGIN:%.*]] = getelementptr inbounds [2 x %struct.S.0], ptr [[S_ARR]], i64 0, i64 0 -// CHECK9-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_BEGIN]], i32 noundef signext 1) -// CHECK9-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[ARRAYINIT_BEGIN]], i64 1 +// CHECK9-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[S_ARR]], i32 noundef signext 1) +// CHECK9-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[S_ARR]], i64 1 // CHECK9-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_ELEMENT]], i32 noundef signext 2) // CHECK9-NEXT: store ptr [[TEST]], ptr [[VAR]], align 8 // CHECK9-NEXT: [[TMP0:%.*]] = load ptr, ptr [[VAR]], align 8 @@ -1744,9 +1742,8 @@ int main() { // CHECK11-NEXT: call void @_ZN1SIfEC1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[TEST]]) // CHECK11-NEXT: store i32 0, ptr [[T_VAR]], align 4 // CHECK11-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 4 [[VEC]], ptr align 4 @__const.main.vec, i32 8, i1 false) -// CHECK11-NEXT: [[ARRAYINIT_BEGIN:%.*]] = getelementptr inbounds [2 x %struct.S], ptr [[S_ARR]], i32 0, i32 0 -// CHECK11-NEXT: call void @_ZN1SIfEC1Ef(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_BEGIN]], float noundef 1.000000e+00) -// CHECK11-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[ARRAYINIT_BEGIN]], i32 1 +// CHECK11-NEXT: call void @_ZN1SIfEC1Ef(ptr noundef nonnull align 4 dereferenceable(4) [[S_ARR]], float noundef 1.000000e+00) +// CHECK11-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[S_ARR]], i32 1 // CHECK11-NEXT: call void @_ZN1SIfEC1Ef(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_ELEMENT]], float noundef 2.000000e+00) // CHECK11-NEXT: store ptr [[TEST]], ptr [[VAR]], align 4 // CHECK11-NEXT: [[TMP0:%.*]] = load ptr, ptr [[VAR]], align 4 @@ -2209,9 +2206,8 @@ int main() { // CHECK11-NEXT: call void @_ZN1SIiEC1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[TEST]]) // CHECK11-NEXT: store i32 0, ptr [[T_VAR]], align 4 // CHECK11-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 4 [[VEC]], ptr align 4 @__const._Z5tmainIiET_v.vec, i32 8, i1 false) -// CHECK11-NEXT: [[ARRAYINIT_BEGIN:%.*]] = getelementptr inbounds [2 x %struct.S.0], ptr [[S_ARR]], i32 0, i32 0 -// CHECK11-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_BEGIN]], i32 noundef 1) -// CHECK11-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[ARRAYINIT_BEGIN]], i32 1 +// CHECK11-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[S_ARR]], i32 noundef 1) +// CHECK11-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[S_ARR]], i32 1 // CHECK11-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_ELEMENT]], i32 noundef 2) // CHECK11-NEXT: store ptr [[TEST]], ptr [[VAR]], align 4 // CHECK11-NEXT: [[TMP0:%.*]] = load ptr, ptr [[VAR]], align 4 diff --git a/clang/test/OpenMP/distribute_parallel_for_private_codegen.cpp b/clang/test/OpenMP/distribute_parallel_for_private_codegen.cpp index 0969a0ca21e7ab56141c21f25661169dab8936d1..03c62ce699b3031a489d22dd515c9f247893d843 100644 --- a/clang/test/OpenMP/distribute_parallel_for_private_codegen.cpp +++ b/clang/test/OpenMP/distribute_parallel_for_private_codegen.cpp @@ -514,9 +514,8 @@ int main() { // CHECK9-NEXT: call void @_ZN1SIfEC1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[TEST]]) // CHECK9-NEXT: store i32 0, ptr [[T_VAR]], align 4 // CHECK9-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 4 [[VEC]], ptr align 4 @__const.main.vec, i64 8, i1 false) -// CHECK9-NEXT: [[ARRAYINIT_BEGIN:%.*]] = getelementptr inbounds [2 x %struct.S], ptr [[S_ARR]], i64 0, i64 0 -// CHECK9-NEXT: call void @_ZN1SIfEC1Ef(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_BEGIN]], float noundef 1.000000e+00) -// CHECK9-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[ARRAYINIT_BEGIN]], i64 1 +// CHECK9-NEXT: call void @_ZN1SIfEC1Ef(ptr noundef nonnull align 4 dereferenceable(4) [[S_ARR]], float noundef 1.000000e+00) +// CHECK9-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[S_ARR]], i64 1 // CHECK9-NEXT: call void @_ZN1SIfEC1Ef(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_ELEMENT]], float noundef 2.000000e+00) // CHECK9-NEXT: store ptr [[TEST]], ptr [[VAR]], align 8 // CHECK9-NEXT: store ptr undef, ptr [[_TMP1]], align 8 @@ -835,9 +834,8 @@ int main() { // CHECK9-NEXT: call void @_ZN1SIiEC1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[TEST]]) // CHECK9-NEXT: store i32 0, ptr [[T_VAR]], align 4 // CHECK9-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 4 [[VEC]], ptr align 4 @__const._Z5tmainIiET_v.vec, i64 8, i1 false) -// CHECK9-NEXT: [[ARRAYINIT_BEGIN:%.*]] = getelementptr inbounds [2 x %struct.S.0], ptr [[S_ARR]], i64 0, i64 0 -// CHECK9-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_BEGIN]], i32 noundef signext 1) -// CHECK9-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[ARRAYINIT_BEGIN]], i64 1 +// CHECK9-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[S_ARR]], i32 noundef signext 1) +// CHECK9-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[S_ARR]], i64 1 // CHECK9-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_ELEMENT]], i32 noundef signext 2) // CHECK9-NEXT: store ptr [[TEST]], ptr [[VAR]], align 8 // CHECK9-NEXT: store ptr undef, ptr [[_TMP1]], align 8 @@ -1225,9 +1223,8 @@ int main() { // CHECK11-NEXT: call void @_ZN1SIfEC1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[TEST]]) // CHECK11-NEXT: store i32 0, ptr [[T_VAR]], align 4 // CHECK11-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 4 [[VEC]], ptr align 4 @__const.main.vec, i32 8, i1 false) -// CHECK11-NEXT: [[ARRAYINIT_BEGIN:%.*]] = getelementptr inbounds [2 x %struct.S], ptr [[S_ARR]], i32 0, i32 0 -// CHECK11-NEXT: call void @_ZN1SIfEC1Ef(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_BEGIN]], float noundef 1.000000e+00) -// CHECK11-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[ARRAYINIT_BEGIN]], i32 1 +// CHECK11-NEXT: call void @_ZN1SIfEC1Ef(ptr noundef nonnull align 4 dereferenceable(4) [[S_ARR]], float noundef 1.000000e+00) +// CHECK11-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[S_ARR]], i32 1 // CHECK11-NEXT: call void @_ZN1SIfEC1Ef(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_ELEMENT]], float noundef 2.000000e+00) // CHECK11-NEXT: store ptr [[TEST]], ptr [[VAR]], align 4 // CHECK11-NEXT: store ptr undef, ptr [[_TMP1]], align 4 @@ -1540,9 +1537,8 @@ int main() { // CHECK11-NEXT: call void @_ZN1SIiEC1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[TEST]]) // CHECK11-NEXT: store i32 0, ptr [[T_VAR]], align 4 // CHECK11-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 4 [[VEC]], ptr align 4 @__const._Z5tmainIiET_v.vec, i32 8, i1 false) -// CHECK11-NEXT: [[ARRAYINIT_BEGIN:%.*]] = getelementptr inbounds [2 x %struct.S.0], ptr [[S_ARR]], i32 0, i32 0 -// CHECK11-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_BEGIN]], i32 noundef 1) -// CHECK11-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[ARRAYINIT_BEGIN]], i32 1 +// CHECK11-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[S_ARR]], i32 noundef 1) +// CHECK11-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[S_ARR]], i32 1 // CHECK11-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_ELEMENT]], i32 noundef 2) // CHECK11-NEXT: store ptr [[TEST]], ptr [[VAR]], align 4 // CHECK11-NEXT: store ptr undef, ptr [[_TMP1]], align 4 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 545ea9f0f43fdf947b726afd6942d0001886171e..cb2cbb039a4e01662ba6bf5538437cbcdad614cc 100644 --- a/clang/test/OpenMP/distribute_parallel_for_simd_firstprivate_codegen.cpp +++ b/clang/test/OpenMP/distribute_parallel_for_simd_firstprivate_codegen.cpp @@ -839,9 +839,8 @@ int main() { // CHECK8-NEXT: call void @_ZN1SIfEC1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[TEST]]) // CHECK8-NEXT: store i32 0, ptr [[T_VAR]], align 4 // CHECK8-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 4 [[VEC]], ptr align 4 @__const.main.vec, i64 8, i1 false) -// CHECK8-NEXT: [[ARRAYINIT_BEGIN:%.*]] = getelementptr inbounds [2 x %struct.S], ptr [[S_ARR]], i64 0, i64 0 -// CHECK8-NEXT: call void @_ZN1SIfEC1Ef(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_BEGIN]], float noundef 1.000000e+00) -// CHECK8-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[ARRAYINIT_BEGIN]], i64 1 +// CHECK8-NEXT: call void @_ZN1SIfEC1Ef(ptr noundef nonnull align 4 dereferenceable(4) [[S_ARR]], float noundef 1.000000e+00) +// CHECK8-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[S_ARR]], i64 1 // CHECK8-NEXT: call void @_ZN1SIfEC1Ef(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_ELEMENT]], float noundef 2.000000e+00) // CHECK8-NEXT: store ptr [[TEST]], ptr [[VAR]], align 8 // CHECK8-NEXT: [[TMP0:%.*]] = load ptr, ptr [[VAR]], align 8 @@ -1288,9 +1287,8 @@ int main() { // CHECK8-NEXT: call void @_ZN1SIiEC1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[TEST]]) // CHECK8-NEXT: store i32 0, ptr [[T_VAR]], align 4 // CHECK8-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 4 [[VEC]], ptr align 4 @__const._Z5tmainIiET_v.vec, i64 8, i1 false) -// CHECK8-NEXT: [[ARRAYINIT_BEGIN:%.*]] = getelementptr inbounds [2 x %struct.S.0], ptr [[S_ARR]], i64 0, i64 0 -// CHECK8-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_BEGIN]], i32 noundef signext 1) -// CHECK8-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[ARRAYINIT_BEGIN]], i64 1 +// CHECK8-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[S_ARR]], i32 noundef signext 1) +// CHECK8-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[S_ARR]], i64 1 // CHECK8-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_ELEMENT]], i32 noundef signext 2) // CHECK8-NEXT: store ptr [[TEST]], ptr [[VAR]], align 8 // CHECK8-NEXT: [[TMP0:%.*]] = load ptr, ptr [[VAR]], align 8 @@ -1786,9 +1784,8 @@ int main() { // CHECK10-NEXT: call void @_ZN1SIfEC1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[TEST]]) // CHECK10-NEXT: store i32 0, ptr [[T_VAR]], align 4 // CHECK10-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 4 [[VEC]], ptr align 4 @__const.main.vec, i32 8, i1 false) -// CHECK10-NEXT: [[ARRAYINIT_BEGIN:%.*]] = getelementptr inbounds [2 x %struct.S], ptr [[S_ARR]], i32 0, i32 0 -// CHECK10-NEXT: call void @_ZN1SIfEC1Ef(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_BEGIN]], float noundef 1.000000e+00) -// CHECK10-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[ARRAYINIT_BEGIN]], i32 1 +// CHECK10-NEXT: call void @_ZN1SIfEC1Ef(ptr noundef nonnull align 4 dereferenceable(4) [[S_ARR]], float noundef 1.000000e+00) +// CHECK10-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[S_ARR]], i32 1 // CHECK10-NEXT: call void @_ZN1SIfEC1Ef(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_ELEMENT]], float noundef 2.000000e+00) // CHECK10-NEXT: store ptr [[TEST]], ptr [[VAR]], align 4 // CHECK10-NEXT: [[TMP0:%.*]] = load ptr, ptr [[VAR]], align 4 @@ -2229,9 +2226,8 @@ int main() { // CHECK10-NEXT: call void @_ZN1SIiEC1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[TEST]]) // CHECK10-NEXT: store i32 0, ptr [[T_VAR]], align 4 // CHECK10-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 4 [[VEC]], ptr align 4 @__const._Z5tmainIiET_v.vec, i32 8, i1 false) -// CHECK10-NEXT: [[ARRAYINIT_BEGIN:%.*]] = getelementptr inbounds [2 x %struct.S.0], ptr [[S_ARR]], i32 0, i32 0 -// CHECK10-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_BEGIN]], i32 noundef 1) -// CHECK10-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[ARRAYINIT_BEGIN]], i32 1 +// CHECK10-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[S_ARR]], i32 noundef 1) +// CHECK10-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[S_ARR]], i32 1 // CHECK10-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_ELEMENT]], i32 noundef 2) // CHECK10-NEXT: store ptr [[TEST]], ptr [[VAR]], align 4 // CHECK10-NEXT: [[TMP0:%.*]] = load ptr, ptr [[VAR]], align 4 @@ -2721,9 +2717,8 @@ int main() { // CHECK12-NEXT: call void @_ZN1SIfEC1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[TEST]]) // CHECK12-NEXT: store i32 0, ptr [[T_VAR]], align 4 // CHECK12-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 4 [[VEC]], ptr align 4 @__const.main.vec, i64 8, i1 false) -// CHECK12-NEXT: [[ARRAYINIT_BEGIN:%.*]] = getelementptr inbounds [2 x %struct.S], ptr [[S_ARR]], i64 0, i64 0 -// CHECK12-NEXT: call void @_ZN1SIfEC1Ef(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_BEGIN]], float noundef 1.000000e+00) -// CHECK12-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[ARRAYINIT_BEGIN]], i64 1 +// CHECK12-NEXT: call void @_ZN1SIfEC1Ef(ptr noundef nonnull align 4 dereferenceable(4) [[S_ARR]], float noundef 1.000000e+00) +// CHECK12-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[S_ARR]], i64 1 // CHECK12-NEXT: call void @_ZN1SIfEC1Ef(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_ELEMENT]], float noundef 2.000000e+00) // CHECK12-NEXT: store ptr [[TEST]], ptr [[VAR]], align 8 // CHECK12-NEXT: [[TMP0:%.*]] = load ptr, ptr [[VAR]], align 8 @@ -2828,9 +2823,8 @@ int main() { // CHECK12-NEXT: call void @_ZN1SIiEC1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[TEST]]) // CHECK12-NEXT: store i32 0, ptr [[T_VAR]], align 4 // CHECK12-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 4 [[VEC]], ptr align 4 @__const._Z5tmainIiET_v.vec, i64 8, i1 false) -// CHECK12-NEXT: [[ARRAYINIT_BEGIN:%.*]] = getelementptr inbounds [2 x %struct.S.0], ptr [[S_ARR]], i64 0, i64 0 -// CHECK12-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_BEGIN]], i32 noundef signext 1) -// CHECK12-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[ARRAYINIT_BEGIN]], i64 1 +// CHECK12-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[S_ARR]], i32 noundef signext 1) +// CHECK12-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[S_ARR]], i64 1 // CHECK12-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_ELEMENT]], i32 noundef signext 2) // CHECK12-NEXT: store ptr [[TEST]], ptr [[VAR]], align 8 // CHECK12-NEXT: [[TMP0:%.*]] = load ptr, ptr [[VAR]], align 8 @@ -3026,9 +3020,8 @@ int main() { // CHECK14-NEXT: call void @_ZN1SIfEC1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[TEST]]) // CHECK14-NEXT: store i32 0, ptr [[T_VAR]], align 4 // CHECK14-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 4 [[VEC]], ptr align 4 @__const.main.vec, i32 8, i1 false) -// CHECK14-NEXT: [[ARRAYINIT_BEGIN:%.*]] = getelementptr inbounds [2 x %struct.S], ptr [[S_ARR]], i32 0, i32 0 -// CHECK14-NEXT: call void @_ZN1SIfEC1Ef(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_BEGIN]], float noundef 1.000000e+00) -// CHECK14-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[ARRAYINIT_BEGIN]], i32 1 +// CHECK14-NEXT: call void @_ZN1SIfEC1Ef(ptr noundef nonnull align 4 dereferenceable(4) [[S_ARR]], float noundef 1.000000e+00) +// CHECK14-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[S_ARR]], i32 1 // CHECK14-NEXT: call void @_ZN1SIfEC1Ef(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_ELEMENT]], float noundef 2.000000e+00) // CHECK14-NEXT: store ptr [[TEST]], ptr [[VAR]], align 4 // CHECK14-NEXT: [[TMP0:%.*]] = load ptr, ptr [[VAR]], align 4 @@ -3131,9 +3124,8 @@ int main() { // CHECK14-NEXT: call void @_ZN1SIiEC1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[TEST]]) // CHECK14-NEXT: store i32 0, ptr [[T_VAR]], align 4 // CHECK14-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 4 [[VEC]], ptr align 4 @__const._Z5tmainIiET_v.vec, i32 8, i1 false) -// CHECK14-NEXT: [[ARRAYINIT_BEGIN:%.*]] = getelementptr inbounds [2 x %struct.S.0], ptr [[S_ARR]], i32 0, i32 0 -// CHECK14-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_BEGIN]], i32 noundef 1) -// CHECK14-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[ARRAYINIT_BEGIN]], i32 1 +// CHECK14-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[S_ARR]], i32 noundef 1) +// CHECK14-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[S_ARR]], i32 1 // CHECK14-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_ELEMENT]], i32 noundef 2) // CHECK14-NEXT: store ptr [[TEST]], ptr [[VAR]], align 4 // CHECK14-NEXT: [[TMP0:%.*]] = load ptr, ptr [[VAR]], align 4 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 675f1313460e659e5822f7375ff1a32bcd28fe38..c8c230b40c50ca9ac8f6aec1caa5a584c7af00b2 100644 --- a/clang/test/OpenMP/distribute_parallel_for_simd_lastprivate_codegen.cpp +++ b/clang/test/OpenMP/distribute_parallel_for_simd_lastprivate_codegen.cpp @@ -819,9 +819,8 @@ int main() { // CHECK9-NEXT: call void @_ZN1SIfEC1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[TEST]]) // CHECK9-NEXT: store i32 0, ptr [[T_VAR]], align 4 // CHECK9-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 4 [[VEC]], ptr align 4 @__const.main.vec, i64 8, i1 false) -// CHECK9-NEXT: [[ARRAYINIT_BEGIN:%.*]] = getelementptr inbounds [2 x %struct.S], ptr [[S_ARR]], i64 0, i64 0 -// CHECK9-NEXT: call void @_ZN1SIfEC1Ef(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_BEGIN]], float noundef 1.000000e+00) -// CHECK9-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[ARRAYINIT_BEGIN]], i64 1 +// CHECK9-NEXT: call void @_ZN1SIfEC1Ef(ptr noundef nonnull align 4 dereferenceable(4) [[S_ARR]], float noundef 1.000000e+00) +// CHECK9-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[S_ARR]], i64 1 // CHECK9-NEXT: call void @_ZN1SIfEC1Ef(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_ELEMENT]], float noundef 2.000000e+00) // CHECK9-NEXT: store ptr [[TEST]], ptr [[VAR]], align 8 // CHECK9-NEXT: [[TMP0:%.*]] = load ptr, ptr [[VAR]], align 8 @@ -1304,9 +1303,8 @@ int main() { // CHECK9-NEXT: call void @_ZN1SIiEC1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[TEST]]) // CHECK9-NEXT: store i32 0, ptr [[T_VAR]], align 4 // CHECK9-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 4 [[VEC]], ptr align 4 @__const._Z5tmainIiET_v.vec, i64 8, i1 false) -// CHECK9-NEXT: [[ARRAYINIT_BEGIN:%.*]] = getelementptr inbounds [2 x %struct.S.0], ptr [[S_ARR]], i64 0, i64 0 -// CHECK9-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_BEGIN]], i32 noundef signext 1) -// CHECK9-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[ARRAYINIT_BEGIN]], i64 1 +// CHECK9-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[S_ARR]], i32 noundef signext 1) +// CHECK9-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[S_ARR]], i64 1 // CHECK9-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_ELEMENT]], i32 noundef signext 2) // CHECK9-NEXT: store ptr [[TEST]], ptr [[VAR]], align 8 // CHECK9-NEXT: [[TMP0:%.*]] = load ptr, ptr [[VAR]], align 8 @@ -1839,9 +1837,8 @@ int main() { // CHECK11-NEXT: call void @_ZN1SIfEC1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[TEST]]) // CHECK11-NEXT: store i32 0, ptr [[T_VAR]], align 4 // CHECK11-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 4 [[VEC]], ptr align 4 @__const.main.vec, i32 8, i1 false) -// CHECK11-NEXT: [[ARRAYINIT_BEGIN:%.*]] = getelementptr inbounds [2 x %struct.S], ptr [[S_ARR]], i32 0, i32 0 -// CHECK11-NEXT: call void @_ZN1SIfEC1Ef(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_BEGIN]], float noundef 1.000000e+00) -// CHECK11-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[ARRAYINIT_BEGIN]], i32 1 +// CHECK11-NEXT: call void @_ZN1SIfEC1Ef(ptr noundef nonnull align 4 dereferenceable(4) [[S_ARR]], float noundef 1.000000e+00) +// CHECK11-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[S_ARR]], i32 1 // CHECK11-NEXT: call void @_ZN1SIfEC1Ef(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_ELEMENT]], float noundef 2.000000e+00) // CHECK11-NEXT: store ptr [[TEST]], ptr [[VAR]], align 4 // CHECK11-NEXT: [[TMP0:%.*]] = load ptr, ptr [[VAR]], align 4 @@ -2318,9 +2315,8 @@ int main() { // CHECK11-NEXT: call void @_ZN1SIiEC1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[TEST]]) // CHECK11-NEXT: store i32 0, ptr [[T_VAR]], align 4 // CHECK11-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 4 [[VEC]], ptr align 4 @__const._Z5tmainIiET_v.vec, i32 8, i1 false) -// CHECK11-NEXT: [[ARRAYINIT_BEGIN:%.*]] = getelementptr inbounds [2 x %struct.S.0], ptr [[S_ARR]], i32 0, i32 0 -// CHECK11-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_BEGIN]], i32 noundef 1) -// CHECK11-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[ARRAYINIT_BEGIN]], i32 1 +// CHECK11-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[S_ARR]], i32 noundef 1) +// CHECK11-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[S_ARR]], i32 1 // CHECK11-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_ELEMENT]], i32 noundef 2) // CHECK11-NEXT: store ptr [[TEST]], ptr [[VAR]], align 4 // CHECK11-NEXT: [[TMP0:%.*]] = load ptr, ptr [[VAR]], align 4 @@ -2853,9 +2849,8 @@ int main() { // CHECK13-NEXT: call void @_ZN1SIfEC1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[TEST]]) // CHECK13-NEXT: store i32 0, ptr [[T_VAR]], align 4 // CHECK13-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 4 [[VEC]], ptr align 4 @__const.main.vec, i64 8, i1 false) -// CHECK13-NEXT: [[ARRAYINIT_BEGIN:%.*]] = getelementptr inbounds [2 x %struct.S], ptr [[S_ARR]], i64 0, i64 0 -// CHECK13-NEXT: call void @_ZN1SIfEC1Ef(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_BEGIN]], float noundef 1.000000e+00) -// CHECK13-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[ARRAYINIT_BEGIN]], i64 1 +// CHECK13-NEXT: call void @_ZN1SIfEC1Ef(ptr noundef nonnull align 4 dereferenceable(4) [[S_ARR]], float noundef 1.000000e+00) +// CHECK13-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[S_ARR]], i64 1 // CHECK13-NEXT: call void @_ZN1SIfEC1Ef(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_ELEMENT]], float noundef 2.000000e+00) // CHECK13-NEXT: store ptr [[TEST]], ptr [[VAR]], align 8 // CHECK13-NEXT: [[TMP0:%.*]] = load ptr, ptr [[VAR]], align 8 @@ -3021,9 +3016,8 @@ int main() { // CHECK13-NEXT: call void @_ZN1SIiEC1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[TEST]]) // CHECK13-NEXT: store i32 0, ptr [[T_VAR]], align 4 // CHECK13-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 4 [[VEC]], ptr align 4 @__const._Z5tmainIiET_v.vec, i64 8, i1 false) -// CHECK13-NEXT: [[ARRAYINIT_BEGIN:%.*]] = getelementptr inbounds [2 x %struct.S.0], ptr [[S_ARR]], i64 0, i64 0 -// CHECK13-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_BEGIN]], i32 noundef signext 1) -// CHECK13-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[ARRAYINIT_BEGIN]], i64 1 +// CHECK13-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[S_ARR]], i32 noundef signext 1) +// CHECK13-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[S_ARR]], i64 1 // CHECK13-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_ELEMENT]], i32 noundef signext 2) // CHECK13-NEXT: store ptr [[TEST]], ptr [[VAR]], align 8 // CHECK13-NEXT: [[TMP0:%.*]] = load ptr, ptr [[VAR]], align 8 @@ -3260,9 +3254,8 @@ int main() { // CHECK15-NEXT: call void @_ZN1SIfEC1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[TEST]]) // CHECK15-NEXT: store i32 0, ptr [[T_VAR]], align 4 // CHECK15-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 4 [[VEC]], ptr align 4 @__const.main.vec, i32 8, i1 false) -// CHECK15-NEXT: [[ARRAYINIT_BEGIN:%.*]] = getelementptr inbounds [2 x %struct.S], ptr [[S_ARR]], i32 0, i32 0 -// CHECK15-NEXT: call void @_ZN1SIfEC1Ef(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_BEGIN]], float noundef 1.000000e+00) -// CHECK15-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[ARRAYINIT_BEGIN]], i32 1 +// CHECK15-NEXT: call void @_ZN1SIfEC1Ef(ptr noundef nonnull align 4 dereferenceable(4) [[S_ARR]], float noundef 1.000000e+00) +// CHECK15-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[S_ARR]], i32 1 // CHECK15-NEXT: call void @_ZN1SIfEC1Ef(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_ELEMENT]], float noundef 2.000000e+00) // CHECK15-NEXT: store ptr [[TEST]], ptr [[VAR]], align 4 // CHECK15-NEXT: [[TMP0:%.*]] = load ptr, ptr [[VAR]], align 4 @@ -3426,9 +3419,8 @@ int main() { // CHECK15-NEXT: call void @_ZN1SIiEC1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[TEST]]) // CHECK15-NEXT: store i32 0, ptr [[T_VAR]], align 4 // CHECK15-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 4 [[VEC]], ptr align 4 @__const._Z5tmainIiET_v.vec, i32 8, i1 false) -// CHECK15-NEXT: [[ARRAYINIT_BEGIN:%.*]] = getelementptr inbounds [2 x %struct.S.0], ptr [[S_ARR]], i32 0, i32 0 -// CHECK15-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_BEGIN]], i32 noundef 1) -// CHECK15-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[ARRAYINIT_BEGIN]], i32 1 +// CHECK15-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[S_ARR]], i32 noundef 1) +// CHECK15-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[S_ARR]], i32 1 // CHECK15-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_ELEMENT]], i32 noundef 2) // CHECK15-NEXT: store ptr [[TEST]], ptr [[VAR]], align 4 // CHECK15-NEXT: [[TMP0:%.*]] = load ptr, ptr [[VAR]], align 4 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 a74af2d7c3932044ea650144b94ea6cacaf2d981..f884babe7e2d90d88477fef6a6131a7ea7e5f76c 100644 --- a/clang/test/OpenMP/distribute_parallel_for_simd_private_codegen.cpp +++ b/clang/test/OpenMP/distribute_parallel_for_simd_private_codegen.cpp @@ -568,9 +568,8 @@ int main() { // CHECK9-NEXT: call void @_ZN1SIfEC1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[TEST]]) // CHECK9-NEXT: store i32 0, ptr [[T_VAR]], align 4 // CHECK9-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 4 [[VEC]], ptr align 4 @__const.main.vec, i64 8, i1 false) -// CHECK9-NEXT: [[ARRAYINIT_BEGIN:%.*]] = getelementptr inbounds [2 x %struct.S], ptr [[S_ARR]], i64 0, i64 0 -// CHECK9-NEXT: call void @_ZN1SIfEC1Ef(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_BEGIN]], float noundef 1.000000e+00) -// CHECK9-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[ARRAYINIT_BEGIN]], i64 1 +// CHECK9-NEXT: call void @_ZN1SIfEC1Ef(ptr noundef nonnull align 4 dereferenceable(4) [[S_ARR]], float noundef 1.000000e+00) +// CHECK9-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[S_ARR]], i64 1 // CHECK9-NEXT: call void @_ZN1SIfEC1Ef(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_ELEMENT]], float noundef 2.000000e+00) // CHECK9-NEXT: store ptr [[TEST]], ptr [[VAR]], align 8 // CHECK9-NEXT: store ptr undef, ptr [[_TMP1]], align 8 @@ -903,9 +902,8 @@ int main() { // CHECK9-NEXT: call void @_ZN1SIiEC1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[TEST]]) // CHECK9-NEXT: store i32 0, ptr [[T_VAR]], align 4 // CHECK9-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 4 [[VEC]], ptr align 4 @__const._Z5tmainIiET_v.vec, i64 8, i1 false) -// CHECK9-NEXT: [[ARRAYINIT_BEGIN:%.*]] = getelementptr inbounds [2 x %struct.S.0], ptr [[S_ARR]], i64 0, i64 0 -// CHECK9-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_BEGIN]], i32 noundef signext 1) -// CHECK9-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[ARRAYINIT_BEGIN]], i64 1 +// CHECK9-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[S_ARR]], i32 noundef signext 1) +// CHECK9-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[S_ARR]], i64 1 // CHECK9-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_ELEMENT]], i32 noundef signext 2) // CHECK9-NEXT: store ptr [[TEST]], ptr [[VAR]], align 8 // CHECK9-NEXT: store ptr undef, ptr [[_TMP1]], align 8 @@ -1307,9 +1305,8 @@ int main() { // CHECK11-NEXT: call void @_ZN1SIfEC1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[TEST]]) // CHECK11-NEXT: store i32 0, ptr [[T_VAR]], align 4 // CHECK11-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 4 [[VEC]], ptr align 4 @__const.main.vec, i32 8, i1 false) -// CHECK11-NEXT: [[ARRAYINIT_BEGIN:%.*]] = getelementptr inbounds [2 x %struct.S], ptr [[S_ARR]], i32 0, i32 0 -// CHECK11-NEXT: call void @_ZN1SIfEC1Ef(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_BEGIN]], float noundef 1.000000e+00) -// CHECK11-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[ARRAYINIT_BEGIN]], i32 1 +// CHECK11-NEXT: call void @_ZN1SIfEC1Ef(ptr noundef nonnull align 4 dereferenceable(4) [[S_ARR]], float noundef 1.000000e+00) +// CHECK11-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[S_ARR]], i32 1 // CHECK11-NEXT: call void @_ZN1SIfEC1Ef(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_ELEMENT]], float noundef 2.000000e+00) // CHECK11-NEXT: store ptr [[TEST]], ptr [[VAR]], align 4 // CHECK11-NEXT: store ptr undef, ptr [[_TMP1]], align 4 @@ -1636,9 +1633,8 @@ int main() { // CHECK11-NEXT: call void @_ZN1SIiEC1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[TEST]]) // CHECK11-NEXT: store i32 0, ptr [[T_VAR]], align 4 // CHECK11-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 4 [[VEC]], ptr align 4 @__const._Z5tmainIiET_v.vec, i32 8, i1 false) -// CHECK11-NEXT: [[ARRAYINIT_BEGIN:%.*]] = getelementptr inbounds [2 x %struct.S.0], ptr [[S_ARR]], i32 0, i32 0 -// CHECK11-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_BEGIN]], i32 noundef 1) -// CHECK11-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[ARRAYINIT_BEGIN]], i32 1 +// CHECK11-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[S_ARR]], i32 noundef 1) +// CHECK11-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[S_ARR]], i32 1 // CHECK11-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_ELEMENT]], i32 noundef 2) // CHECK11-NEXT: store ptr [[TEST]], ptr [[VAR]], align 4 // CHECK11-NEXT: store ptr undef, ptr [[_TMP1]], align 4 @@ -2043,9 +2039,8 @@ int main() { // CHECK13-NEXT: call void @_ZN1SIfEC1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[TEST]]) // CHECK13-NEXT: store i32 0, ptr [[T_VAR]], align 4 // CHECK13-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 4 [[VEC]], ptr align 4 @__const.main.vec, i64 8, i1 false) -// CHECK13-NEXT: [[ARRAYINIT_BEGIN:%.*]] = getelementptr inbounds [2 x %struct.S], ptr [[S_ARR]], i64 0, i64 0 -// CHECK13-NEXT: call void @_ZN1SIfEC1Ef(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_BEGIN]], float noundef 1.000000e+00) -// CHECK13-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[ARRAYINIT_BEGIN]], i64 1 +// CHECK13-NEXT: call void @_ZN1SIfEC1Ef(ptr noundef nonnull align 4 dereferenceable(4) [[S_ARR]], float noundef 1.000000e+00) +// CHECK13-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[S_ARR]], i64 1 // CHECK13-NEXT: call void @_ZN1SIfEC1Ef(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_ELEMENT]], float noundef 2.000000e+00) // CHECK13-NEXT: store ptr [[TEST]], ptr [[VAR]], align 8 // CHECK13-NEXT: store ptr undef, ptr [[_TMP1]], align 8 @@ -2182,9 +2177,8 @@ int main() { // CHECK13-NEXT: call void @_ZN1SIiEC1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[TEST]]) // CHECK13-NEXT: store i32 0, ptr [[T_VAR]], align 4 // CHECK13-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 4 [[VEC]], ptr align 4 @__const._Z5tmainIiET_v.vec, i64 8, i1 false) -// CHECK13-NEXT: [[ARRAYINIT_BEGIN:%.*]] = getelementptr inbounds [2 x %struct.S.0], ptr [[S_ARR]], i64 0, i64 0 -// CHECK13-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_BEGIN]], i32 noundef signext 1) -// CHECK13-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[ARRAYINIT_BEGIN]], i64 1 +// CHECK13-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[S_ARR]], i32 noundef signext 1) +// CHECK13-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[S_ARR]], i64 1 // CHECK13-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_ELEMENT]], i32 noundef signext 2) // CHECK13-NEXT: store ptr [[TEST]], ptr [[VAR]], align 8 // CHECK13-NEXT: store ptr undef, ptr [[_TMP1]], align 8 @@ -2393,9 +2387,8 @@ int main() { // CHECK15-NEXT: call void @_ZN1SIfEC1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[TEST]]) // CHECK15-NEXT: store i32 0, ptr [[T_VAR]], align 4 // CHECK15-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 4 [[VEC]], ptr align 4 @__const.main.vec, i32 8, i1 false) -// CHECK15-NEXT: [[ARRAYINIT_BEGIN:%.*]] = getelementptr inbounds [2 x %struct.S], ptr [[S_ARR]], i32 0, i32 0 -// CHECK15-NEXT: call void @_ZN1SIfEC1Ef(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_BEGIN]], float noundef 1.000000e+00) -// CHECK15-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[ARRAYINIT_BEGIN]], i32 1 +// CHECK15-NEXT: call void @_ZN1SIfEC1Ef(ptr noundef nonnull align 4 dereferenceable(4) [[S_ARR]], float noundef 1.000000e+00) +// CHECK15-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[S_ARR]], i32 1 // CHECK15-NEXT: call void @_ZN1SIfEC1Ef(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_ELEMENT]], float noundef 2.000000e+00) // CHECK15-NEXT: store ptr [[TEST]], ptr [[VAR]], align 4 // CHECK15-NEXT: store ptr undef, ptr [[_TMP1]], align 4 @@ -2530,9 +2523,8 @@ int main() { // CHECK15-NEXT: call void @_ZN1SIiEC1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[TEST]]) // CHECK15-NEXT: store i32 0, ptr [[T_VAR]], align 4 // CHECK15-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 4 [[VEC]], ptr align 4 @__const._Z5tmainIiET_v.vec, i32 8, i1 false) -// CHECK15-NEXT: [[ARRAYINIT_BEGIN:%.*]] = getelementptr inbounds [2 x %struct.S.0], ptr [[S_ARR]], i32 0, i32 0 -// CHECK15-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_BEGIN]], i32 noundef 1) -// CHECK15-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[ARRAYINIT_BEGIN]], i32 1 +// CHECK15-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[S_ARR]], i32 noundef 1) +// CHECK15-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[S_ARR]], i32 1 // CHECK15-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_ELEMENT]], i32 noundef 2) // CHECK15-NEXT: store ptr [[TEST]], ptr [[VAR]], align 4 // CHECK15-NEXT: store ptr undef, ptr [[_TMP1]], align 4 diff --git a/clang/test/OpenMP/distribute_private_codegen.cpp b/clang/test/OpenMP/distribute_private_codegen.cpp index b6e796fb8027c05168fb1fdefce7e3fd79ce5410..7544d429934241c331c2adcbe745b5782c6c0134 100644 --- a/clang/test/OpenMP/distribute_private_codegen.cpp +++ b/clang/test/OpenMP/distribute_private_codegen.cpp @@ -344,9 +344,8 @@ int main() { // CHECK9-NEXT: call void @_ZN1SIfEC1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[TEST]]) // CHECK9-NEXT: store i32 0, ptr [[T_VAR]], align 4 // CHECK9-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 4 [[VEC]], ptr align 4 @__const.main.vec, i64 8, i1 false) -// CHECK9-NEXT: [[ARRAYINIT_BEGIN:%.*]] = getelementptr inbounds [2 x %struct.S], ptr [[S_ARR]], i64 0, i64 0 -// CHECK9-NEXT: call void @_ZN1SIfEC1Ef(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_BEGIN]], float noundef 1.000000e+00) -// CHECK9-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[ARRAYINIT_BEGIN]], i64 1 +// CHECK9-NEXT: call void @_ZN1SIfEC1Ef(ptr noundef nonnull align 4 dereferenceable(4) [[S_ARR]], float noundef 1.000000e+00) +// CHECK9-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[S_ARR]], i64 1 // CHECK9-NEXT: call void @_ZN1SIfEC1Ef(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_ELEMENT]], float noundef 2.000000e+00) // CHECK9-NEXT: store ptr [[TEST]], ptr [[VAR]], align 8 // CHECK9-NEXT: store ptr undef, ptr [[_TMP1]], align 8 @@ -661,9 +660,8 @@ int main() { // CHECK9-NEXT: call void @_ZN1SIiEC1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[TEST]]) // CHECK9-NEXT: store i32 0, ptr [[T_VAR]], align 4 // CHECK9-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 4 [[VEC]], ptr align 4 @__const._Z5tmainIiET_v.vec, i64 8, i1 false) -// CHECK9-NEXT: [[ARRAYINIT_BEGIN:%.*]] = getelementptr inbounds [2 x %struct.S.0], ptr [[S_ARR]], i64 0, i64 0 -// CHECK9-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_BEGIN]], i32 noundef signext 1) -// CHECK9-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[ARRAYINIT_BEGIN]], i64 1 +// CHECK9-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[S_ARR]], i32 noundef signext 1) +// CHECK9-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[S_ARR]], i64 1 // CHECK9-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_ELEMENT]], i32 noundef signext 2) // CHECK9-NEXT: store ptr [[TEST]], ptr [[VAR]], align 8 // CHECK9-NEXT: store ptr undef, ptr [[_TMP1]], align 8 @@ -950,9 +948,8 @@ int main() { // CHECK11-NEXT: call void @_ZN1SIfEC1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[TEST]]) // CHECK11-NEXT: store i32 0, ptr [[T_VAR]], align 4 // CHECK11-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 4 [[VEC]], ptr align 4 @__const.main.vec, i32 8, i1 false) -// CHECK11-NEXT: [[ARRAYINIT_BEGIN:%.*]] = getelementptr inbounds [2 x %struct.S], ptr [[S_ARR]], i32 0, i32 0 -// CHECK11-NEXT: call void @_ZN1SIfEC1Ef(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_BEGIN]], float noundef 1.000000e+00) -// CHECK11-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[ARRAYINIT_BEGIN]], i32 1 +// CHECK11-NEXT: call void @_ZN1SIfEC1Ef(ptr noundef nonnull align 4 dereferenceable(4) [[S_ARR]], float noundef 1.000000e+00) +// CHECK11-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[S_ARR]], i32 1 // CHECK11-NEXT: call void @_ZN1SIfEC1Ef(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_ELEMENT]], float noundef 2.000000e+00) // CHECK11-NEXT: store ptr [[TEST]], ptr [[VAR]], align 4 // CHECK11-NEXT: store ptr undef, ptr [[_TMP1]], align 4 @@ -1265,9 +1262,8 @@ int main() { // CHECK11-NEXT: call void @_ZN1SIiEC1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[TEST]]) // CHECK11-NEXT: store i32 0, ptr [[T_VAR]], align 4 // CHECK11-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 4 [[VEC]], ptr align 4 @__const._Z5tmainIiET_v.vec, i32 8, i1 false) -// CHECK11-NEXT: [[ARRAYINIT_BEGIN:%.*]] = getelementptr inbounds [2 x %struct.S.0], ptr [[S_ARR]], i32 0, i32 0 -// CHECK11-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_BEGIN]], i32 noundef 1) -// CHECK11-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[ARRAYINIT_BEGIN]], i32 1 +// CHECK11-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[S_ARR]], i32 noundef 1) +// CHECK11-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[S_ARR]], i32 1 // CHECK11-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_ELEMENT]], i32 noundef 2) // CHECK11-NEXT: store ptr [[TEST]], ptr [[VAR]], align 4 // CHECK11-NEXT: store ptr undef, ptr [[_TMP1]], align 4 diff --git a/clang/test/OpenMP/distribute_simd_firstprivate_codegen.cpp b/clang/test/OpenMP/distribute_simd_firstprivate_codegen.cpp index 1b5950ce11d7fa2af7edcdfdde6fd55213266424..35284a50c3866672bf81270ac288d430ef4b21ca 100644 --- a/clang/test/OpenMP/distribute_simd_firstprivate_codegen.cpp +++ b/clang/test/OpenMP/distribute_simd_firstprivate_codegen.cpp @@ -546,9 +546,8 @@ int main() { // CHECK9-NEXT: call void @_ZN1SIfEC1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[TEST]]) // CHECK9-NEXT: store i32 0, ptr [[T_VAR]], align 4 // CHECK9-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 4 [[VEC]], ptr align 4 @__const.main.vec, i64 8, i1 false) -// CHECK9-NEXT: [[ARRAYINIT_BEGIN:%.*]] = getelementptr inbounds [2 x %struct.S], ptr [[S_ARR]], i64 0, i64 0 -// CHECK9-NEXT: call void @_ZN1SIfEC1Ef(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_BEGIN]], float noundef 1.000000e+00) -// CHECK9-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[ARRAYINIT_BEGIN]], i64 1 +// CHECK9-NEXT: call void @_ZN1SIfEC1Ef(ptr noundef nonnull align 4 dereferenceable(4) [[S_ARR]], float noundef 1.000000e+00) +// CHECK9-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[S_ARR]], i64 1 // CHECK9-NEXT: call void @_ZN1SIfEC1Ef(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_ELEMENT]], float noundef 2.000000e+00) // CHECK9-NEXT: store ptr [[TEST]], ptr [[VAR]], align 8 // CHECK9-NEXT: [[TMP0:%.*]] = load ptr, ptr [[VAR]], align 8 @@ -858,9 +857,8 @@ int main() { // CHECK9-NEXT: call void @_ZN1SIiEC1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[TEST]]) // CHECK9-NEXT: store i32 0, ptr [[T_VAR]], align 4 // CHECK9-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 4 [[VEC]], ptr align 4 @__const._Z5tmainIiET_v.vec, i64 8, i1 false) -// CHECK9-NEXT: [[ARRAYINIT_BEGIN:%.*]] = getelementptr inbounds [2 x %struct.S.0], ptr [[S_ARR]], i64 0, i64 0 -// CHECK9-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_BEGIN]], i32 noundef signext 1) -// CHECK9-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[ARRAYINIT_BEGIN]], i64 1 +// CHECK9-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[S_ARR]], i32 noundef signext 1) +// CHECK9-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[S_ARR]], i64 1 // CHECK9-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_ELEMENT]], i32 noundef signext 2) // CHECK9-NEXT: store ptr [[TEST]], ptr [[VAR]], align 8 // CHECK9-NEXT: [[TMP0:%.*]] = load ptr, ptr [[VAR]], align 8 @@ -1225,9 +1223,8 @@ int main() { // CHECK11-NEXT: call void @_ZN1SIfEC1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[TEST]]) // CHECK11-NEXT: store i32 0, ptr [[T_VAR]], align 4 // CHECK11-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 4 [[VEC]], ptr align 4 @__const.main.vec, i32 8, i1 false) -// CHECK11-NEXT: [[ARRAYINIT_BEGIN:%.*]] = getelementptr inbounds [2 x %struct.S], ptr [[S_ARR]], i32 0, i32 0 -// CHECK11-NEXT: call void @_ZN1SIfEC1Ef(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_BEGIN]], float noundef 1.000000e+00) -// CHECK11-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[ARRAYINIT_BEGIN]], i32 1 +// CHECK11-NEXT: call void @_ZN1SIfEC1Ef(ptr noundef nonnull align 4 dereferenceable(4) [[S_ARR]], float noundef 1.000000e+00) +// CHECK11-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[S_ARR]], i32 1 // CHECK11-NEXT: call void @_ZN1SIfEC1Ef(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_ELEMENT]], float noundef 2.000000e+00) // CHECK11-NEXT: store ptr [[TEST]], ptr [[VAR]], align 4 // CHECK11-NEXT: [[TMP0:%.*]] = load ptr, ptr [[VAR]], align 4 @@ -1535,9 +1532,8 @@ int main() { // CHECK11-NEXT: call void @_ZN1SIiEC1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[TEST]]) // CHECK11-NEXT: store i32 0, ptr [[T_VAR]], align 4 // CHECK11-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 4 [[VEC]], ptr align 4 @__const._Z5tmainIiET_v.vec, i32 8, i1 false) -// CHECK11-NEXT: [[ARRAYINIT_BEGIN:%.*]] = getelementptr inbounds [2 x %struct.S.0], ptr [[S_ARR]], i32 0, i32 0 -// CHECK11-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_BEGIN]], i32 noundef 1) -// CHECK11-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[ARRAYINIT_BEGIN]], i32 1 +// CHECK11-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[S_ARR]], i32 noundef 1) +// CHECK11-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[S_ARR]], i32 1 // CHECK11-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_ELEMENT]], i32 noundef 2) // CHECK11-NEXT: store ptr [[TEST]], ptr [[VAR]], align 4 // CHECK11-NEXT: [[TMP0:%.*]] = load ptr, ptr [[VAR]], align 4 @@ -1900,9 +1896,8 @@ int main() { // CHECK13-NEXT: call void @_ZN1SIfEC1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[TEST]]) // CHECK13-NEXT: store i32 0, ptr [[T_VAR]], align 4 // CHECK13-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 4 [[VEC]], ptr align 4 @__const.main.vec, i64 8, i1 false) -// CHECK13-NEXT: [[ARRAYINIT_BEGIN:%.*]] = getelementptr inbounds [2 x %struct.S], ptr [[S_ARR]], i64 0, i64 0 -// CHECK13-NEXT: call void @_ZN1SIfEC1Ef(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_BEGIN]], float noundef 1.000000e+00) -// CHECK13-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[ARRAYINIT_BEGIN]], i64 1 +// CHECK13-NEXT: call void @_ZN1SIfEC1Ef(ptr noundef nonnull align 4 dereferenceable(4) [[S_ARR]], float noundef 1.000000e+00) +// CHECK13-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[S_ARR]], i64 1 // CHECK13-NEXT: call void @_ZN1SIfEC1Ef(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_ELEMENT]], float noundef 2.000000e+00) // CHECK13-NEXT: store ptr [[TEST]], ptr [[VAR]], align 8 // CHECK13-NEXT: [[TMP0:%.*]] = load ptr, ptr [[VAR]], align 8 @@ -2007,9 +2002,8 @@ int main() { // CHECK13-NEXT: call void @_ZN1SIiEC1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[TEST]]) // CHECK13-NEXT: store i32 0, ptr [[T_VAR]], align 4 // CHECK13-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 4 [[VEC]], ptr align 4 @__const._Z5tmainIiET_v.vec, i64 8, i1 false) -// CHECK13-NEXT: [[ARRAYINIT_BEGIN:%.*]] = getelementptr inbounds [2 x %struct.S.0], ptr [[S_ARR]], i64 0, i64 0 -// CHECK13-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_BEGIN]], i32 noundef signext 1) -// CHECK13-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[ARRAYINIT_BEGIN]], i64 1 +// CHECK13-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[S_ARR]], i32 noundef signext 1) +// CHECK13-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[S_ARR]], i64 1 // CHECK13-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_ELEMENT]], i32 noundef signext 2) // CHECK13-NEXT: store ptr [[TEST]], ptr [[VAR]], align 8 // CHECK13-NEXT: [[TMP0:%.*]] = load ptr, ptr [[VAR]], align 8 @@ -2205,9 +2199,8 @@ int main() { // CHECK15-NEXT: call void @_ZN1SIfEC1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[TEST]]) // CHECK15-NEXT: store i32 0, ptr [[T_VAR]], align 4 // CHECK15-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 4 [[VEC]], ptr align 4 @__const.main.vec, i32 8, i1 false) -// CHECK15-NEXT: [[ARRAYINIT_BEGIN:%.*]] = getelementptr inbounds [2 x %struct.S], ptr [[S_ARR]], i32 0, i32 0 -// CHECK15-NEXT: call void @_ZN1SIfEC1Ef(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_BEGIN]], float noundef 1.000000e+00) -// CHECK15-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[ARRAYINIT_BEGIN]], i32 1 +// CHECK15-NEXT: call void @_ZN1SIfEC1Ef(ptr noundef nonnull align 4 dereferenceable(4) [[S_ARR]], float noundef 1.000000e+00) +// CHECK15-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[S_ARR]], i32 1 // CHECK15-NEXT: call void @_ZN1SIfEC1Ef(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_ELEMENT]], float noundef 2.000000e+00) // CHECK15-NEXT: store ptr [[TEST]], ptr [[VAR]], align 4 // CHECK15-NEXT: [[TMP0:%.*]] = load ptr, ptr [[VAR]], align 4 @@ -2310,9 +2303,8 @@ int main() { // CHECK15-NEXT: call void @_ZN1SIiEC1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[TEST]]) // CHECK15-NEXT: store i32 0, ptr [[T_VAR]], align 4 // CHECK15-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 4 [[VEC]], ptr align 4 @__const._Z5tmainIiET_v.vec, i32 8, i1 false) -// CHECK15-NEXT: [[ARRAYINIT_BEGIN:%.*]] = getelementptr inbounds [2 x %struct.S.0], ptr [[S_ARR]], i32 0, i32 0 -// CHECK15-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_BEGIN]], i32 noundef 1) -// CHECK15-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[ARRAYINIT_BEGIN]], i32 1 +// CHECK15-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[S_ARR]], i32 noundef 1) +// CHECK15-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[S_ARR]], i32 1 // CHECK15-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_ELEMENT]], i32 noundef 2) // CHECK15-NEXT: store ptr [[TEST]], ptr [[VAR]], align 4 // CHECK15-NEXT: [[TMP0:%.*]] = load ptr, ptr [[VAR]], align 4 diff --git a/clang/test/OpenMP/distribute_simd_lastprivate_codegen.cpp b/clang/test/OpenMP/distribute_simd_lastprivate_codegen.cpp index 92b73b220bcc218e30c0e86b180df8b4aa1636b1..33c488eedf3a9c51ab27c91e98cd7ee3627e5025 100644 --- a/clang/test/OpenMP/distribute_simd_lastprivate_codegen.cpp +++ b/clang/test/OpenMP/distribute_simd_lastprivate_codegen.cpp @@ -533,9 +533,8 @@ int main() { // CHECK9-NEXT: call void @_ZN1SIfEC1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[TEST]]) // CHECK9-NEXT: store i32 0, ptr [[T_VAR]], align 4 // CHECK9-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 4 [[VEC]], ptr align 4 @__const.main.vec, i64 8, i1 false) -// CHECK9-NEXT: [[ARRAYINIT_BEGIN:%.*]] = getelementptr inbounds [2 x %struct.S], ptr [[S_ARR]], i64 0, i64 0 -// CHECK9-NEXT: call void @_ZN1SIfEC1Ef(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_BEGIN]], float noundef 1.000000e+00) -// CHECK9-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[ARRAYINIT_BEGIN]], i64 1 +// CHECK9-NEXT: call void @_ZN1SIfEC1Ef(ptr noundef nonnull align 4 dereferenceable(4) [[S_ARR]], float noundef 1.000000e+00) +// CHECK9-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[S_ARR]], i64 1 // CHECK9-NEXT: call void @_ZN1SIfEC1Ef(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_ELEMENT]], float noundef 2.000000e+00) // CHECK9-NEXT: store ptr [[TEST]], ptr [[VAR]], align 8 // CHECK9-NEXT: [[TMP0:%.*]] = load ptr, ptr [[VAR]], align 8 @@ -863,9 +862,8 @@ int main() { // CHECK9-NEXT: call void @_ZN1SIiEC1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[TEST]]) // CHECK9-NEXT: store i32 0, ptr [[T_VAR]], align 4 // CHECK9-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 4 [[VEC]], ptr align 4 @__const._Z5tmainIiET_v.vec, i64 8, i1 false) -// CHECK9-NEXT: [[ARRAYINIT_BEGIN:%.*]] = getelementptr inbounds [2 x %struct.S.0], ptr [[S_ARR]], i64 0, i64 0 -// CHECK9-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_BEGIN]], i32 noundef signext 1) -// CHECK9-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[ARRAYINIT_BEGIN]], i64 1 +// CHECK9-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[S_ARR]], i32 noundef signext 1) +// CHECK9-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[S_ARR]], i64 1 // CHECK9-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_ELEMENT]], i32 noundef signext 2) // CHECK9-NEXT: store ptr [[TEST]], ptr [[VAR]], align 8 // CHECK9-NEXT: [[TMP0:%.*]] = load ptr, ptr [[VAR]], align 8 @@ -1249,9 +1247,8 @@ int main() { // CHECK11-NEXT: call void @_ZN1SIfEC1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[TEST]]) // CHECK11-NEXT: store i32 0, ptr [[T_VAR]], align 4 // CHECK11-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 4 [[VEC]], ptr align 4 @__const.main.vec, i32 8, i1 false) -// CHECK11-NEXT: [[ARRAYINIT_BEGIN:%.*]] = getelementptr inbounds [2 x %struct.S], ptr [[S_ARR]], i32 0, i32 0 -// CHECK11-NEXT: call void @_ZN1SIfEC1Ef(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_BEGIN]], float noundef 1.000000e+00) -// CHECK11-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[ARRAYINIT_BEGIN]], i32 1 +// CHECK11-NEXT: call void @_ZN1SIfEC1Ef(ptr noundef nonnull align 4 dereferenceable(4) [[S_ARR]], float noundef 1.000000e+00) +// CHECK11-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[S_ARR]], i32 1 // CHECK11-NEXT: call void @_ZN1SIfEC1Ef(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_ELEMENT]], float noundef 2.000000e+00) // CHECK11-NEXT: store ptr [[TEST]], ptr [[VAR]], align 4 // CHECK11-NEXT: [[TMP0:%.*]] = load ptr, ptr [[VAR]], align 4 @@ -1577,9 +1574,8 @@ int main() { // CHECK11-NEXT: call void @_ZN1SIiEC1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[TEST]]) // CHECK11-NEXT: store i32 0, ptr [[T_VAR]], align 4 // CHECK11-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 4 [[VEC]], ptr align 4 @__const._Z5tmainIiET_v.vec, i32 8, i1 false) -// CHECK11-NEXT: [[ARRAYINIT_BEGIN:%.*]] = getelementptr inbounds [2 x %struct.S.0], ptr [[S_ARR]], i32 0, i32 0 -// CHECK11-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_BEGIN]], i32 noundef 1) -// CHECK11-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[ARRAYINIT_BEGIN]], i32 1 +// CHECK11-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[S_ARR]], i32 noundef 1) +// CHECK11-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[S_ARR]], i32 1 // CHECK11-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_ELEMENT]], i32 noundef 2) // CHECK11-NEXT: store ptr [[TEST]], ptr [[VAR]], align 4 // CHECK11-NEXT: [[TMP0:%.*]] = load ptr, ptr [[VAR]], align 4 @@ -1967,9 +1963,8 @@ int main() { // CHECK13-NEXT: call void @_ZN1SIfEC1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[TEST]]) // CHECK13-NEXT: store i32 0, ptr [[T_VAR]], align 4 // CHECK13-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 4 [[VEC]], ptr align 4 @__const.main.vec, i64 8, i1 false) -// CHECK13-NEXT: [[ARRAYINIT_BEGIN:%.*]] = getelementptr inbounds [2 x %struct.S], ptr [[S_ARR]], i64 0, i64 0 -// CHECK13-NEXT: call void @_ZN1SIfEC1Ef(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_BEGIN]], float noundef 1.000000e+00) -// CHECK13-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[ARRAYINIT_BEGIN]], i64 1 +// CHECK13-NEXT: call void @_ZN1SIfEC1Ef(ptr noundef nonnull align 4 dereferenceable(4) [[S_ARR]], float noundef 1.000000e+00) +// CHECK13-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[S_ARR]], i64 1 // CHECK13-NEXT: call void @_ZN1SIfEC1Ef(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_ELEMENT]], float noundef 2.000000e+00) // CHECK13-NEXT: store ptr [[TEST]], ptr [[VAR]], align 8 // CHECK13-NEXT: [[TMP0:%.*]] = load ptr, ptr [[VAR]], align 8 @@ -2135,9 +2130,8 @@ int main() { // CHECK13-NEXT: call void @_ZN1SIiEC1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[TEST]]) // CHECK13-NEXT: store i32 0, ptr [[T_VAR]], align 4 // CHECK13-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 4 [[VEC]], ptr align 4 @__const._Z5tmainIiET_v.vec, i64 8, i1 false) -// CHECK13-NEXT: [[ARRAYINIT_BEGIN:%.*]] = getelementptr inbounds [2 x %struct.S.0], ptr [[S_ARR]], i64 0, i64 0 -// CHECK13-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_BEGIN]], i32 noundef signext 1) -// CHECK13-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[ARRAYINIT_BEGIN]], i64 1 +// CHECK13-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[S_ARR]], i32 noundef signext 1) +// CHECK13-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[S_ARR]], i64 1 // CHECK13-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_ELEMENT]], i32 noundef signext 2) // CHECK13-NEXT: store ptr [[TEST]], ptr [[VAR]], align 8 // CHECK13-NEXT: [[TMP0:%.*]] = load ptr, ptr [[VAR]], align 8 @@ -2374,9 +2368,8 @@ int main() { // CHECK15-NEXT: call void @_ZN1SIfEC1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[TEST]]) // CHECK15-NEXT: store i32 0, ptr [[T_VAR]], align 4 // CHECK15-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 4 [[VEC]], ptr align 4 @__const.main.vec, i32 8, i1 false) -// CHECK15-NEXT: [[ARRAYINIT_BEGIN:%.*]] = getelementptr inbounds [2 x %struct.S], ptr [[S_ARR]], i32 0, i32 0 -// CHECK15-NEXT: call void @_ZN1SIfEC1Ef(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_BEGIN]], float noundef 1.000000e+00) -// CHECK15-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[ARRAYINIT_BEGIN]], i32 1 +// CHECK15-NEXT: call void @_ZN1SIfEC1Ef(ptr noundef nonnull align 4 dereferenceable(4) [[S_ARR]], float noundef 1.000000e+00) +// CHECK15-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[S_ARR]], i32 1 // CHECK15-NEXT: call void @_ZN1SIfEC1Ef(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_ELEMENT]], float noundef 2.000000e+00) // CHECK15-NEXT: store ptr [[TEST]], ptr [[VAR]], align 4 // CHECK15-NEXT: [[TMP0:%.*]] = load ptr, ptr [[VAR]], align 4 @@ -2540,9 +2533,8 @@ int main() { // CHECK15-NEXT: call void @_ZN1SIiEC1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[TEST]]) // CHECK15-NEXT: store i32 0, ptr [[T_VAR]], align 4 // CHECK15-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 4 [[VEC]], ptr align 4 @__const._Z5tmainIiET_v.vec, i32 8, i1 false) -// CHECK15-NEXT: [[ARRAYINIT_BEGIN:%.*]] = getelementptr inbounds [2 x %struct.S.0], ptr [[S_ARR]], i32 0, i32 0 -// CHECK15-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_BEGIN]], i32 noundef 1) -// CHECK15-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[ARRAYINIT_BEGIN]], i32 1 +// CHECK15-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[S_ARR]], i32 noundef 1) +// CHECK15-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[S_ARR]], i32 1 // CHECK15-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_ELEMENT]], i32 noundef 2) // CHECK15-NEXT: store ptr [[TEST]], ptr [[VAR]], align 4 // CHECK15-NEXT: [[TMP0:%.*]] = load ptr, ptr [[VAR]], align 4 diff --git a/clang/test/OpenMP/distribute_simd_private_codegen.cpp b/clang/test/OpenMP/distribute_simd_private_codegen.cpp index 93b2bd8b12a8ee3b738b7b950d7bf4c3c9a08799..534903e0afbe77ea5c824402d06fef8610372122 100644 --- a/clang/test/OpenMP/distribute_simd_private_codegen.cpp +++ b/clang/test/OpenMP/distribute_simd_private_codegen.cpp @@ -389,9 +389,8 @@ int main() { // CHECK9-NEXT: call void @_ZN1SIfEC1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[TEST]]) // CHECK9-NEXT: store i32 0, ptr [[T_VAR]], align 4 // CHECK9-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 4 [[VEC]], ptr align 4 @__const.main.vec, i64 8, i1 false) -// CHECK9-NEXT: [[ARRAYINIT_BEGIN:%.*]] = getelementptr inbounds [2 x %struct.S], ptr [[S_ARR]], i64 0, i64 0 -// CHECK9-NEXT: call void @_ZN1SIfEC1Ef(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_BEGIN]], float noundef 1.000000e+00) -// CHECK9-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[ARRAYINIT_BEGIN]], i64 1 +// CHECK9-NEXT: call void @_ZN1SIfEC1Ef(ptr noundef nonnull align 4 dereferenceable(4) [[S_ARR]], float noundef 1.000000e+00) +// CHECK9-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[S_ARR]], i64 1 // CHECK9-NEXT: call void @_ZN1SIfEC1Ef(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_ELEMENT]], float noundef 2.000000e+00) // CHECK9-NEXT: store ptr [[TEST]], ptr [[VAR]], align 8 // CHECK9-NEXT: store ptr undef, ptr [[_TMP1]], align 8 @@ -735,9 +734,8 @@ int main() { // CHECK9-NEXT: call void @_ZN1SIiEC1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[TEST]]) // CHECK9-NEXT: store i32 0, ptr [[T_VAR]], align 4 // CHECK9-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 4 [[VEC]], ptr align 4 @__const._Z5tmainIiET_v.vec, i64 8, i1 false) -// CHECK9-NEXT: [[ARRAYINIT_BEGIN:%.*]] = getelementptr inbounds [2 x %struct.S.0], ptr [[S_ARR]], i64 0, i64 0 -// CHECK9-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_BEGIN]], i32 noundef signext 1) -// CHECK9-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[ARRAYINIT_BEGIN]], i64 1 +// CHECK9-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[S_ARR]], i32 noundef signext 1) +// CHECK9-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[S_ARR]], i64 1 // CHECK9-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_ELEMENT]], i32 noundef signext 2) // CHECK9-NEXT: store ptr [[TEST]], ptr [[VAR]], align 8 // CHECK9-NEXT: store ptr undef, ptr [[_TMP1]], align 8 @@ -1035,9 +1033,8 @@ int main() { // CHECK11-NEXT: call void @_ZN1SIfEC1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[TEST]]) // CHECK11-NEXT: store i32 0, ptr [[T_VAR]], align 4 // CHECK11-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 4 [[VEC]], ptr align 4 @__const.main.vec, i32 8, i1 false) -// CHECK11-NEXT: [[ARRAYINIT_BEGIN:%.*]] = getelementptr inbounds [2 x %struct.S], ptr [[S_ARR]], i32 0, i32 0 -// CHECK11-NEXT: call void @_ZN1SIfEC1Ef(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_BEGIN]], float noundef 1.000000e+00) -// CHECK11-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[ARRAYINIT_BEGIN]], i32 1 +// CHECK11-NEXT: call void @_ZN1SIfEC1Ef(ptr noundef nonnull align 4 dereferenceable(4) [[S_ARR]], float noundef 1.000000e+00) +// CHECK11-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[S_ARR]], i32 1 // CHECK11-NEXT: call void @_ZN1SIfEC1Ef(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_ELEMENT]], float noundef 2.000000e+00) // CHECK11-NEXT: store ptr [[TEST]], ptr [[VAR]], align 4 // CHECK11-NEXT: store ptr undef, ptr [[_TMP1]], align 4 @@ -1379,9 +1376,8 @@ int main() { // CHECK11-NEXT: call void @_ZN1SIiEC1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[TEST]]) // CHECK11-NEXT: store i32 0, ptr [[T_VAR]], align 4 // CHECK11-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 4 [[VEC]], ptr align 4 @__const._Z5tmainIiET_v.vec, i32 8, i1 false) -// CHECK11-NEXT: [[ARRAYINIT_BEGIN:%.*]] = getelementptr inbounds [2 x %struct.S.0], ptr [[S_ARR]], i32 0, i32 0 -// CHECK11-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_BEGIN]], i32 noundef 1) -// CHECK11-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[ARRAYINIT_BEGIN]], i32 1 +// CHECK11-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[S_ARR]], i32 noundef 1) +// CHECK11-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[S_ARR]], i32 1 // CHECK11-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_ELEMENT]], i32 noundef 2) // CHECK11-NEXT: store ptr [[TEST]], ptr [[VAR]], align 4 // CHECK11-NEXT: store ptr undef, ptr [[_TMP1]], align 4 @@ -1685,9 +1681,8 @@ int main() { // CHECK13-NEXT: call void @_ZN1SIfEC1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[TEST]]) // CHECK13-NEXT: store i32 0, ptr [[T_VAR]], align 4 // CHECK13-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 4 [[VEC]], ptr align 4 @__const.main.vec, i64 8, i1 false) -// CHECK13-NEXT: [[ARRAYINIT_BEGIN:%.*]] = getelementptr inbounds [2 x %struct.S], ptr [[S_ARR]], i64 0, i64 0 -// CHECK13-NEXT: call void @_ZN1SIfEC1Ef(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_BEGIN]], float noundef 1.000000e+00) -// CHECK13-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[ARRAYINIT_BEGIN]], i64 1 +// CHECK13-NEXT: call void @_ZN1SIfEC1Ef(ptr noundef nonnull align 4 dereferenceable(4) [[S_ARR]], float noundef 1.000000e+00) +// CHECK13-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[S_ARR]], i64 1 // CHECK13-NEXT: call void @_ZN1SIfEC1Ef(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_ELEMENT]], float noundef 2.000000e+00) // CHECK13-NEXT: store ptr [[TEST]], ptr [[VAR]], align 8 // CHECK13-NEXT: store ptr undef, ptr [[_TMP1]], align 8 @@ -1849,9 +1844,8 @@ int main() { // CHECK13-NEXT: call void @_ZN1SIiEC1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[TEST]]) // CHECK13-NEXT: store i32 0, ptr [[T_VAR]], align 4 // CHECK13-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 4 [[VEC]], ptr align 4 @__const._Z5tmainIiET_v.vec, i64 8, i1 false) -// CHECK13-NEXT: [[ARRAYINIT_BEGIN:%.*]] = getelementptr inbounds [2 x %struct.S.0], ptr [[S_ARR]], i64 0, i64 0 -// CHECK13-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_BEGIN]], i32 noundef signext 1) -// CHECK13-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[ARRAYINIT_BEGIN]], i64 1 +// CHECK13-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[S_ARR]], i32 noundef signext 1) +// CHECK13-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[S_ARR]], i64 1 // CHECK13-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_ELEMENT]], i32 noundef signext 2) // CHECK13-NEXT: store ptr [[TEST]], ptr [[VAR]], align 8 // CHECK13-NEXT: store ptr undef, ptr [[_TMP1]], align 8 @@ -2066,9 +2060,8 @@ int main() { // CHECK15-NEXT: call void @_ZN1SIfEC1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[TEST]]) // CHECK15-NEXT: store i32 0, ptr [[T_VAR]], align 4 // CHECK15-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 4 [[VEC]], ptr align 4 @__const.main.vec, i32 8, i1 false) -// CHECK15-NEXT: [[ARRAYINIT_BEGIN:%.*]] = getelementptr inbounds [2 x %struct.S], ptr [[S_ARR]], i32 0, i32 0 -// CHECK15-NEXT: call void @_ZN1SIfEC1Ef(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_BEGIN]], float noundef 1.000000e+00) -// CHECK15-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[ARRAYINIT_BEGIN]], i32 1 +// CHECK15-NEXT: call void @_ZN1SIfEC1Ef(ptr noundef nonnull align 4 dereferenceable(4) [[S_ARR]], float noundef 1.000000e+00) +// CHECK15-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[S_ARR]], i32 1 // CHECK15-NEXT: call void @_ZN1SIfEC1Ef(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_ELEMENT]], float noundef 2.000000e+00) // CHECK15-NEXT: store ptr [[TEST]], ptr [[VAR]], align 4 // CHECK15-NEXT: store ptr undef, ptr [[_TMP1]], align 4 @@ -2228,9 +2221,8 @@ int main() { // CHECK15-NEXT: call void @_ZN1SIiEC1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[TEST]]) // CHECK15-NEXT: store i32 0, ptr [[T_VAR]], align 4 // CHECK15-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 4 [[VEC]], ptr align 4 @__const._Z5tmainIiET_v.vec, i32 8, i1 false) -// CHECK15-NEXT: [[ARRAYINIT_BEGIN:%.*]] = getelementptr inbounds [2 x %struct.S.0], ptr [[S_ARR]], i32 0, i32 0 -// CHECK15-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_BEGIN]], i32 noundef 1) -// CHECK15-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[ARRAYINIT_BEGIN]], i32 1 +// CHECK15-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[S_ARR]], i32 noundef 1) +// CHECK15-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[S_ARR]], i32 1 // CHECK15-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_ELEMENT]], i32 noundef 2) // CHECK15-NEXT: store ptr [[TEST]], ptr [[VAR]], align 4 // CHECK15-NEXT: store ptr undef, ptr [[_TMP1]], align 4 diff --git a/clang/test/OpenMP/error_unsupport_feature.c b/clang/test/OpenMP/error_unsupport_feature.c new file mode 100644 index 0000000000000000000000000000000000000000..eb381b3bea1e1ac36c390dd4945dbcd7db5809f1 --- /dev/null +++ b/clang/test/OpenMP/error_unsupport_feature.c @@ -0,0 +1,8 @@ +// RUN: %clang_cc1 -emit-llvm-only -verify -fopenmp %s + +int main () { + int r = 0; +#pragma omp scope reduction(+:r) // expected-error {{cannot compile this scope with FE outlining yet}} + r++; + return r; +} diff --git a/clang/test/OpenMP/for_firstprivate_codegen.cpp b/clang/test/OpenMP/for_firstprivate_codegen.cpp index 79f76bd0f4482a149bd1f9f4822051b46e0fba2e..6f51b82668be3bafde507aa578c77b123c0f8333 100644 --- a/clang/test/OpenMP/for_firstprivate_codegen.cpp +++ b/clang/test/OpenMP/for_firstprivate_codegen.cpp @@ -423,9 +423,8 @@ int main() { // CHECK1-NEXT: call void @_ZN1SIiEC1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[TEST]]) // CHECK1-NEXT: store i32 0, ptr [[T_VAR]], align 4 // CHECK1-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 4 [[VEC]], ptr align 4 @__const._Z5tmainIiET_v.vec, i64 8, i1 false) -// CHECK1-NEXT: [[ARRAYINIT_BEGIN:%.*]] = getelementptr inbounds [2 x %struct.S.0], ptr [[S_ARR]], i64 0, i64 0 -// CHECK1-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_BEGIN]], i32 noundef 1) -// CHECK1-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[ARRAYINIT_BEGIN]], i64 1 +// CHECK1-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[S_ARR]], i32 noundef 1) +// CHECK1-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[S_ARR]], i64 1 // CHECK1-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_ELEMENT]], i32 noundef 2) // CHECK1-NEXT: store ptr [[TEST]], ptr [[VAR]], align 8 // CHECK1-NEXT: [[TMP0:%.*]] = load ptr, ptr [[VAR]], align 8 diff --git a/clang/test/OpenMP/for_lastprivate_codegen.cpp b/clang/test/OpenMP/for_lastprivate_codegen.cpp index c7ef60afcfc03293d695400a3d600127cafa86c6..f89969d85a3204764e95aa94274fad76ab98374c 100644 --- a/clang/test/OpenMP/for_lastprivate_codegen.cpp +++ b/clang/test/OpenMP/for_lastprivate_codegen.cpp @@ -374,9 +374,8 @@ int main() { // CHECK1-NEXT: call void @_ZN1SIfEC1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[TEST]]) // CHECK1-NEXT: store i32 0, ptr [[T_VAR]], align 4 // CHECK1-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 4 [[VEC]], ptr align 4 @__const.main.vec, i64 8, i1 false) -// CHECK1-NEXT: [[ARRAYINIT_BEGIN:%.*]] = getelementptr inbounds [2 x %struct.S], ptr [[S_ARR]], i64 0, i64 0 -// CHECK1-NEXT: call void @_ZN1SIfEC1Ef(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_BEGIN]], float noundef 1.000000e+00) -// CHECK1-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[ARRAYINIT_BEGIN]], i64 1 +// CHECK1-NEXT: call void @_ZN1SIfEC1Ef(ptr noundef nonnull align 4 dereferenceable(4) [[S_ARR]], float noundef 1.000000e+00) +// CHECK1-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[S_ARR]], i64 1 // CHECK1-NEXT: call void @_ZN1SIfEC1Ef(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_ELEMENT]], float noundef 2.000000e+00) // CHECK1-NEXT: call void @_ZN1SIfEC1Ef(ptr noundef nonnull align 4 dereferenceable(4) [[VAR]], float noundef 3.000000e+00) // CHECK1-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr @[[GLOB3:[0-9]+]], i32 5, ptr @main.omp_outlined, ptr [[T_VAR]], ptr [[VEC]], ptr [[S_ARR]], ptr [[VAR]], ptr @_ZZ4mainE5sivar) @@ -848,9 +847,8 @@ int main() { // CHECK1-NEXT: call void @_ZN3SSTIiEC1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[SST]]) // CHECK1-NEXT: store i32 0, ptr [[T_VAR]], align 128 // CHECK1-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 128 [[VEC]], ptr align 128 @__const._Z5tmainIiET_v.vec, i64 8, i1 false) -// CHECK1-NEXT: [[ARRAYINIT_BEGIN:%.*]] = getelementptr inbounds [2 x %struct.S.0], ptr [[S_ARR]], i64 0, i64 0 -// CHECK1-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_BEGIN]], i32 noundef 1) -// CHECK1-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[ARRAYINIT_BEGIN]], i64 1 +// CHECK1-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[S_ARR]], i32 noundef 1) +// CHECK1-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[S_ARR]], i64 1 // CHECK1-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_ELEMENT]], i32 noundef 2) // CHECK1-NEXT: store ptr [[TEST]], ptr [[VAR]], align 128 // CHECK1-NEXT: [[TMP0:%.*]] = load ptr, ptr [[VAR]], align 128 @@ -2798,9 +2796,8 @@ int main() { // CHECK5-NEXT: call void @_ZN1SIfEC1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[TEST]]) // CHECK5-NEXT: store i32 0, ptr [[T_VAR]], align 4 // CHECK5-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 4 [[VEC]], ptr align 4 @__const.main.vec, i64 8, i1 false) -// CHECK5-NEXT: [[ARRAYINIT_BEGIN:%.*]] = getelementptr inbounds [2 x %struct.S], ptr [[S_ARR]], i64 0, i64 0 -// CHECK5-NEXT: call void @_ZN1SIfEC1Ef(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_BEGIN]], float noundef 1.000000e+00) -// CHECK5-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[ARRAYINIT_BEGIN]], i64 1 +// CHECK5-NEXT: call void @_ZN1SIfEC1Ef(ptr noundef nonnull align 4 dereferenceable(4) [[S_ARR]], float noundef 1.000000e+00) +// CHECK5-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[S_ARR]], i64 1 // CHECK5-NEXT: call void @_ZN1SIfEC1Ef(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_ELEMENT]], float noundef 2.000000e+00) // CHECK5-NEXT: call void @_ZN1SIfEC1Ef(ptr noundef nonnull align 4 dereferenceable(4) [[VAR]], float noundef 3.000000e+00) // CHECK5-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr @[[GLOB3:[0-9]+]], i32 5, ptr @main.omp_outlined, ptr [[T_VAR]], ptr [[VEC]], ptr [[S_ARR]], ptr [[VAR]], ptr @_ZZ4mainE5sivar) @@ -3290,9 +3287,8 @@ int main() { // CHECK5-NEXT: call void @_ZN3SSTIiEC1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[SST]]) // CHECK5-NEXT: store i32 0, ptr [[T_VAR]], align 128 // CHECK5-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 128 [[VEC]], ptr align 128 @__const._Z5tmainIiET_v.vec, i64 8, i1 false) -// CHECK5-NEXT: [[ARRAYINIT_BEGIN:%.*]] = getelementptr inbounds [2 x %struct.S.0], ptr [[S_ARR]], i64 0, i64 0 -// CHECK5-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_BEGIN]], i32 noundef 1) -// CHECK5-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[ARRAYINIT_BEGIN]], i64 1 +// CHECK5-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[S_ARR]], i32 noundef 1) +// CHECK5-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[S_ARR]], i64 1 // CHECK5-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_ELEMENT]], i32 noundef 2) // CHECK5-NEXT: store ptr [[TEST]], ptr [[VAR]], align 128 // CHECK5-NEXT: [[TMP0:%.*]] = load ptr, ptr [[VAR]], align 128 diff --git a/clang/test/OpenMP/for_private_codegen.cpp b/clang/test/OpenMP/for_private_codegen.cpp index 463e5305e9fb667cfa6f60531d7da7a72b54370f..d140f0f51cdf1e8264cbe812b6fff24c3e209199 100644 --- a/clang/test/OpenMP/for_private_codegen.cpp +++ b/clang/test/OpenMP/for_private_codegen.cpp @@ -121,9 +121,8 @@ int main() { // CHECK1-NEXT: call void @_ZN1SIfEC1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[TEST]]) // CHECK1-NEXT: store i32 0, ptr [[T_VAR]], align 4 // CHECK1-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 4 [[VEC]], ptr align 4 @__const.main.vec, i64 8, i1 false) -// CHECK1-NEXT: [[ARRAYINIT_BEGIN:%.*]] = getelementptr inbounds [2 x %struct.S], ptr [[S_ARR]], i64 0, i64 0 -// CHECK1-NEXT: call void @_ZN1SIfEC1Ef(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_BEGIN]], float noundef 1.000000e+00) -// CHECK1-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[ARRAYINIT_BEGIN]], i64 1 +// CHECK1-NEXT: call void @_ZN1SIfEC1Ef(ptr noundef nonnull align 4 dereferenceable(4) [[S_ARR]], float noundef 1.000000e+00) +// CHECK1-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[S_ARR]], i64 1 // CHECK1-NEXT: call void @_ZN1SIfEC1Ef(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_ELEMENT]], float noundef 2.000000e+00) // CHECK1-NEXT: store ptr [[TEST]], ptr [[VAR]], align 8 // CHECK1-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr @[[GLOB3:[0-9]+]], i32 0, ptr @main.omp_outlined) @@ -360,9 +359,8 @@ int main() { // CHECK1-NEXT: call void @_ZN1SIiEC1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[TEST]]) // CHECK1-NEXT: store i32 0, ptr [[T_VAR]], align 4 // CHECK1-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 4 [[VEC]], ptr align 4 @__const._Z5tmainIiET_v.vec, i64 8, i1 false) -// CHECK1-NEXT: [[ARRAYINIT_BEGIN:%.*]] = getelementptr inbounds [2 x %struct.S.0], ptr [[S_ARR]], i64 0, i64 0 -// CHECK1-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_BEGIN]], i32 noundef 1) -// CHECK1-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[ARRAYINIT_BEGIN]], i64 1 +// CHECK1-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[S_ARR]], i32 noundef 1) +// CHECK1-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[S_ARR]], i64 1 // CHECK1-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_ELEMENT]], i32 noundef 2) // CHECK1-NEXT: store ptr [[TEST]], ptr [[VAR]], align 8 // CHECK1-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr @[[GLOB3]], i32 0, ptr @_Z5tmainIiET_v.omp_outlined) diff --git a/clang/test/OpenMP/for_reduction_codegen.cpp b/clang/test/OpenMP/for_reduction_codegen.cpp index d025c6d6e571f88774cb764073ad4cb2bbe71d96..498845d1f4d15c1634c24a83e851968eb71c8604 100644 --- a/clang/test/OpenMP/for_reduction_codegen.cpp +++ b/clang/test/OpenMP/for_reduction_codegen.cpp @@ -556,13 +556,12 @@ int main() { // CHECK1-NEXT: call void @_ZN1SIfEC1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[TEST]]) // CHECK1-NEXT: store float 0.000000e+00, ptr [[T_VAR]], align 4 // CHECK1-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 4 [[VEC]], ptr align 4 @__const.main.vec, i64 8, i1 false) -// CHECK1-NEXT: [[ARRAYINIT_BEGIN:%.*]] = getelementptr inbounds [4 x %struct.S], ptr [[S_ARR]], i64 0, i64 0 -// CHECK1-NEXT: call void @_ZN1SIfEC1Ef(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_BEGIN]], float noundef 1.000000e+00) -// CHECK1-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[ARRAYINIT_BEGIN]], i64 1 +// CHECK1-NEXT: call void @_ZN1SIfEC1Ef(ptr noundef nonnull align 4 dereferenceable(4) [[S_ARR]], float noundef 1.000000e+00) +// CHECK1-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[S_ARR]], i64 1 // CHECK1-NEXT: call void @_ZN1SIfEC1Ef(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_ELEMENT]], float noundef 2.000000e+00) -// CHECK1-NEXT: [[ARRAYINIT_ELEMENT1:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[ARRAYINIT_ELEMENT]], i64 1 +// CHECK1-NEXT: [[ARRAYINIT_ELEMENT1:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[S_ARR]], i64 2 // CHECK1-NEXT: call void @_ZN1SIfEC1Ef(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_ELEMENT1]], float noundef 3.000000e+00) -// CHECK1-NEXT: [[ARRAYINIT_ELEMENT2:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[ARRAYINIT_ELEMENT1]], i64 1 +// CHECK1-NEXT: [[ARRAYINIT_ELEMENT2:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[S_ARR]], i64 3 // CHECK1-NEXT: call void @_ZN1SIfEC1Ef(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_ELEMENT2]], float noundef 4.000000e+00) // CHECK1-NEXT: store ptr [[TEST]], ptr [[VAR]], align 8 // CHECK1-NEXT: call void @_ZN1SIfEC1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[VAR1]]) @@ -3377,9 +3376,8 @@ int main() { // CHECK1-NEXT: call void @_ZN1SIiEC1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[TEST]]) // CHECK1-NEXT: store i32 0, ptr [[T_VAR]], align 4 // CHECK1-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 4 [[VEC]], ptr align 4 @__const._Z5tmainIiLi42EET_v.vec, i64 8, i1 false) -// CHECK1-NEXT: [[ARRAYINIT_BEGIN:%.*]] = getelementptr inbounds [2 x %struct.S.0], ptr [[S_ARR]], i64 0, i64 0 -// CHECK1-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_BEGIN]], i32 noundef 1) -// CHECK1-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[ARRAYINIT_BEGIN]], i64 1 +// CHECK1-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[S_ARR]], i32 noundef 1) +// CHECK1-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[S_ARR]], i64 1 // CHECK1-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_ELEMENT]], i32 noundef 2) // CHECK1-NEXT: store ptr [[TEST]], ptr [[VAR]], align 8 // CHECK1-NEXT: call void @_ZN1SIiEC1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[VAR1]]) diff --git a/clang/test/OpenMP/for_reduction_codegen_UDR.cpp b/clang/test/OpenMP/for_reduction_codegen_UDR.cpp index 999e062bbe264d278b84ba546ccdd2e6f2b4cb09..f0ab531e1d9924c529694cdd7dfefc5213e1daab 100644 --- a/clang/test/OpenMP/for_reduction_codegen_UDR.cpp +++ b/clang/test/OpenMP/for_reduction_codegen_UDR.cpp @@ -622,13 +622,12 @@ int main() { // CHECK1-NEXT: call void @_ZN1SIfEC1Ev(ptr noundef nonnull align 4 dereferenceable(12) [[TEST]]) // CHECK1-NEXT: store float 0.000000e+00, ptr [[T_VAR]], align 4 // CHECK1-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 4 [[VEC]], ptr align 4 @__const.main.vec, i64 8, i1 false) -// CHECK1-NEXT: [[ARRAYINIT_BEGIN:%.*]] = getelementptr inbounds [4 x %struct.S.0], ptr [[S_ARR]], i64 0, i64 0 -// CHECK1-NEXT: call void @_ZN1SIfEC1Ef(ptr noundef nonnull align 4 dereferenceable(12) [[ARRAYINIT_BEGIN]], float noundef 1.000000e+00) -// CHECK1-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[ARRAYINIT_BEGIN]], i64 1 +// CHECK1-NEXT: call void @_ZN1SIfEC1Ef(ptr noundef nonnull align 4 dereferenceable(12) [[S_ARR]], float noundef 1.000000e+00) +// CHECK1-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[S_ARR]], i64 1 // CHECK1-NEXT: call void @_ZN1SIfEC1Ef(ptr noundef nonnull align 4 dereferenceable(12) [[ARRAYINIT_ELEMENT]], float noundef 2.000000e+00) -// CHECK1-NEXT: [[ARRAYINIT_ELEMENT1:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[ARRAYINIT_ELEMENT]], i64 1 +// CHECK1-NEXT: [[ARRAYINIT_ELEMENT1:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[S_ARR]], i64 2 // CHECK1-NEXT: call void @_ZN1SIfEC1Ef(ptr noundef nonnull align 4 dereferenceable(12) [[ARRAYINIT_ELEMENT1]], float noundef 3.000000e+00) -// CHECK1-NEXT: [[ARRAYINIT_ELEMENT2:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[ARRAYINIT_ELEMENT1]], i64 1 +// CHECK1-NEXT: [[ARRAYINIT_ELEMENT2:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[S_ARR]], i64 3 // CHECK1-NEXT: call void @_ZN1SIfEC1Ef(ptr noundef nonnull align 4 dereferenceable(12) [[ARRAYINIT_ELEMENT2]], float noundef 4.000000e+00) // CHECK1-NEXT: store ptr [[TEST]], ptr [[VAR]], align 8 // CHECK1-NEXT: call void @_ZN1SIfEC1Ev(ptr noundef nonnull align 4 dereferenceable(12) [[VAR1]]) @@ -2421,9 +2420,8 @@ int main() { // CHECK1-NEXT: call void @_ZN1SIiEC1Ev(ptr noundef nonnull align 4 dereferenceable(12) [[TEST]]) // CHECK1-NEXT: store i32 0, ptr [[T_VAR]], align 4 // CHECK1-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 4 [[VEC]], ptr align 4 @__const._Z5tmainIiLi42EET_v.vec, i64 8, i1 false) -// CHECK1-NEXT: [[ARRAYINIT_BEGIN:%.*]] = getelementptr inbounds [2 x %struct.S], ptr [[S_ARR]], i64 0, i64 0 -// CHECK1-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(12) [[ARRAYINIT_BEGIN]], i32 noundef 1) -// CHECK1-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[ARRAYINIT_BEGIN]], i64 1 +// CHECK1-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(12) [[S_ARR]], i32 noundef 1) +// CHECK1-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[S_ARR]], i64 1 // CHECK1-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(12) [[ARRAYINIT_ELEMENT]], i32 noundef 2) // CHECK1-NEXT: store ptr [[TEST]], ptr [[VAR]], align 8 // CHECK1-NEXT: call void @_ZN1SIiEC1Ev(ptr noundef nonnull align 4 dereferenceable(12) [[VAR1]]) @@ -3318,13 +3316,12 @@ int main() { // CHECK3-NEXT: call void @_ZN1SIfEC1Ev(ptr noundef nonnull align 4 dereferenceable(12) [[TEST]]) // CHECK3-NEXT: store float 0.000000e+00, ptr [[T_VAR]], align 4 // CHECK3-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 4 [[VEC]], ptr align 4 @__const.main.vec, i64 8, i1 false) -// CHECK3-NEXT: [[ARRAYINIT_BEGIN:%.*]] = getelementptr inbounds [4 x %struct.S.0], ptr [[S_ARR]], i64 0, i64 0 -// CHECK3-NEXT: call void @_ZN1SIfEC1Ef(ptr noundef nonnull align 4 dereferenceable(12) [[ARRAYINIT_BEGIN]], float noundef 1.000000e+00) -// CHECK3-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[ARRAYINIT_BEGIN]], i64 1 +// CHECK3-NEXT: call void @_ZN1SIfEC1Ef(ptr noundef nonnull align 4 dereferenceable(12) [[S_ARR]], float noundef 1.000000e+00) +// CHECK3-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[S_ARR]], i64 1 // CHECK3-NEXT: call void @_ZN1SIfEC1Ef(ptr noundef nonnull align 4 dereferenceable(12) [[ARRAYINIT_ELEMENT]], float noundef 2.000000e+00) -// CHECK3-NEXT: [[ARRAYINIT_ELEMENT1:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[ARRAYINIT_ELEMENT]], i64 1 +// CHECK3-NEXT: [[ARRAYINIT_ELEMENT1:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[S_ARR]], i64 2 // CHECK3-NEXT: call void @_ZN1SIfEC1Ef(ptr noundef nonnull align 4 dereferenceable(12) [[ARRAYINIT_ELEMENT1]], float noundef 3.000000e+00) -// CHECK3-NEXT: [[ARRAYINIT_ELEMENT2:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[ARRAYINIT_ELEMENT1]], i64 1 +// CHECK3-NEXT: [[ARRAYINIT_ELEMENT2:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[S_ARR]], i64 3 // CHECK3-NEXT: call void @_ZN1SIfEC1Ef(ptr noundef nonnull align 4 dereferenceable(12) [[ARRAYINIT_ELEMENT2]], float noundef 4.000000e+00) // CHECK3-NEXT: store ptr [[TEST]], ptr [[VAR]], align 8 // CHECK3-NEXT: call void @_ZN1SIfEC1Ev(ptr noundef nonnull align 4 dereferenceable(12) [[VAR1]]) @@ -3584,9 +3581,8 @@ int main() { // CHECK3-NEXT: call void @_ZN1SIiEC1Ev(ptr noundef nonnull align 4 dereferenceable(12) [[TEST]]) // CHECK3-NEXT: store i32 0, ptr [[T_VAR]], align 4 // CHECK3-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 4 [[VEC]], ptr align 4 @__const._Z5tmainIiLi42EET_v.vec, i64 8, i1 false) -// CHECK3-NEXT: [[ARRAYINIT_BEGIN:%.*]] = getelementptr inbounds [2 x %struct.S], ptr [[S_ARR]], i64 0, i64 0 -// CHECK3-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(12) [[ARRAYINIT_BEGIN]], i32 noundef 1) -// CHECK3-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[ARRAYINIT_BEGIN]], i64 1 +// CHECK3-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(12) [[S_ARR]], i32 noundef 1) +// CHECK3-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[S_ARR]], i64 1 // CHECK3-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(12) [[ARRAYINIT_ELEMENT]], i32 noundef 2) // CHECK3-NEXT: store ptr [[TEST]], ptr [[VAR]], align 8 // CHECK3-NEXT: call void @_ZN1SIiEC1Ev(ptr noundef nonnull align 4 dereferenceable(12) [[VAR1]]) diff --git a/clang/test/OpenMP/parallel_copyin_codegen.cpp b/clang/test/OpenMP/parallel_copyin_codegen.cpp index 57a563d49b31e89c6768dab35d4bd08c3c099e08..e653a7734161b724bba7fcffa85bc22194598a5f 100644 --- a/clang/test/OpenMP/parallel_copyin_codegen.cpp +++ b/clang/test/OpenMP/parallel_copyin_codegen.cpp @@ -297,9 +297,8 @@ void foo() { // CHECK1-NEXT: [[DOTADDR:%.*]] = alloca ptr, align 8 // CHECK1-NEXT: store ptr [[TMP0]], ptr [[DOTADDR]], align 8 // CHECK1-NEXT: [[TMP1:%.*]] = load ptr, ptr [[DOTADDR]], align 8 -// CHECK1-NEXT: [[ARRAYINIT_BEGIN:%.*]] = getelementptr inbounds [2 x %struct.S], ptr [[TMP1]], i64 0, i64 0 -// CHECK1-NEXT: call void @_ZN1SIfEC1Ef(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_BEGIN]], float noundef 1.000000e+00) -// CHECK1-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S:%.*]], ptr [[ARRAYINIT_BEGIN]], i64 1 +// CHECK1-NEXT: call void @_ZN1SIfEC1Ef(ptr noundef nonnull align 4 dereferenceable(4) [[TMP1]], float noundef 1.000000e+00) +// CHECK1-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S:%.*]], ptr [[TMP1]], i64 1 // CHECK1-NEXT: call void @_ZN1SIfEC1Ef(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_ELEMENT]], float noundef 2.000000e+00) // CHECK1-NEXT: [[TMP2:%.*]] = load ptr, ptr [[DOTADDR]], align 8 // CHECK1-NEXT: ret ptr [[TMP2]] @@ -574,9 +573,8 @@ void foo() { // CHECK1-NEXT: [[DOTADDR:%.*]] = alloca ptr, align 8 // CHECK1-NEXT: store ptr [[TMP0]], ptr [[DOTADDR]], align 8 // CHECK1-NEXT: [[TMP1:%.*]] = load ptr, ptr [[DOTADDR]], align 8 -// CHECK1-NEXT: [[ARRAYINIT_BEGIN:%.*]] = getelementptr inbounds [2 x %struct.S.0], ptr [[TMP1]], i64 0, i64 0 -// CHECK1-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_BEGIN]], i32 noundef 1) -// CHECK1-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S_0:%.*]], ptr [[ARRAYINIT_BEGIN]], i64 1 +// CHECK1-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[TMP1]], i32 noundef 1) +// CHECK1-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S_0:%.*]], ptr [[TMP1]], i64 1 // CHECK1-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_ELEMENT]], i32 noundef 2) // CHECK1-NEXT: [[TMP2:%.*]] = load ptr, ptr [[DOTADDR]], align 8 // CHECK1-NEXT: ret ptr [[TMP2]] diff --git a/clang/test/OpenMP/parallel_firstprivate_codegen.cpp b/clang/test/OpenMP/parallel_firstprivate_codegen.cpp index e5374c384d2ab2423ffa22134e1a03fa8a026f88..1cfba8c3159584ee37b319b44d57a0a2cc590d89 100644 --- a/clang/test/OpenMP/parallel_firstprivate_codegen.cpp +++ b/clang/test/OpenMP/parallel_firstprivate_codegen.cpp @@ -258,9 +258,8 @@ void array_func(float a[3], St s[2], int n, long double vla1[n]) { // CHECK1-NEXT: call void @_ZN1SIfEC1Ev(ptr nonnull align 4 dereferenceable(4) [[TEST]]) // CHECK1-NEXT: store i32 0, ptr [[T_VAR]], align 4 // CHECK1-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 4 [[VEC]], ptr align 4 @__const.main.vec, i32 8, i1 false) -// CHECK1-NEXT: [[ARRAYINIT_BEGIN:%.*]] = getelementptr inbounds [2 x %struct.S], ptr [[S_ARR]], i32 0, i32 0 -// CHECK1-NEXT: call void @_ZN1SIfEC1Ef(ptr nonnull align 4 dereferenceable(4) [[ARRAYINIT_BEGIN]], float 1.000000e+00) -// CHECK1-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[ARRAYINIT_BEGIN]], i32 1 +// CHECK1-NEXT: call void @_ZN1SIfEC1Ef(ptr nonnull align 4 dereferenceable(4) [[S_ARR]], float 1.000000e+00) +// CHECK1-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[S_ARR]], i32 1 // CHECK1-NEXT: call void @_ZN1SIfEC1Ef(ptr nonnull align 4 dereferenceable(4) [[ARRAYINIT_ELEMENT]], float 2.000000e+00) // CHECK1-NEXT: call void @_ZN1SIfEC1Ef(ptr nonnull align 4 dereferenceable(4) [[VAR]], float 3.000000e+00) // CHECK1-NEXT: [[TMP0:%.*]] = load i32, ptr [[T_VAR]], align 4 @@ -473,9 +472,8 @@ void array_func(float a[3], St s[2], int n, long double vla1[n]) { // CHECK1-NEXT: call void @_ZN3SSTIiEC1Ev(ptr nonnull align 4 dereferenceable(4) [[SST]]) // CHECK1-NEXT: store i32 0, ptr [[T_VAR]], align 128 // CHECK1-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 128 [[VEC]], ptr align 128 @__const._Z5tmainIiET_v.vec, i32 8, i1 false) -// CHECK1-NEXT: [[ARRAYINIT_BEGIN:%.*]] = getelementptr inbounds [2 x %struct.S.0], ptr [[S_ARR]], i32 0, i32 0 -// CHECK1-NEXT: call void @_ZN1SIiEC1Ei(ptr nonnull align 4 dereferenceable(4) [[ARRAYINIT_BEGIN]], i32 1) -// CHECK1-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[ARRAYINIT_BEGIN]], i32 1 +// CHECK1-NEXT: call void @_ZN1SIiEC1Ei(ptr nonnull align 4 dereferenceable(4) [[S_ARR]], i32 1) +// CHECK1-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[S_ARR]], i32 1 // CHECK1-NEXT: call void @_ZN1SIiEC1Ei(ptr nonnull align 4 dereferenceable(4) [[ARRAYINIT_ELEMENT]], i32 2) // CHECK1-NEXT: call void @_ZN1SIiEC1Ei(ptr nonnull align 4 dereferenceable(4) [[VAR]], i32 3) // CHECK1-NEXT: [[TMP0:%.*]] = load i32, ptr [[T_VAR]], align 128 @@ -1440,9 +1438,8 @@ void array_func(float a[3], St s[2], int n, long double vla1[n]) { // CHECK9-NEXT: call void @_ZN1SIfEC1Ev(ptr nonnull align 4 dereferenceable(4) [[TEST]]) // CHECK9-NEXT: store i32 0, ptr [[T_VAR]], align 4 // CHECK9-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 4 [[VEC]], ptr align 4 @__const.main.vec, i64 8, i1 false) -// CHECK9-NEXT: [[ARRAYINIT_BEGIN:%.*]] = getelementptr inbounds [2 x %struct.S], ptr [[S_ARR]], i64 0, i64 0 -// CHECK9-NEXT: call void @_ZN1SIfEC1Ef(ptr nonnull align 4 dereferenceable(4) [[ARRAYINIT_BEGIN]], float 1.000000e+00) -// CHECK9-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[ARRAYINIT_BEGIN]], i64 1 +// CHECK9-NEXT: call void @_ZN1SIfEC1Ef(ptr nonnull align 4 dereferenceable(4) [[S_ARR]], float 1.000000e+00) +// CHECK9-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[S_ARR]], i64 1 // CHECK9-NEXT: call void @_ZN1SIfEC1Ef(ptr nonnull align 4 dereferenceable(4) [[ARRAYINIT_ELEMENT]], float 2.000000e+00) // CHECK9-NEXT: call void @_ZN1SIfEC1Ef(ptr nonnull align 4 dereferenceable(4) [[VAR]], float 3.000000e+00) // CHECK9-NEXT: [[TMP0:%.*]] = load i32, ptr [[T_VAR]], align 4 @@ -1655,9 +1652,8 @@ void array_func(float a[3], St s[2], int n, long double vla1[n]) { // CHECK9-NEXT: call void @_ZN3SSTIiEC1Ev(ptr nonnull align 4 dereferenceable(4) [[SST]]) // CHECK9-NEXT: store i32 0, ptr [[T_VAR]], align 128 // CHECK9-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 128 [[VEC]], ptr align 128 @__const._Z5tmainIiET_v.vec, i64 8, i1 false) -// CHECK9-NEXT: [[ARRAYINIT_BEGIN:%.*]] = getelementptr inbounds [2 x %struct.S.0], ptr [[S_ARR]], i64 0, i64 0 -// CHECK9-NEXT: call void @_ZN1SIiEC1Ei(ptr nonnull align 4 dereferenceable(4) [[ARRAYINIT_BEGIN]], i32 1) -// CHECK9-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[ARRAYINIT_BEGIN]], i64 1 +// CHECK9-NEXT: call void @_ZN1SIiEC1Ei(ptr nonnull align 4 dereferenceable(4) [[S_ARR]], i32 1) +// CHECK9-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[S_ARR]], i64 1 // CHECK9-NEXT: call void @_ZN1SIiEC1Ei(ptr nonnull align 4 dereferenceable(4) [[ARRAYINIT_ELEMENT]], i32 2) // CHECK9-NEXT: call void @_ZN1SIiEC1Ei(ptr nonnull align 4 dereferenceable(4) [[VAR]], i32 3) // CHECK9-NEXT: [[TMP0:%.*]] = load i32, ptr [[T_VAR]], align 128 diff --git a/clang/test/OpenMP/parallel_master_taskloop_firstprivate_codegen.cpp b/clang/test/OpenMP/parallel_master_taskloop_firstprivate_codegen.cpp index fa631854ccae8870812f9c007ce1685d7b806d4c..bfb31c3003c3beb6a098887b9fe799f1cb91cc47 100644 --- a/clang/test/OpenMP/parallel_master_taskloop_firstprivate_codegen.cpp +++ b/clang/test/OpenMP/parallel_master_taskloop_firstprivate_codegen.cpp @@ -206,9 +206,8 @@ void array_func(int n, float a[n], St s[2]) { // CHECK-NEXT: call void @_ZN1SIdEC1ERKS0_d(ptr noundef nonnull align 8 dereferenceable(8) [[TEST]], ptr noundef nonnull align 8 dereferenceable(8) [[TTT]], double noundef 0.000000e+00) // CHECK-NEXT: store i32 0, ptr [[T_VAR]], align 4 // CHECK-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 4 [[VEC]], ptr align 4 @__const.main.vec, i64 8, i1 false) -// CHECK-NEXT: [[ARRAYINIT_BEGIN:%.*]] = getelementptr inbounds [2 x %struct.S], ptr [[S_ARR]], i64 0, i64 0 -// CHECK-NEXT: call void @_ZN1SIdEC1Ed(ptr noundef nonnull align 8 dereferenceable(8) [[ARRAYINIT_BEGIN]], double noundef 1.000000e+00) -// CHECK-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[ARRAYINIT_BEGIN]], i64 1 +// CHECK-NEXT: call void @_ZN1SIdEC1Ed(ptr noundef nonnull align 8 dereferenceable(8) [[S_ARR]], double noundef 1.000000e+00) +// CHECK-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[S_ARR]], i64 1 // CHECK-NEXT: call void @_ZN1SIdEC1Ed(ptr noundef nonnull align 8 dereferenceable(8) [[ARRAYINIT_ELEMENT]], double noundef 2.000000e+00) // CHECK-NEXT: call void @_ZN1SIdEC1Ed(ptr noundef nonnull align 8 dereferenceable(8) [[VAR]], double noundef 3.000000e+00) // CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[T_VAR]], align 4 @@ -569,9 +568,8 @@ void array_func(int n, float a[n], St s[2]) { // CHECK-NEXT: call void @_ZN1SIiEC1ERKS0_i(ptr noundef nonnull align 4 dereferenceable(4) [[TEST]], ptr noundef nonnull align 4 dereferenceable(4) [[TTT]], i32 noundef 0) // CHECK-NEXT: store i32 0, ptr [[T_VAR]], align 128 // CHECK-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 4 [[VEC]], ptr align 4 @__const._Z5tmainIiET_v.vec, i64 8, i1 false) -// CHECK-NEXT: [[ARRAYINIT_BEGIN:%.*]] = getelementptr inbounds [2 x %struct.S.0], ptr [[S_ARR]], i64 0, i64 0 -// CHECK-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_BEGIN]], i32 noundef 1) -// CHECK-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[ARRAYINIT_BEGIN]], i64 1 +// CHECK-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[S_ARR]], i32 noundef 1) +// CHECK-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[S_ARR]], i64 1 // CHECK-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_ELEMENT]], i32 noundef 2) // CHECK-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[VAR]], i32 noundef 3) // CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[T_VAR]], align 128 @@ -1519,9 +1517,8 @@ void array_func(int n, float a[n], St s[2]) { // SIMD-ONLY0-NEXT: call void @_ZN1SIdEC1ERKS0_d(ptr noundef nonnull align 8 dereferenceable(8) [[TEST]], ptr noundef nonnull align 8 dereferenceable(8) [[TTT]], double noundef 0.000000e+00) // SIMD-ONLY0-NEXT: store i32 0, ptr [[T_VAR]], align 4 // SIMD-ONLY0-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 4 [[VEC]], ptr align 4 @__const.main.vec, i64 8, i1 false) -// SIMD-ONLY0-NEXT: [[ARRAYINIT_BEGIN:%.*]] = getelementptr inbounds [2 x %struct.S], ptr [[S_ARR]], i64 0, i64 0 -// SIMD-ONLY0-NEXT: call void @_ZN1SIdEC1Ed(ptr noundef nonnull align 8 dereferenceable(8) [[ARRAYINIT_BEGIN]], double noundef 1.000000e+00) -// SIMD-ONLY0-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[ARRAYINIT_BEGIN]], i64 1 +// SIMD-ONLY0-NEXT: call void @_ZN1SIdEC1Ed(ptr noundef nonnull align 8 dereferenceable(8) [[S_ARR]], double noundef 1.000000e+00) +// SIMD-ONLY0-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[S_ARR]], i64 1 // SIMD-ONLY0-NEXT: call void @_ZN1SIdEC1Ed(ptr noundef nonnull align 8 dereferenceable(8) [[ARRAYINIT_ELEMENT]], double noundef 2.000000e+00) // SIMD-ONLY0-NEXT: call void @_ZN1SIdEC1Ed(ptr noundef nonnull align 8 dereferenceable(8) [[VAR]], double noundef 3.000000e+00) // SIMD-ONLY0-NEXT: store i32 0, ptr [[I]], align 4 @@ -1617,9 +1614,8 @@ void array_func(int n, float a[n], St s[2]) { // SIMD-ONLY0-NEXT: call void @_ZN1SIiEC1ERKS0_i(ptr noundef nonnull align 4 dereferenceable(4) [[TEST]], ptr noundef nonnull align 4 dereferenceable(4) [[TTT]], i32 noundef 0) // SIMD-ONLY0-NEXT: store i32 0, ptr [[T_VAR]], align 128 // SIMD-ONLY0-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 4 [[VEC]], ptr align 4 @__const._Z5tmainIiET_v.vec, i64 8, i1 false) -// SIMD-ONLY0-NEXT: [[ARRAYINIT_BEGIN:%.*]] = getelementptr inbounds [2 x %struct.S.0], ptr [[S_ARR]], i64 0, i64 0 -// SIMD-ONLY0-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_BEGIN]], i32 noundef 1) -// SIMD-ONLY0-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[ARRAYINIT_BEGIN]], i64 1 +// SIMD-ONLY0-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[S_ARR]], i32 noundef 1) +// SIMD-ONLY0-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[S_ARR]], i64 1 // SIMD-ONLY0-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_ELEMENT]], i32 noundef 2) // SIMD-ONLY0-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[VAR]], i32 noundef 3) // SIMD-ONLY0-NEXT: store i32 0, ptr [[I]], align 4 @@ -1842,9 +1838,8 @@ void array_func(int n, float a[n], St s[2]) { // SIMD-ONLY1-NEXT: call void @_ZN1SIdEC1ERKS0_d(ptr noundef nonnull align 8 dereferenceable(8) [[TEST]], ptr noundef nonnull align 8 dereferenceable(8) [[TTT]], double noundef 0.000000e+00) // SIMD-ONLY1-NEXT: store i32 0, ptr [[T_VAR]], align 4 // SIMD-ONLY1-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 4 [[VEC]], ptr align 4 @__const.main.vec, i64 8, i1 false) -// SIMD-ONLY1-NEXT: [[ARRAYINIT_BEGIN:%.*]] = getelementptr inbounds [2 x %struct.S], ptr [[S_ARR]], i64 0, i64 0 -// SIMD-ONLY1-NEXT: call void @_ZN1SIdEC1Ed(ptr noundef nonnull align 8 dereferenceable(8) [[ARRAYINIT_BEGIN]], double noundef 1.000000e+00) -// SIMD-ONLY1-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[ARRAYINIT_BEGIN]], i64 1 +// SIMD-ONLY1-NEXT: call void @_ZN1SIdEC1Ed(ptr noundef nonnull align 8 dereferenceable(8) [[S_ARR]], double noundef 1.000000e+00) +// SIMD-ONLY1-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[S_ARR]], i64 1 // SIMD-ONLY1-NEXT: call void @_ZN1SIdEC1Ed(ptr noundef nonnull align 8 dereferenceable(8) [[ARRAYINIT_ELEMENT]], double noundef 2.000000e+00) // SIMD-ONLY1-NEXT: call void @_ZN1SIdEC1Ed(ptr noundef nonnull align 8 dereferenceable(8) [[VAR]], double noundef 3.000000e+00) // SIMD-ONLY1-NEXT: store i32 0, ptr [[I]], align 4 @@ -1940,9 +1935,8 @@ void array_func(int n, float a[n], St s[2]) { // SIMD-ONLY1-NEXT: call void @_ZN1SIiEC1ERKS0_i(ptr noundef nonnull align 4 dereferenceable(4) [[TEST]], ptr noundef nonnull align 4 dereferenceable(4) [[TTT]], i32 noundef 0) // SIMD-ONLY1-NEXT: store i32 0, ptr [[T_VAR]], align 128 // SIMD-ONLY1-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 4 [[VEC]], ptr align 4 @__const._Z5tmainIiET_v.vec, i64 8, i1 false) -// SIMD-ONLY1-NEXT: [[ARRAYINIT_BEGIN:%.*]] = getelementptr inbounds [2 x %struct.S.0], ptr [[S_ARR]], i64 0, i64 0 -// SIMD-ONLY1-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_BEGIN]], i32 noundef 1) -// SIMD-ONLY1-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[ARRAYINIT_BEGIN]], i64 1 +// SIMD-ONLY1-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[S_ARR]], i32 noundef 1) +// SIMD-ONLY1-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[S_ARR]], i64 1 // SIMD-ONLY1-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_ELEMENT]], i32 noundef 2) // SIMD-ONLY1-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[VAR]], i32 noundef 3) // SIMD-ONLY1-NEXT: store i32 0, ptr [[I]], align 4 diff --git a/clang/test/OpenMP/parallel_master_taskloop_lastprivate_codegen.cpp b/clang/test/OpenMP/parallel_master_taskloop_lastprivate_codegen.cpp index 409a983f3121d9400d9a39a0b30442840a04cc88..f86d53777bd4a188c7f33874a3645b3d446024e2 100644 --- a/clang/test/OpenMP/parallel_master_taskloop_lastprivate_codegen.cpp +++ b/clang/test/OpenMP/parallel_master_taskloop_lastprivate_codegen.cpp @@ -212,9 +212,8 @@ void loop() { // CHECK1-NEXT: call void @_ZN1SIdEC1Ev(ptr noundef nonnull align 8 dereferenceable(8) [[TEST]]) // CHECK1-NEXT: store i32 0, ptr [[T_VAR]], align 4 // CHECK1-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 4 [[VEC]], ptr align 4 @__const.main.vec, i64 8, i1 false) -// CHECK1-NEXT: [[ARRAYINIT_BEGIN:%.*]] = getelementptr inbounds [2 x %struct.S], ptr [[S_ARR]], i64 0, i64 0 -// CHECK1-NEXT: call void @_ZN1SIdEC1Ed(ptr noundef nonnull align 8 dereferenceable(8) [[ARRAYINIT_BEGIN]], double noundef 1.000000e+00) -// CHECK1-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[ARRAYINIT_BEGIN]], i64 1 +// CHECK1-NEXT: call void @_ZN1SIdEC1Ed(ptr noundef nonnull align 8 dereferenceable(8) [[S_ARR]], double noundef 1.000000e+00) +// CHECK1-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[S_ARR]], i64 1 // CHECK1-NEXT: call void @_ZN1SIdEC1Ed(ptr noundef nonnull align 8 dereferenceable(8) [[ARRAYINIT_ELEMENT]], double noundef 2.000000e+00) // CHECK1-NEXT: call void @_ZN1SIdEC1Ed(ptr noundef nonnull align 8 dereferenceable(8) [[VAR]], double noundef 3.000000e+00) // CHECK1-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr @[[GLOB1:[0-9]+]], i32 4, ptr @main.omp_outlined, ptr [[VEC]], ptr [[T_VAR]], ptr [[S_ARR]], ptr [[VAR]]) @@ -580,9 +579,8 @@ void loop() { // CHECK1-NEXT: call void @_ZN1SIiEC1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[TEST]]) // CHECK1-NEXT: store i32 0, ptr [[T_VAR]], align 128 // CHECK1-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 4 [[VEC]], ptr align 4 @__const._Z5tmainIiET_v.vec, i64 8, i1 false) -// CHECK1-NEXT: [[ARRAYINIT_BEGIN:%.*]] = getelementptr inbounds [2 x %struct.S.0], ptr [[S_ARR]], i64 0, i64 0 -// CHECK1-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_BEGIN]], i32 noundef 1) -// CHECK1-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[ARRAYINIT_BEGIN]], i64 1 +// CHECK1-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[S_ARR]], i32 noundef 1) +// CHECK1-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[S_ARR]], i64 1 // CHECK1-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_ELEMENT]], i32 noundef 2) // CHECK1-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[VAR]], i32 noundef 3) // CHECK1-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr @[[GLOB1]], i32 4, ptr @_Z5tmainIiET_v.omp_outlined, ptr [[VEC]], ptr [[T_VAR]], ptr [[S_ARR]], ptr [[VAR]]) diff --git a/clang/test/OpenMP/parallel_master_taskloop_simd_firstprivate_codegen.cpp b/clang/test/OpenMP/parallel_master_taskloop_simd_firstprivate_codegen.cpp index 46c35833a4e635c23bebf8a09cb61e2b43024235..68a7257a019c28c302979b54a1aec614dcf7ba01 100644 --- a/clang/test/OpenMP/parallel_master_taskloop_simd_firstprivate_codegen.cpp +++ b/clang/test/OpenMP/parallel_master_taskloop_simd_firstprivate_codegen.cpp @@ -206,9 +206,8 @@ void array_func(int n, float a[n], St s[2]) { // CHECK-NEXT: call void @_ZN1SIdEC1ERKS0_d(ptr noundef nonnull align 8 dereferenceable(8) [[TEST]], ptr noundef nonnull align 8 dereferenceable(8) [[TTT]], double noundef 0.000000e+00) // CHECK-NEXT: store i32 0, ptr [[T_VAR]], align 4 // CHECK-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 4 [[VEC]], ptr align 4 @__const.main.vec, i64 8, i1 false) -// CHECK-NEXT: [[ARRAYINIT_BEGIN:%.*]] = getelementptr inbounds [2 x %struct.S], ptr [[S_ARR]], i64 0, i64 0 -// CHECK-NEXT: call void @_ZN1SIdEC1Ed(ptr noundef nonnull align 8 dereferenceable(8) [[ARRAYINIT_BEGIN]], double noundef 1.000000e+00) -// CHECK-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[ARRAYINIT_BEGIN]], i64 1 +// CHECK-NEXT: call void @_ZN1SIdEC1Ed(ptr noundef nonnull align 8 dereferenceable(8) [[S_ARR]], double noundef 1.000000e+00) +// CHECK-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[S_ARR]], i64 1 // CHECK-NEXT: call void @_ZN1SIdEC1Ed(ptr noundef nonnull align 8 dereferenceable(8) [[ARRAYINIT_ELEMENT]], double noundef 2.000000e+00) // CHECK-NEXT: call void @_ZN1SIdEC1Ed(ptr noundef nonnull align 8 dereferenceable(8) [[VAR]], double noundef 3.000000e+00) // CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[T_VAR]], align 4 @@ -569,9 +568,8 @@ void array_func(int n, float a[n], St s[2]) { // CHECK-NEXT: call void @_ZN1SIiEC1ERKS0_i(ptr noundef nonnull align 4 dereferenceable(4) [[TEST]], ptr noundef nonnull align 4 dereferenceable(4) [[TTT]], i32 noundef 0) // CHECK-NEXT: store i32 0, ptr [[T_VAR]], align 128 // CHECK-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 4 [[VEC]], ptr align 4 @__const._Z5tmainIiET_v.vec, i64 8, i1 false) -// CHECK-NEXT: [[ARRAYINIT_BEGIN:%.*]] = getelementptr inbounds [2 x %struct.S.0], ptr [[S_ARR]], i64 0, i64 0 -// CHECK-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_BEGIN]], i32 noundef 1) -// CHECK-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[ARRAYINIT_BEGIN]], i64 1 +// CHECK-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[S_ARR]], i32 noundef 1) +// CHECK-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[S_ARR]], i64 1 // CHECK-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_ELEMENT]], i32 noundef 2) // CHECK-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[VAR]], i32 noundef 3) // CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[T_VAR]], align 128 @@ -1523,9 +1521,8 @@ void array_func(int n, float a[n], St s[2]) { // SIMD-ONLY0-NEXT: call void @_ZN1SIdEC1ERKS0_d(ptr noundef nonnull align 8 dereferenceable(8) [[TEST]], ptr noundef nonnull align 8 dereferenceable(8) [[TTT]], double noundef 0.000000e+00) // SIMD-ONLY0-NEXT: store i32 0, ptr [[T_VAR]], align 4 // SIMD-ONLY0-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 4 [[VEC]], ptr align 4 @__const.main.vec, i64 8, i1 false) -// SIMD-ONLY0-NEXT: [[ARRAYINIT_BEGIN:%.*]] = getelementptr inbounds [2 x %struct.S], ptr [[S_ARR]], i64 0, i64 0 -// SIMD-ONLY0-NEXT: call void @_ZN1SIdEC1Ed(ptr noundef nonnull align 8 dereferenceable(8) [[ARRAYINIT_BEGIN]], double noundef 1.000000e+00) -// SIMD-ONLY0-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[ARRAYINIT_BEGIN]], i64 1 +// SIMD-ONLY0-NEXT: call void @_ZN1SIdEC1Ed(ptr noundef nonnull align 8 dereferenceable(8) [[S_ARR]], double noundef 1.000000e+00) +// SIMD-ONLY0-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[S_ARR]], i64 1 // SIMD-ONLY0-NEXT: call void @_ZN1SIdEC1Ed(ptr noundef nonnull align 8 dereferenceable(8) [[ARRAYINIT_ELEMENT]], double noundef 2.000000e+00) // SIMD-ONLY0-NEXT: call void @_ZN1SIdEC1Ed(ptr noundef nonnull align 8 dereferenceable(8) [[VAR]], double noundef 3.000000e+00) // SIMD-ONLY0-NEXT: store i64 0, ptr [[DOTOMP_LB]], align 8 @@ -1638,9 +1635,8 @@ void array_func(int n, float a[n], St s[2]) { // SIMD-ONLY0-NEXT: call void @_ZN1SIiEC1ERKS0_i(ptr noundef nonnull align 4 dereferenceable(4) [[TEST]], ptr noundef nonnull align 4 dereferenceable(4) [[TTT]], i32 noundef 0) // SIMD-ONLY0-NEXT: store i32 0, ptr [[T_VAR]], align 128 // SIMD-ONLY0-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 4 [[VEC]], ptr align 4 @__const._Z5tmainIiET_v.vec, i64 8, i1 false) -// SIMD-ONLY0-NEXT: [[ARRAYINIT_BEGIN:%.*]] = getelementptr inbounds [2 x %struct.S.0], ptr [[S_ARR]], i64 0, i64 0 -// SIMD-ONLY0-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_BEGIN]], i32 noundef 1) -// SIMD-ONLY0-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[ARRAYINIT_BEGIN]], i64 1 +// SIMD-ONLY0-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[S_ARR]], i32 noundef 1) +// SIMD-ONLY0-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[S_ARR]], i64 1 // SIMD-ONLY0-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_ELEMENT]], i32 noundef 2) // SIMD-ONLY0-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[VAR]], i32 noundef 3) // SIMD-ONLY0-NEXT: store i64 0, ptr [[DOTOMP_LB]], align 8 @@ -1880,9 +1876,8 @@ void array_func(int n, float a[n], St s[2]) { // SIMD-ONLY1-NEXT: call void @_ZN1SIdEC1ERKS0_d(ptr noundef nonnull align 8 dereferenceable(8) [[TEST]], ptr noundef nonnull align 8 dereferenceable(8) [[TTT]], double noundef 0.000000e+00) // SIMD-ONLY1-NEXT: store i32 0, ptr [[T_VAR]], align 4 // SIMD-ONLY1-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 4 [[VEC]], ptr align 4 @__const.main.vec, i64 8, i1 false) -// SIMD-ONLY1-NEXT: [[ARRAYINIT_BEGIN:%.*]] = getelementptr inbounds [2 x %struct.S], ptr [[S_ARR]], i64 0, i64 0 -// SIMD-ONLY1-NEXT: call void @_ZN1SIdEC1Ed(ptr noundef nonnull align 8 dereferenceable(8) [[ARRAYINIT_BEGIN]], double noundef 1.000000e+00) -// SIMD-ONLY1-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[ARRAYINIT_BEGIN]], i64 1 +// SIMD-ONLY1-NEXT: call void @_ZN1SIdEC1Ed(ptr noundef nonnull align 8 dereferenceable(8) [[S_ARR]], double noundef 1.000000e+00) +// SIMD-ONLY1-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[S_ARR]], i64 1 // SIMD-ONLY1-NEXT: call void @_ZN1SIdEC1Ed(ptr noundef nonnull align 8 dereferenceable(8) [[ARRAYINIT_ELEMENT]], double noundef 2.000000e+00) // SIMD-ONLY1-NEXT: call void @_ZN1SIdEC1Ed(ptr noundef nonnull align 8 dereferenceable(8) [[VAR]], double noundef 3.000000e+00) // SIMD-ONLY1-NEXT: store i64 0, ptr [[DOTOMP_LB]], align 8 @@ -1995,9 +1990,8 @@ void array_func(int n, float a[n], St s[2]) { // SIMD-ONLY1-NEXT: call void @_ZN1SIiEC1ERKS0_i(ptr noundef nonnull align 4 dereferenceable(4) [[TEST]], ptr noundef nonnull align 4 dereferenceable(4) [[TTT]], i32 noundef 0) // SIMD-ONLY1-NEXT: store i32 0, ptr [[T_VAR]], align 128 // SIMD-ONLY1-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 4 [[VEC]], ptr align 4 @__const._Z5tmainIiET_v.vec, i64 8, i1 false) -// SIMD-ONLY1-NEXT: [[ARRAYINIT_BEGIN:%.*]] = getelementptr inbounds [2 x %struct.S.0], ptr [[S_ARR]], i64 0, i64 0 -// SIMD-ONLY1-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_BEGIN]], i32 noundef 1) -// SIMD-ONLY1-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[ARRAYINIT_BEGIN]], i64 1 +// SIMD-ONLY1-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[S_ARR]], i32 noundef 1) +// SIMD-ONLY1-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[S_ARR]], i64 1 // SIMD-ONLY1-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_ELEMENT]], i32 noundef 2) // SIMD-ONLY1-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[VAR]], i32 noundef 3) // SIMD-ONLY1-NEXT: store i64 0, ptr [[DOTOMP_LB]], align 8 diff --git a/clang/test/OpenMP/parallel_master_taskloop_simd_lastprivate_codegen.cpp b/clang/test/OpenMP/parallel_master_taskloop_simd_lastprivate_codegen.cpp index 5e2c192497b5b93af8be9ab1097d02522a4bd5e9..8495cfa2e027e55828f31509c90778c8acc542b2 100644 --- a/clang/test/OpenMP/parallel_master_taskloop_simd_lastprivate_codegen.cpp +++ b/clang/test/OpenMP/parallel_master_taskloop_simd_lastprivate_codegen.cpp @@ -212,9 +212,8 @@ void loop() { // CHECK1-NEXT: call void @_ZN1SIdEC1Ev(ptr noundef nonnull align 8 dereferenceable(8) [[TEST]]) // CHECK1-NEXT: store i32 0, ptr [[T_VAR]], align 4 // CHECK1-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 4 [[VEC]], ptr align 4 @__const.main.vec, i64 8, i1 false) -// CHECK1-NEXT: [[ARRAYINIT_BEGIN:%.*]] = getelementptr inbounds [2 x %struct.S], ptr [[S_ARR]], i64 0, i64 0 -// CHECK1-NEXT: call void @_ZN1SIdEC1Ed(ptr noundef nonnull align 8 dereferenceable(8) [[ARRAYINIT_BEGIN]], double noundef 1.000000e+00) -// CHECK1-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[ARRAYINIT_BEGIN]], i64 1 +// CHECK1-NEXT: call void @_ZN1SIdEC1Ed(ptr noundef nonnull align 8 dereferenceable(8) [[S_ARR]], double noundef 1.000000e+00) +// CHECK1-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[S_ARR]], i64 1 // CHECK1-NEXT: call void @_ZN1SIdEC1Ed(ptr noundef nonnull align 8 dereferenceable(8) [[ARRAYINIT_ELEMENT]], double noundef 2.000000e+00) // CHECK1-NEXT: call void @_ZN1SIdEC1Ed(ptr noundef nonnull align 8 dereferenceable(8) [[VAR]], double noundef 3.000000e+00) // CHECK1-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr @[[GLOB1:[0-9]+]], i32 4, ptr @main.omp_outlined, ptr [[VEC]], ptr [[T_VAR]], ptr [[S_ARR]], ptr [[VAR]]) @@ -580,9 +579,8 @@ void loop() { // CHECK1-NEXT: call void @_ZN1SIiEC1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[TEST]]) // CHECK1-NEXT: store i32 0, ptr [[T_VAR]], align 128 // CHECK1-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 4 [[VEC]], ptr align 4 @__const._Z5tmainIiET_v.vec, i64 8, i1 false) -// CHECK1-NEXT: [[ARRAYINIT_BEGIN:%.*]] = getelementptr inbounds [2 x %struct.S.0], ptr [[S_ARR]], i64 0, i64 0 -// CHECK1-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_BEGIN]], i32 noundef 1) -// CHECK1-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[ARRAYINIT_BEGIN]], i64 1 +// CHECK1-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[S_ARR]], i32 noundef 1) +// CHECK1-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[S_ARR]], i64 1 // CHECK1-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_ELEMENT]], i32 noundef 2) // CHECK1-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[VAR]], i32 noundef 3) // CHECK1-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr @[[GLOB1]], i32 4, ptr @_Z5tmainIiET_v.omp_outlined, ptr [[VEC]], ptr [[T_VAR]], ptr [[S_ARR]], ptr [[VAR]]) @@ -1755,9 +1753,8 @@ void loop() { // CHECK7-NEXT: call void @_ZN1SIdEC1Ev(ptr noundef nonnull align 8 dereferenceable(8) [[TEST]]) // CHECK7-NEXT: store i32 0, ptr [[T_VAR]], align 4 // CHECK7-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 4 [[VEC]], ptr align 4 @__const.main.vec, i64 8, i1 false) -// CHECK7-NEXT: [[ARRAYINIT_BEGIN:%.*]] = getelementptr inbounds [2 x %struct.S], ptr [[S_ARR]], i64 0, i64 0 -// CHECK7-NEXT: call void @_ZN1SIdEC1Ed(ptr noundef nonnull align 8 dereferenceable(8) [[ARRAYINIT_BEGIN]], double noundef 1.000000e+00) -// CHECK7-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[ARRAYINIT_BEGIN]], i64 1 +// CHECK7-NEXT: call void @_ZN1SIdEC1Ed(ptr noundef nonnull align 8 dereferenceable(8) [[S_ARR]], double noundef 1.000000e+00) +// CHECK7-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[S_ARR]], i64 1 // CHECK7-NEXT: call void @_ZN1SIdEC1Ed(ptr noundef nonnull align 8 dereferenceable(8) [[ARRAYINIT_ELEMENT]], double noundef 2.000000e+00) // CHECK7-NEXT: call void @_ZN1SIdEC1Ed(ptr noundef nonnull align 8 dereferenceable(8) [[VAR]], double noundef 3.000000e+00) // CHECK7-NEXT: store i64 0, ptr [[DOTOMP_LB]], align 8 @@ -1911,9 +1908,8 @@ void loop() { // CHECK7-NEXT: call void @_ZN1SIiEC1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[TEST]]) // CHECK7-NEXT: store i32 0, ptr [[T_VAR]], align 128 // CHECK7-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 4 [[VEC]], ptr align 4 @__const._Z5tmainIiET_v.vec, i64 8, i1 false) -// CHECK7-NEXT: [[ARRAYINIT_BEGIN:%.*]] = getelementptr inbounds [2 x %struct.S.0], ptr [[S_ARR]], i64 0, i64 0 -// CHECK7-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_BEGIN]], i32 noundef 1) -// CHECK7-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[ARRAYINIT_BEGIN]], i64 1 +// CHECK7-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[S_ARR]], i32 noundef 1) +// CHECK7-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[S_ARR]], i64 1 // CHECK7-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_ELEMENT]], i32 noundef 2) // CHECK7-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[VAR]], i32 noundef 3) // CHECK7-NEXT: store i64 0, ptr [[DOTOMP_LB]], align 8 diff --git a/clang/test/OpenMP/parallel_private_codegen.cpp b/clang/test/OpenMP/parallel_private_codegen.cpp index 586399ba89a6bfaec83aed0d4c42ead5fdc5ae40..b86f4e48a33527750764654861db84303e65ff1e 100644 --- a/clang/test/OpenMP/parallel_private_codegen.cpp +++ b/clang/test/OpenMP/parallel_private_codegen.cpp @@ -182,9 +182,8 @@ int main() { // CHECK1-NEXT: call void @_ZN1SIfEC1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[TEST]]) // CHECK1-NEXT: store i32 0, ptr [[T_VAR]], align 4 // CHECK1-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 4 [[VEC]], ptr align 4 @__const.main.vec, i64 8, i1 false) -// CHECK1-NEXT: [[ARRAYINIT_BEGIN:%.*]] = getelementptr inbounds [2 x %struct.S], ptr [[S_ARR]], i64 0, i64 0 -// CHECK1-NEXT: call void @_ZN1SIfEC1Ef(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_BEGIN]], float noundef 1.000000e+00) -// CHECK1-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[ARRAYINIT_BEGIN]], i64 1 +// CHECK1-NEXT: call void @_ZN1SIfEC1Ef(ptr noundef nonnull align 4 dereferenceable(4) [[S_ARR]], float noundef 1.000000e+00) +// CHECK1-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[S_ARR]], i64 1 // CHECK1-NEXT: call void @_ZN1SIfEC1Ef(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_ELEMENT]], float noundef 2.000000e+00) // CHECK1-NEXT: call void @_ZN1SIfEC1Ef(ptr noundef nonnull align 4 dereferenceable(4) [[VAR]], float noundef 3.000000e+00) // CHECK1-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr @[[GLOB1:[0-9]+]], i32 0, ptr @main.omp_outlined) @@ -309,9 +308,8 @@ int main() { // CHECK1-NEXT: call void @_ZN3SSTIiEC1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[SST]]) // CHECK1-NEXT: store i32 0, ptr [[T_VAR]], align 128 // CHECK1-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 128 [[VEC]], ptr align 128 @__const._Z5tmainIiET_v.vec, i64 8, i1 false) -// CHECK1-NEXT: [[ARRAYINIT_BEGIN:%.*]] = getelementptr inbounds [2 x %struct.S.0], ptr [[S_ARR]], i64 0, i64 0 -// CHECK1-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_BEGIN]], i32 noundef 1) -// CHECK1-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[ARRAYINIT_BEGIN]], i64 1 +// CHECK1-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[S_ARR]], i32 noundef 1) +// CHECK1-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[S_ARR]], i64 1 // CHECK1-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_ELEMENT]], i32 noundef 2) // CHECK1-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[VAR]], i32 noundef 3) // CHECK1-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr @[[GLOB1]], i32 0, ptr @_Z5tmainIiET_v.omp_outlined) diff --git a/clang/test/OpenMP/parallel_reduction_codegen.cpp b/clang/test/OpenMP/parallel_reduction_codegen.cpp index 88a10a16615d0a04485366c59180da5fd6c7d496..d27ef4913a38649535151add7e460c77076cd8fa 100644 --- a/clang/test/OpenMP/parallel_reduction_codegen.cpp +++ b/clang/test/OpenMP/parallel_reduction_codegen.cpp @@ -511,9 +511,8 @@ int main() { // CHECK1-NEXT: call void @_ZN1SIfEC1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[TEST]]) // CHECK1-NEXT: store float 0.000000e+00, ptr [[T_VAR]], align 4 // CHECK1-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 4 [[VEC]], ptr align 4 @__const.main.vec, i64 8, i1 false) -// CHECK1-NEXT: [[ARRAYINIT_BEGIN:%.*]] = getelementptr inbounds [2 x %struct.S], ptr [[S_ARR]], i64 0, i64 0 -// CHECK1-NEXT: call void @_ZN1SIfEC1Ef(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_BEGIN]], float noundef 1.000000e+00) -// CHECK1-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[ARRAYINIT_BEGIN]], i64 1 +// CHECK1-NEXT: call void @_ZN1SIfEC1Ef(ptr noundef nonnull align 4 dereferenceable(4) [[S_ARR]], float noundef 1.000000e+00) +// CHECK1-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[S_ARR]], i64 1 // CHECK1-NEXT: call void @_ZN1SIfEC1Ef(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_ELEMENT]], float noundef 2.000000e+00) // CHECK1-NEXT: call void @_ZN1SIfEC1Ef(ptr noundef nonnull align 4 dereferenceable(4) [[VAR]], float noundef 3.000000e+00) // CHECK1-NEXT: call void @_ZN1SIfEC1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[VAR1]]) @@ -997,9 +996,8 @@ int main() { // CHECK1-NEXT: call void @_ZN3SSTIiEC1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[SST]]) // CHECK1-NEXT: store i32 0, ptr [[T_VAR]], align 128 // CHECK1-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 4 [[VEC]], ptr align 4 @__const._Z5tmainIiET_v.vec, i64 8, i1 false) -// CHECK1-NEXT: [[ARRAYINIT_BEGIN:%.*]] = getelementptr inbounds [2 x %struct.S.0], ptr [[S_ARR]], i64 0, i64 0 -// CHECK1-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_BEGIN]], i32 noundef 1) -// CHECK1-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[ARRAYINIT_BEGIN]], i64 1 +// CHECK1-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[S_ARR]], i32 noundef 1) +// CHECK1-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[S_ARR]], i64 1 // CHECK1-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_ELEMENT]], i32 noundef 2) // CHECK1-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[VAR]], i32 noundef 3) // CHECK1-NEXT: call void @_ZN1SIiEC1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[VAR1]]) diff --git a/clang/test/OpenMP/sections_firstprivate_codegen.cpp b/clang/test/OpenMP/sections_firstprivate_codegen.cpp index af67c429ac1125d89a9d5c9b30ccad39c1b216ba..3cf6cc29d56ae6241384c03ff1f8669b000053ce 100644 --- a/clang/test/OpenMP/sections_firstprivate_codegen.cpp +++ b/clang/test/OpenMP/sections_firstprivate_codegen.cpp @@ -402,9 +402,8 @@ int main() { // CHECK1-NEXT: call void @_ZN1SIiEC1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[TEST]]) // CHECK1-NEXT: store i32 0, ptr [[T_VAR]], align 4 // CHECK1-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 4 [[VEC]], ptr align 4 @__const._Z5tmainIiET_v.vec, i64 8, i1 false) -// CHECK1-NEXT: [[ARRAYINIT_BEGIN:%.*]] = getelementptr inbounds [2 x %struct.S.0], ptr [[S_ARR]], i64 0, i64 0 -// CHECK1-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_BEGIN]], i32 noundef 1) -// CHECK1-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[ARRAYINIT_BEGIN]], i64 1 +// CHECK1-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[S_ARR]], i32 noundef 1) +// CHECK1-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[S_ARR]], i64 1 // CHECK1-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_ELEMENT]], i32 noundef 2) // CHECK1-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[VAR]], i32 noundef 3) // CHECK1-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr @[[GLOB2]], i32 4, ptr @_Z5tmainIiET_v.omp_outlined, ptr [[T_VAR]], ptr [[VEC]], ptr [[S_ARR]], ptr [[VAR]]) diff --git a/clang/test/OpenMP/sections_lastprivate_codegen.cpp b/clang/test/OpenMP/sections_lastprivate_codegen.cpp index fb7f29077bb50c655eecfa63cd7f99f5b8e807f3..126a3ba87e8182aa89ad13a8c6f50d9dbdeac9fa 100644 --- a/clang/test/OpenMP/sections_lastprivate_codegen.cpp +++ b/clang/test/OpenMP/sections_lastprivate_codegen.cpp @@ -201,9 +201,8 @@ int main() { // CHECK1-NEXT: call void @_ZN1SIfEC1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[TEST]]) // CHECK1-NEXT: store i32 0, ptr [[T_VAR]], align 4 // CHECK1-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 4 [[VEC]], ptr align 4 @__const.main.vec, i64 8, i1 false) -// CHECK1-NEXT: [[ARRAYINIT_BEGIN:%.*]] = getelementptr inbounds [2 x %struct.S], ptr [[S_ARR]], i64 0, i64 0 -// CHECK1-NEXT: call void @_ZN1SIfEC1Ef(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_BEGIN]], float noundef 1.000000e+00) -// CHECK1-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[ARRAYINIT_BEGIN]], i64 1 +// CHECK1-NEXT: call void @_ZN1SIfEC1Ef(ptr noundef nonnull align 4 dereferenceable(4) [[S_ARR]], float noundef 1.000000e+00) +// CHECK1-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[S_ARR]], i64 1 // CHECK1-NEXT: call void @_ZN1SIfEC1Ef(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_ELEMENT]], float noundef 2.000000e+00) // CHECK1-NEXT: call void @_ZN1SIfEC1Ef(ptr noundef nonnull align 4 dereferenceable(4) [[VAR]], float noundef 3.000000e+00) // CHECK1-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr @[[GLOB3:[0-9]+]], i32 5, ptr @main.omp_outlined, ptr [[T_VAR]], ptr [[VEC]], ptr [[S_ARR]], ptr [[VAR]], ptr @_ZZ4mainE5sivar) @@ -465,9 +464,8 @@ int main() { // CHECK1-NEXT: call void @_ZN1SIiEC1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[TEST]]) // CHECK1-NEXT: store i32 0, ptr [[T_VAR]], align 4 // CHECK1-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 4 [[VEC]], ptr align 4 @__const._Z5tmainIiET_v.vec, i64 8, i1 false) -// CHECK1-NEXT: [[ARRAYINIT_BEGIN:%.*]] = getelementptr inbounds [2 x %struct.S.0], ptr [[S_ARR]], i64 0, i64 0 -// CHECK1-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_BEGIN]], i32 noundef 1) -// CHECK1-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[ARRAYINIT_BEGIN]], i64 1 +// CHECK1-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[S_ARR]], i32 noundef 1) +// CHECK1-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[S_ARR]], i64 1 // CHECK1-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_ELEMENT]], i32 noundef 2) // CHECK1-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[VAR]], i32 noundef 3) // CHECK1-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr @[[GLOB3]], i32 4, ptr @_Z5tmainIiET_v.omp_outlined, ptr [[T_VAR]], ptr [[VEC]], ptr [[S_ARR]], ptr [[VAR]]) @@ -879,9 +877,8 @@ int main() { // CHECK5-NEXT: call void @_ZN1SIfEC1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[TEST]]) // CHECK5-NEXT: store i32 0, ptr [[T_VAR]], align 4 // CHECK5-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 4 [[VEC]], ptr align 4 @__const.main.vec, i64 8, i1 false) -// CHECK5-NEXT: [[ARRAYINIT_BEGIN:%.*]] = getelementptr inbounds [2 x %struct.S], ptr [[S_ARR]], i64 0, i64 0 -// CHECK5-NEXT: call void @_ZN1SIfEC1Ef(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_BEGIN]], float noundef 1.000000e+00) -// CHECK5-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[ARRAYINIT_BEGIN]], i64 1 +// CHECK5-NEXT: call void @_ZN1SIfEC1Ef(ptr noundef nonnull align 4 dereferenceable(4) [[S_ARR]], float noundef 1.000000e+00) +// CHECK5-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[S_ARR]], i64 1 // CHECK5-NEXT: call void @_ZN1SIfEC1Ef(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_ELEMENT]], float noundef 2.000000e+00) // CHECK5-NEXT: call void @_ZN1SIfEC1Ef(ptr noundef nonnull align 4 dereferenceable(4) [[VAR]], float noundef 3.000000e+00) // CHECK5-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr @[[GLOB3:[0-9]+]], i32 5, ptr @main.omp_outlined, ptr [[T_VAR]], ptr [[VEC]], ptr [[S_ARR]], ptr [[VAR]], ptr @_ZZ4mainE5sivar) @@ -1161,9 +1158,8 @@ int main() { // CHECK5-NEXT: call void @_ZN1SIiEC1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[TEST]]) // CHECK5-NEXT: store i32 0, ptr [[T_VAR]], align 4 // CHECK5-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 4 [[VEC]], ptr align 4 @__const._Z5tmainIiET_v.vec, i64 8, i1 false) -// CHECK5-NEXT: [[ARRAYINIT_BEGIN:%.*]] = getelementptr inbounds [2 x %struct.S.0], ptr [[S_ARR]], i64 0, i64 0 -// CHECK5-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_BEGIN]], i32 noundef 1) -// CHECK5-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[ARRAYINIT_BEGIN]], i64 1 +// CHECK5-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[S_ARR]], i32 noundef 1) +// CHECK5-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[S_ARR]], i64 1 // CHECK5-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_ELEMENT]], i32 noundef 2) // CHECK5-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[VAR]], i32 noundef 3) // CHECK5-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr @[[GLOB3]], i32 4, ptr @_Z5tmainIiET_v.omp_outlined, ptr [[T_VAR]], ptr [[VEC]], ptr [[S_ARR]], ptr [[VAR]]) diff --git a/clang/test/OpenMP/sections_private_codegen.cpp b/clang/test/OpenMP/sections_private_codegen.cpp index 034a8b38dac4c9d510f64308159d33fe761897b6..ee29fd953f97aee066e8f97dbd4cdbc78c4783a7 100644 --- a/clang/test/OpenMP/sections_private_codegen.cpp +++ b/clang/test/OpenMP/sections_private_codegen.cpp @@ -117,9 +117,8 @@ int main() { // CHECK1-NEXT: call void @_ZN1SIfEC1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[TEST]]) // CHECK1-NEXT: store i32 0, ptr [[T_VAR]], align 4 // CHECK1-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 4 [[VEC]], ptr align 4 @__const.main.vec, i64 8, i1 false) -// CHECK1-NEXT: [[ARRAYINIT_BEGIN:%.*]] = getelementptr inbounds [2 x %struct.S], ptr [[S_ARR]], i64 0, i64 0 -// CHECK1-NEXT: call void @_ZN1SIfEC1Ef(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_BEGIN]], float noundef 1.000000e+00) -// CHECK1-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[ARRAYINIT_BEGIN]], i64 1 +// CHECK1-NEXT: call void @_ZN1SIfEC1Ef(ptr noundef nonnull align 4 dereferenceable(4) [[S_ARR]], float noundef 1.000000e+00) +// CHECK1-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[S_ARR]], i64 1 // CHECK1-NEXT: call void @_ZN1SIfEC1Ef(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_ELEMENT]], float noundef 2.000000e+00) // CHECK1-NEXT: call void @_ZN1SIfEC1Ef(ptr noundef nonnull align 4 dereferenceable(4) [[VAR]], float noundef 3.000000e+00) // CHECK1-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr @[[GLOB3:[0-9]+]], i32 0, ptr @main.omp_outlined) @@ -274,9 +273,8 @@ int main() { // CHECK1-NEXT: call void @_ZN1SIiEC1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[TEST]]) // CHECK1-NEXT: store i32 0, ptr [[T_VAR]], align 4 // CHECK1-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 4 [[VEC]], ptr align 4 @__const._Z5tmainIiET_v.vec, i64 8, i1 false) -// CHECK1-NEXT: [[ARRAYINIT_BEGIN:%.*]] = getelementptr inbounds [2 x %struct.S.0], ptr [[S_ARR]], i64 0, i64 0 -// CHECK1-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_BEGIN]], i32 noundef 1) -// CHECK1-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[ARRAYINIT_BEGIN]], i64 1 +// CHECK1-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[S_ARR]], i32 noundef 1) +// CHECK1-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[S_ARR]], i64 1 // CHECK1-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_ELEMENT]], i32 noundef 2) // CHECK1-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[VAR]], i32 noundef 3) // CHECK1-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr @[[GLOB3]], i32 0, ptr @_Z5tmainIiET_v.omp_outlined) diff --git a/clang/test/OpenMP/sections_reduction_codegen.cpp b/clang/test/OpenMP/sections_reduction_codegen.cpp index 6166b5b3f9486c8ceb3cae5bbbde75841c6f831f..3eb7a1f8c54e5a87dcfe1c8e5f3850c969cc45f2 100644 --- a/clang/test/OpenMP/sections_reduction_codegen.cpp +++ b/clang/test/OpenMP/sections_reduction_codegen.cpp @@ -196,9 +196,8 @@ int main() { // CHECK1-NEXT: call void @_ZN1SIfEC1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[TEST]]) // CHECK1-NEXT: store float 0.000000e+00, ptr [[T_VAR]], align 4 // CHECK1-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 4 [[VEC]], ptr align 4 @__const.main.vec, i64 8, i1 false) -// CHECK1-NEXT: [[ARRAYINIT_BEGIN:%.*]] = getelementptr inbounds [2 x %struct.S], ptr [[S_ARR]], i64 0, i64 0 -// CHECK1-NEXT: call void @_ZN1SIfEC1Ef(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_BEGIN]], float noundef 1.000000e+00) -// CHECK1-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[ARRAYINIT_BEGIN]], i64 1 +// CHECK1-NEXT: call void @_ZN1SIfEC1Ef(ptr noundef nonnull align 4 dereferenceable(4) [[S_ARR]], float noundef 1.000000e+00) +// CHECK1-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[S_ARR]], i64 1 // CHECK1-NEXT: call void @_ZN1SIfEC1Ef(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_ELEMENT]], float noundef 2.000000e+00) // CHECK1-NEXT: call void @_ZN1SIfEC1Ef(ptr noundef nonnull align 4 dereferenceable(4) [[VAR]], float noundef 3.000000e+00) // CHECK1-NEXT: call void @_ZN1SIfEC1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[VAR1]]) @@ -546,9 +545,8 @@ int main() { // CHECK1-NEXT: call void @_ZN1SIiEC1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[TEST]]) // CHECK1-NEXT: store i32 0, ptr [[T_VAR]], align 4 // CHECK1-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 4 [[VEC]], ptr align 4 @__const._Z5tmainIiET_v.vec, i64 8, i1 false) -// CHECK1-NEXT: [[ARRAYINIT_BEGIN:%.*]] = getelementptr inbounds [2 x %struct.S.0], ptr [[S_ARR]], i64 0, i64 0 -// CHECK1-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_BEGIN]], i32 noundef 1) -// CHECK1-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[ARRAYINIT_BEGIN]], i64 1 +// CHECK1-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[S_ARR]], i32 noundef 1) +// CHECK1-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[S_ARR]], i64 1 // CHECK1-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_ELEMENT]], i32 noundef 2) // CHECK1-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[VAR]], i32 noundef 3) // CHECK1-NEXT: call void @_ZN1SIiEC1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[VAR1]]) diff --git a/clang/test/OpenMP/simd_private_taskloop_codegen.cpp b/clang/test/OpenMP/simd_private_taskloop_codegen.cpp index 50726b201523a0f78318ac98e5629fce5eb2031d..7e81f6f4dac600d271bf2713acd1235e12e672cf 100644 --- a/clang/test/OpenMP/simd_private_taskloop_codegen.cpp +++ b/clang/test/OpenMP/simd_private_taskloop_codegen.cpp @@ -470,9 +470,8 @@ int main() { // CHECK9-NEXT: call void @_ZN1SIfEC1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[TEST]]) // CHECK9-NEXT: store i32 0, ptr [[T_VAR]], align 4 // CHECK9-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 4 [[VEC]], ptr align 4 @__const.main.vec, i64 8, i1 false) -// CHECK9-NEXT: [[ARRAYINIT_BEGIN:%.*]] = getelementptr inbounds [2 x %struct.S], ptr [[S_ARR]], i64 0, i64 0 -// CHECK9-NEXT: call void @_ZN1SIfEC1Ef(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_BEGIN]], float noundef 1.000000e+00) -// CHECK9-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[ARRAYINIT_BEGIN]], i64 1 +// CHECK9-NEXT: call void @_ZN1SIfEC1Ef(ptr noundef nonnull align 4 dereferenceable(4) [[S_ARR]], float noundef 1.000000e+00) +// CHECK9-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[S_ARR]], i64 1 // CHECK9-NEXT: call void @_ZN1SIfEC1Ef(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_ELEMENT]], float noundef 2.000000e+00) // CHECK9-NEXT: store ptr [[TEST]], ptr [[VAR]], align 8 // CHECK9-NEXT: call void @__kmpc_taskgroup(ptr @[[GLOB1]], i32 [[TMP0]]) @@ -850,9 +849,8 @@ int main() { // CHECK9-NEXT: call void @_ZN1SIiEC1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[TEST]]) // CHECK9-NEXT: store i32 0, ptr [[T_VAR]], align 4 // CHECK9-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 4 [[VEC]], ptr align 4 @__const._Z5tmainIiET_v.vec, i64 8, i1 false) -// CHECK9-NEXT: [[ARRAYINIT_BEGIN:%.*]] = getelementptr inbounds [2 x %struct.S.2], ptr [[S_ARR]], i64 0, i64 0 -// CHECK9-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_BEGIN]], i32 noundef signext 1) -// CHECK9-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S_2]], ptr [[ARRAYINIT_BEGIN]], i64 1 +// CHECK9-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[S_ARR]], i32 noundef signext 1) +// CHECK9-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S_2]], ptr [[S_ARR]], i64 1 // CHECK9-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_ELEMENT]], i32 noundef signext 2) // CHECK9-NEXT: store ptr [[TEST]], ptr [[VAR]], align 8 // CHECK9-NEXT: call void @__kmpc_taskgroup(ptr @[[GLOB1]], i32 [[TMP0]]) @@ -1209,9 +1207,8 @@ int main() { // CHECK11-NEXT: call void @_ZN1SIfEC1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[TEST]]) // CHECK11-NEXT: store i32 0, ptr [[T_VAR]], align 4 // CHECK11-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 4 [[VEC]], ptr align 4 @__const.main.vec, i32 8, i1 false) -// CHECK11-NEXT: [[ARRAYINIT_BEGIN:%.*]] = getelementptr inbounds [2 x %struct.S], ptr [[S_ARR]], i32 0, i32 0 -// CHECK11-NEXT: call void @_ZN1SIfEC1Ef(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_BEGIN]], float noundef 1.000000e+00) -// CHECK11-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[ARRAYINIT_BEGIN]], i32 1 +// CHECK11-NEXT: call void @_ZN1SIfEC1Ef(ptr noundef nonnull align 4 dereferenceable(4) [[S_ARR]], float noundef 1.000000e+00) +// CHECK11-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[S_ARR]], i32 1 // CHECK11-NEXT: call void @_ZN1SIfEC1Ef(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_ELEMENT]], float noundef 2.000000e+00) // CHECK11-NEXT: store ptr [[TEST]], ptr [[VAR]], align 4 // CHECK11-NEXT: call void @__kmpc_taskgroup(ptr @[[GLOB1]], i32 [[TMP0]]) @@ -1587,9 +1584,8 @@ int main() { // CHECK11-NEXT: call void @_ZN1SIiEC1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[TEST]]) // CHECK11-NEXT: store i32 0, ptr [[T_VAR]], align 4 // CHECK11-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 4 [[VEC]], ptr align 4 @__const._Z5tmainIiET_v.vec, i32 8, i1 false) -// CHECK11-NEXT: [[ARRAYINIT_BEGIN:%.*]] = getelementptr inbounds [2 x %struct.S.2], ptr [[S_ARR]], i32 0, i32 0 -// CHECK11-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_BEGIN]], i32 noundef 1) -// CHECK11-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S_2]], ptr [[ARRAYINIT_BEGIN]], i32 1 +// CHECK11-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[S_ARR]], i32 noundef 1) +// CHECK11-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S_2]], ptr [[S_ARR]], i32 1 // CHECK11-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_ELEMENT]], i32 noundef 2) // CHECK11-NEXT: store ptr [[TEST]], ptr [[VAR]], align 4 // CHECK11-NEXT: call void @__kmpc_taskgroup(ptr @[[GLOB1]], i32 [[TMP0]]) @@ -1955,9 +1951,8 @@ int main() { // CHECK13-NEXT: call void @_ZN1SIfEC1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[TEST]]) // CHECK13-NEXT: store i32 0, ptr [[T_VAR]], align 4 // CHECK13-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 4 [[VEC]], ptr align 4 @__const.main.vec, i64 8, i1 false) -// CHECK13-NEXT: [[ARRAYINIT_BEGIN:%.*]] = getelementptr inbounds [2 x %struct.S], ptr [[S_ARR]], i64 0, i64 0 -// CHECK13-NEXT: call void @_ZN1SIfEC1Ef(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_BEGIN]], float noundef 1.000000e+00) -// CHECK13-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[ARRAYINIT_BEGIN]], i64 1 +// CHECK13-NEXT: call void @_ZN1SIfEC1Ef(ptr noundef nonnull align 4 dereferenceable(4) [[S_ARR]], float noundef 1.000000e+00) +// CHECK13-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[S_ARR]], i64 1 // CHECK13-NEXT: call void @_ZN1SIfEC1Ef(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_ELEMENT]], float noundef 2.000000e+00) // CHECK13-NEXT: store ptr [[TEST]], ptr [[VAR]], align 8 // CHECK13-NEXT: store ptr undef, ptr [[_TMP1]], align 8 @@ -2123,9 +2118,8 @@ int main() { // CHECK13-NEXT: call void @_ZN1SIiEC1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[TEST]]) // CHECK13-NEXT: store i32 0, ptr [[T_VAR]], align 4 // CHECK13-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 4 [[VEC]], ptr align 4 @__const._Z5tmainIiET_v.vec, i64 8, i1 false) -// CHECK13-NEXT: [[ARRAYINIT_BEGIN:%.*]] = getelementptr inbounds [2 x %struct.S.0], ptr [[S_ARR]], i64 0, i64 0 -// CHECK13-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_BEGIN]], i32 noundef signext 1) -// CHECK13-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[ARRAYINIT_BEGIN]], i64 1 +// CHECK13-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[S_ARR]], i32 noundef signext 1) +// CHECK13-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[S_ARR]], i64 1 // CHECK13-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_ELEMENT]], i32 noundef signext 2) // CHECK13-NEXT: store ptr [[TEST]], ptr [[VAR]], align 8 // CHECK13-NEXT: store ptr undef, ptr [[_TMP1]], align 8 @@ -2342,9 +2336,8 @@ int main() { // CHECK15-NEXT: call void @_ZN1SIfEC1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[TEST]]) // CHECK15-NEXT: store i32 0, ptr [[T_VAR]], align 4 // CHECK15-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 4 [[VEC]], ptr align 4 @__const.main.vec, i32 8, i1 false) -// CHECK15-NEXT: [[ARRAYINIT_BEGIN:%.*]] = getelementptr inbounds [2 x %struct.S], ptr [[S_ARR]], i32 0, i32 0 -// CHECK15-NEXT: call void @_ZN1SIfEC1Ef(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_BEGIN]], float noundef 1.000000e+00) -// CHECK15-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[ARRAYINIT_BEGIN]], i32 1 +// CHECK15-NEXT: call void @_ZN1SIfEC1Ef(ptr noundef nonnull align 4 dereferenceable(4) [[S_ARR]], float noundef 1.000000e+00) +// CHECK15-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[S_ARR]], i32 1 // CHECK15-NEXT: call void @_ZN1SIfEC1Ef(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_ELEMENT]], float noundef 2.000000e+00) // CHECK15-NEXT: store ptr [[TEST]], ptr [[VAR]], align 4 // CHECK15-NEXT: store ptr undef, ptr [[_TMP1]], align 4 @@ -2508,9 +2501,8 @@ int main() { // CHECK15-NEXT: call void @_ZN1SIiEC1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[TEST]]) // CHECK15-NEXT: store i32 0, ptr [[T_VAR]], align 4 // CHECK15-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 4 [[VEC]], ptr align 4 @__const._Z5tmainIiET_v.vec, i32 8, i1 false) -// CHECK15-NEXT: [[ARRAYINIT_BEGIN:%.*]] = getelementptr inbounds [2 x %struct.S.0], ptr [[S_ARR]], i32 0, i32 0 -// CHECK15-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_BEGIN]], i32 noundef 1) -// CHECK15-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[ARRAYINIT_BEGIN]], i32 1 +// CHECK15-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[S_ARR]], i32 noundef 1) +// CHECK15-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[S_ARR]], i32 1 // CHECK15-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_ELEMENT]], i32 noundef 2) // CHECK15-NEXT: store ptr [[TEST]], ptr [[VAR]], align 4 // CHECK15-NEXT: store ptr undef, ptr [[_TMP1]], align 4 diff --git a/clang/test/OpenMP/single_firstprivate_codegen.cpp b/clang/test/OpenMP/single_firstprivate_codegen.cpp index f7156bf1c54d67c46e48c3ec3dc7ddd39cd1aa97..4b4c96655fccbff0932854284da1dfcc6a410cbd 100644 --- a/clang/test/OpenMP/single_firstprivate_codegen.cpp +++ b/clang/test/OpenMP/single_firstprivate_codegen.cpp @@ -357,9 +357,8 @@ int main() { // CHECK1-NEXT: call void @_ZN1SIiEC1Ev(ptr nonnull align 4 dereferenceable(4) [[TEST]]) // CHECK1-NEXT: store i32 0, ptr [[T_VAR]], align 4 // CHECK1-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 4 [[VEC]], ptr align 4 @__const._Z5tmainIiET_v.vec, i64 8, i1 false) -// CHECK1-NEXT: [[ARRAYINIT_BEGIN:%.*]] = getelementptr inbounds [2 x %struct.S.0], ptr [[S_ARR]], i64 0, i64 0 -// CHECK1-NEXT: call void @_ZN1SIiEC1Ei(ptr nonnull align 4 dereferenceable(4) [[ARRAYINIT_BEGIN]], i32 1) -// CHECK1-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[ARRAYINIT_BEGIN]], i64 1 +// CHECK1-NEXT: call void @_ZN1SIiEC1Ei(ptr nonnull align 4 dereferenceable(4) [[S_ARR]], i32 1) +// CHECK1-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[S_ARR]], i64 1 // CHECK1-NEXT: call void @_ZN1SIiEC1Ei(ptr nonnull align 4 dereferenceable(4) [[ARRAYINIT_ELEMENT]], i32 2) // CHECK1-NEXT: call void @_ZN1SIiEC1Ei(ptr nonnull align 4 dereferenceable(4) [[VAR]], i32 3) // CHECK1-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr @[[GLOB1]], i32 4, ptr @_Z5tmainIiET_v.omp_outlined, ptr [[T_VAR]], ptr [[VEC]], ptr [[S_ARR]], ptr [[VAR]]) diff --git a/clang/test/OpenMP/single_private_codegen.cpp b/clang/test/OpenMP/single_private_codegen.cpp index e657d7bcbe8881c34d64a112dfdbd4a22cae67cb..ce79cfd1bd2690c5459552571940a4087c34d200 100644 --- a/clang/test/OpenMP/single_private_codegen.cpp +++ b/clang/test/OpenMP/single_private_codegen.cpp @@ -104,9 +104,8 @@ int main() { // CHECK1-NEXT: call void @_ZN1SIfEC1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[TEST]]) // CHECK1-NEXT: store i32 0, ptr [[T_VAR]], align 4 // CHECK1-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 4 [[VEC]], ptr align 4 @__const.main.vec, i64 8, i1 false) -// CHECK1-NEXT: [[ARRAYINIT_BEGIN:%.*]] = getelementptr inbounds [2 x %struct.S], ptr [[S_ARR]], i64 0, i64 0 -// CHECK1-NEXT: call void @_ZN1SIfEC1Ef(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_BEGIN]], float noundef 1.000000e+00) -// CHECK1-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[ARRAYINIT_BEGIN]], i64 1 +// CHECK1-NEXT: call void @_ZN1SIfEC1Ef(ptr noundef nonnull align 4 dereferenceable(4) [[S_ARR]], float noundef 1.000000e+00) +// CHECK1-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[S_ARR]], i64 1 // CHECK1-NEXT: call void @_ZN1SIfEC1Ef(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_ELEMENT]], float noundef 2.000000e+00) // CHECK1-NEXT: call void @_ZN1SIfEC1Ef(ptr noundef nonnull align 4 dereferenceable(4) [[VAR]], float noundef 3.000000e+00) // CHECK1-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr @[[GLOB1:[0-9]+]], i32 0, ptr @main.omp_outlined) @@ -226,9 +225,8 @@ int main() { // CHECK1-NEXT: call void @_ZN1SIiEC1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[TEST]]) // CHECK1-NEXT: store i32 0, ptr [[T_VAR]], align 4 // CHECK1-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 4 [[VEC]], ptr align 4 @__const._Z5tmainIiET_v.vec, i64 8, i1 false) -// CHECK1-NEXT: [[ARRAYINIT_BEGIN:%.*]] = getelementptr inbounds [2 x %struct.S.0], ptr [[S_ARR]], i64 0, i64 0 -// CHECK1-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_BEGIN]], i32 noundef 1) -// CHECK1-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[ARRAYINIT_BEGIN]], i64 1 +// CHECK1-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[S_ARR]], i32 noundef 1) +// CHECK1-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[S_ARR]], i64 1 // CHECK1-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_ELEMENT]], i32 noundef 2) // CHECK1-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[VAR]], i32 noundef 3) // CHECK1-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr @[[GLOB1]], i32 0, ptr @_Z5tmainIiET_v.omp_outlined) diff --git a/clang/test/OpenMP/target_teams_distribute_firstprivate_codegen.cpp b/clang/test/OpenMP/target_teams_distribute_firstprivate_codegen.cpp index da69e19a890efa72621f2a9e7e176f7d8e4ea551..ab0a35f791a3168eff0394768a0fe650551924d6 100644 --- a/clang/test/OpenMP/target_teams_distribute_firstprivate_codegen.cpp +++ b/clang/test/OpenMP/target_teams_distribute_firstprivate_codegen.cpp @@ -546,9 +546,8 @@ int main() { // CHECK1-NEXT: call void @_ZN1SIiEC1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[TEST]]) // CHECK1-NEXT: store i32 0, ptr [[T_VAR]], align 4 // CHECK1-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 4 [[VEC]], ptr align 4 @__const._Z5tmainIiET_v.vec, i64 8, i1 false) -// CHECK1-NEXT: [[ARRAYINIT_BEGIN:%.*]] = getelementptr inbounds [2 x %struct.S.0], ptr [[S_ARR]], i64 0, i64 0 -// CHECK1-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_BEGIN]], i32 noundef signext 1) -// CHECK1-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[ARRAYINIT_BEGIN]], i64 1 +// CHECK1-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[S_ARR]], i32 noundef signext 1) +// CHECK1-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[S_ARR]], i64 1 // CHECK1-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_ELEMENT]], i32 noundef signext 2) // CHECK1-NEXT: store ptr [[TEST]], ptr [[VAR]], align 8 // CHECK1-NEXT: [[TMP0:%.*]] = load ptr, ptr [[VAR]], align 8 @@ -1346,9 +1345,8 @@ int main() { // CHECK3-NEXT: call void @_ZN1SIiEC1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[TEST]]) // CHECK3-NEXT: store i32 0, ptr [[T_VAR]], align 4 // CHECK3-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 4 [[VEC]], ptr align 4 @__const._Z5tmainIiET_v.vec, i32 8, i1 false) -// CHECK3-NEXT: [[ARRAYINIT_BEGIN:%.*]] = getelementptr inbounds [2 x %struct.S.0], ptr [[S_ARR]], i32 0, i32 0 -// CHECK3-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_BEGIN]], i32 noundef 1) -// CHECK3-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[ARRAYINIT_BEGIN]], i32 1 +// CHECK3-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[S_ARR]], i32 noundef 1) +// CHECK3-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[S_ARR]], i32 1 // CHECK3-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_ELEMENT]], i32 noundef 2) // CHECK3-NEXT: store ptr [[TEST]], ptr [[VAR]], align 4 // CHECK3-NEXT: [[TMP0:%.*]] = load ptr, ptr [[VAR]], align 4 diff --git a/clang/test/OpenMP/target_teams_distribute_lastprivate_codegen.cpp b/clang/test/OpenMP/target_teams_distribute_lastprivate_codegen.cpp index e23435d13e9aecd37d41e59d4e8d8932065f4151..adbab5d8775f7f3669a0944a7e6cd41626dbf337 100644 --- a/clang/test/OpenMP/target_teams_distribute_lastprivate_codegen.cpp +++ b/clang/test/OpenMP/target_teams_distribute_lastprivate_codegen.cpp @@ -475,9 +475,8 @@ int main() { // CHECK9-NEXT: call void @_ZN1SIfEC1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[TEST]]) // CHECK9-NEXT: store i32 0, ptr [[T_VAR]], align 4 // CHECK9-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 4 [[VEC]], ptr align 4 @__const.main.vec, i64 8, i1 false) -// CHECK9-NEXT: [[ARRAYINIT_BEGIN:%.*]] = getelementptr inbounds [2 x %struct.S], ptr [[S_ARR]], i64 0, i64 0 -// CHECK9-NEXT: call void @_ZN1SIfEC1Ef(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_BEGIN]], float noundef 1.000000e+00) -// CHECK9-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[ARRAYINIT_BEGIN]], i64 1 +// CHECK9-NEXT: call void @_ZN1SIfEC1Ef(ptr noundef nonnull align 4 dereferenceable(4) [[S_ARR]], float noundef 1.000000e+00) +// CHECK9-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[S_ARR]], i64 1 // CHECK9-NEXT: call void @_ZN1SIfEC1Ef(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_ELEMENT]], float noundef 2.000000e+00) // CHECK9-NEXT: store ptr [[TEST]], ptr [[VAR]], align 8 // CHECK9-NEXT: [[TMP0:%.*]] = load ptr, ptr [[VAR]], align 8 @@ -799,9 +798,8 @@ int main() { // CHECK9-NEXT: call void @_ZN1SIiEC1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[TEST]]) // CHECK9-NEXT: store i32 0, ptr [[T_VAR]], align 4 // CHECK9-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 4 [[VEC]], ptr align 4 @__const._Z5tmainIiET_v.vec, i64 8, i1 false) -// CHECK9-NEXT: [[ARRAYINIT_BEGIN:%.*]] = getelementptr inbounds [2 x %struct.S.0], ptr [[S_ARR]], i64 0, i64 0 -// CHECK9-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_BEGIN]], i32 noundef signext 1) -// CHECK9-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[ARRAYINIT_BEGIN]], i64 1 +// CHECK9-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[S_ARR]], i32 noundef signext 1) +// CHECK9-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[S_ARR]], i64 1 // CHECK9-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_ELEMENT]], i32 noundef signext 2) // CHECK9-NEXT: store ptr [[TEST]], ptr [[VAR]], align 8 // CHECK9-NEXT: [[TMP0:%.*]] = load ptr, ptr [[VAR]], align 8 @@ -1176,9 +1174,8 @@ int main() { // CHECK11-NEXT: call void @_ZN1SIfEC1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[TEST]]) // CHECK11-NEXT: store i32 0, ptr [[T_VAR]], align 4 // CHECK11-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 4 [[VEC]], ptr align 4 @__const.main.vec, i32 8, i1 false) -// CHECK11-NEXT: [[ARRAYINIT_BEGIN:%.*]] = getelementptr inbounds [2 x %struct.S], ptr [[S_ARR]], i32 0, i32 0 -// CHECK11-NEXT: call void @_ZN1SIfEC1Ef(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_BEGIN]], float noundef 1.000000e+00) -// CHECK11-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[ARRAYINIT_BEGIN]], i32 1 +// CHECK11-NEXT: call void @_ZN1SIfEC1Ef(ptr noundef nonnull align 4 dereferenceable(4) [[S_ARR]], float noundef 1.000000e+00) +// CHECK11-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[S_ARR]], i32 1 // CHECK11-NEXT: call void @_ZN1SIfEC1Ef(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_ELEMENT]], float noundef 2.000000e+00) // CHECK11-NEXT: store ptr [[TEST]], ptr [[VAR]], align 4 // CHECK11-NEXT: [[TMP0:%.*]] = load ptr, ptr [[VAR]], align 4 @@ -1498,9 +1495,8 @@ int main() { // CHECK11-NEXT: call void @_ZN1SIiEC1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[TEST]]) // CHECK11-NEXT: store i32 0, ptr [[T_VAR]], align 4 // CHECK11-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 4 [[VEC]], ptr align 4 @__const._Z5tmainIiET_v.vec, i32 8, i1 false) -// CHECK11-NEXT: [[ARRAYINIT_BEGIN:%.*]] = getelementptr inbounds [2 x %struct.S.0], ptr [[S_ARR]], i32 0, i32 0 -// CHECK11-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_BEGIN]], i32 noundef 1) -// CHECK11-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[ARRAYINIT_BEGIN]], i32 1 +// CHECK11-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[S_ARR]], i32 noundef 1) +// CHECK11-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[S_ARR]], i32 1 // CHECK11-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_ELEMENT]], i32 noundef 2) // CHECK11-NEXT: store ptr [[TEST]], ptr [[VAR]], align 4 // CHECK11-NEXT: [[TMP0:%.*]] = load ptr, ptr [[VAR]], align 4 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 bf1fc1d7cbae5f6b94645116ca0f9822f9cc16a1..0806a71f95bcc524ee1f1fb816b17f0b33abdac0 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 @@ -737,9 +737,8 @@ int main() { // CHECK1-NEXT: call void @_ZN1SIiEC1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[TEST]]) // CHECK1-NEXT: store i32 0, ptr [[T_VAR]], align 4 // CHECK1-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 4 [[VEC]], ptr align 4 @__const._Z5tmainIiET_v.vec, i64 8, i1 false) -// CHECK1-NEXT: [[ARRAYINIT_BEGIN:%.*]] = getelementptr inbounds [2 x %struct.S.0], ptr [[S_ARR]], i64 0, i64 0 -// CHECK1-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_BEGIN]], i32 noundef signext 1) -// CHECK1-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[ARRAYINIT_BEGIN]], i64 1 +// CHECK1-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[S_ARR]], i32 noundef signext 1) +// CHECK1-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[S_ARR]], i64 1 // CHECK1-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_ELEMENT]], i32 noundef signext 2) // CHECK1-NEXT: store ptr [[TEST]], ptr [[VAR]], align 8 // CHECK1-NEXT: [[TMP0:%.*]] = load ptr, ptr [[VAR]], align 8 @@ -1793,9 +1792,8 @@ int main() { // CHECK3-NEXT: call void @_ZN1SIiEC1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[TEST]]) // CHECK3-NEXT: store i32 0, ptr [[T_VAR]], align 4 // CHECK3-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 4 [[VEC]], ptr align 4 @__const._Z5tmainIiET_v.vec, i32 8, i1 false) -// CHECK3-NEXT: [[ARRAYINIT_BEGIN:%.*]] = getelementptr inbounds [2 x %struct.S.0], ptr [[S_ARR]], i32 0, i32 0 -// CHECK3-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_BEGIN]], i32 noundef 1) -// CHECK3-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[ARRAYINIT_BEGIN]], i32 1 +// CHECK3-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[S_ARR]], i32 noundef 1) +// CHECK3-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[S_ARR]], i32 1 // CHECK3-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_ELEMENT]], i32 noundef 2) // CHECK3-NEXT: store ptr [[TEST]], ptr [[VAR]], align 4 // CHECK3-NEXT: [[TMP0:%.*]] = load ptr, ptr [[VAR]], align 4 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 ae900d2dc53b9c1914c580f0b6b029fae008a871..6f14f5113ee274eb9fefa9cc6b82bf7bbe2dbc7f 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 @@ -736,9 +736,8 @@ int main() { // CHECK5-NEXT: call void @_ZN1SIfEC1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[TEST]]) // CHECK5-NEXT: store i32 0, ptr [[T_VAR]], align 4 // CHECK5-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 4 [[VEC]], ptr align 4 @__const.main.vec, i64 8, i1 false) -// CHECK5-NEXT: [[ARRAYINIT_BEGIN:%.*]] = getelementptr inbounds [2 x %struct.S], ptr [[S_ARR]], i64 0, i64 0 -// CHECK5-NEXT: call void @_ZN1SIfEC1Ef(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_BEGIN]], float noundef 1.000000e+00) -// CHECK5-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[ARRAYINIT_BEGIN]], i64 1 +// CHECK5-NEXT: call void @_ZN1SIfEC1Ef(ptr noundef nonnull align 4 dereferenceable(4) [[S_ARR]], float noundef 1.000000e+00) +// CHECK5-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[S_ARR]], i64 1 // CHECK5-NEXT: call void @_ZN1SIfEC1Ef(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_ELEMENT]], float noundef 2.000000e+00) // CHECK5-NEXT: store ptr [[TEST]], ptr [[VAR]], align 8 // CHECK5-NEXT: [[TMP0:%.*]] = load ptr, ptr [[VAR]], align 8 @@ -1214,9 +1213,8 @@ int main() { // CHECK5-NEXT: call void @_ZN1SIiEC1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[TEST]]) // CHECK5-NEXT: store i32 0, ptr [[T_VAR]], align 4 // CHECK5-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 4 [[VEC]], ptr align 4 @__const._Z5tmainIiET_v.vec, i64 8, i1 false) -// CHECK5-NEXT: [[ARRAYINIT_BEGIN:%.*]] = getelementptr inbounds [2 x %struct.S.0], ptr [[S_ARR]], i64 0, i64 0 -// CHECK5-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_BEGIN]], i32 noundef signext 1) -// CHECK5-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[ARRAYINIT_BEGIN]], i64 1 +// CHECK5-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[S_ARR]], i32 noundef signext 1) +// CHECK5-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[S_ARR]], i64 1 // CHECK5-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_ELEMENT]], i32 noundef signext 2) // CHECK5-NEXT: store ptr [[TEST]], ptr [[VAR]], align 8 // CHECK5-NEXT: [[TMP0:%.*]] = load ptr, ptr [[VAR]], align 8 @@ -1736,9 +1734,8 @@ int main() { // CHECK7-NEXT: call void @_ZN1SIfEC1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[TEST]]) // CHECK7-NEXT: store i32 0, ptr [[T_VAR]], align 4 // CHECK7-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 4 [[VEC]], ptr align 4 @__const.main.vec, i32 8, i1 false) -// CHECK7-NEXT: [[ARRAYINIT_BEGIN:%.*]] = getelementptr inbounds [2 x %struct.S], ptr [[S_ARR]], i32 0, i32 0 -// CHECK7-NEXT: call void @_ZN1SIfEC1Ef(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_BEGIN]], float noundef 1.000000e+00) -// CHECK7-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[ARRAYINIT_BEGIN]], i32 1 +// CHECK7-NEXT: call void @_ZN1SIfEC1Ef(ptr noundef nonnull align 4 dereferenceable(4) [[S_ARR]], float noundef 1.000000e+00) +// CHECK7-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[S_ARR]], i32 1 // CHECK7-NEXT: call void @_ZN1SIfEC1Ef(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_ELEMENT]], float noundef 2.000000e+00) // CHECK7-NEXT: store ptr [[TEST]], ptr [[VAR]], align 4 // CHECK7-NEXT: [[TMP0:%.*]] = load ptr, ptr [[VAR]], align 4 @@ -2208,9 +2205,8 @@ int main() { // CHECK7-NEXT: call void @_ZN1SIiEC1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[TEST]]) // CHECK7-NEXT: store i32 0, ptr [[T_VAR]], align 4 // CHECK7-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 4 [[VEC]], ptr align 4 @__const._Z5tmainIiET_v.vec, i32 8, i1 false) -// CHECK7-NEXT: [[ARRAYINIT_BEGIN:%.*]] = getelementptr inbounds [2 x %struct.S.0], ptr [[S_ARR]], i32 0, i32 0 -// CHECK7-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_BEGIN]], i32 noundef 1) -// CHECK7-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[ARRAYINIT_BEGIN]], i32 1 +// CHECK7-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[S_ARR]], i32 noundef 1) +// CHECK7-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[S_ARR]], i32 1 // CHECK7-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_ELEMENT]], i32 noundef 2) // CHECK7-NEXT: store ptr [[TEST]], ptr [[VAR]], align 4 // CHECK7-NEXT: [[TMP0:%.*]] = load ptr, ptr [[VAR]], align 4 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 49e4681c051530b603ac7c12bc8859effa6a1488..05ab657a3c83ea3e1811ca597a076c18873e886a 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 @@ -564,9 +564,8 @@ int main() { // CHECK1-NEXT: call void @_ZN1SIiEC1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[TEST]]) // CHECK1-NEXT: store i32 0, ptr [[T_VAR]], align 4 // CHECK1-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 4 [[VEC]], ptr align 4 @__const._Z5tmainIiET_v.vec, i64 8, i1 false) -// CHECK1-NEXT: [[ARRAYINIT_BEGIN:%.*]] = getelementptr inbounds [2 x %struct.S.0], ptr [[S_ARR]], i64 0, i64 0 -// CHECK1-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_BEGIN]], i32 noundef signext 1) -// CHECK1-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[ARRAYINIT_BEGIN]], i64 1 +// CHECK1-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[S_ARR]], i32 noundef signext 1) +// CHECK1-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[S_ARR]], i64 1 // CHECK1-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_ELEMENT]], i32 noundef signext 2) // CHECK1-NEXT: store ptr [[TEST]], ptr [[VAR]], align 8 // CHECK1-NEXT: store ptr undef, ptr [[_TMP1]], align 8 @@ -1291,9 +1290,8 @@ int main() { // CHECK3-NEXT: call void @_ZN1SIiEC1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[TEST]]) // CHECK3-NEXT: store i32 0, ptr [[T_VAR]], align 4 // CHECK3-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 4 [[VEC]], ptr align 4 @__const._Z5tmainIiET_v.vec, i32 8, i1 false) -// CHECK3-NEXT: [[ARRAYINIT_BEGIN:%.*]] = getelementptr inbounds [2 x %struct.S.0], ptr [[S_ARR]], i32 0, i32 0 -// CHECK3-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_BEGIN]], i32 noundef 1) -// CHECK3-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[ARRAYINIT_BEGIN]], i32 1 +// CHECK3-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[S_ARR]], i32 noundef 1) +// CHECK3-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[S_ARR]], i32 1 // CHECK3-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_ELEMENT]], i32 noundef 2) // CHECK3-NEXT: store ptr [[TEST]], ptr [[VAR]], align 4 // CHECK3-NEXT: store ptr undef, ptr [[_TMP1]], align 4 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 ea05aecebf3713cbd319dcee8509eb4520fc279f..fbf0b842542258ba6c79b2da6191f5bc86e25f84 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 @@ -749,9 +749,8 @@ int main() { // CHECK1-NEXT: call void @_ZN1SIiEC1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[TEST]]) // CHECK1-NEXT: store i32 0, ptr [[T_VAR]], align 4 // CHECK1-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 4 [[VEC]], ptr align 4 @__const._Z5tmainIiET_v.vec, i64 8, i1 false) -// CHECK1-NEXT: [[ARRAYINIT_BEGIN:%.*]] = getelementptr inbounds [2 x %struct.S.0], ptr [[S_ARR]], i64 0, i64 0 -// CHECK1-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_BEGIN]], i32 noundef signext 1) -// CHECK1-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[ARRAYINIT_BEGIN]], i64 1 +// CHECK1-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[S_ARR]], i32 noundef signext 1) +// CHECK1-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[S_ARR]], i64 1 // CHECK1-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_ELEMENT]], i32 noundef signext 2) // CHECK1-NEXT: store ptr [[TEST]], ptr [[VAR]], align 8 // CHECK1-NEXT: [[TMP0:%.*]] = load ptr, ptr [[VAR]], align 8 @@ -1833,9 +1832,8 @@ int main() { // CHECK3-NEXT: call void @_ZN1SIiEC1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[TEST]]) // CHECK3-NEXT: store i32 0, ptr [[T_VAR]], align 4 // CHECK3-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 4 [[VEC]], ptr align 4 @__const._Z5tmainIiET_v.vec, i32 8, i1 false) -// CHECK3-NEXT: [[ARRAYINIT_BEGIN:%.*]] = getelementptr inbounds [2 x %struct.S.0], ptr [[S_ARR]], i32 0, i32 0 -// CHECK3-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_BEGIN]], i32 noundef 1) -// CHECK3-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[ARRAYINIT_BEGIN]], i32 1 +// CHECK3-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[S_ARR]], i32 noundef 1) +// CHECK3-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[S_ARR]], i32 1 // CHECK3-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_ELEMENT]], i32 noundef 2) // CHECK3-NEXT: store ptr [[TEST]], ptr [[VAR]], align 4 // CHECK3-NEXT: [[TMP0:%.*]] = load ptr, ptr [[VAR]], align 4 @@ -2856,9 +2854,8 @@ int main() { // CHECK7-NEXT: call void @_ZN1SIiEC1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[TEST]]) // CHECK7-NEXT: store i32 0, ptr [[T_VAR]], align 4 // CHECK7-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 4 [[VEC]], ptr align 4 @__const._Z5tmainIiET_v.vec, i64 8, i1 false) -// CHECK7-NEXT: [[ARRAYINIT_BEGIN:%.*]] = getelementptr inbounds [2 x %struct.S.0], ptr [[S_ARR]], i64 0, i64 0 -// CHECK7-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_BEGIN]], i32 noundef signext 1) -// CHECK7-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[ARRAYINIT_BEGIN]], i64 1 +// CHECK7-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[S_ARR]], i32 noundef signext 1) +// CHECK7-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[S_ARR]], i64 1 // CHECK7-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_ELEMENT]], i32 noundef signext 2) // CHECK7-NEXT: store ptr [[TEST]], ptr [[VAR]], align 8 // CHECK7-NEXT: [[TMP0:%.*]] = load ptr, ptr [[VAR]], align 8 @@ -3177,9 +3174,8 @@ int main() { // CHECK9-NEXT: call void @_ZN1SIiEC1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[TEST]]) // CHECK9-NEXT: store i32 0, ptr [[T_VAR]], align 4 // CHECK9-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 4 [[VEC]], ptr align 4 @__const._Z5tmainIiET_v.vec, i32 8, i1 false) -// CHECK9-NEXT: [[ARRAYINIT_BEGIN:%.*]] = getelementptr inbounds [2 x %struct.S.0], ptr [[S_ARR]], i32 0, i32 0 -// CHECK9-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_BEGIN]], i32 noundef 1) -// CHECK9-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[ARRAYINIT_BEGIN]], i32 1 +// CHECK9-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[S_ARR]], i32 noundef 1) +// CHECK9-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[S_ARR]], i32 1 // CHECK9-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_ELEMENT]], i32 noundef 2) // CHECK9-NEXT: store ptr [[TEST]], ptr [[VAR]], align 4 // CHECK9-NEXT: [[TMP0:%.*]] = load ptr, ptr [[VAR]], align 4 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 b2b9e2082fa3a8dd1e01d4de683805c26930587f..cb8e091e8b02cdf270df3e3764ec9d1b6d6a49a1 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 @@ -764,9 +764,8 @@ int main() { // CHECK5-NEXT: call void @_ZN1SIfEC1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[TEST]]) // CHECK5-NEXT: store i32 0, ptr [[T_VAR]], align 4 // CHECK5-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 4 [[VEC]], ptr align 4 @__const.main.vec, i64 8, i1 false) -// CHECK5-NEXT: [[ARRAYINIT_BEGIN:%.*]] = getelementptr inbounds [2 x %struct.S], ptr [[S_ARR]], i64 0, i64 0 -// CHECK5-NEXT: call void @_ZN1SIfEC1Ef(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_BEGIN]], float noundef 1.000000e+00) -// CHECK5-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[ARRAYINIT_BEGIN]], i64 1 +// CHECK5-NEXT: call void @_ZN1SIfEC1Ef(ptr noundef nonnull align 4 dereferenceable(4) [[S_ARR]], float noundef 1.000000e+00) +// CHECK5-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[S_ARR]], i64 1 // CHECK5-NEXT: call void @_ZN1SIfEC1Ef(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_ELEMENT]], float noundef 2.000000e+00) // CHECK5-NEXT: store ptr [[TEST]], ptr [[VAR]], align 8 // CHECK5-NEXT: [[TMP0:%.*]] = load ptr, ptr [[VAR]], align 8 @@ -1256,9 +1255,8 @@ int main() { // CHECK5-NEXT: call void @_ZN1SIiEC1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[TEST]]) // CHECK5-NEXT: store i32 0, ptr [[T_VAR]], align 4 // CHECK5-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 4 [[VEC]], ptr align 4 @__const._Z5tmainIiET_v.vec, i64 8, i1 false) -// CHECK5-NEXT: [[ARRAYINIT_BEGIN:%.*]] = getelementptr inbounds [2 x %struct.S.0], ptr [[S_ARR]], i64 0, i64 0 -// CHECK5-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_BEGIN]], i32 noundef signext 1) -// CHECK5-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[ARRAYINIT_BEGIN]], i64 1 +// CHECK5-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[S_ARR]], i32 noundef signext 1) +// CHECK5-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[S_ARR]], i64 1 // CHECK5-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_ELEMENT]], i32 noundef signext 2) // CHECK5-NEXT: store ptr [[TEST]], ptr [[VAR]], align 8 // CHECK5-NEXT: [[TMP0:%.*]] = load ptr, ptr [[VAR]], align 8 @@ -1792,9 +1790,8 @@ int main() { // CHECK7-NEXT: call void @_ZN1SIfEC1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[TEST]]) // CHECK7-NEXT: store i32 0, ptr [[T_VAR]], align 4 // CHECK7-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 4 [[VEC]], ptr align 4 @__const.main.vec, i32 8, i1 false) -// CHECK7-NEXT: [[ARRAYINIT_BEGIN:%.*]] = getelementptr inbounds [2 x %struct.S], ptr [[S_ARR]], i32 0, i32 0 -// CHECK7-NEXT: call void @_ZN1SIfEC1Ef(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_BEGIN]], float noundef 1.000000e+00) -// CHECK7-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[ARRAYINIT_BEGIN]], i32 1 +// CHECK7-NEXT: call void @_ZN1SIfEC1Ef(ptr noundef nonnull align 4 dereferenceable(4) [[S_ARR]], float noundef 1.000000e+00) +// CHECK7-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[S_ARR]], i32 1 // CHECK7-NEXT: call void @_ZN1SIfEC1Ef(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_ELEMENT]], float noundef 2.000000e+00) // CHECK7-NEXT: store ptr [[TEST]], ptr [[VAR]], align 4 // CHECK7-NEXT: [[TMP0:%.*]] = load ptr, ptr [[VAR]], align 4 @@ -2278,9 +2275,8 @@ int main() { // CHECK7-NEXT: call void @_ZN1SIiEC1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[TEST]]) // CHECK7-NEXT: store i32 0, ptr [[T_VAR]], align 4 // CHECK7-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 4 [[VEC]], ptr align 4 @__const._Z5tmainIiET_v.vec, i32 8, i1 false) -// CHECK7-NEXT: [[ARRAYINIT_BEGIN:%.*]] = getelementptr inbounds [2 x %struct.S.0], ptr [[S_ARR]], i32 0, i32 0 -// CHECK7-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_BEGIN]], i32 noundef 1) -// CHECK7-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[ARRAYINIT_BEGIN]], i32 1 +// CHECK7-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[S_ARR]], i32 noundef 1) +// CHECK7-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[S_ARR]], i32 1 // CHECK7-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_ELEMENT]], i32 noundef 2) // CHECK7-NEXT: store ptr [[TEST]], ptr [[VAR]], align 4 // CHECK7-NEXT: [[TMP0:%.*]] = load ptr, ptr [[VAR]], align 4 @@ -2848,9 +2844,8 @@ int main() { // CHECK13-NEXT: call void @_ZN1SIfEC1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[TEST]]) // CHECK13-NEXT: store i32 0, ptr [[T_VAR]], align 4 // CHECK13-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 4 [[VEC]], ptr align 4 @__const.main.vec, i64 8, i1 false) -// CHECK13-NEXT: [[ARRAYINIT_BEGIN:%.*]] = getelementptr inbounds [2 x %struct.S], ptr [[S_ARR]], i64 0, i64 0 -// CHECK13-NEXT: call void @_ZN1SIfEC1Ef(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_BEGIN]], float noundef 1.000000e+00) -// CHECK13-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[ARRAYINIT_BEGIN]], i64 1 +// CHECK13-NEXT: call void @_ZN1SIfEC1Ef(ptr noundef nonnull align 4 dereferenceable(4) [[S_ARR]], float noundef 1.000000e+00) +// CHECK13-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[S_ARR]], i64 1 // CHECK13-NEXT: call void @_ZN1SIfEC1Ef(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_ELEMENT]], float noundef 2.000000e+00) // CHECK13-NEXT: store ptr [[TEST]], ptr [[VAR]], align 8 // CHECK13-NEXT: [[TMP0:%.*]] = load ptr, ptr [[VAR]], align 8 @@ -3012,9 +3007,8 @@ int main() { // CHECK13-NEXT: call void @_ZN1SIiEC1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[TEST]]) // CHECK13-NEXT: store i32 0, ptr [[T_VAR]], align 4 // CHECK13-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 4 [[VEC]], ptr align 4 @__const._Z5tmainIiET_v.vec, i64 8, i1 false) -// CHECK13-NEXT: [[ARRAYINIT_BEGIN:%.*]] = getelementptr inbounds [2 x %struct.S.0], ptr [[S_ARR]], i64 0, i64 0 -// CHECK13-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_BEGIN]], i32 noundef signext 1) -// CHECK13-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[ARRAYINIT_BEGIN]], i64 1 +// CHECK13-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[S_ARR]], i32 noundef signext 1) +// CHECK13-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[S_ARR]], i64 1 // CHECK13-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_ELEMENT]], i32 noundef signext 2) // CHECK13-NEXT: store ptr [[TEST]], ptr [[VAR]], align 8 // CHECK13-NEXT: [[TMP0:%.*]] = load ptr, ptr [[VAR]], align 8 @@ -3247,9 +3241,8 @@ int main() { // CHECK15-NEXT: call void @_ZN1SIfEC1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[TEST]]) // CHECK15-NEXT: store i32 0, ptr [[T_VAR]], align 4 // CHECK15-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 4 [[VEC]], ptr align 4 @__const.main.vec, i32 8, i1 false) -// CHECK15-NEXT: [[ARRAYINIT_BEGIN:%.*]] = getelementptr inbounds [2 x %struct.S], ptr [[S_ARR]], i32 0, i32 0 -// CHECK15-NEXT: call void @_ZN1SIfEC1Ef(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_BEGIN]], float noundef 1.000000e+00) -// CHECK15-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[ARRAYINIT_BEGIN]], i32 1 +// CHECK15-NEXT: call void @_ZN1SIfEC1Ef(ptr noundef nonnull align 4 dereferenceable(4) [[S_ARR]], float noundef 1.000000e+00) +// CHECK15-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[S_ARR]], i32 1 // CHECK15-NEXT: call void @_ZN1SIfEC1Ef(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_ELEMENT]], float noundef 2.000000e+00) // CHECK15-NEXT: store ptr [[TEST]], ptr [[VAR]], align 4 // CHECK15-NEXT: [[TMP0:%.*]] = load ptr, ptr [[VAR]], align 4 @@ -3409,9 +3402,8 @@ int main() { // CHECK15-NEXT: call void @_ZN1SIiEC1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[TEST]]) // CHECK15-NEXT: store i32 0, ptr [[T_VAR]], align 4 // CHECK15-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 4 [[VEC]], ptr align 4 @__const._Z5tmainIiET_v.vec, i32 8, i1 false) -// CHECK15-NEXT: [[ARRAYINIT_BEGIN:%.*]] = getelementptr inbounds [2 x %struct.S.0], ptr [[S_ARR]], i32 0, i32 0 -// CHECK15-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_BEGIN]], i32 noundef 1) -// CHECK15-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[ARRAYINIT_BEGIN]], i32 1 +// CHECK15-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[S_ARR]], i32 noundef 1) +// CHECK15-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[S_ARR]], i32 1 // CHECK15-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_ELEMENT]], i32 noundef 2) // CHECK15-NEXT: store ptr [[TEST]], ptr [[VAR]], align 4 // CHECK15-NEXT: [[TMP0:%.*]] = load ptr, ptr [[VAR]], align 4 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 0cc07c86aaea7d7e694730c8a4ca53cd5536f296..c7b919cfbb443a0a913cd89fbf9afcf14539a9c3 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 @@ -578,9 +578,8 @@ int main() { // CHECK1-NEXT: call void @_ZN1SIiEC1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[TEST]]) // CHECK1-NEXT: store i32 0, ptr [[T_VAR]], align 4 // CHECK1-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 4 [[VEC]], ptr align 4 @__const._Z5tmainIiET_v.vec, i64 8, i1 false) -// CHECK1-NEXT: [[ARRAYINIT_BEGIN:%.*]] = getelementptr inbounds [2 x %struct.S.0], ptr [[S_ARR]], i64 0, i64 0 -// CHECK1-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_BEGIN]], i32 noundef signext 1) -// CHECK1-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[ARRAYINIT_BEGIN]], i64 1 +// CHECK1-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[S_ARR]], i32 noundef signext 1) +// CHECK1-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[S_ARR]], i64 1 // CHECK1-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_ELEMENT]], i32 noundef signext 2) // CHECK1-NEXT: store ptr [[TEST]], ptr [[VAR]], align 8 // CHECK1-NEXT: store ptr undef, ptr [[_TMP1]], align 8 @@ -1333,9 +1332,8 @@ int main() { // CHECK3-NEXT: call void @_ZN1SIiEC1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[TEST]]) // CHECK3-NEXT: store i32 0, ptr [[T_VAR]], align 4 // CHECK3-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 4 [[VEC]], ptr align 4 @__const._Z5tmainIiET_v.vec, i32 8, i1 false) -// CHECK3-NEXT: [[ARRAYINIT_BEGIN:%.*]] = getelementptr inbounds [2 x %struct.S.0], ptr [[S_ARR]], i32 0, i32 0 -// CHECK3-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_BEGIN]], i32 noundef 1) -// CHECK3-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[ARRAYINIT_BEGIN]], i32 1 +// CHECK3-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[S_ARR]], i32 noundef 1) +// CHECK3-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[S_ARR]], i32 1 // CHECK3-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_ELEMENT]], i32 noundef 2) // CHECK3-NEXT: store ptr [[TEST]], ptr [[VAR]], align 4 // CHECK3-NEXT: store ptr undef, ptr [[_TMP1]], align 4 @@ -2178,9 +2176,8 @@ int main() { // CHECK7-NEXT: call void @_ZN1SIiEC1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[TEST]]) // CHECK7-NEXT: store i32 0, ptr [[T_VAR]], align 4 // CHECK7-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 4 [[VEC]], ptr align 4 @__const._Z5tmainIiET_v.vec, i64 8, i1 false) -// CHECK7-NEXT: [[ARRAYINIT_BEGIN:%.*]] = getelementptr inbounds [2 x %struct.S.0], ptr [[S_ARR]], i64 0, i64 0 -// CHECK7-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_BEGIN]], i32 noundef signext 1) -// CHECK7-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[ARRAYINIT_BEGIN]], i64 1 +// CHECK7-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[S_ARR]], i32 noundef signext 1) +// CHECK7-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[S_ARR]], i64 1 // CHECK7-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_ELEMENT]], i32 noundef signext 2) // CHECK7-NEXT: store ptr [[TEST]], ptr [[VAR]], align 8 // CHECK7-NEXT: store ptr undef, ptr [[_TMP1]], align 8 @@ -2554,9 +2551,8 @@ int main() { // CHECK9-NEXT: call void @_ZN1SIiEC1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[TEST]]) // CHECK9-NEXT: store i32 0, ptr [[T_VAR]], align 4 // CHECK9-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 4 [[VEC]], ptr align 4 @__const._Z5tmainIiET_v.vec, i32 8, i1 false) -// CHECK9-NEXT: [[ARRAYINIT_BEGIN:%.*]] = getelementptr inbounds [2 x %struct.S.0], ptr [[S_ARR]], i32 0, i32 0 -// CHECK9-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_BEGIN]], i32 noundef 1) -// CHECK9-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[ARRAYINIT_BEGIN]], i32 1 +// CHECK9-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[S_ARR]], i32 noundef 1) +// CHECK9-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[S_ARR]], i32 1 // CHECK9-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_ELEMENT]], i32 noundef 2) // CHECK9-NEXT: store ptr [[TEST]], ptr [[VAR]], align 4 // CHECK9-NEXT: store ptr undef, ptr [[_TMP1]], align 4 diff --git a/clang/test/OpenMP/target_teams_distribute_private_codegen.cpp b/clang/test/OpenMP/target_teams_distribute_private_codegen.cpp index 3cb2d2c2f9b43ef8d18036ae718a1024be5984e6..b718173246f383fb1356bd5f64cab1f1c395e280 100644 --- a/clang/test/OpenMP/target_teams_distribute_private_codegen.cpp +++ b/clang/test/OpenMP/target_teams_distribute_private_codegen.cpp @@ -402,9 +402,8 @@ int main() { // CHECK1-NEXT: call void @_ZN1SIiEC1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[TEST]]) // CHECK1-NEXT: store i32 0, ptr [[T_VAR]], align 4 // CHECK1-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 4 [[VEC]], ptr align 4 @__const._Z5tmainIiET_v.vec, i64 8, i1 false) -// CHECK1-NEXT: [[ARRAYINIT_BEGIN:%.*]] = getelementptr inbounds [2 x %struct.S.0], ptr [[S_ARR]], i64 0, i64 0 -// CHECK1-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_BEGIN]], i32 noundef signext 1) -// CHECK1-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[ARRAYINIT_BEGIN]], i64 1 +// CHECK1-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[S_ARR]], i32 noundef signext 1) +// CHECK1-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[S_ARR]], i64 1 // CHECK1-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_ELEMENT]], i32 noundef signext 2) // CHECK1-NEXT: store ptr [[TEST]], ptr [[VAR]], align 8 // CHECK1-NEXT: store ptr undef, ptr [[_TMP1]], align 8 @@ -928,9 +927,8 @@ int main() { // CHECK3-NEXT: call void @_ZN1SIiEC1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[TEST]]) // CHECK3-NEXT: store i32 0, ptr [[T_VAR]], align 4 // CHECK3-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 4 [[VEC]], ptr align 4 @__const._Z5tmainIiET_v.vec, i32 8, i1 false) -// CHECK3-NEXT: [[ARRAYINIT_BEGIN:%.*]] = getelementptr inbounds [2 x %struct.S.0], ptr [[S_ARR]], i32 0, i32 0 -// CHECK3-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_BEGIN]], i32 noundef 1) -// CHECK3-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[ARRAYINIT_BEGIN]], i32 1 +// CHECK3-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[S_ARR]], i32 noundef 1) +// CHECK3-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[S_ARR]], i32 1 // CHECK3-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_ELEMENT]], i32 noundef 2) // CHECK3-NEXT: store ptr [[TEST]], ptr [[VAR]], align 4 // CHECK3-NEXT: store ptr undef, ptr [[_TMP1]], align 4 diff --git a/clang/test/OpenMP/target_teams_distribute_simd_firstprivate_codegen.cpp b/clang/test/OpenMP/target_teams_distribute_simd_firstprivate_codegen.cpp index d22aeee120d5d5caf73e9e489cf0c56ab4f26fe9..3e1cfb00209041b22d8d29a6d5f3f38371ac90c1 100644 --- a/clang/test/OpenMP/target_teams_distribute_simd_firstprivate_codegen.cpp +++ b/clang/test/OpenMP/target_teams_distribute_simd_firstprivate_codegen.cpp @@ -553,9 +553,8 @@ int main() { // CHECK1-NEXT: call void @_ZN1SIiEC1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[TEST]]) // CHECK1-NEXT: store i32 0, ptr [[T_VAR]], align 4 // CHECK1-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 4 [[VEC]], ptr align 4 @__const._Z5tmainIiET_v.vec, i64 8, i1 false) -// CHECK1-NEXT: [[ARRAYINIT_BEGIN:%.*]] = getelementptr inbounds [2 x %struct.S.0], ptr [[S_ARR]], i64 0, i64 0 -// CHECK1-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_BEGIN]], i32 noundef signext 1) -// CHECK1-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[ARRAYINIT_BEGIN]], i64 1 +// CHECK1-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[S_ARR]], i32 noundef signext 1) +// CHECK1-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[S_ARR]], i64 1 // CHECK1-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_ELEMENT]], i32 noundef signext 2) // CHECK1-NEXT: store ptr [[TEST]], ptr [[VAR]], align 8 // CHECK1-NEXT: [[TMP0:%.*]] = load ptr, ptr [[VAR]], align 8 @@ -1367,9 +1366,8 @@ int main() { // CHECK3-NEXT: call void @_ZN1SIiEC1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[TEST]]) // CHECK3-NEXT: store i32 0, ptr [[T_VAR]], align 4 // CHECK3-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 4 [[VEC]], ptr align 4 @__const._Z5tmainIiET_v.vec, i32 8, i1 false) -// CHECK3-NEXT: [[ARRAYINIT_BEGIN:%.*]] = getelementptr inbounds [2 x %struct.S.0], ptr [[S_ARR]], i32 0, i32 0 -// CHECK3-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_BEGIN]], i32 noundef 1) -// CHECK3-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[ARRAYINIT_BEGIN]], i32 1 +// CHECK3-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[S_ARR]], i32 noundef 1) +// CHECK3-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[S_ARR]], i32 1 // CHECK3-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_ELEMENT]], i32 noundef 2) // CHECK3-NEXT: store ptr [[TEST]], ptr [[VAR]], align 4 // CHECK3-NEXT: [[TMP0:%.*]] = load ptr, ptr [[VAR]], align 4 @@ -1911,9 +1909,8 @@ int main() { // CHECK5-NEXT: call void @_ZN1SIiEC1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[TEST]]) // CHECK5-NEXT: store i32 0, ptr [[T_VAR]], align 4 // CHECK5-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 4 [[VEC]], ptr align 4 @__const._Z5tmainIiET_v.vec, i64 8, i1 false) -// CHECK5-NEXT: [[ARRAYINIT_BEGIN:%.*]] = getelementptr inbounds [2 x %struct.S.0], ptr [[S_ARR]], i64 0, i64 0 -// CHECK5-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_BEGIN]], i32 noundef signext 1) -// CHECK5-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[ARRAYINIT_BEGIN]], i64 1 +// CHECK5-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[S_ARR]], i32 noundef signext 1) +// CHECK5-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[S_ARR]], i64 1 // CHECK5-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_ELEMENT]], i32 noundef signext 2) // CHECK5-NEXT: store ptr [[TEST]], ptr [[VAR]], align 8 // CHECK5-NEXT: [[TMP0:%.*]] = load ptr, ptr [[VAR]], align 8 @@ -2231,9 +2228,8 @@ int main() { // CHECK7-NEXT: call void @_ZN1SIiEC1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[TEST]]) // CHECK7-NEXT: store i32 0, ptr [[T_VAR]], align 4 // CHECK7-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 4 [[VEC]], ptr align 4 @__const._Z5tmainIiET_v.vec, i32 8, i1 false) -// CHECK7-NEXT: [[ARRAYINIT_BEGIN:%.*]] = getelementptr inbounds [2 x %struct.S.0], ptr [[S_ARR]], i32 0, i32 0 -// CHECK7-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_BEGIN]], i32 noundef 1) -// CHECK7-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[ARRAYINIT_BEGIN]], i32 1 +// CHECK7-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[S_ARR]], i32 noundef 1) +// CHECK7-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[S_ARR]], i32 1 // CHECK7-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_ELEMENT]], i32 noundef 2) // CHECK7-NEXT: store ptr [[TEST]], ptr [[VAR]], align 4 // CHECK7-NEXT: [[TMP0:%.*]] = load ptr, ptr [[VAR]], align 4 diff --git a/clang/test/OpenMP/target_teams_distribute_simd_lastprivate_codegen.cpp b/clang/test/OpenMP/target_teams_distribute_simd_lastprivate_codegen.cpp index 93c570ac0604ff4e3ca364a9188b297fc8a37f26..fc17caae823282d71e5a095e1614e4380bcbbfc4 100644 --- a/clang/test/OpenMP/target_teams_distribute_simd_lastprivate_codegen.cpp +++ b/clang/test/OpenMP/target_teams_distribute_simd_lastprivate_codegen.cpp @@ -525,9 +525,8 @@ int main() { // CHECK9-NEXT: call void @_ZN1SIfEC1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[TEST]]) // CHECK9-NEXT: store i32 0, ptr [[T_VAR]], align 4 // CHECK9-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 4 [[VEC]], ptr align 4 @__const.main.vec, i64 8, i1 false) -// CHECK9-NEXT: [[ARRAYINIT_BEGIN:%.*]] = getelementptr inbounds [2 x %struct.S], ptr [[S_ARR]], i64 0, i64 0 -// CHECK9-NEXT: call void @_ZN1SIfEC1Ef(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_BEGIN]], float noundef 1.000000e+00) -// CHECK9-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[ARRAYINIT_BEGIN]], i64 1 +// CHECK9-NEXT: call void @_ZN1SIfEC1Ef(ptr noundef nonnull align 4 dereferenceable(4) [[S_ARR]], float noundef 1.000000e+00) +// CHECK9-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[S_ARR]], i64 1 // CHECK9-NEXT: call void @_ZN1SIfEC1Ef(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_ELEMENT]], float noundef 2.000000e+00) // CHECK9-NEXT: store ptr [[TEST]], ptr [[VAR]], align 8 // CHECK9-NEXT: [[TMP0:%.*]] = load ptr, ptr [[VAR]], align 8 @@ -856,9 +855,8 @@ int main() { // CHECK9-NEXT: call void @_ZN1SIiEC1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[TEST]]) // CHECK9-NEXT: store i32 0, ptr [[T_VAR]], align 4 // CHECK9-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 4 [[VEC]], ptr align 4 @__const._Z5tmainIiET_v.vec, i64 8, i1 false) -// CHECK9-NEXT: [[ARRAYINIT_BEGIN:%.*]] = getelementptr inbounds [2 x %struct.S.0], ptr [[S_ARR]], i64 0, i64 0 -// CHECK9-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_BEGIN]], i32 noundef signext 1) -// CHECK9-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[ARRAYINIT_BEGIN]], i64 1 +// CHECK9-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[S_ARR]], i32 noundef signext 1) +// CHECK9-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[S_ARR]], i64 1 // CHECK9-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_ELEMENT]], i32 noundef signext 2) // CHECK9-NEXT: store ptr [[TEST]], ptr [[VAR]], align 8 // CHECK9-NEXT: [[TMP0:%.*]] = load ptr, ptr [[VAR]], align 8 @@ -1240,9 +1238,8 @@ int main() { // CHECK11-NEXT: call void @_ZN1SIfEC1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[TEST]]) // CHECK11-NEXT: store i32 0, ptr [[T_VAR]], align 4 // CHECK11-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 4 [[VEC]], ptr align 4 @__const.main.vec, i32 8, i1 false) -// CHECK11-NEXT: [[ARRAYINIT_BEGIN:%.*]] = getelementptr inbounds [2 x %struct.S], ptr [[S_ARR]], i32 0, i32 0 -// CHECK11-NEXT: call void @_ZN1SIfEC1Ef(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_BEGIN]], float noundef 1.000000e+00) -// CHECK11-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[ARRAYINIT_BEGIN]], i32 1 +// CHECK11-NEXT: call void @_ZN1SIfEC1Ef(ptr noundef nonnull align 4 dereferenceable(4) [[S_ARR]], float noundef 1.000000e+00) +// CHECK11-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[S_ARR]], i32 1 // CHECK11-NEXT: call void @_ZN1SIfEC1Ef(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_ELEMENT]], float noundef 2.000000e+00) // CHECK11-NEXT: store ptr [[TEST]], ptr [[VAR]], align 4 // CHECK11-NEXT: [[TMP0:%.*]] = load ptr, ptr [[VAR]], align 4 @@ -1569,9 +1566,8 @@ int main() { // CHECK11-NEXT: call void @_ZN1SIiEC1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[TEST]]) // CHECK11-NEXT: store i32 0, ptr [[T_VAR]], align 4 // CHECK11-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 4 [[VEC]], ptr align 4 @__const._Z5tmainIiET_v.vec, i32 8, i1 false) -// CHECK11-NEXT: [[ARRAYINIT_BEGIN:%.*]] = getelementptr inbounds [2 x %struct.S.0], ptr [[S_ARR]], i32 0, i32 0 -// CHECK11-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_BEGIN]], i32 noundef 1) -// CHECK11-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[ARRAYINIT_BEGIN]], i32 1 +// CHECK11-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[S_ARR]], i32 noundef 1) +// CHECK11-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[S_ARR]], i32 1 // CHECK11-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_ELEMENT]], i32 noundef 2) // CHECK11-NEXT: store ptr [[TEST]], ptr [[VAR]], align 4 // CHECK11-NEXT: [[TMP0:%.*]] = load ptr, ptr [[VAR]], align 4 @@ -1955,9 +1951,8 @@ int main() { // CHECK13-NEXT: call void @_ZN1SIfEC1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[TEST]]) // CHECK13-NEXT: store i32 0, ptr [[T_VAR]], align 4 // CHECK13-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 4 [[VEC]], ptr align 4 @__const.main.vec, i64 8, i1 false) -// CHECK13-NEXT: [[ARRAYINIT_BEGIN:%.*]] = getelementptr inbounds [2 x %struct.S], ptr [[S_ARR]], i64 0, i64 0 -// CHECK13-NEXT: call void @_ZN1SIfEC1Ef(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_BEGIN]], float noundef 1.000000e+00) -// CHECK13-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[ARRAYINIT_BEGIN]], i64 1 +// CHECK13-NEXT: call void @_ZN1SIfEC1Ef(ptr noundef nonnull align 4 dereferenceable(4) [[S_ARR]], float noundef 1.000000e+00) +// CHECK13-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[S_ARR]], i64 1 // CHECK13-NEXT: call void @_ZN1SIfEC1Ef(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_ELEMENT]], float noundef 2.000000e+00) // CHECK13-NEXT: store ptr [[TEST]], ptr [[VAR]], align 8 // CHECK13-NEXT: [[TMP0:%.*]] = load ptr, ptr [[VAR]], align 8 @@ -2118,9 +2113,8 @@ int main() { // CHECK13-NEXT: call void @_ZN1SIiEC1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[TEST]]) // CHECK13-NEXT: store i32 0, ptr [[T_VAR]], align 4 // CHECK13-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 4 [[VEC]], ptr align 4 @__const._Z5tmainIiET_v.vec, i64 8, i1 false) -// CHECK13-NEXT: [[ARRAYINIT_BEGIN:%.*]] = getelementptr inbounds [2 x %struct.S.0], ptr [[S_ARR]], i64 0, i64 0 -// CHECK13-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_BEGIN]], i32 noundef signext 1) -// CHECK13-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[ARRAYINIT_BEGIN]], i64 1 +// CHECK13-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[S_ARR]], i32 noundef signext 1) +// CHECK13-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[S_ARR]], i64 1 // CHECK13-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_ELEMENT]], i32 noundef signext 2) // CHECK13-NEXT: store ptr [[TEST]], ptr [[VAR]], align 8 // CHECK13-NEXT: [[TMP0:%.*]] = load ptr, ptr [[VAR]], align 8 @@ -2352,9 +2346,8 @@ int main() { // CHECK15-NEXT: call void @_ZN1SIfEC1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[TEST]]) // CHECK15-NEXT: store i32 0, ptr [[T_VAR]], align 4 // CHECK15-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 4 [[VEC]], ptr align 4 @__const.main.vec, i32 8, i1 false) -// CHECK15-NEXT: [[ARRAYINIT_BEGIN:%.*]] = getelementptr inbounds [2 x %struct.S], ptr [[S_ARR]], i32 0, i32 0 -// CHECK15-NEXT: call void @_ZN1SIfEC1Ef(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_BEGIN]], float noundef 1.000000e+00) -// CHECK15-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[ARRAYINIT_BEGIN]], i32 1 +// CHECK15-NEXT: call void @_ZN1SIfEC1Ef(ptr noundef nonnull align 4 dereferenceable(4) [[S_ARR]], float noundef 1.000000e+00) +// CHECK15-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[S_ARR]], i32 1 // CHECK15-NEXT: call void @_ZN1SIfEC1Ef(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_ELEMENT]], float noundef 2.000000e+00) // CHECK15-NEXT: store ptr [[TEST]], ptr [[VAR]], align 4 // CHECK15-NEXT: [[TMP0:%.*]] = load ptr, ptr [[VAR]], align 4 @@ -2513,9 +2506,8 @@ int main() { // CHECK15-NEXT: call void @_ZN1SIiEC1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[TEST]]) // CHECK15-NEXT: store i32 0, ptr [[T_VAR]], align 4 // CHECK15-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 4 [[VEC]], ptr align 4 @__const._Z5tmainIiET_v.vec, i32 8, i1 false) -// CHECK15-NEXT: [[ARRAYINIT_BEGIN:%.*]] = getelementptr inbounds [2 x %struct.S.0], ptr [[S_ARR]], i32 0, i32 0 -// CHECK15-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_BEGIN]], i32 noundef 1) -// CHECK15-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[ARRAYINIT_BEGIN]], i32 1 +// CHECK15-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[S_ARR]], i32 noundef 1) +// CHECK15-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[S_ARR]], i32 1 // CHECK15-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_ELEMENT]], i32 noundef 2) // CHECK15-NEXT: store ptr [[TEST]], ptr [[VAR]], align 4 // CHECK15-NEXT: [[TMP0:%.*]] = load ptr, ptr [[VAR]], align 4 diff --git a/clang/test/OpenMP/target_teams_distribute_simd_private_codegen.cpp b/clang/test/OpenMP/target_teams_distribute_simd_private_codegen.cpp index 4e9b4e1027e6863d619fddea390ed445c33028a7..c1f3530e484c27cc8b783c6466dab5a348b71d9e 100644 --- a/clang/test/OpenMP/target_teams_distribute_simd_private_codegen.cpp +++ b/clang/test/OpenMP/target_teams_distribute_simd_private_codegen.cpp @@ -409,9 +409,8 @@ int main() { // CHECK1-NEXT: call void @_ZN1SIiEC1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[TEST]]) // CHECK1-NEXT: store i32 0, ptr [[T_VAR]], align 4 // CHECK1-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 4 [[VEC]], ptr align 4 @__const._Z5tmainIiET_v.vec, i64 8, i1 false) -// CHECK1-NEXT: [[ARRAYINIT_BEGIN:%.*]] = getelementptr inbounds [2 x %struct.S.0], ptr [[S_ARR]], i64 0, i64 0 -// CHECK1-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_BEGIN]], i32 noundef signext 1) -// CHECK1-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[ARRAYINIT_BEGIN]], i64 1 +// CHECK1-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[S_ARR]], i32 noundef signext 1) +// CHECK1-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[S_ARR]], i64 1 // CHECK1-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_ELEMENT]], i32 noundef signext 2) // CHECK1-NEXT: store ptr [[TEST]], ptr [[VAR]], align 8 // CHECK1-NEXT: store ptr undef, ptr [[_TMP1]], align 8 @@ -949,9 +948,8 @@ int main() { // CHECK3-NEXT: call void @_ZN1SIiEC1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[TEST]]) // CHECK3-NEXT: store i32 0, ptr [[T_VAR]], align 4 // CHECK3-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 4 [[VEC]], ptr align 4 @__const._Z5tmainIiET_v.vec, i32 8, i1 false) -// CHECK3-NEXT: [[ARRAYINIT_BEGIN:%.*]] = getelementptr inbounds [2 x %struct.S.0], ptr [[S_ARR]], i32 0, i32 0 -// CHECK3-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_BEGIN]], i32 noundef 1) -// CHECK3-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[ARRAYINIT_BEGIN]], i32 1 +// CHECK3-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[S_ARR]], i32 noundef 1) +// CHECK3-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[S_ARR]], i32 1 // CHECK3-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_ELEMENT]], i32 noundef 2) // CHECK3-NEXT: store ptr [[TEST]], ptr [[VAR]], align 4 // CHECK3-NEXT: store ptr undef, ptr [[_TMP1]], align 4 @@ -1377,9 +1375,8 @@ int main() { // CHECK5-NEXT: call void @_ZN1SIiEC1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[TEST]]) // CHECK5-NEXT: store i32 0, ptr [[T_VAR]], align 4 // CHECK5-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 4 [[VEC]], ptr align 4 @__const._Z5tmainIiET_v.vec, i64 8, i1 false) -// CHECK5-NEXT: [[ARRAYINIT_BEGIN:%.*]] = getelementptr inbounds [2 x %struct.S.0], ptr [[S_ARR]], i64 0, i64 0 -// CHECK5-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_BEGIN]], i32 noundef signext 1) -// CHECK5-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[ARRAYINIT_BEGIN]], i64 1 +// CHECK5-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[S_ARR]], i32 noundef signext 1) +// CHECK5-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[S_ARR]], i64 1 // CHECK5-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_ELEMENT]], i32 noundef signext 2) // CHECK5-NEXT: store ptr [[TEST]], ptr [[VAR]], align 8 // CHECK5-NEXT: store ptr undef, ptr [[_TMP1]], align 8 @@ -1753,9 +1750,8 @@ int main() { // CHECK7-NEXT: call void @_ZN1SIiEC1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[TEST]]) // CHECK7-NEXT: store i32 0, ptr [[T_VAR]], align 4 // CHECK7-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 4 [[VEC]], ptr align 4 @__const._Z5tmainIiET_v.vec, i32 8, i1 false) -// CHECK7-NEXT: [[ARRAYINIT_BEGIN:%.*]] = getelementptr inbounds [2 x %struct.S.0], ptr [[S_ARR]], i32 0, i32 0 -// CHECK7-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_BEGIN]], i32 noundef 1) -// CHECK7-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[ARRAYINIT_BEGIN]], i32 1 +// CHECK7-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[S_ARR]], i32 noundef 1) +// CHECK7-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[S_ARR]], i32 1 // CHECK7-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_ELEMENT]], i32 noundef 2) // CHECK7-NEXT: store ptr [[TEST]], ptr [[VAR]], align 4 // CHECK7-NEXT: store ptr undef, ptr [[_TMP1]], align 4 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 9b3d77f5b0adcf1893cff7df0451c9bee3396feb..5efad5b4327cfc61f48c0534f351fc290866a460 100644 --- a/clang/test/OpenMP/target_teams_generic_loop_private_codegen.cpp +++ b/clang/test/OpenMP/target_teams_generic_loop_private_codegen.cpp @@ -463,9 +463,8 @@ int main() { // CHECK1-NEXT: call void @_ZN1SIiEC1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[TEST]]) // CHECK1-NEXT: store i32 0, ptr [[T_VAR]], align 4 // CHECK1-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 4 [[VEC]], ptr align 4 @__const._Z5tmainIiET_v.vec, i64 8, i1 false) -// CHECK1-NEXT: [[ARRAYINIT_BEGIN:%.*]] = getelementptr inbounds [2 x %struct.S.0], ptr [[S_ARR]], i64 0, i64 0 -// CHECK1-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_BEGIN]], i32 noundef signext 1) -// CHECK1-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[ARRAYINIT_BEGIN]], i64 1 +// CHECK1-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[S_ARR]], i32 noundef signext 1) +// CHECK1-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[S_ARR]], i64 1 // CHECK1-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_ELEMENT]], i32 noundef signext 2) // CHECK1-NEXT: store ptr [[TEST]], ptr [[VAR]], align 8 // CHECK1-NEXT: store ptr undef, ptr [[_TMP1]], align 8 @@ -989,9 +988,8 @@ int main() { // CHECK3-NEXT: call void @_ZN1SIiEC1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[TEST]]) // CHECK3-NEXT: store i32 0, ptr [[T_VAR]], align 4 // CHECK3-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 4 [[VEC]], ptr align 4 @__const._Z5tmainIiET_v.vec, i32 8, i1 false) -// CHECK3-NEXT: [[ARRAYINIT_BEGIN:%.*]] = getelementptr inbounds [2 x %struct.S.0], ptr [[S_ARR]], i32 0, i32 0 -// CHECK3-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_BEGIN]], i32 noundef 1) -// CHECK3-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[ARRAYINIT_BEGIN]], i32 1 +// CHECK3-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[S_ARR]], i32 noundef 1) +// CHECK3-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[S_ARR]], i32 1 // CHECK3-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_ELEMENT]], i32 noundef 2) // CHECK3-NEXT: store ptr [[TEST]], ptr [[VAR]], align 4 // CHECK3-NEXT: store ptr undef, ptr [[_TMP1]], align 4 diff --git a/clang/test/OpenMP/teams_distribute_firstprivate_codegen.cpp b/clang/test/OpenMP/teams_distribute_firstprivate_codegen.cpp index 8b3e657428ec64253c51669fe91f4a88e90e40af..2ebedb8dd03eeece28a7640164113b57ae5ae4a2 100644 --- a/clang/test/OpenMP/teams_distribute_firstprivate_codegen.cpp +++ b/clang/test/OpenMP/teams_distribute_firstprivate_codegen.cpp @@ -549,9 +549,8 @@ int main() { // CHECK1-NEXT: call void @_ZN1SIiEC1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[TEST]]) // CHECK1-NEXT: store i32 0, ptr [[T_VAR]], align 4 // CHECK1-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 4 [[VEC]], ptr align 4 @__const._Z5tmainIiET_v.vec, i64 8, i1 false) -// CHECK1-NEXT: [[ARRAYINIT_BEGIN:%.*]] = getelementptr inbounds [2 x %struct.S.0], ptr [[S_ARR]], i64 0, i64 0 -// CHECK1-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_BEGIN]], i32 noundef signext 1) -// CHECK1-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[ARRAYINIT_BEGIN]], i64 1 +// CHECK1-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[S_ARR]], i32 noundef signext 1) +// CHECK1-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[S_ARR]], i64 1 // CHECK1-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_ELEMENT]], i32 noundef signext 2) // CHECK1-NEXT: store ptr [[TEST]], ptr [[VAR]], align 8 // CHECK1-NEXT: [[TMP0:%.*]] = load ptr, ptr [[VAR]], align 8 @@ -1351,9 +1350,8 @@ int main() { // CHECK3-NEXT: call void @_ZN1SIiEC1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[TEST]]) // CHECK3-NEXT: store i32 0, ptr [[T_VAR]], align 4 // CHECK3-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 4 [[VEC]], ptr align 4 @__const._Z5tmainIiET_v.vec, i32 8, i1 false) -// CHECK3-NEXT: [[ARRAYINIT_BEGIN:%.*]] = getelementptr inbounds [2 x %struct.S.0], ptr [[S_ARR]], i32 0, i32 0 -// CHECK3-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_BEGIN]], i32 noundef 1) -// CHECK3-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[ARRAYINIT_BEGIN]], i32 1 +// CHECK3-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[S_ARR]], i32 noundef 1) +// CHECK3-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[S_ARR]], i32 1 // CHECK3-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_ELEMENT]], i32 noundef 2) // CHECK3-NEXT: store ptr [[TEST]], ptr [[VAR]], align 4 // CHECK3-NEXT: [[TMP0:%.*]] = load ptr, ptr [[VAR]], align 4 diff --git a/clang/test/OpenMP/teams_distribute_lastprivate_codegen.cpp b/clang/test/OpenMP/teams_distribute_lastprivate_codegen.cpp index 66c952f3281fb54e3f0454c3acef1f933df2b0c3..96ba444d402efc485bfa8dd6665b6fb2d1b81bb2 100644 --- a/clang/test/OpenMP/teams_distribute_lastprivate_codegen.cpp +++ b/clang/test/OpenMP/teams_distribute_lastprivate_codegen.cpp @@ -469,9 +469,8 @@ int main() { // CHECK9-NEXT: call void @_ZN1SIfEC1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[TEST]]) // CHECK9-NEXT: store i32 0, ptr [[T_VAR]], align 4 // CHECK9-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 4 [[VEC]], ptr align 4 @__const.main.vec, i64 8, i1 false) -// CHECK9-NEXT: [[ARRAYINIT_BEGIN:%.*]] = getelementptr inbounds [2 x %struct.S], ptr [[S_ARR]], i64 0, i64 0 -// CHECK9-NEXT: call void @_ZN1SIfEC1Ef(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_BEGIN]], float noundef 1.000000e+00) -// CHECK9-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[ARRAYINIT_BEGIN]], i64 1 +// CHECK9-NEXT: call void @_ZN1SIfEC1Ef(ptr noundef nonnull align 4 dereferenceable(4) [[S_ARR]], float noundef 1.000000e+00) +// CHECK9-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[S_ARR]], i64 1 // CHECK9-NEXT: call void @_ZN1SIfEC1Ef(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_ELEMENT]], float noundef 2.000000e+00) // CHECK9-NEXT: store ptr [[TEST]], ptr [[VAR]], align 8 // CHECK9-NEXT: [[TMP0:%.*]] = load ptr, ptr [[VAR]], align 8 @@ -789,9 +788,8 @@ int main() { // CHECK9-NEXT: call void @_ZN1SIiEC1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[TEST]]) // CHECK9-NEXT: store i32 0, ptr [[T_VAR]], align 4 // CHECK9-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 4 [[VEC]], ptr align 4 @__const._Z5tmainIiET_v.vec, i64 8, i1 false) -// CHECK9-NEXT: [[ARRAYINIT_BEGIN:%.*]] = getelementptr inbounds [2 x %struct.S.0], ptr [[S_ARR]], i64 0, i64 0 -// CHECK9-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_BEGIN]], i32 noundef signext 1) -// CHECK9-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[ARRAYINIT_BEGIN]], i64 1 +// CHECK9-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[S_ARR]], i32 noundef signext 1) +// CHECK9-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[S_ARR]], i64 1 // CHECK9-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_ELEMENT]], i32 noundef signext 2) // CHECK9-NEXT: store ptr [[TEST]], ptr [[VAR]], align 8 // CHECK9-NEXT: [[TMP0:%.*]] = load ptr, ptr [[VAR]], align 8 @@ -1165,9 +1163,8 @@ int main() { // CHECK11-NEXT: call void @_ZN1SIfEC1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[TEST]]) // CHECK11-NEXT: store i32 0, ptr [[T_VAR]], align 4 // CHECK11-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 4 [[VEC]], ptr align 4 @__const.main.vec, i32 8, i1 false) -// CHECK11-NEXT: [[ARRAYINIT_BEGIN:%.*]] = getelementptr inbounds [2 x %struct.S], ptr [[S_ARR]], i32 0, i32 0 -// CHECK11-NEXT: call void @_ZN1SIfEC1Ef(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_BEGIN]], float noundef 1.000000e+00) -// CHECK11-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[ARRAYINIT_BEGIN]], i32 1 +// CHECK11-NEXT: call void @_ZN1SIfEC1Ef(ptr noundef nonnull align 4 dereferenceable(4) [[S_ARR]], float noundef 1.000000e+00) +// CHECK11-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[S_ARR]], i32 1 // CHECK11-NEXT: call void @_ZN1SIfEC1Ef(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_ELEMENT]], float noundef 2.000000e+00) // CHECK11-NEXT: store ptr [[TEST]], ptr [[VAR]], align 4 // CHECK11-NEXT: [[TMP0:%.*]] = load ptr, ptr [[VAR]], align 4 @@ -1483,9 +1480,8 @@ int main() { // CHECK11-NEXT: call void @_ZN1SIiEC1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[TEST]]) // CHECK11-NEXT: store i32 0, ptr [[T_VAR]], align 4 // CHECK11-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 4 [[VEC]], ptr align 4 @__const._Z5tmainIiET_v.vec, i32 8, i1 false) -// CHECK11-NEXT: [[ARRAYINIT_BEGIN:%.*]] = getelementptr inbounds [2 x %struct.S.0], ptr [[S_ARR]], i32 0, i32 0 -// CHECK11-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_BEGIN]], i32 noundef 1) -// CHECK11-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[ARRAYINIT_BEGIN]], i32 1 +// CHECK11-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[S_ARR]], i32 noundef 1) +// CHECK11-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[S_ARR]], i32 1 // CHECK11-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_ELEMENT]], i32 noundef 2) // CHECK11-NEXT: store ptr [[TEST]], ptr [[VAR]], align 4 // CHECK11-NEXT: [[TMP0:%.*]] = load ptr, ptr [[VAR]], align 4 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 0726fb659e7d15d990cf2157d43efd9ccf2e3ac6..8c411dee8a97adbb7611dbd9b06cc079fad4bdb7 100644 --- a/clang/test/OpenMP/teams_distribute_parallel_for_firstprivate_codegen.cpp +++ b/clang/test/OpenMP/teams_distribute_parallel_for_firstprivate_codegen.cpp @@ -713,9 +713,8 @@ int main() { // CHECK1-NEXT: call void @_ZN1SIiEC1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[TEST]]) // CHECK1-NEXT: store i32 0, ptr [[T_VAR]], align 4 // CHECK1-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 4 [[VEC]], ptr align 4 @__const._Z5tmainIiET_v.vec, i64 8, i1 false) -// CHECK1-NEXT: [[ARRAYINIT_BEGIN:%.*]] = getelementptr inbounds [2 x %struct.S.0], ptr [[S_ARR]], i64 0, i64 0 -// CHECK1-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_BEGIN]], i32 noundef signext 1) -// CHECK1-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[ARRAYINIT_BEGIN]], i64 1 +// CHECK1-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[S_ARR]], i32 noundef signext 1) +// CHECK1-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[S_ARR]], i64 1 // CHECK1-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_ELEMENT]], i32 noundef signext 2) // CHECK1-NEXT: store ptr [[TEST]], ptr [[VAR]], align 8 // CHECK1-NEXT: [[TMP0:%.*]] = load ptr, ptr [[VAR]], align 8 @@ -1771,9 +1770,8 @@ int main() { // CHECK3-NEXT: call void @_ZN1SIiEC1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[TEST]]) // CHECK3-NEXT: store i32 0, ptr [[T_VAR]], align 4 // CHECK3-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 4 [[VEC]], ptr align 4 @__const._Z5tmainIiET_v.vec, i32 8, i1 false) -// CHECK3-NEXT: [[ARRAYINIT_BEGIN:%.*]] = getelementptr inbounds [2 x %struct.S.0], ptr [[S_ARR]], i32 0, i32 0 -// CHECK3-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_BEGIN]], i32 noundef 1) -// CHECK3-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[ARRAYINIT_BEGIN]], i32 1 +// CHECK3-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[S_ARR]], i32 noundef 1) +// CHECK3-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[S_ARR]], i32 1 // CHECK3-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_ELEMENT]], i32 noundef 2) // CHECK3-NEXT: store ptr [[TEST]], ptr [[VAR]], align 4 // CHECK3-NEXT: [[TMP0:%.*]] = load ptr, ptr [[VAR]], align 4 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 06fc87d7da4c6c3c626293fa8fa5a735939b3b21..3e4afe969013e94b67b89e3b9fddb965c8e250ee 100644 --- a/clang/test/OpenMP/teams_distribute_parallel_for_lastprivate_codegen.cpp +++ b/clang/test/OpenMP/teams_distribute_parallel_for_lastprivate_codegen.cpp @@ -717,9 +717,8 @@ int main() { // CHECK9-NEXT: call void @_ZN1SIfEC1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[TEST]]) // CHECK9-NEXT: store i32 0, ptr [[T_VAR]], align 4 // CHECK9-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 4 [[VEC]], ptr align 4 @__const.main.vec, i64 8, i1 false) -// CHECK9-NEXT: [[ARRAYINIT_BEGIN:%.*]] = getelementptr inbounds [2 x %struct.S], ptr [[S_ARR]], i64 0, i64 0 -// CHECK9-NEXT: call void @_ZN1SIfEC1Ef(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_BEGIN]], float noundef 1.000000e+00) -// CHECK9-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[ARRAYINIT_BEGIN]], i64 1 +// CHECK9-NEXT: call void @_ZN1SIfEC1Ef(ptr noundef nonnull align 4 dereferenceable(4) [[S_ARR]], float noundef 1.000000e+00) +// CHECK9-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[S_ARR]], i64 1 // CHECK9-NEXT: call void @_ZN1SIfEC1Ef(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_ELEMENT]], float noundef 2.000000e+00) // CHECK9-NEXT: store ptr [[TEST]], ptr [[VAR]], align 8 // CHECK9-NEXT: [[TMP0:%.*]] = load ptr, ptr [[VAR]], align 8 @@ -1185,9 +1184,8 @@ int main() { // CHECK9-NEXT: call void @_ZN1SIiEC1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[TEST]]) // CHECK9-NEXT: store i32 0, ptr [[T_VAR]], align 4 // CHECK9-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 4 [[VEC]], ptr align 4 @__const._Z5tmainIiET_v.vec, i64 8, i1 false) -// CHECK9-NEXT: [[ARRAYINIT_BEGIN:%.*]] = getelementptr inbounds [2 x %struct.S.0], ptr [[S_ARR]], i64 0, i64 0 -// CHECK9-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_BEGIN]], i32 noundef signext 1) -// CHECK9-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[ARRAYINIT_BEGIN]], i64 1 +// CHECK9-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[S_ARR]], i32 noundef signext 1) +// CHECK9-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[S_ARR]], i64 1 // CHECK9-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_ELEMENT]], i32 noundef signext 2) // CHECK9-NEXT: store ptr [[TEST]], ptr [[VAR]], align 8 // CHECK9-NEXT: [[TMP0:%.*]] = load ptr, ptr [[VAR]], align 8 @@ -1703,9 +1701,8 @@ int main() { // CHECK11-NEXT: call void @_ZN1SIfEC1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[TEST]]) // CHECK11-NEXT: store i32 0, ptr [[T_VAR]], align 4 // CHECK11-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 4 [[VEC]], ptr align 4 @__const.main.vec, i32 8, i1 false) -// CHECK11-NEXT: [[ARRAYINIT_BEGIN:%.*]] = getelementptr inbounds [2 x %struct.S], ptr [[S_ARR]], i32 0, i32 0 -// CHECK11-NEXT: call void @_ZN1SIfEC1Ef(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_BEGIN]], float noundef 1.000000e+00) -// CHECK11-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[ARRAYINIT_BEGIN]], i32 1 +// CHECK11-NEXT: call void @_ZN1SIfEC1Ef(ptr noundef nonnull align 4 dereferenceable(4) [[S_ARR]], float noundef 1.000000e+00) +// CHECK11-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[S_ARR]], i32 1 // CHECK11-NEXT: call void @_ZN1SIfEC1Ef(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_ELEMENT]], float noundef 2.000000e+00) // CHECK11-NEXT: store ptr [[TEST]], ptr [[VAR]], align 4 // CHECK11-NEXT: [[TMP0:%.*]] = load ptr, ptr [[VAR]], align 4 @@ -2165,9 +2162,8 @@ int main() { // CHECK11-NEXT: call void @_ZN1SIiEC1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[TEST]]) // CHECK11-NEXT: store i32 0, ptr [[T_VAR]], align 4 // CHECK11-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 4 [[VEC]], ptr align 4 @__const._Z5tmainIiET_v.vec, i32 8, i1 false) -// CHECK11-NEXT: [[ARRAYINIT_BEGIN:%.*]] = getelementptr inbounds [2 x %struct.S.0], ptr [[S_ARR]], i32 0, i32 0 -// CHECK11-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_BEGIN]], i32 noundef 1) -// CHECK11-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[ARRAYINIT_BEGIN]], i32 1 +// CHECK11-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[S_ARR]], i32 noundef 1) +// CHECK11-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[S_ARR]], i32 1 // CHECK11-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_ELEMENT]], i32 noundef 2) // CHECK11-NEXT: store ptr [[TEST]], ptr [[VAR]], align 4 // CHECK11-NEXT: [[TMP0:%.*]] = load ptr, ptr [[VAR]], align 4 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 4d10d16f47ed8716661415c52c45a663de983f5d..c9535d156d2ccb200797efc45d45d6a7e7048ad2 100644 --- a/clang/test/OpenMP/teams_distribute_parallel_for_private_codegen.cpp +++ b/clang/test/OpenMP/teams_distribute_parallel_for_private_codegen.cpp @@ -526,9 +526,8 @@ int main() { // CHECK1-NEXT: call void @_ZN1SIiEC1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[TEST]]) // CHECK1-NEXT: store i32 0, ptr [[T_VAR]], align 4 // CHECK1-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 4 [[VEC]], ptr align 4 @__const._Z5tmainIiET_v.vec, i64 8, i1 false) -// CHECK1-NEXT: [[ARRAYINIT_BEGIN:%.*]] = getelementptr inbounds [2 x %struct.S.0], ptr [[S_ARR]], i64 0, i64 0 -// CHECK1-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_BEGIN]], i32 noundef signext 1) -// CHECK1-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[ARRAYINIT_BEGIN]], i64 1 +// CHECK1-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[S_ARR]], i32 noundef signext 1) +// CHECK1-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[S_ARR]], i64 1 // CHECK1-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_ELEMENT]], i32 noundef signext 2) // CHECK1-NEXT: store ptr [[TEST]], ptr [[VAR]], align 8 // CHECK1-NEXT: store ptr undef, ptr [[_TMP1]], align 8 @@ -1253,9 +1252,8 @@ int main() { // CHECK3-NEXT: call void @_ZN1SIiEC1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[TEST]]) // CHECK3-NEXT: store i32 0, ptr [[T_VAR]], align 4 // CHECK3-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 4 [[VEC]], ptr align 4 @__const._Z5tmainIiET_v.vec, i32 8, i1 false) -// CHECK3-NEXT: [[ARRAYINIT_BEGIN:%.*]] = getelementptr inbounds [2 x %struct.S.0], ptr [[S_ARR]], i32 0, i32 0 -// CHECK3-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_BEGIN]], i32 noundef 1) -// CHECK3-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[ARRAYINIT_BEGIN]], i32 1 +// CHECK3-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[S_ARR]], i32 noundef 1) +// CHECK3-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[S_ARR]], i32 1 // CHECK3-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_ELEMENT]], i32 noundef 2) // CHECK3-NEXT: store ptr [[TEST]], ptr [[VAR]], align 4 // CHECK3-NEXT: store ptr undef, ptr [[_TMP1]], align 4 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 7d9e2ab89676f689576d3084493a5d1aa54bd0c7..7c13f557c1c13ac8176b401a1c55cd7f8ee37d6e 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 @@ -730,9 +730,8 @@ int main() { // CHECK1-NEXT: call void @_ZN1SIiEC1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[TEST]]) // CHECK1-NEXT: store i32 0, ptr [[T_VAR]], align 4 // CHECK1-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 4 [[VEC]], ptr align 4 @__const._Z5tmainIiET_v.vec, i64 8, i1 false) -// CHECK1-NEXT: [[ARRAYINIT_BEGIN:%.*]] = getelementptr inbounds [2 x %struct.S.0], ptr [[S_ARR]], i64 0, i64 0 -// CHECK1-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_BEGIN]], i32 noundef signext 1) -// CHECK1-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[ARRAYINIT_BEGIN]], i64 1 +// CHECK1-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[S_ARR]], i32 noundef signext 1) +// CHECK1-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[S_ARR]], i64 1 // CHECK1-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_ELEMENT]], i32 noundef signext 2) // CHECK1-NEXT: store ptr [[TEST]], ptr [[VAR]], align 8 // CHECK1-NEXT: [[TMP0:%.*]] = load ptr, ptr [[VAR]], align 8 @@ -1816,9 +1815,8 @@ int main() { // CHECK3-NEXT: call void @_ZN1SIiEC1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[TEST]]) // CHECK3-NEXT: store i32 0, ptr [[T_VAR]], align 4 // CHECK3-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 4 [[VEC]], ptr align 4 @__const._Z5tmainIiET_v.vec, i32 8, i1 false) -// CHECK3-NEXT: [[ARRAYINIT_BEGIN:%.*]] = getelementptr inbounds [2 x %struct.S.0], ptr [[S_ARR]], i32 0, i32 0 -// CHECK3-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_BEGIN]], i32 noundef 1) -// CHECK3-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[ARRAYINIT_BEGIN]], i32 1 +// CHECK3-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[S_ARR]], i32 noundef 1) +// CHECK3-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[S_ARR]], i32 1 // CHECK3-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_ELEMENT]], i32 noundef 2) // CHECK3-NEXT: store ptr [[TEST]], ptr [[VAR]], align 4 // CHECK3-NEXT: [[TMP0:%.*]] = load ptr, ptr [[VAR]], align 4 @@ -2496,9 +2494,8 @@ int main() { // CHECK5-NEXT: call void @_ZN1SIiEC1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[TEST]]) // CHECK5-NEXT: store i32 0, ptr [[T_VAR]], align 4 // CHECK5-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 4 [[VEC]], ptr align 4 @__const._Z5tmainIiET_v.vec, i64 8, i1 false) -// CHECK5-NEXT: [[ARRAYINIT_BEGIN:%.*]] = getelementptr inbounds [2 x %struct.S.0], ptr [[S_ARR]], i64 0, i64 0 -// CHECK5-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_BEGIN]], i32 noundef signext 1) -// CHECK5-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[ARRAYINIT_BEGIN]], i64 1 +// CHECK5-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[S_ARR]], i32 noundef signext 1) +// CHECK5-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[S_ARR]], i64 1 // CHECK5-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_ELEMENT]], i32 noundef signext 2) // CHECK5-NEXT: store ptr [[TEST]], ptr [[VAR]], align 8 // CHECK5-NEXT: [[TMP0:%.*]] = load ptr, ptr [[VAR]], align 8 @@ -2819,9 +2816,8 @@ int main() { // CHECK7-NEXT: call void @_ZN1SIiEC1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[TEST]]) // CHECK7-NEXT: store i32 0, ptr [[T_VAR]], align 4 // CHECK7-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 4 [[VEC]], ptr align 4 @__const._Z5tmainIiET_v.vec, i32 8, i1 false) -// CHECK7-NEXT: [[ARRAYINIT_BEGIN:%.*]] = getelementptr inbounds [2 x %struct.S.0], ptr [[S_ARR]], i32 0, i32 0 -// CHECK7-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_BEGIN]], i32 noundef 1) -// CHECK7-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[ARRAYINIT_BEGIN]], i32 1 +// CHECK7-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[S_ARR]], i32 noundef 1) +// CHECK7-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[S_ARR]], i32 1 // CHECK7-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_ELEMENT]], i32 noundef 2) // CHECK7-NEXT: store ptr [[TEST]], ptr [[VAR]], align 4 // CHECK7-NEXT: [[TMP0:%.*]] = load ptr, ptr [[VAR]], align 4 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 8643cb9bb84a8bd8ac3ba2c562cfbcfe6c7430c8..77a51286ff4970c2ba0716cd804b7717960887a6 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 @@ -790,9 +790,8 @@ int main() { // CHECK9-NEXT: call void @_ZN1SIfEC1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[TEST]]) // CHECK9-NEXT: store i32 0, ptr [[T_VAR]], align 4 // CHECK9-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 4 [[VEC]], ptr align 4 @__const.main.vec, i64 8, i1 false) -// CHECK9-NEXT: [[ARRAYINIT_BEGIN:%.*]] = getelementptr inbounds [2 x %struct.S], ptr [[S_ARR]], i64 0, i64 0 -// CHECK9-NEXT: call void @_ZN1SIfEC1Ef(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_BEGIN]], float noundef 1.000000e+00) -// CHECK9-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[ARRAYINIT_BEGIN]], i64 1 +// CHECK9-NEXT: call void @_ZN1SIfEC1Ef(ptr noundef nonnull align 4 dereferenceable(4) [[S_ARR]], float noundef 1.000000e+00) +// CHECK9-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[S_ARR]], i64 1 // CHECK9-NEXT: call void @_ZN1SIfEC1Ef(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_ELEMENT]], float noundef 2.000000e+00) // CHECK9-NEXT: store ptr [[TEST]], ptr [[VAR]], align 8 // CHECK9-NEXT: [[TMP0:%.*]] = load ptr, ptr [[VAR]], align 8 @@ -1272,9 +1271,8 @@ int main() { // CHECK9-NEXT: call void @_ZN1SIiEC1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[TEST]]) // CHECK9-NEXT: store i32 0, ptr [[T_VAR]], align 4 // CHECK9-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 4 [[VEC]], ptr align 4 @__const._Z5tmainIiET_v.vec, i64 8, i1 false) -// CHECK9-NEXT: [[ARRAYINIT_BEGIN:%.*]] = getelementptr inbounds [2 x %struct.S.0], ptr [[S_ARR]], i64 0, i64 0 -// CHECK9-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_BEGIN]], i32 noundef signext 1) -// CHECK9-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[ARRAYINIT_BEGIN]], i64 1 +// CHECK9-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[S_ARR]], i32 noundef signext 1) +// CHECK9-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[S_ARR]], i64 1 // CHECK9-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_ELEMENT]], i32 noundef signext 2) // CHECK9-NEXT: store ptr [[TEST]], ptr [[VAR]], align 8 // CHECK9-NEXT: [[TMP0:%.*]] = load ptr, ptr [[VAR]], align 8 @@ -1804,9 +1802,8 @@ int main() { // CHECK11-NEXT: call void @_ZN1SIfEC1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[TEST]]) // CHECK11-NEXT: store i32 0, ptr [[T_VAR]], align 4 // CHECK11-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 4 [[VEC]], ptr align 4 @__const.main.vec, i32 8, i1 false) -// CHECK11-NEXT: [[ARRAYINIT_BEGIN:%.*]] = getelementptr inbounds [2 x %struct.S], ptr [[S_ARR]], i32 0, i32 0 -// CHECK11-NEXT: call void @_ZN1SIfEC1Ef(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_BEGIN]], float noundef 1.000000e+00) -// CHECK11-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[ARRAYINIT_BEGIN]], i32 1 +// CHECK11-NEXT: call void @_ZN1SIfEC1Ef(ptr noundef nonnull align 4 dereferenceable(4) [[S_ARR]], float noundef 1.000000e+00) +// CHECK11-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[S_ARR]], i32 1 // CHECK11-NEXT: call void @_ZN1SIfEC1Ef(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_ELEMENT]], float noundef 2.000000e+00) // CHECK11-NEXT: store ptr [[TEST]], ptr [[VAR]], align 4 // CHECK11-NEXT: [[TMP0:%.*]] = load ptr, ptr [[VAR]], align 4 @@ -2280,9 +2277,8 @@ int main() { // CHECK11-NEXT: call void @_ZN1SIiEC1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[TEST]]) // CHECK11-NEXT: store i32 0, ptr [[T_VAR]], align 4 // CHECK11-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 4 [[VEC]], ptr align 4 @__const._Z5tmainIiET_v.vec, i32 8, i1 false) -// CHECK11-NEXT: [[ARRAYINIT_BEGIN:%.*]] = getelementptr inbounds [2 x %struct.S.0], ptr [[S_ARR]], i32 0, i32 0 -// CHECK11-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_BEGIN]], i32 noundef 1) -// CHECK11-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[ARRAYINIT_BEGIN]], i32 1 +// CHECK11-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[S_ARR]], i32 noundef 1) +// CHECK11-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[S_ARR]], i32 1 // CHECK11-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_ELEMENT]], i32 noundef 2) // CHECK11-NEXT: store ptr [[TEST]], ptr [[VAR]], align 4 // CHECK11-NEXT: [[TMP0:%.*]] = load ptr, ptr [[VAR]], align 4 @@ -2811,9 +2807,8 @@ int main() { // CHECK13-NEXT: call void @_ZN1SIfEC1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[TEST]]) // CHECK13-NEXT: store i32 0, ptr [[T_VAR]], align 4 // CHECK13-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 4 [[VEC]], ptr align 4 @__const.main.vec, i64 8, i1 false) -// CHECK13-NEXT: [[ARRAYINIT_BEGIN:%.*]] = getelementptr inbounds [2 x %struct.S], ptr [[S_ARR]], i64 0, i64 0 -// CHECK13-NEXT: call void @_ZN1SIfEC1Ef(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_BEGIN]], float noundef 1.000000e+00) -// CHECK13-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[ARRAYINIT_BEGIN]], i64 1 +// CHECK13-NEXT: call void @_ZN1SIfEC1Ef(ptr noundef nonnull align 4 dereferenceable(4) [[S_ARR]], float noundef 1.000000e+00) +// CHECK13-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[S_ARR]], i64 1 // CHECK13-NEXT: call void @_ZN1SIfEC1Ef(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_ELEMENT]], float noundef 2.000000e+00) // CHECK13-NEXT: store ptr [[TEST]], ptr [[VAR]], align 8 // CHECK13-NEXT: [[TMP0:%.*]] = load ptr, ptr [[VAR]], align 8 @@ -2977,9 +2972,8 @@ int main() { // CHECK13-NEXT: call void @_ZN1SIiEC1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[TEST]]) // CHECK13-NEXT: store i32 0, ptr [[T_VAR]], align 4 // CHECK13-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 4 [[VEC]], ptr align 4 @__const._Z5tmainIiET_v.vec, i64 8, i1 false) -// CHECK13-NEXT: [[ARRAYINIT_BEGIN:%.*]] = getelementptr inbounds [2 x %struct.S.0], ptr [[S_ARR]], i64 0, i64 0 -// CHECK13-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_BEGIN]], i32 noundef signext 1) -// CHECK13-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[ARRAYINIT_BEGIN]], i64 1 +// CHECK13-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[S_ARR]], i32 noundef signext 1) +// CHECK13-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[S_ARR]], i64 1 // CHECK13-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_ELEMENT]], i32 noundef signext 2) // CHECK13-NEXT: store ptr [[TEST]], ptr [[VAR]], align 8 // CHECK13-NEXT: [[TMP0:%.*]] = load ptr, ptr [[VAR]], align 8 @@ -3214,9 +3208,8 @@ int main() { // CHECK15-NEXT: call void @_ZN1SIfEC1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[TEST]]) // CHECK15-NEXT: store i32 0, ptr [[T_VAR]], align 4 // CHECK15-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 4 [[VEC]], ptr align 4 @__const.main.vec, i32 8, i1 false) -// CHECK15-NEXT: [[ARRAYINIT_BEGIN:%.*]] = getelementptr inbounds [2 x %struct.S], ptr [[S_ARR]], i32 0, i32 0 -// CHECK15-NEXT: call void @_ZN1SIfEC1Ef(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_BEGIN]], float noundef 1.000000e+00) -// CHECK15-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[ARRAYINIT_BEGIN]], i32 1 +// CHECK15-NEXT: call void @_ZN1SIfEC1Ef(ptr noundef nonnull align 4 dereferenceable(4) [[S_ARR]], float noundef 1.000000e+00) +// CHECK15-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[S_ARR]], i32 1 // CHECK15-NEXT: call void @_ZN1SIfEC1Ef(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_ELEMENT]], float noundef 2.000000e+00) // CHECK15-NEXT: store ptr [[TEST]], ptr [[VAR]], align 4 // CHECK15-NEXT: [[TMP0:%.*]] = load ptr, ptr [[VAR]], align 4 @@ -3378,9 +3371,8 @@ int main() { // CHECK15-NEXT: call void @_ZN1SIiEC1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[TEST]]) // CHECK15-NEXT: store i32 0, ptr [[T_VAR]], align 4 // CHECK15-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 4 [[VEC]], ptr align 4 @__const._Z5tmainIiET_v.vec, i32 8, i1 false) -// CHECK15-NEXT: [[ARRAYINIT_BEGIN:%.*]] = getelementptr inbounds [2 x %struct.S.0], ptr [[S_ARR]], i32 0, i32 0 -// CHECK15-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_BEGIN]], i32 noundef 1) -// CHECK15-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[ARRAYINIT_BEGIN]], i32 1 +// CHECK15-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[S_ARR]], i32 noundef 1) +// CHECK15-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[S_ARR]], i32 1 // CHECK15-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_ELEMENT]], i32 noundef 2) // CHECK15-NEXT: store ptr [[TEST]], ptr [[VAR]], align 4 // CHECK15-NEXT: [[TMP0:%.*]] = load ptr, ptr [[VAR]], align 4 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 f40acb42f9dae46b935242d75278471a760f1223..4d0c7f00d316a2ec17b41544260c1070e3a4869b 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 @@ -542,9 +542,8 @@ int main() { // CHECK1-NEXT: call void @_ZN1SIiEC1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[TEST]]) // CHECK1-NEXT: store i32 0, ptr [[T_VAR]], align 4 // CHECK1-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 4 [[VEC]], ptr align 4 @__const._Z5tmainIiET_v.vec, i64 8, i1 false) -// CHECK1-NEXT: [[ARRAYINIT_BEGIN:%.*]] = getelementptr inbounds [2 x %struct.S.0], ptr [[S_ARR]], i64 0, i64 0 -// CHECK1-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_BEGIN]], i32 noundef signext 1) -// CHECK1-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[ARRAYINIT_BEGIN]], i64 1 +// CHECK1-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[S_ARR]], i32 noundef signext 1) +// CHECK1-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[S_ARR]], i64 1 // CHECK1-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_ELEMENT]], i32 noundef signext 2) // CHECK1-NEXT: store ptr [[TEST]], ptr [[VAR]], align 8 // CHECK1-NEXT: store ptr undef, ptr [[_TMP1]], align 8 @@ -1297,9 +1296,8 @@ int main() { // CHECK3-NEXT: call void @_ZN1SIiEC1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[TEST]]) // CHECK3-NEXT: store i32 0, ptr [[T_VAR]], align 4 // CHECK3-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 4 [[VEC]], ptr align 4 @__const._Z5tmainIiET_v.vec, i32 8, i1 false) -// CHECK3-NEXT: [[ARRAYINIT_BEGIN:%.*]] = getelementptr inbounds [2 x %struct.S.0], ptr [[S_ARR]], i32 0, i32 0 -// CHECK3-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_BEGIN]], i32 noundef 1) -// CHECK3-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[ARRAYINIT_BEGIN]], i32 1 +// CHECK3-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[S_ARR]], i32 noundef 1) +// CHECK3-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[S_ARR]], i32 1 // CHECK3-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_ELEMENT]], i32 noundef 2) // CHECK3-NEXT: store ptr [[TEST]], ptr [[VAR]], align 4 // CHECK3-NEXT: store ptr undef, ptr [[_TMP1]], align 4 @@ -1832,9 +1830,8 @@ int main() { // CHECK5-NEXT: call void @_ZN1SIiEC1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[TEST]]) // CHECK5-NEXT: store i32 0, ptr [[T_VAR]], align 4 // CHECK5-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 4 [[VEC]], ptr align 4 @__const._Z5tmainIiET_v.vec, i64 8, i1 false) -// CHECK5-NEXT: [[ARRAYINIT_BEGIN:%.*]] = getelementptr inbounds [2 x %struct.S.0], ptr [[S_ARR]], i64 0, i64 0 -// CHECK5-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_BEGIN]], i32 noundef signext 1) -// CHECK5-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[ARRAYINIT_BEGIN]], i64 1 +// CHECK5-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[S_ARR]], i32 noundef signext 1) +// CHECK5-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[S_ARR]], i64 1 // CHECK5-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_ELEMENT]], i32 noundef signext 2) // CHECK5-NEXT: store ptr [[TEST]], ptr [[VAR]], align 8 // CHECK5-NEXT: store ptr undef, ptr [[_TMP1]], align 8 @@ -2208,9 +2205,8 @@ int main() { // CHECK7-NEXT: call void @_ZN1SIiEC1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[TEST]]) // CHECK7-NEXT: store i32 0, ptr [[T_VAR]], align 4 // CHECK7-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 4 [[VEC]], ptr align 4 @__const._Z5tmainIiET_v.vec, i32 8, i1 false) -// CHECK7-NEXT: [[ARRAYINIT_BEGIN:%.*]] = getelementptr inbounds [2 x %struct.S.0], ptr [[S_ARR]], i32 0, i32 0 -// CHECK7-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_BEGIN]], i32 noundef 1) -// CHECK7-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[ARRAYINIT_BEGIN]], i32 1 +// CHECK7-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[S_ARR]], i32 noundef 1) +// CHECK7-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[S_ARR]], i32 1 // CHECK7-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_ELEMENT]], i32 noundef 2) // CHECK7-NEXT: store ptr [[TEST]], ptr [[VAR]], align 4 // CHECK7-NEXT: store ptr undef, ptr [[_TMP1]], align 4 diff --git a/clang/test/OpenMP/teams_distribute_private_codegen.cpp b/clang/test/OpenMP/teams_distribute_private_codegen.cpp index 78b42e3194c796067eeb3a7ce56a5005dacedb08..1f49d9334f31f703200c940357e701b156f82db8 100644 --- a/clang/test/OpenMP/teams_distribute_private_codegen.cpp +++ b/clang/test/OpenMP/teams_distribute_private_codegen.cpp @@ -405,9 +405,8 @@ int main() { // CHECK1-NEXT: call void @_ZN1SIiEC1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[TEST]]) // CHECK1-NEXT: store i32 0, ptr [[T_VAR]], align 4 // CHECK1-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 4 [[VEC]], ptr align 4 @__const._Z5tmainIiET_v.vec, i64 8, i1 false) -// CHECK1-NEXT: [[ARRAYINIT_BEGIN:%.*]] = getelementptr inbounds [2 x %struct.S.0], ptr [[S_ARR]], i64 0, i64 0 -// CHECK1-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_BEGIN]], i32 noundef signext 1) -// CHECK1-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[ARRAYINIT_BEGIN]], i64 1 +// CHECK1-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[S_ARR]], i32 noundef signext 1) +// CHECK1-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[S_ARR]], i64 1 // CHECK1-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_ELEMENT]], i32 noundef signext 2) // CHECK1-NEXT: store ptr [[TEST]], ptr [[VAR]], align 8 // CHECK1-NEXT: store ptr undef, ptr [[_TMP1]], align 8 @@ -931,9 +930,8 @@ int main() { // CHECK3-NEXT: call void @_ZN1SIiEC1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[TEST]]) // CHECK3-NEXT: store i32 0, ptr [[T_VAR]], align 4 // CHECK3-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 4 [[VEC]], ptr align 4 @__const._Z5tmainIiET_v.vec, i32 8, i1 false) -// CHECK3-NEXT: [[ARRAYINIT_BEGIN:%.*]] = getelementptr inbounds [2 x %struct.S.0], ptr [[S_ARR]], i32 0, i32 0 -// CHECK3-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_BEGIN]], i32 noundef 1) -// CHECK3-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[ARRAYINIT_BEGIN]], i32 1 +// CHECK3-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[S_ARR]], i32 noundef 1) +// CHECK3-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[S_ARR]], i32 1 // CHECK3-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_ELEMENT]], i32 noundef 2) // CHECK3-NEXT: store ptr [[TEST]], ptr [[VAR]], align 4 // CHECK3-NEXT: store ptr undef, ptr [[_TMP1]], align 4 diff --git a/clang/test/OpenMP/teams_distribute_simd_firstprivate_codegen.cpp b/clang/test/OpenMP/teams_distribute_simd_firstprivate_codegen.cpp index 2d3fccd90c0a5d19867d7283a20bad0ce81ccdc6..9e6825d57cf9ad53ac8a4519f96b3b8bda591c1e 100644 --- a/clang/test/OpenMP/teams_distribute_simd_firstprivate_codegen.cpp +++ b/clang/test/OpenMP/teams_distribute_simd_firstprivate_codegen.cpp @@ -556,9 +556,8 @@ int main() { // CHECK1-NEXT: call void @_ZN1SIiEC1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[TEST]]) // CHECK1-NEXT: store i32 0, ptr [[T_VAR]], align 4 // CHECK1-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 4 [[VEC]], ptr align 4 @__const._Z5tmainIiET_v.vec, i64 8, i1 false) -// CHECK1-NEXT: [[ARRAYINIT_BEGIN:%.*]] = getelementptr inbounds [2 x %struct.S.0], ptr [[S_ARR]], i64 0, i64 0 -// CHECK1-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_BEGIN]], i32 noundef signext 1) -// CHECK1-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[ARRAYINIT_BEGIN]], i64 1 +// CHECK1-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[S_ARR]], i32 noundef signext 1) +// CHECK1-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[S_ARR]], i64 1 // CHECK1-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_ELEMENT]], i32 noundef signext 2) // CHECK1-NEXT: store ptr [[TEST]], ptr [[VAR]], align 8 // CHECK1-NEXT: [[TMP0:%.*]] = load ptr, ptr [[VAR]], align 8 @@ -1372,9 +1371,8 @@ int main() { // CHECK3-NEXT: call void @_ZN1SIiEC1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[TEST]]) // CHECK3-NEXT: store i32 0, ptr [[T_VAR]], align 4 // CHECK3-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 4 [[VEC]], ptr align 4 @__const._Z5tmainIiET_v.vec, i32 8, i1 false) -// CHECK3-NEXT: [[ARRAYINIT_BEGIN:%.*]] = getelementptr inbounds [2 x %struct.S.0], ptr [[S_ARR]], i32 0, i32 0 -// CHECK3-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_BEGIN]], i32 noundef 1) -// CHECK3-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[ARRAYINIT_BEGIN]], i32 1 +// CHECK3-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[S_ARR]], i32 noundef 1) +// CHECK3-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[S_ARR]], i32 1 // CHECK3-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_ELEMENT]], i32 noundef 2) // CHECK3-NEXT: store ptr [[TEST]], ptr [[VAR]], align 4 // CHECK3-NEXT: [[TMP0:%.*]] = load ptr, ptr [[VAR]], align 4 @@ -1919,9 +1917,8 @@ int main() { // CHECK5-NEXT: call void @_ZN1SIiEC1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[TEST]]) // CHECK5-NEXT: store i32 0, ptr [[T_VAR]], align 4 // CHECK5-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 4 [[VEC]], ptr align 4 @__const._Z5tmainIiET_v.vec, i64 8, i1 false) -// CHECK5-NEXT: [[ARRAYINIT_BEGIN:%.*]] = getelementptr inbounds [2 x %struct.S.0], ptr [[S_ARR]], i64 0, i64 0 -// CHECK5-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_BEGIN]], i32 noundef signext 1) -// CHECK5-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[ARRAYINIT_BEGIN]], i64 1 +// CHECK5-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[S_ARR]], i32 noundef signext 1) +// CHECK5-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[S_ARR]], i64 1 // CHECK5-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_ELEMENT]], i32 noundef signext 2) // CHECK5-NEXT: store ptr [[TEST]], ptr [[VAR]], align 8 // CHECK5-NEXT: [[TMP0:%.*]] = load ptr, ptr [[VAR]], align 8 @@ -2241,9 +2238,8 @@ int main() { // CHECK7-NEXT: call void @_ZN1SIiEC1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[TEST]]) // CHECK7-NEXT: store i32 0, ptr [[T_VAR]], align 4 // CHECK7-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 4 [[VEC]], ptr align 4 @__const._Z5tmainIiET_v.vec, i32 8, i1 false) -// CHECK7-NEXT: [[ARRAYINIT_BEGIN:%.*]] = getelementptr inbounds [2 x %struct.S.0], ptr [[S_ARR]], i32 0, i32 0 -// CHECK7-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_BEGIN]], i32 noundef 1) -// CHECK7-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[ARRAYINIT_BEGIN]], i32 1 +// CHECK7-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[S_ARR]], i32 noundef 1) +// CHECK7-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[S_ARR]], i32 1 // CHECK7-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_ELEMENT]], i32 noundef 2) // CHECK7-NEXT: store ptr [[TEST]], ptr [[VAR]], align 4 // CHECK7-NEXT: [[TMP0:%.*]] = load ptr, ptr [[VAR]], align 4 diff --git a/clang/test/OpenMP/teams_distribute_simd_lastprivate_codegen.cpp b/clang/test/OpenMP/teams_distribute_simd_lastprivate_codegen.cpp index ec95ab55b1552a9911931f9786a95418fa27d164..3f01eab5a7352bcc444df4761e84eb0ec9d416b7 100644 --- a/clang/test/OpenMP/teams_distribute_simd_lastprivate_codegen.cpp +++ b/clang/test/OpenMP/teams_distribute_simd_lastprivate_codegen.cpp @@ -519,9 +519,8 @@ int main() { // CHECK9-NEXT: call void @_ZN1SIfEC1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[TEST]]) // CHECK9-NEXT: store i32 0, ptr [[T_VAR]], align 4 // CHECK9-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 4 [[VEC]], ptr align 4 @__const.main.vec, i64 8, i1 false) -// CHECK9-NEXT: [[ARRAYINIT_BEGIN:%.*]] = getelementptr inbounds [2 x %struct.S], ptr [[S_ARR]], i64 0, i64 0 -// CHECK9-NEXT: call void @_ZN1SIfEC1Ef(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_BEGIN]], float noundef 1.000000e+00) -// CHECK9-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[ARRAYINIT_BEGIN]], i64 1 +// CHECK9-NEXT: call void @_ZN1SIfEC1Ef(ptr noundef nonnull align 4 dereferenceable(4) [[S_ARR]], float noundef 1.000000e+00) +// CHECK9-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[S_ARR]], i64 1 // CHECK9-NEXT: call void @_ZN1SIfEC1Ef(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_ELEMENT]], float noundef 2.000000e+00) // CHECK9-NEXT: store ptr [[TEST]], ptr [[VAR]], align 8 // CHECK9-NEXT: [[TMP0:%.*]] = load ptr, ptr [[VAR]], align 8 @@ -846,9 +845,8 @@ int main() { // CHECK9-NEXT: call void @_ZN1SIiEC1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[TEST]]) // CHECK9-NEXT: store i32 0, ptr [[T_VAR]], align 4 // CHECK9-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 4 [[VEC]], ptr align 4 @__const._Z5tmainIiET_v.vec, i64 8, i1 false) -// CHECK9-NEXT: [[ARRAYINIT_BEGIN:%.*]] = getelementptr inbounds [2 x %struct.S.0], ptr [[S_ARR]], i64 0, i64 0 -// CHECK9-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_BEGIN]], i32 noundef signext 1) -// CHECK9-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[ARRAYINIT_BEGIN]], i64 1 +// CHECK9-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[S_ARR]], i32 noundef signext 1) +// CHECK9-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[S_ARR]], i64 1 // CHECK9-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_ELEMENT]], i32 noundef signext 2) // CHECK9-NEXT: store ptr [[TEST]], ptr [[VAR]], align 8 // CHECK9-NEXT: [[TMP0:%.*]] = load ptr, ptr [[VAR]], align 8 @@ -1229,9 +1227,8 @@ int main() { // CHECK11-NEXT: call void @_ZN1SIfEC1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[TEST]]) // CHECK11-NEXT: store i32 0, ptr [[T_VAR]], align 4 // CHECK11-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 4 [[VEC]], ptr align 4 @__const.main.vec, i32 8, i1 false) -// CHECK11-NEXT: [[ARRAYINIT_BEGIN:%.*]] = getelementptr inbounds [2 x %struct.S], ptr [[S_ARR]], i32 0, i32 0 -// CHECK11-NEXT: call void @_ZN1SIfEC1Ef(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_BEGIN]], float noundef 1.000000e+00) -// CHECK11-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[ARRAYINIT_BEGIN]], i32 1 +// CHECK11-NEXT: call void @_ZN1SIfEC1Ef(ptr noundef nonnull align 4 dereferenceable(4) [[S_ARR]], float noundef 1.000000e+00) +// CHECK11-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[S_ARR]], i32 1 // CHECK11-NEXT: call void @_ZN1SIfEC1Ef(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_ELEMENT]], float noundef 2.000000e+00) // CHECK11-NEXT: store ptr [[TEST]], ptr [[VAR]], align 4 // CHECK11-NEXT: [[TMP0:%.*]] = load ptr, ptr [[VAR]], align 4 @@ -1554,9 +1551,8 @@ int main() { // CHECK11-NEXT: call void @_ZN1SIiEC1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[TEST]]) // CHECK11-NEXT: store i32 0, ptr [[T_VAR]], align 4 // CHECK11-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 4 [[VEC]], ptr align 4 @__const._Z5tmainIiET_v.vec, i32 8, i1 false) -// CHECK11-NEXT: [[ARRAYINIT_BEGIN:%.*]] = getelementptr inbounds [2 x %struct.S.0], ptr [[S_ARR]], i32 0, i32 0 -// CHECK11-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_BEGIN]], i32 noundef 1) -// CHECK11-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[ARRAYINIT_BEGIN]], i32 1 +// CHECK11-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[S_ARR]], i32 noundef 1) +// CHECK11-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[S_ARR]], i32 1 // CHECK11-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_ELEMENT]], i32 noundef 2) // CHECK11-NEXT: store ptr [[TEST]], ptr [[VAR]], align 4 // CHECK11-NEXT: [[TMP0:%.*]] = load ptr, ptr [[VAR]], align 4 @@ -1940,9 +1936,8 @@ int main() { // CHECK13-NEXT: call void @_ZN1SIfEC1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[TEST]]) // CHECK13-NEXT: store i32 0, ptr [[T_VAR]], align 4 // CHECK13-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 4 [[VEC]], ptr align 4 @__const.main.vec, i64 8, i1 false) -// CHECK13-NEXT: [[ARRAYINIT_BEGIN:%.*]] = getelementptr inbounds [2 x %struct.S], ptr [[S_ARR]], i64 0, i64 0 -// CHECK13-NEXT: call void @_ZN1SIfEC1Ef(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_BEGIN]], float noundef 1.000000e+00) -// CHECK13-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[ARRAYINIT_BEGIN]], i64 1 +// CHECK13-NEXT: call void @_ZN1SIfEC1Ef(ptr noundef nonnull align 4 dereferenceable(4) [[S_ARR]], float noundef 1.000000e+00) +// CHECK13-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[S_ARR]], i64 1 // CHECK13-NEXT: call void @_ZN1SIfEC1Ef(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_ELEMENT]], float noundef 2.000000e+00) // CHECK13-NEXT: store ptr [[TEST]], ptr [[VAR]], align 8 // CHECK13-NEXT: [[TMP0:%.*]] = load ptr, ptr [[VAR]], align 8 @@ -2105,9 +2100,8 @@ int main() { // CHECK13-NEXT: call void @_ZN1SIiEC1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[TEST]]) // CHECK13-NEXT: store i32 0, ptr [[T_VAR]], align 4 // CHECK13-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 4 [[VEC]], ptr align 4 @__const._Z5tmainIiET_v.vec, i64 8, i1 false) -// CHECK13-NEXT: [[ARRAYINIT_BEGIN:%.*]] = getelementptr inbounds [2 x %struct.S.0], ptr [[S_ARR]], i64 0, i64 0 -// CHECK13-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_BEGIN]], i32 noundef signext 1) -// CHECK13-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[ARRAYINIT_BEGIN]], i64 1 +// CHECK13-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[S_ARR]], i32 noundef signext 1) +// CHECK13-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[S_ARR]], i64 1 // CHECK13-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_ELEMENT]], i32 noundef signext 2) // CHECK13-NEXT: store ptr [[TEST]], ptr [[VAR]], align 8 // CHECK13-NEXT: [[TMP0:%.*]] = load ptr, ptr [[VAR]], align 8 @@ -2341,9 +2335,8 @@ int main() { // CHECK15-NEXT: call void @_ZN1SIfEC1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[TEST]]) // CHECK15-NEXT: store i32 0, ptr [[T_VAR]], align 4 // CHECK15-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 4 [[VEC]], ptr align 4 @__const.main.vec, i32 8, i1 false) -// CHECK15-NEXT: [[ARRAYINIT_BEGIN:%.*]] = getelementptr inbounds [2 x %struct.S], ptr [[S_ARR]], i32 0, i32 0 -// CHECK15-NEXT: call void @_ZN1SIfEC1Ef(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_BEGIN]], float noundef 1.000000e+00) -// CHECK15-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[ARRAYINIT_BEGIN]], i32 1 +// CHECK15-NEXT: call void @_ZN1SIfEC1Ef(ptr noundef nonnull align 4 dereferenceable(4) [[S_ARR]], float noundef 1.000000e+00) +// CHECK15-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[S_ARR]], i32 1 // CHECK15-NEXT: call void @_ZN1SIfEC1Ef(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_ELEMENT]], float noundef 2.000000e+00) // CHECK15-NEXT: store ptr [[TEST]], ptr [[VAR]], align 4 // CHECK15-NEXT: [[TMP0:%.*]] = load ptr, ptr [[VAR]], align 4 @@ -2504,9 +2497,8 @@ int main() { // CHECK15-NEXT: call void @_ZN1SIiEC1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[TEST]]) // CHECK15-NEXT: store i32 0, ptr [[T_VAR]], align 4 // CHECK15-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 4 [[VEC]], ptr align 4 @__const._Z5tmainIiET_v.vec, i32 8, i1 false) -// CHECK15-NEXT: [[ARRAYINIT_BEGIN:%.*]] = getelementptr inbounds [2 x %struct.S.0], ptr [[S_ARR]], i32 0, i32 0 -// CHECK15-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_BEGIN]], i32 noundef 1) -// CHECK15-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[ARRAYINIT_BEGIN]], i32 1 +// CHECK15-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[S_ARR]], i32 noundef 1) +// CHECK15-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[S_ARR]], i32 1 // CHECK15-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_ELEMENT]], i32 noundef 2) // CHECK15-NEXT: store ptr [[TEST]], ptr [[VAR]], align 4 // CHECK15-NEXT: [[TMP0:%.*]] = load ptr, ptr [[VAR]], align 4 diff --git a/clang/test/OpenMP/teams_distribute_simd_private_codegen.cpp b/clang/test/OpenMP/teams_distribute_simd_private_codegen.cpp index c839268ada753485516ae92981bf19e6c5410c83..4c87b2dcc111be8096ce95546c415324fe39d7b2 100644 --- a/clang/test/OpenMP/teams_distribute_simd_private_codegen.cpp +++ b/clang/test/OpenMP/teams_distribute_simd_private_codegen.cpp @@ -413,9 +413,8 @@ int main() { // CHECK1-NEXT: call void @_ZN1SIiEC1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[TEST]]) // CHECK1-NEXT: store i32 0, ptr [[T_VAR]], align 4 // CHECK1-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 4 [[VEC]], ptr align 4 @__const._Z5tmainIiET_v.vec, i64 8, i1 false) -// CHECK1-NEXT: [[ARRAYINIT_BEGIN:%.*]] = getelementptr inbounds [2 x %struct.S.0], ptr [[S_ARR]], i64 0, i64 0 -// CHECK1-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_BEGIN]], i32 noundef signext 1) -// CHECK1-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[ARRAYINIT_BEGIN]], i64 1 +// CHECK1-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[S_ARR]], i32 noundef signext 1) +// CHECK1-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[S_ARR]], i64 1 // CHECK1-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_ELEMENT]], i32 noundef signext 2) // CHECK1-NEXT: store ptr [[TEST]], ptr [[VAR]], align 8 // CHECK1-NEXT: store ptr undef, ptr [[_TMP1]], align 8 @@ -953,9 +952,8 @@ int main() { // CHECK3-NEXT: call void @_ZN1SIiEC1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[TEST]]) // CHECK3-NEXT: store i32 0, ptr [[T_VAR]], align 4 // CHECK3-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 4 [[VEC]], ptr align 4 @__const._Z5tmainIiET_v.vec, i32 8, i1 false) -// CHECK3-NEXT: [[ARRAYINIT_BEGIN:%.*]] = getelementptr inbounds [2 x %struct.S.0], ptr [[S_ARR]], i32 0, i32 0 -// CHECK3-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_BEGIN]], i32 noundef 1) -// CHECK3-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[ARRAYINIT_BEGIN]], i32 1 +// CHECK3-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[S_ARR]], i32 noundef 1) +// CHECK3-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[S_ARR]], i32 1 // CHECK3-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_ELEMENT]], i32 noundef 2) // CHECK3-NEXT: store ptr [[TEST]], ptr [[VAR]], align 4 // CHECK3-NEXT: store ptr undef, ptr [[_TMP1]], align 4 @@ -1381,9 +1379,8 @@ int main() { // CHECK5-NEXT: call void @_ZN1SIiEC1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[TEST]]) // CHECK5-NEXT: store i32 0, ptr [[T_VAR]], align 4 // CHECK5-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 4 [[VEC]], ptr align 4 @__const._Z5tmainIiET_v.vec, i64 8, i1 false) -// CHECK5-NEXT: [[ARRAYINIT_BEGIN:%.*]] = getelementptr inbounds [2 x %struct.S.0], ptr [[S_ARR]], i64 0, i64 0 -// CHECK5-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_BEGIN]], i32 noundef signext 1) -// CHECK5-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[ARRAYINIT_BEGIN]], i64 1 +// CHECK5-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[S_ARR]], i32 noundef signext 1) +// CHECK5-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[S_ARR]], i64 1 // CHECK5-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_ELEMENT]], i32 noundef signext 2) // CHECK5-NEXT: store ptr [[TEST]], ptr [[VAR]], align 8 // CHECK5-NEXT: store ptr undef, ptr [[_TMP1]], align 8 @@ -1757,9 +1754,8 @@ int main() { // CHECK7-NEXT: call void @_ZN1SIiEC1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[TEST]]) // CHECK7-NEXT: store i32 0, ptr [[T_VAR]], align 4 // CHECK7-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 4 [[VEC]], ptr align 4 @__const._Z5tmainIiET_v.vec, i32 8, i1 false) -// CHECK7-NEXT: [[ARRAYINIT_BEGIN:%.*]] = getelementptr inbounds [2 x %struct.S.0], ptr [[S_ARR]], i32 0, i32 0 -// CHECK7-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_BEGIN]], i32 noundef 1) -// CHECK7-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[ARRAYINIT_BEGIN]], i32 1 +// CHECK7-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[S_ARR]], i32 noundef 1) +// CHECK7-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[S_ARR]], i32 1 // CHECK7-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_ELEMENT]], i32 noundef 2) // CHECK7-NEXT: store ptr [[TEST]], ptr [[VAR]], align 4 // CHECK7-NEXT: store ptr undef, ptr [[_TMP1]], align 4 diff --git a/clang/test/OpenMP/teams_firstprivate_codegen.cpp b/clang/test/OpenMP/teams_firstprivate_codegen.cpp index 649fae99b21ac35a6a7ce3b38e325b010713ea52..304bd5dbb50ef387e8c73abd6e9d8c184d396cb1 100644 --- a/clang/test/OpenMP/teams_firstprivate_codegen.cpp +++ b/clang/test/OpenMP/teams_firstprivate_codegen.cpp @@ -283,9 +283,8 @@ void array_func(float a[3], St s[2], int n, long double vla1[n]) { // CHECK9-NEXT: call void @_ZN1SIfEC1Ev(ptr nonnull align 4 dereferenceable(4) [[TEST]]) // CHECK9-NEXT: store i32 0, ptr [[T_VAR]], align 4 // CHECK9-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 4 [[VEC]], ptr align 4 @__const.main.vec, i64 8, i1 false) -// CHECK9-NEXT: [[ARRAYINIT_BEGIN:%.*]] = getelementptr inbounds [2 x %struct.S], ptr [[S_ARR]], i64 0, i64 0 -// CHECK9-NEXT: call void @_ZN1SIfEC1Ef(ptr nonnull align 4 dereferenceable(4) [[ARRAYINIT_BEGIN]], float 1.000000e+00) -// CHECK9-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[ARRAYINIT_BEGIN]], i64 1 +// CHECK9-NEXT: call void @_ZN1SIfEC1Ef(ptr nonnull align 4 dereferenceable(4) [[S_ARR]], float 1.000000e+00) +// CHECK9-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[S_ARR]], i64 1 // CHECK9-NEXT: call void @_ZN1SIfEC1Ef(ptr nonnull align 4 dereferenceable(4) [[ARRAYINIT_ELEMENT]], float 2.000000e+00) // CHECK9-NEXT: call void @_ZN1SIfEC1Ef(ptr nonnull align 4 dereferenceable(4) [[VAR]], float 3.000000e+00) // CHECK9-NEXT: [[TMP0:%.*]] = load i32, ptr [[T_VAR]], align 4 @@ -628,9 +627,8 @@ void array_func(float a[3], St s[2], int n, long double vla1[n]) { // CHECK9-NEXT: call void @_ZN1SIiEC1Ev(ptr nonnull align 4 dereferenceable(4) [[TEST]]) // CHECK9-NEXT: store i32 0, ptr [[T_VAR]], align 128 // CHECK9-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 128 [[VEC]], ptr align 128 @__const._Z5tmainIiET_v.vec, i64 8, i1 false) -// CHECK9-NEXT: [[ARRAYINIT_BEGIN:%.*]] = getelementptr inbounds [2 x %struct.S.0], ptr [[S_ARR]], i64 0, i64 0 -// CHECK9-NEXT: call void @_ZN1SIiEC1Ei(ptr nonnull align 4 dereferenceable(4) [[ARRAYINIT_BEGIN]], i32 signext 1) -// CHECK9-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[ARRAYINIT_BEGIN]], i64 1 +// CHECK9-NEXT: call void @_ZN1SIiEC1Ei(ptr nonnull align 4 dereferenceable(4) [[S_ARR]], i32 signext 1) +// CHECK9-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[S_ARR]], i64 1 // CHECK9-NEXT: call void @_ZN1SIiEC1Ei(ptr nonnull align 4 dereferenceable(4) [[ARRAYINIT_ELEMENT]], i32 signext 2) // CHECK9-NEXT: call void @_ZN1SIiEC1Ei(ptr nonnull align 4 dereferenceable(4) [[VAR]], i32 signext 3) // CHECK9-NEXT: [[TMP0:%.*]] = load i32, ptr [[T_VAR]], align 128 @@ -1077,9 +1075,8 @@ void array_func(float a[3], St s[2], int n, long double vla1[n]) { // CHECK11-NEXT: call void @_ZN1SIfEC1Ev(ptr nonnull align 4 dereferenceable(4) [[TEST]]) // CHECK11-NEXT: store i32 0, ptr [[T_VAR]], align 4 // CHECK11-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 4 [[VEC]], ptr align 4 @__const.main.vec, i32 8, i1 false) -// CHECK11-NEXT: [[ARRAYINIT_BEGIN:%.*]] = getelementptr inbounds [2 x %struct.S], ptr [[S_ARR]], i32 0, i32 0 -// CHECK11-NEXT: call void @_ZN1SIfEC1Ef(ptr nonnull align 4 dereferenceable(4) [[ARRAYINIT_BEGIN]], float 1.000000e+00) -// CHECK11-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[ARRAYINIT_BEGIN]], i32 1 +// CHECK11-NEXT: call void @_ZN1SIfEC1Ef(ptr nonnull align 4 dereferenceable(4) [[S_ARR]], float 1.000000e+00) +// CHECK11-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[S_ARR]], i32 1 // CHECK11-NEXT: call void @_ZN1SIfEC1Ef(ptr nonnull align 4 dereferenceable(4) [[ARRAYINIT_ELEMENT]], float 2.000000e+00) // CHECK11-NEXT: call void @_ZN1SIfEC1Ef(ptr nonnull align 4 dereferenceable(4) [[VAR]], float 3.000000e+00) // CHECK11-NEXT: [[TMP0:%.*]] = load i32, ptr [[T_VAR]], align 4 @@ -1422,9 +1419,8 @@ void array_func(float a[3], St s[2], int n, long double vla1[n]) { // CHECK11-NEXT: call void @_ZN1SIiEC1Ev(ptr nonnull align 4 dereferenceable(4) [[TEST]]) // CHECK11-NEXT: store i32 0, ptr [[T_VAR]], align 128 // CHECK11-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 128 [[VEC]], ptr align 128 @__const._Z5tmainIiET_v.vec, i32 8, i1 false) -// CHECK11-NEXT: [[ARRAYINIT_BEGIN:%.*]] = getelementptr inbounds [2 x %struct.S.0], ptr [[S_ARR]], i32 0, i32 0 -// CHECK11-NEXT: call void @_ZN1SIiEC1Ei(ptr nonnull align 4 dereferenceable(4) [[ARRAYINIT_BEGIN]], i32 1) -// CHECK11-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[ARRAYINIT_BEGIN]], i32 1 +// CHECK11-NEXT: call void @_ZN1SIiEC1Ei(ptr nonnull align 4 dereferenceable(4) [[S_ARR]], i32 1) +// CHECK11-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[S_ARR]], i32 1 // CHECK11-NEXT: call void @_ZN1SIiEC1Ei(ptr nonnull align 4 dereferenceable(4) [[ARRAYINIT_ELEMENT]], i32 2) // CHECK11-NEXT: call void @_ZN1SIiEC1Ei(ptr nonnull align 4 dereferenceable(4) [[VAR]], i32 3) // CHECK11-NEXT: [[TMP0:%.*]] = load i32, ptr [[T_VAR]], align 128 diff --git a/clang/test/OpenMP/teams_generic_loop_private_codegen.cpp b/clang/test/OpenMP/teams_generic_loop_private_codegen.cpp index e955db129d1da60ffa94643609791298d910eecb..f44acf211b5e3bbc959cf6fcb941a641f162a2c6 100644 --- a/clang/test/OpenMP/teams_generic_loop_private_codegen.cpp +++ b/clang/test/OpenMP/teams_generic_loop_private_codegen.cpp @@ -425,9 +425,8 @@ int main() { // CHECK1-NEXT: call void @_ZN1SIiEC1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[TEST]]) // CHECK1-NEXT: store i32 0, ptr [[T_VAR]], align 4 // CHECK1-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 4 [[VEC]], ptr align 4 @__const._Z5tmainIiET_v.vec, i64 8, i1 false) -// CHECK1-NEXT: [[ARRAYINIT_BEGIN:%.*]] = getelementptr inbounds [2 x %struct.S.0], ptr [[S_ARR]], i64 0, i64 0 -// CHECK1-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_BEGIN]], i32 noundef signext 1) -// CHECK1-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[ARRAYINIT_BEGIN]], i64 1 +// CHECK1-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[S_ARR]], i32 noundef signext 1) +// CHECK1-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[S_ARR]], i64 1 // CHECK1-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_ELEMENT]], i32 noundef signext 2) // CHECK1-NEXT: store ptr [[TEST]], ptr [[VAR]], align 8 // CHECK1-NEXT: store ptr undef, ptr [[_TMP1]], align 8 @@ -951,9 +950,8 @@ int main() { // CHECK3-NEXT: call void @_ZN1SIiEC1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[TEST]]) // CHECK3-NEXT: store i32 0, ptr [[T_VAR]], align 4 // CHECK3-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 4 [[VEC]], ptr align 4 @__const._Z5tmainIiET_v.vec, i32 8, i1 false) -// CHECK3-NEXT: [[ARRAYINIT_BEGIN:%.*]] = getelementptr inbounds [2 x %struct.S.0], ptr [[S_ARR]], i32 0, i32 0 -// CHECK3-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_BEGIN]], i32 noundef 1) -// CHECK3-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[ARRAYINIT_BEGIN]], i32 1 +// CHECK3-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[S_ARR]], i32 noundef 1) +// CHECK3-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[S_ARR]], i32 1 // CHECK3-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_ELEMENT]], i32 noundef 2) // CHECK3-NEXT: store ptr [[TEST]], ptr [[VAR]], align 4 // CHECK3-NEXT: store ptr undef, ptr [[_TMP1]], align 4 diff --git a/clang/test/OpenMP/teams_private_codegen.cpp b/clang/test/OpenMP/teams_private_codegen.cpp index 1d0b2435ff005819dd23f8d460f510c769c6f901..81c0ea77f1b048715ca51c96195c86791f86ab60 100644 --- a/clang/test/OpenMP/teams_private_codegen.cpp +++ b/clang/test/OpenMP/teams_private_codegen.cpp @@ -551,9 +551,8 @@ int main() { // CHECK9-NEXT: call void @_ZN1SIfEC1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[TEST]]) // CHECK9-NEXT: store i32 0, ptr [[T_VAR]], align 4 // CHECK9-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 4 [[VEC]], ptr align 4 @__const.main.vec, i64 8, i1 false) -// CHECK9-NEXT: [[ARRAYINIT_BEGIN:%.*]] = getelementptr inbounds [2 x %struct.S], ptr [[S_ARR]], i64 0, i64 0 -// CHECK9-NEXT: call void @_ZN1SIfEC1Ef(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_BEGIN]], float noundef 1.000000e+00) -// CHECK9-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[ARRAYINIT_BEGIN]], i64 1 +// CHECK9-NEXT: call void @_ZN1SIfEC1Ef(ptr noundef nonnull align 4 dereferenceable(4) [[S_ARR]], float noundef 1.000000e+00) +// CHECK9-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[S_ARR]], i64 1 // CHECK9-NEXT: call void @_ZN1SIfEC1Ef(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_ELEMENT]], float noundef 2.000000e+00) // CHECK9-NEXT: call void @_ZN1SIfEC1Ef(ptr noundef nonnull align 4 dereferenceable(4) [[VAR]], float noundef 3.000000e+00) // CHECK9-NEXT: [[TMP0:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 @@ -718,9 +717,8 @@ int main() { // CHECK9-NEXT: call void @_ZN3SSTIiEC1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[SST]]) // CHECK9-NEXT: store i32 0, ptr [[T_VAR]], align 128 // CHECK9-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 128 [[VEC]], ptr align 128 @__const._Z5tmainIiET_v.vec, i64 8, i1 false) -// CHECK9-NEXT: [[ARRAYINIT_BEGIN:%.*]] = getelementptr inbounds [2 x %struct.S.0], ptr [[S_ARR]], i64 0, i64 0 -// CHECK9-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_BEGIN]], i32 noundef signext 1) -// CHECK9-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[ARRAYINIT_BEGIN]], i64 1 +// CHECK9-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[S_ARR]], i32 noundef signext 1) +// CHECK9-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[S_ARR]], i64 1 // CHECK9-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_ELEMENT]], i32 noundef signext 2) // CHECK9-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[VAR]], i32 noundef signext 3) // CHECK9-NEXT: [[TMP0:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 @@ -1141,9 +1139,8 @@ int main() { // CHECK11-NEXT: call void @_ZN1SIfEC1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[TEST]]) // CHECK11-NEXT: store i32 0, ptr [[T_VAR]], align 4 // CHECK11-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 4 [[VEC]], ptr align 4 @__const.main.vec, i32 8, i1 false) -// CHECK11-NEXT: [[ARRAYINIT_BEGIN:%.*]] = getelementptr inbounds [2 x %struct.S], ptr [[S_ARR]], i32 0, i32 0 -// CHECK11-NEXT: call void @_ZN1SIfEC1Ef(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_BEGIN]], float noundef 1.000000e+00) -// CHECK11-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[ARRAYINIT_BEGIN]], i32 1 +// CHECK11-NEXT: call void @_ZN1SIfEC1Ef(ptr noundef nonnull align 4 dereferenceable(4) [[S_ARR]], float noundef 1.000000e+00) +// CHECK11-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[S_ARR]], i32 1 // CHECK11-NEXT: call void @_ZN1SIfEC1Ef(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_ELEMENT]], float noundef 2.000000e+00) // CHECK11-NEXT: call void @_ZN1SIfEC1Ef(ptr noundef nonnull align 4 dereferenceable(4) [[VAR]], float noundef 3.000000e+00) // CHECK11-NEXT: [[TMP0:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 @@ -1308,9 +1305,8 @@ int main() { // CHECK11-NEXT: call void @_ZN3SSTIiEC1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[SST]]) // CHECK11-NEXT: store i32 0, ptr [[T_VAR]], align 128 // CHECK11-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 128 [[VEC]], ptr align 128 @__const._Z5tmainIiET_v.vec, i32 8, i1 false) -// CHECK11-NEXT: [[ARRAYINIT_BEGIN:%.*]] = getelementptr inbounds [2 x %struct.S.0], ptr [[S_ARR]], i32 0, i32 0 -// CHECK11-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_BEGIN]], i32 noundef 1) -// CHECK11-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[ARRAYINIT_BEGIN]], i32 1 +// CHECK11-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[S_ARR]], i32 noundef 1) +// CHECK11-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[S_ARR]], i32 1 // CHECK11-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_ELEMENT]], i32 noundef 2) // CHECK11-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[VAR]], i32 noundef 3) // CHECK11-NEXT: [[TMP0:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 diff --git a/clang/test/OpenMP/threadprivate_codegen.cpp b/clang/test/OpenMP/threadprivate_codegen.cpp index 5087451b944b981015659dd47ed114381a3093e8..2ee328008cc4bf09a143981efe966e9cdf483478 100644 --- a/clang/test/OpenMP/threadprivate_codegen.cpp +++ b/clang/test/OpenMP/threadprivate_codegen.cpp @@ -1028,46 +1028,43 @@ int foobar() { // CHECK1-NEXT: entry: // CHECK1-NEXT: [[DOTADDR:%.*]] = alloca ptr, align 8 // CHECK1-NEXT: [[ARRAYINIT_ENDOFINIT:%.*]] = alloca ptr, align 8 -// CHECK1-NEXT: [[ARRAYINIT_ENDOFINIT2:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: [[ARRAYINIT_ENDOFINIT1:%.*]] = alloca ptr, align 8 // CHECK1-NEXT: [[EXN_SLOT:%.*]] = alloca ptr, align 8 // CHECK1-NEXT: [[EHSELECTOR_SLOT:%.*]] = alloca i32, align 4 -// CHECK1-NEXT: [[ARRAYINIT_ENDOFINIT9:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: [[ARRAYINIT_ENDOFINIT7:%.*]] = alloca ptr, align 8 // CHECK1-NEXT: store ptr [[TMP0]], ptr [[DOTADDR]], align 8 // CHECK1-NEXT: [[TMP1:%.*]] = load ptr, ptr [[DOTADDR]], align 8 -// CHECK1-NEXT: [[ARRAYINIT_BEGIN:%.*]] = getelementptr inbounds [2 x [3 x %struct.S1]], ptr [[TMP1]], i64 0, i64 0 -// CHECK1-NEXT: store ptr [[ARRAYINIT_BEGIN]], ptr [[ARRAYINIT_ENDOFINIT]], align 8 -// CHECK1-NEXT: [[ARRAYINIT_BEGIN1:%.*]] = getelementptr inbounds [3 x %struct.S1], ptr [[ARRAYINIT_BEGIN]], i64 0, i64 0 -// CHECK1-NEXT: store ptr [[ARRAYINIT_BEGIN1]], ptr [[ARRAYINIT_ENDOFINIT2]], align 8 -// CHECK1-NEXT: invoke void @_ZN2S1C1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_BEGIN1]], i32 noundef 1) +// CHECK1-NEXT: store ptr [[TMP1]], ptr [[ARRAYINIT_ENDOFINIT]], align 8 +// CHECK1-NEXT: store ptr [[TMP1]], ptr [[ARRAYINIT_ENDOFINIT1]], align 8 +// CHECK1-NEXT: invoke void @_ZN2S1C1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[TMP1]], i32 noundef 1) // CHECK1-NEXT: to label [[INVOKE_CONT:%.*]] unwind label [[LPAD:%.*]] // CHECK1: invoke.cont: -// CHECK1-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S1:%.*]], ptr [[ARRAYINIT_BEGIN1]], i64 1 -// CHECK1-NEXT: store ptr [[ARRAYINIT_ELEMENT]], ptr [[ARRAYINIT_ENDOFINIT2]], align 8 +// CHECK1-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S1:%.*]], ptr [[TMP1]], i64 1 +// CHECK1-NEXT: store ptr [[ARRAYINIT_ELEMENT]], ptr [[ARRAYINIT_ENDOFINIT1]], align 8 // CHECK1-NEXT: invoke void @_ZN2S1C1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_ELEMENT]], i32 noundef 2) -// CHECK1-NEXT: to label [[INVOKE_CONT3:%.*]] unwind label [[LPAD]] -// CHECK1: invoke.cont3: -// CHECK1-NEXT: [[ARRAYINIT_ELEMENT4:%.*]] = getelementptr inbounds [[STRUCT_S1]], ptr [[ARRAYINIT_ELEMENT]], i64 1 -// CHECK1-NEXT: store ptr [[ARRAYINIT_ELEMENT4]], ptr [[ARRAYINIT_ENDOFINIT2]], align 8 -// CHECK1-NEXT: invoke void @_ZN2S1C1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_ELEMENT4]], i32 noundef 3) -// CHECK1-NEXT: to label [[INVOKE_CONT5:%.*]] unwind label [[LPAD]] -// CHECK1: invoke.cont5: -// CHECK1-NEXT: [[ARRAYINIT_ELEMENT7:%.*]] = getelementptr inbounds [3 x %struct.S1], ptr [[ARRAYINIT_BEGIN]], i64 1 -// CHECK1-NEXT: store ptr [[ARRAYINIT_ELEMENT7]], ptr [[ARRAYINIT_ENDOFINIT]], align 8 -// CHECK1-NEXT: [[ARRAYINIT_BEGIN8:%.*]] = getelementptr inbounds [3 x %struct.S1], ptr [[ARRAYINIT_ELEMENT7]], i64 0, i64 0 -// CHECK1-NEXT: store ptr [[ARRAYINIT_BEGIN8]], ptr [[ARRAYINIT_ENDOFINIT9]], align 8 -// CHECK1-NEXT: invoke void @_ZN2S1C1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_BEGIN8]], i32 noundef 4) -// CHECK1-NEXT: to label [[INVOKE_CONT11:%.*]] unwind label [[LPAD10:%.*]] +// CHECK1-NEXT: to label [[INVOKE_CONT2:%.*]] unwind label [[LPAD]] +// CHECK1: invoke.cont2: +// CHECK1-NEXT: [[ARRAYINIT_ELEMENT3:%.*]] = getelementptr inbounds [[STRUCT_S1]], ptr [[TMP1]], i64 2 +// CHECK1-NEXT: store ptr [[ARRAYINIT_ELEMENT3]], ptr [[ARRAYINIT_ENDOFINIT1]], align 8 +// CHECK1-NEXT: invoke void @_ZN2S1C1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_ELEMENT3]], i32 noundef 3) +// CHECK1-NEXT: to label [[INVOKE_CONT4:%.*]] unwind label [[LPAD]] +// CHECK1: invoke.cont4: +// CHECK1-NEXT: [[ARRAYINIT_ELEMENT6:%.*]] = getelementptr inbounds [3 x %struct.S1], ptr [[TMP1]], i64 1 +// CHECK1-NEXT: store ptr [[ARRAYINIT_ELEMENT6]], ptr [[ARRAYINIT_ENDOFINIT]], align 8 +// CHECK1-NEXT: store ptr [[ARRAYINIT_ELEMENT6]], ptr [[ARRAYINIT_ENDOFINIT7]], align 8 +// CHECK1-NEXT: invoke void @_ZN2S1C1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_ELEMENT6]], i32 noundef 4) +// CHECK1-NEXT: to label [[INVOKE_CONT9:%.*]] unwind label [[LPAD8:%.*]] +// CHECK1: invoke.cont9: +// CHECK1-NEXT: [[ARRAYINIT_ELEMENT10:%.*]] = getelementptr inbounds [[STRUCT_S1]], ptr [[ARRAYINIT_ELEMENT6]], i64 1 +// CHECK1-NEXT: store ptr [[ARRAYINIT_ELEMENT10]], ptr [[ARRAYINIT_ENDOFINIT7]], align 8 +// CHECK1-NEXT: invoke void @_ZN2S1C1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_ELEMENT10]], i32 noundef 5) +// CHECK1-NEXT: to label [[INVOKE_CONT11:%.*]] unwind label [[LPAD8]] // CHECK1: invoke.cont11: -// CHECK1-NEXT: [[ARRAYINIT_ELEMENT12:%.*]] = getelementptr inbounds [[STRUCT_S1]], ptr [[ARRAYINIT_BEGIN8]], i64 1 -// CHECK1-NEXT: store ptr [[ARRAYINIT_ELEMENT12]], ptr [[ARRAYINIT_ENDOFINIT9]], align 8 -// CHECK1-NEXT: invoke void @_ZN2S1C1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_ELEMENT12]], i32 noundef 5) -// CHECK1-NEXT: to label [[INVOKE_CONT13:%.*]] unwind label [[LPAD10]] +// CHECK1-NEXT: [[ARRAYINIT_ELEMENT12:%.*]] = getelementptr inbounds [[STRUCT_S1]], ptr [[ARRAYINIT_ELEMENT6]], i64 2 +// CHECK1-NEXT: store ptr [[ARRAYINIT_ELEMENT12]], ptr [[ARRAYINIT_ENDOFINIT7]], align 8 +// CHECK1-NEXT: invoke void @_ZN2S1C1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_ELEMENT12]], i32 noundef 6) +// CHECK1-NEXT: to label [[INVOKE_CONT13:%.*]] unwind label [[LPAD8]] // CHECK1: invoke.cont13: -// CHECK1-NEXT: [[ARRAYINIT_ELEMENT14:%.*]] = getelementptr inbounds [[STRUCT_S1]], ptr [[ARRAYINIT_ELEMENT12]], i64 1 -// CHECK1-NEXT: store ptr [[ARRAYINIT_ELEMENT14]], ptr [[ARRAYINIT_ENDOFINIT9]], align 8 -// CHECK1-NEXT: invoke void @_ZN2S1C1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_ELEMENT14]], i32 noundef 6) -// CHECK1-NEXT: to label [[INVOKE_CONT15:%.*]] unwind label [[LPAD10]] -// CHECK1: invoke.cont15: // CHECK1-NEXT: [[TMP2:%.*]] = load ptr, ptr [[DOTADDR]], align 8 // CHECK1-NEXT: ret ptr [[TMP2]] // CHECK1: lpad: @@ -1077,55 +1074,55 @@ int foobar() { // CHECK1-NEXT: store ptr [[TMP4]], ptr [[EXN_SLOT]], align 8 // CHECK1-NEXT: [[TMP5:%.*]] = extractvalue { ptr, i32 } [[TMP3]], 1 // CHECK1-NEXT: store i32 [[TMP5]], ptr [[EHSELECTOR_SLOT]], align 4 -// CHECK1-NEXT: [[TMP6:%.*]] = load ptr, ptr [[ARRAYINIT_ENDOFINIT2]], align 8 -// CHECK1-NEXT: [[ARRAYDESTROY_ISEMPTY:%.*]] = icmp eq ptr [[ARRAYINIT_BEGIN1]], [[TMP6]] -// CHECK1-NEXT: br i1 [[ARRAYDESTROY_ISEMPTY]], label [[ARRAYDESTROY_DONE6:%.*]], label [[ARRAYDESTROY_BODY:%.*]] +// CHECK1-NEXT: [[TMP6:%.*]] = load ptr, ptr [[ARRAYINIT_ENDOFINIT1]], align 8 +// CHECK1-NEXT: [[ARRAYDESTROY_ISEMPTY:%.*]] = icmp eq ptr [[TMP1]], [[TMP6]] +// CHECK1-NEXT: br i1 [[ARRAYDESTROY_ISEMPTY]], label [[ARRAYDESTROY_DONE5:%.*]], label [[ARRAYDESTROY_BODY:%.*]] // CHECK1: arraydestroy.body: // CHECK1-NEXT: [[ARRAYDESTROY_ELEMENTPAST:%.*]] = phi ptr [ [[TMP6]], [[LPAD]] ], [ [[ARRAYDESTROY_ELEMENT:%.*]], [[ARRAYDESTROY_BODY]] ] // CHECK1-NEXT: [[ARRAYDESTROY_ELEMENT]] = getelementptr inbounds [[STRUCT_S1]], ptr [[ARRAYDESTROY_ELEMENTPAST]], i64 -1 // CHECK1-NEXT: call void @_ZN2S1D1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYDESTROY_ELEMENT]]) #[[ATTR3]] -// CHECK1-NEXT: [[ARRAYDESTROY_DONE:%.*]] = icmp eq ptr [[ARRAYDESTROY_ELEMENT]], [[ARRAYINIT_BEGIN1]] -// CHECK1-NEXT: br i1 [[ARRAYDESTROY_DONE]], label [[ARRAYDESTROY_DONE6]], label [[ARRAYDESTROY_BODY]] -// CHECK1: arraydestroy.done6: +// CHECK1-NEXT: [[ARRAYDESTROY_DONE:%.*]] = icmp eq ptr [[ARRAYDESTROY_ELEMENT]], [[TMP1]] +// CHECK1-NEXT: br i1 [[ARRAYDESTROY_DONE]], label [[ARRAYDESTROY_DONE5]], label [[ARRAYDESTROY_BODY]] +// CHECK1: arraydestroy.done5: // CHECK1-NEXT: br label [[EHCLEANUP:%.*]] -// CHECK1: lpad10: +// CHECK1: lpad8: // CHECK1-NEXT: [[TMP7:%.*]] = landingpad { ptr, i32 } // CHECK1-NEXT: cleanup // CHECK1-NEXT: [[TMP8:%.*]] = extractvalue { ptr, i32 } [[TMP7]], 0 // CHECK1-NEXT: store ptr [[TMP8]], ptr [[EXN_SLOT]], align 8 // CHECK1-NEXT: [[TMP9:%.*]] = extractvalue { ptr, i32 } [[TMP7]], 1 // CHECK1-NEXT: store i32 [[TMP9]], ptr [[EHSELECTOR_SLOT]], align 4 -// CHECK1-NEXT: [[TMP10:%.*]] = load ptr, ptr [[ARRAYINIT_ENDOFINIT9]], align 8 -// CHECK1-NEXT: [[ARRAYDESTROY_ISEMPTY16:%.*]] = icmp eq ptr [[ARRAYINIT_BEGIN8]], [[TMP10]] -// CHECK1-NEXT: br i1 [[ARRAYDESTROY_ISEMPTY16]], label [[ARRAYDESTROY_DONE21:%.*]], label [[ARRAYDESTROY_BODY17:%.*]] -// CHECK1: arraydestroy.body17: -// CHECK1-NEXT: [[ARRAYDESTROY_ELEMENTPAST18:%.*]] = phi ptr [ [[TMP10]], [[LPAD10]] ], [ [[ARRAYDESTROY_ELEMENT19:%.*]], [[ARRAYDESTROY_BODY17]] ] -// CHECK1-NEXT: [[ARRAYDESTROY_ELEMENT19]] = getelementptr inbounds [[STRUCT_S1]], ptr [[ARRAYDESTROY_ELEMENTPAST18]], i64 -1 -// CHECK1-NEXT: call void @_ZN2S1D1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYDESTROY_ELEMENT19]]) #[[ATTR3]] -// CHECK1-NEXT: [[ARRAYDESTROY_DONE20:%.*]] = icmp eq ptr [[ARRAYDESTROY_ELEMENT19]], [[ARRAYINIT_BEGIN8]] -// CHECK1-NEXT: br i1 [[ARRAYDESTROY_DONE20]], label [[ARRAYDESTROY_DONE21]], label [[ARRAYDESTROY_BODY17]] -// CHECK1: arraydestroy.done21: +// CHECK1-NEXT: [[TMP10:%.*]] = load ptr, ptr [[ARRAYINIT_ENDOFINIT7]], align 8 +// CHECK1-NEXT: [[ARRAYDESTROY_ISEMPTY14:%.*]] = icmp eq ptr [[ARRAYINIT_ELEMENT6]], [[TMP10]] +// CHECK1-NEXT: br i1 [[ARRAYDESTROY_ISEMPTY14]], label [[ARRAYDESTROY_DONE19:%.*]], label [[ARRAYDESTROY_BODY15:%.*]] +// CHECK1: arraydestroy.body15: +// CHECK1-NEXT: [[ARRAYDESTROY_ELEMENTPAST16:%.*]] = phi ptr [ [[TMP10]], [[LPAD8]] ], [ [[ARRAYDESTROY_ELEMENT17:%.*]], [[ARRAYDESTROY_BODY15]] ] +// CHECK1-NEXT: [[ARRAYDESTROY_ELEMENT17]] = getelementptr inbounds [[STRUCT_S1]], ptr [[ARRAYDESTROY_ELEMENTPAST16]], i64 -1 +// CHECK1-NEXT: call void @_ZN2S1D1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYDESTROY_ELEMENT17]]) #[[ATTR3]] +// CHECK1-NEXT: [[ARRAYDESTROY_DONE18:%.*]] = icmp eq ptr [[ARRAYDESTROY_ELEMENT17]], [[ARRAYINIT_ELEMENT6]] +// CHECK1-NEXT: br i1 [[ARRAYDESTROY_DONE18]], label [[ARRAYDESTROY_DONE19]], label [[ARRAYDESTROY_BODY15]] +// CHECK1: arraydestroy.done19: // CHECK1-NEXT: br label [[EHCLEANUP]] // CHECK1: ehcleanup: // CHECK1-NEXT: [[TMP11:%.*]] = load ptr, ptr [[ARRAYINIT_ENDOFINIT]], align 8 -// CHECK1-NEXT: [[PAD_ARRAYBEGIN:%.*]] = getelementptr inbounds [3 x %struct.S1], ptr [[ARRAYINIT_BEGIN]], i64 0, i64 0 +// CHECK1-NEXT: [[PAD_ARRAYBEGIN:%.*]] = getelementptr inbounds [3 x %struct.S1], ptr [[TMP1]], i64 0, i64 0 // CHECK1-NEXT: [[PAD_ARRAYEND:%.*]] = getelementptr inbounds [3 x %struct.S1], ptr [[TMP11]], i64 0, i64 0 -// CHECK1-NEXT: [[ARRAYDESTROY_ISEMPTY22:%.*]] = icmp eq ptr [[PAD_ARRAYBEGIN]], [[PAD_ARRAYEND]] -// CHECK1-NEXT: br i1 [[ARRAYDESTROY_ISEMPTY22]], label [[ARRAYDESTROY_DONE27:%.*]], label [[ARRAYDESTROY_BODY23:%.*]] -// CHECK1: arraydestroy.body23: -// CHECK1-NEXT: [[ARRAYDESTROY_ELEMENTPAST24:%.*]] = phi ptr [ [[PAD_ARRAYEND]], [[EHCLEANUP]] ], [ [[ARRAYDESTROY_ELEMENT25:%.*]], [[ARRAYDESTROY_BODY23]] ] -// CHECK1-NEXT: [[ARRAYDESTROY_ELEMENT25]] = getelementptr inbounds [[STRUCT_S1]], ptr [[ARRAYDESTROY_ELEMENTPAST24]], i64 -1 -// CHECK1-NEXT: call void @_ZN2S1D1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYDESTROY_ELEMENT25]]) #[[ATTR3]] -// CHECK1-NEXT: [[ARRAYDESTROY_DONE26:%.*]] = icmp eq ptr [[ARRAYDESTROY_ELEMENT25]], [[PAD_ARRAYBEGIN]] -// CHECK1-NEXT: br i1 [[ARRAYDESTROY_DONE26]], label [[ARRAYDESTROY_DONE27]], label [[ARRAYDESTROY_BODY23]] -// CHECK1: arraydestroy.done27: +// CHECK1-NEXT: [[ARRAYDESTROY_ISEMPTY20:%.*]] = icmp eq ptr [[PAD_ARRAYBEGIN]], [[PAD_ARRAYEND]] +// CHECK1-NEXT: br i1 [[ARRAYDESTROY_ISEMPTY20]], label [[ARRAYDESTROY_DONE25:%.*]], label [[ARRAYDESTROY_BODY21:%.*]] +// CHECK1: arraydestroy.body21: +// CHECK1-NEXT: [[ARRAYDESTROY_ELEMENTPAST22:%.*]] = phi ptr [ [[PAD_ARRAYEND]], [[EHCLEANUP]] ], [ [[ARRAYDESTROY_ELEMENT23:%.*]], [[ARRAYDESTROY_BODY21]] ] +// CHECK1-NEXT: [[ARRAYDESTROY_ELEMENT23]] = getelementptr inbounds [[STRUCT_S1]], ptr [[ARRAYDESTROY_ELEMENTPAST22]], i64 -1 +// CHECK1-NEXT: call void @_ZN2S1D1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYDESTROY_ELEMENT23]]) #[[ATTR3]] +// CHECK1-NEXT: [[ARRAYDESTROY_DONE24:%.*]] = icmp eq ptr [[ARRAYDESTROY_ELEMENT23]], [[PAD_ARRAYBEGIN]] +// CHECK1-NEXT: br i1 [[ARRAYDESTROY_DONE24]], label [[ARRAYDESTROY_DONE25]], label [[ARRAYDESTROY_BODY21]] +// CHECK1: arraydestroy.done25: // CHECK1-NEXT: br label [[EH_RESUME:%.*]] // CHECK1: eh.resume: // CHECK1-NEXT: [[EXN:%.*]] = load ptr, ptr [[EXN_SLOT]], align 8 // CHECK1-NEXT: [[SEL:%.*]] = load i32, ptr [[EHSELECTOR_SLOT]], align 4 // CHECK1-NEXT: [[LPAD_VAL:%.*]] = insertvalue { ptr, i32 } poison, ptr [[EXN]], 0 -// CHECK1-NEXT: [[LPAD_VAL28:%.*]] = insertvalue { ptr, i32 } [[LPAD_VAL]], i32 [[SEL]], 1 -// CHECK1-NEXT: resume { ptr, i32 } [[LPAD_VAL28]] +// CHECK1-NEXT: [[LPAD_VAL26:%.*]] = insertvalue { ptr, i32 } [[LPAD_VAL]], i32 [[SEL]], 1 +// CHECK1-NEXT: resume { ptr, i32 } [[LPAD_VAL26]] // // // CHECK1-LABEL: define {{[^@]+}}@.__kmpc_global_dtor_..2 @@ -1880,46 +1877,43 @@ int foobar() { // CHECK2-NEXT: entry: // CHECK2-NEXT: [[DOTADDR:%.*]] = alloca ptr, align 8 // CHECK2-NEXT: [[ARRAYINIT_ENDOFINIT:%.*]] = alloca ptr, align 8 -// CHECK2-NEXT: [[ARRAYINIT_ENDOFINIT2:%.*]] = alloca ptr, align 8 +// CHECK2-NEXT: [[ARRAYINIT_ENDOFINIT1:%.*]] = alloca ptr, align 8 // CHECK2-NEXT: [[EXN_SLOT:%.*]] = alloca ptr, align 8 // CHECK2-NEXT: [[EHSELECTOR_SLOT:%.*]] = alloca i32, align 4 -// CHECK2-NEXT: [[ARRAYINIT_ENDOFINIT9:%.*]] = alloca ptr, align 8 +// CHECK2-NEXT: [[ARRAYINIT_ENDOFINIT7:%.*]] = alloca ptr, align 8 // CHECK2-NEXT: store ptr [[TMP0]], ptr [[DOTADDR]], align 8 // CHECK2-NEXT: [[TMP1:%.*]] = load ptr, ptr [[DOTADDR]], align 8 -// CHECK2-NEXT: [[ARRAYINIT_BEGIN:%.*]] = getelementptr inbounds [2 x [3 x %struct.S1]], ptr [[TMP1]], i64 0, i64 0 -// CHECK2-NEXT: store ptr [[ARRAYINIT_BEGIN]], ptr [[ARRAYINIT_ENDOFINIT]], align 8 -// CHECK2-NEXT: [[ARRAYINIT_BEGIN1:%.*]] = getelementptr inbounds [3 x %struct.S1], ptr [[ARRAYINIT_BEGIN]], i64 0, i64 0 -// CHECK2-NEXT: store ptr [[ARRAYINIT_BEGIN1]], ptr [[ARRAYINIT_ENDOFINIT2]], align 8 -// CHECK2-NEXT: invoke void @_ZN2S1C1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_BEGIN1]], i32 noundef 1) +// CHECK2-NEXT: store ptr [[TMP1]], ptr [[ARRAYINIT_ENDOFINIT]], align 8 +// CHECK2-NEXT: store ptr [[TMP1]], ptr [[ARRAYINIT_ENDOFINIT1]], align 8 +// CHECK2-NEXT: invoke void @_ZN2S1C1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[TMP1]], i32 noundef 1) // CHECK2-NEXT: to label [[INVOKE_CONT:%.*]] unwind label [[LPAD:%.*]] // CHECK2: invoke.cont: -// CHECK2-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S1:%.*]], ptr [[ARRAYINIT_BEGIN1]], i64 1 -// CHECK2-NEXT: store ptr [[ARRAYINIT_ELEMENT]], ptr [[ARRAYINIT_ENDOFINIT2]], align 8 +// CHECK2-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S1:%.*]], ptr [[TMP1]], i64 1 +// CHECK2-NEXT: store ptr [[ARRAYINIT_ELEMENT]], ptr [[ARRAYINIT_ENDOFINIT1]], align 8 // CHECK2-NEXT: invoke void @_ZN2S1C1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_ELEMENT]], i32 noundef 2) -// CHECK2-NEXT: to label [[INVOKE_CONT3:%.*]] unwind label [[LPAD]] -// CHECK2: invoke.cont3: -// CHECK2-NEXT: [[ARRAYINIT_ELEMENT4:%.*]] = getelementptr inbounds [[STRUCT_S1]], ptr [[ARRAYINIT_ELEMENT]], i64 1 -// CHECK2-NEXT: store ptr [[ARRAYINIT_ELEMENT4]], ptr [[ARRAYINIT_ENDOFINIT2]], align 8 -// CHECK2-NEXT: invoke void @_ZN2S1C1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_ELEMENT4]], i32 noundef 3) -// CHECK2-NEXT: to label [[INVOKE_CONT5:%.*]] unwind label [[LPAD]] -// CHECK2: invoke.cont5: -// CHECK2-NEXT: [[ARRAYINIT_ELEMENT7:%.*]] = getelementptr inbounds [3 x %struct.S1], ptr [[ARRAYINIT_BEGIN]], i64 1 -// CHECK2-NEXT: store ptr [[ARRAYINIT_ELEMENT7]], ptr [[ARRAYINIT_ENDOFINIT]], align 8 -// CHECK2-NEXT: [[ARRAYINIT_BEGIN8:%.*]] = getelementptr inbounds [3 x %struct.S1], ptr [[ARRAYINIT_ELEMENT7]], i64 0, i64 0 -// CHECK2-NEXT: store ptr [[ARRAYINIT_BEGIN8]], ptr [[ARRAYINIT_ENDOFINIT9]], align 8 -// CHECK2-NEXT: invoke void @_ZN2S1C1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_BEGIN8]], i32 noundef 4) -// CHECK2-NEXT: to label [[INVOKE_CONT11:%.*]] unwind label [[LPAD10:%.*]] +// CHECK2-NEXT: to label [[INVOKE_CONT2:%.*]] unwind label [[LPAD]] +// CHECK2: invoke.cont2: +// CHECK2-NEXT: [[ARRAYINIT_ELEMENT3:%.*]] = getelementptr inbounds [[STRUCT_S1]], ptr [[TMP1]], i64 2 +// CHECK2-NEXT: store ptr [[ARRAYINIT_ELEMENT3]], ptr [[ARRAYINIT_ENDOFINIT1]], align 8 +// CHECK2-NEXT: invoke void @_ZN2S1C1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_ELEMENT3]], i32 noundef 3) +// CHECK2-NEXT: to label [[INVOKE_CONT4:%.*]] unwind label [[LPAD]] +// CHECK2: invoke.cont4: +// CHECK2-NEXT: [[ARRAYINIT_ELEMENT6:%.*]] = getelementptr inbounds [3 x %struct.S1], ptr [[TMP1]], i64 1 +// CHECK2-NEXT: store ptr [[ARRAYINIT_ELEMENT6]], ptr [[ARRAYINIT_ENDOFINIT]], align 8 +// CHECK2-NEXT: store ptr [[ARRAYINIT_ELEMENT6]], ptr [[ARRAYINIT_ENDOFINIT7]], align 8 +// CHECK2-NEXT: invoke void @_ZN2S1C1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_ELEMENT6]], i32 noundef 4) +// CHECK2-NEXT: to label [[INVOKE_CONT9:%.*]] unwind label [[LPAD8:%.*]] +// CHECK2: invoke.cont9: +// CHECK2-NEXT: [[ARRAYINIT_ELEMENT10:%.*]] = getelementptr inbounds [[STRUCT_S1]], ptr [[ARRAYINIT_ELEMENT6]], i64 1 +// CHECK2-NEXT: store ptr [[ARRAYINIT_ELEMENT10]], ptr [[ARRAYINIT_ENDOFINIT7]], align 8 +// CHECK2-NEXT: invoke void @_ZN2S1C1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_ELEMENT10]], i32 noundef 5) +// CHECK2-NEXT: to label [[INVOKE_CONT11:%.*]] unwind label [[LPAD8]] // CHECK2: invoke.cont11: -// CHECK2-NEXT: [[ARRAYINIT_ELEMENT12:%.*]] = getelementptr inbounds [[STRUCT_S1]], ptr [[ARRAYINIT_BEGIN8]], i64 1 -// CHECK2-NEXT: store ptr [[ARRAYINIT_ELEMENT12]], ptr [[ARRAYINIT_ENDOFINIT9]], align 8 -// CHECK2-NEXT: invoke void @_ZN2S1C1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_ELEMENT12]], i32 noundef 5) -// CHECK2-NEXT: to label [[INVOKE_CONT13:%.*]] unwind label [[LPAD10]] +// CHECK2-NEXT: [[ARRAYINIT_ELEMENT12:%.*]] = getelementptr inbounds [[STRUCT_S1]], ptr [[ARRAYINIT_ELEMENT6]], i64 2 +// CHECK2-NEXT: store ptr [[ARRAYINIT_ELEMENT12]], ptr [[ARRAYINIT_ENDOFINIT7]], align 8 +// CHECK2-NEXT: invoke void @_ZN2S1C1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_ELEMENT12]], i32 noundef 6) +// CHECK2-NEXT: to label [[INVOKE_CONT13:%.*]] unwind label [[LPAD8]] // CHECK2: invoke.cont13: -// CHECK2-NEXT: [[ARRAYINIT_ELEMENT14:%.*]] = getelementptr inbounds [[STRUCT_S1]], ptr [[ARRAYINIT_ELEMENT12]], i64 1 -// CHECK2-NEXT: store ptr [[ARRAYINIT_ELEMENT14]], ptr [[ARRAYINIT_ENDOFINIT9]], align 8 -// CHECK2-NEXT: invoke void @_ZN2S1C1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_ELEMENT14]], i32 noundef 6) -// CHECK2-NEXT: to label [[INVOKE_CONT15:%.*]] unwind label [[LPAD10]] -// CHECK2: invoke.cont15: // CHECK2-NEXT: [[TMP2:%.*]] = load ptr, ptr [[DOTADDR]], align 8 // CHECK2-NEXT: ret ptr [[TMP2]] // CHECK2: lpad: @@ -1929,55 +1923,55 @@ int foobar() { // CHECK2-NEXT: store ptr [[TMP4]], ptr [[EXN_SLOT]], align 8 // CHECK2-NEXT: [[TMP5:%.*]] = extractvalue { ptr, i32 } [[TMP3]], 1 // CHECK2-NEXT: store i32 [[TMP5]], ptr [[EHSELECTOR_SLOT]], align 4 -// CHECK2-NEXT: [[TMP6:%.*]] = load ptr, ptr [[ARRAYINIT_ENDOFINIT2]], align 8 -// CHECK2-NEXT: [[ARRAYDESTROY_ISEMPTY:%.*]] = icmp eq ptr [[ARRAYINIT_BEGIN1]], [[TMP6]] -// CHECK2-NEXT: br i1 [[ARRAYDESTROY_ISEMPTY]], label [[ARRAYDESTROY_DONE6:%.*]], label [[ARRAYDESTROY_BODY:%.*]] +// CHECK2-NEXT: [[TMP6:%.*]] = load ptr, ptr [[ARRAYINIT_ENDOFINIT1]], align 8 +// CHECK2-NEXT: [[ARRAYDESTROY_ISEMPTY:%.*]] = icmp eq ptr [[TMP1]], [[TMP6]] +// CHECK2-NEXT: br i1 [[ARRAYDESTROY_ISEMPTY]], label [[ARRAYDESTROY_DONE5:%.*]], label [[ARRAYDESTROY_BODY:%.*]] // CHECK2: arraydestroy.body: // CHECK2-NEXT: [[ARRAYDESTROY_ELEMENTPAST:%.*]] = phi ptr [ [[TMP6]], [[LPAD]] ], [ [[ARRAYDESTROY_ELEMENT:%.*]], [[ARRAYDESTROY_BODY]] ] // CHECK2-NEXT: [[ARRAYDESTROY_ELEMENT]] = getelementptr inbounds [[STRUCT_S1]], ptr [[ARRAYDESTROY_ELEMENTPAST]], i64 -1 // CHECK2-NEXT: call void @_ZN2S1D1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYDESTROY_ELEMENT]]) #[[ATTR3]] -// CHECK2-NEXT: [[ARRAYDESTROY_DONE:%.*]] = icmp eq ptr [[ARRAYDESTROY_ELEMENT]], [[ARRAYINIT_BEGIN1]] -// CHECK2-NEXT: br i1 [[ARRAYDESTROY_DONE]], label [[ARRAYDESTROY_DONE6]], label [[ARRAYDESTROY_BODY]] -// CHECK2: arraydestroy.done6: +// CHECK2-NEXT: [[ARRAYDESTROY_DONE:%.*]] = icmp eq ptr [[ARRAYDESTROY_ELEMENT]], [[TMP1]] +// CHECK2-NEXT: br i1 [[ARRAYDESTROY_DONE]], label [[ARRAYDESTROY_DONE5]], label [[ARRAYDESTROY_BODY]] +// CHECK2: arraydestroy.done5: // CHECK2-NEXT: br label [[EHCLEANUP:%.*]] -// CHECK2: lpad10: +// CHECK2: lpad8: // CHECK2-NEXT: [[TMP7:%.*]] = landingpad { ptr, i32 } // CHECK2-NEXT: cleanup // CHECK2-NEXT: [[TMP8:%.*]] = extractvalue { ptr, i32 } [[TMP7]], 0 // CHECK2-NEXT: store ptr [[TMP8]], ptr [[EXN_SLOT]], align 8 // CHECK2-NEXT: [[TMP9:%.*]] = extractvalue { ptr, i32 } [[TMP7]], 1 // CHECK2-NEXT: store i32 [[TMP9]], ptr [[EHSELECTOR_SLOT]], align 4 -// CHECK2-NEXT: [[TMP10:%.*]] = load ptr, ptr [[ARRAYINIT_ENDOFINIT9]], align 8 -// CHECK2-NEXT: [[ARRAYDESTROY_ISEMPTY16:%.*]] = icmp eq ptr [[ARRAYINIT_BEGIN8]], [[TMP10]] -// CHECK2-NEXT: br i1 [[ARRAYDESTROY_ISEMPTY16]], label [[ARRAYDESTROY_DONE21:%.*]], label [[ARRAYDESTROY_BODY17:%.*]] -// CHECK2: arraydestroy.body17: -// CHECK2-NEXT: [[ARRAYDESTROY_ELEMENTPAST18:%.*]] = phi ptr [ [[TMP10]], [[LPAD10]] ], [ [[ARRAYDESTROY_ELEMENT19:%.*]], [[ARRAYDESTROY_BODY17]] ] -// CHECK2-NEXT: [[ARRAYDESTROY_ELEMENT19]] = getelementptr inbounds [[STRUCT_S1]], ptr [[ARRAYDESTROY_ELEMENTPAST18]], i64 -1 -// CHECK2-NEXT: call void @_ZN2S1D1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYDESTROY_ELEMENT19]]) #[[ATTR3]] -// CHECK2-NEXT: [[ARRAYDESTROY_DONE20:%.*]] = icmp eq ptr [[ARRAYDESTROY_ELEMENT19]], [[ARRAYINIT_BEGIN8]] -// CHECK2-NEXT: br i1 [[ARRAYDESTROY_DONE20]], label [[ARRAYDESTROY_DONE21]], label [[ARRAYDESTROY_BODY17]] -// CHECK2: arraydestroy.done21: +// CHECK2-NEXT: [[TMP10:%.*]] = load ptr, ptr [[ARRAYINIT_ENDOFINIT7]], align 8 +// CHECK2-NEXT: [[ARRAYDESTROY_ISEMPTY14:%.*]] = icmp eq ptr [[ARRAYINIT_ELEMENT6]], [[TMP10]] +// CHECK2-NEXT: br i1 [[ARRAYDESTROY_ISEMPTY14]], label [[ARRAYDESTROY_DONE19:%.*]], label [[ARRAYDESTROY_BODY15:%.*]] +// CHECK2: arraydestroy.body15: +// CHECK2-NEXT: [[ARRAYDESTROY_ELEMENTPAST16:%.*]] = phi ptr [ [[TMP10]], [[LPAD8]] ], [ [[ARRAYDESTROY_ELEMENT17:%.*]], [[ARRAYDESTROY_BODY15]] ] +// CHECK2-NEXT: [[ARRAYDESTROY_ELEMENT17]] = getelementptr inbounds [[STRUCT_S1]], ptr [[ARRAYDESTROY_ELEMENTPAST16]], i64 -1 +// CHECK2-NEXT: call void @_ZN2S1D1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYDESTROY_ELEMENT17]]) #[[ATTR3]] +// CHECK2-NEXT: [[ARRAYDESTROY_DONE18:%.*]] = icmp eq ptr [[ARRAYDESTROY_ELEMENT17]], [[ARRAYINIT_ELEMENT6]] +// CHECK2-NEXT: br i1 [[ARRAYDESTROY_DONE18]], label [[ARRAYDESTROY_DONE19]], label [[ARRAYDESTROY_BODY15]] +// CHECK2: arraydestroy.done19: // CHECK2-NEXT: br label [[EHCLEANUP]] // CHECK2: ehcleanup: // CHECK2-NEXT: [[TMP11:%.*]] = load ptr, ptr [[ARRAYINIT_ENDOFINIT]], align 8 -// CHECK2-NEXT: [[PAD_ARRAYBEGIN:%.*]] = getelementptr inbounds [3 x %struct.S1], ptr [[ARRAYINIT_BEGIN]], i64 0, i64 0 +// CHECK2-NEXT: [[PAD_ARRAYBEGIN:%.*]] = getelementptr inbounds [3 x %struct.S1], ptr [[TMP1]], i64 0, i64 0 // CHECK2-NEXT: [[PAD_ARRAYEND:%.*]] = getelementptr inbounds [3 x %struct.S1], ptr [[TMP11]], i64 0, i64 0 -// CHECK2-NEXT: [[ARRAYDESTROY_ISEMPTY22:%.*]] = icmp eq ptr [[PAD_ARRAYBEGIN]], [[PAD_ARRAYEND]] -// CHECK2-NEXT: br i1 [[ARRAYDESTROY_ISEMPTY22]], label [[ARRAYDESTROY_DONE27:%.*]], label [[ARRAYDESTROY_BODY23:%.*]] -// CHECK2: arraydestroy.body23: -// CHECK2-NEXT: [[ARRAYDESTROY_ELEMENTPAST24:%.*]] = phi ptr [ [[PAD_ARRAYEND]], [[EHCLEANUP]] ], [ [[ARRAYDESTROY_ELEMENT25:%.*]], [[ARRAYDESTROY_BODY23]] ] -// CHECK2-NEXT: [[ARRAYDESTROY_ELEMENT25]] = getelementptr inbounds [[STRUCT_S1]], ptr [[ARRAYDESTROY_ELEMENTPAST24]], i64 -1 -// CHECK2-NEXT: call void @_ZN2S1D1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYDESTROY_ELEMENT25]]) #[[ATTR3]] -// CHECK2-NEXT: [[ARRAYDESTROY_DONE26:%.*]] = icmp eq ptr [[ARRAYDESTROY_ELEMENT25]], [[PAD_ARRAYBEGIN]] -// CHECK2-NEXT: br i1 [[ARRAYDESTROY_DONE26]], label [[ARRAYDESTROY_DONE27]], label [[ARRAYDESTROY_BODY23]] -// CHECK2: arraydestroy.done27: +// CHECK2-NEXT: [[ARRAYDESTROY_ISEMPTY20:%.*]] = icmp eq ptr [[PAD_ARRAYBEGIN]], [[PAD_ARRAYEND]] +// CHECK2-NEXT: br i1 [[ARRAYDESTROY_ISEMPTY20]], label [[ARRAYDESTROY_DONE25:%.*]], label [[ARRAYDESTROY_BODY21:%.*]] +// CHECK2: arraydestroy.body21: +// CHECK2-NEXT: [[ARRAYDESTROY_ELEMENTPAST22:%.*]] = phi ptr [ [[PAD_ARRAYEND]], [[EHCLEANUP]] ], [ [[ARRAYDESTROY_ELEMENT23:%.*]], [[ARRAYDESTROY_BODY21]] ] +// CHECK2-NEXT: [[ARRAYDESTROY_ELEMENT23]] = getelementptr inbounds [[STRUCT_S1]], ptr [[ARRAYDESTROY_ELEMENTPAST22]], i64 -1 +// CHECK2-NEXT: call void @_ZN2S1D1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYDESTROY_ELEMENT23]]) #[[ATTR3]] +// CHECK2-NEXT: [[ARRAYDESTROY_DONE24:%.*]] = icmp eq ptr [[ARRAYDESTROY_ELEMENT23]], [[PAD_ARRAYBEGIN]] +// CHECK2-NEXT: br i1 [[ARRAYDESTROY_DONE24]], label [[ARRAYDESTROY_DONE25]], label [[ARRAYDESTROY_BODY21]] +// CHECK2: arraydestroy.done25: // CHECK2-NEXT: br label [[EH_RESUME:%.*]] // CHECK2: eh.resume: // CHECK2-NEXT: [[EXN:%.*]] = load ptr, ptr [[EXN_SLOT]], align 8 // CHECK2-NEXT: [[SEL:%.*]] = load i32, ptr [[EHSELECTOR_SLOT]], align 4 // CHECK2-NEXT: [[LPAD_VAL:%.*]] = insertvalue { ptr, i32 } poison, ptr [[EXN]], 0 -// CHECK2-NEXT: [[LPAD_VAL28:%.*]] = insertvalue { ptr, i32 } [[LPAD_VAL]], i32 [[SEL]], 1 -// CHECK2-NEXT: resume { ptr, i32 } [[LPAD_VAL28]] +// CHECK2-NEXT: [[LPAD_VAL26:%.*]] = insertvalue { ptr, i32 } [[LPAD_VAL]], i32 [[SEL]], 1 +// CHECK2-NEXT: resume { ptr, i32 } [[LPAD_VAL26]] // // // CHECK2-LABEL: define {{[^@]+}}@.__kmpc_global_dtor_..4 @@ -6505,47 +6499,44 @@ int foobar() { // DEBUG1-NEXT: entry: // DEBUG1-NEXT: [[DOTADDR:%.*]] = alloca ptr, align 8 // DEBUG1-NEXT: [[ARRAYINIT_ENDOFINIT:%.*]] = alloca ptr, align 8 -// DEBUG1-NEXT: [[ARRAYINIT_ENDOFINIT2:%.*]] = alloca ptr, align 8 +// DEBUG1-NEXT: [[ARRAYINIT_ENDOFINIT1:%.*]] = alloca ptr, align 8 // DEBUG1-NEXT: [[EXN_SLOT:%.*]] = alloca ptr, align 8 // DEBUG1-NEXT: [[EHSELECTOR_SLOT:%.*]] = alloca i32, align 4 -// DEBUG1-NEXT: [[ARRAYINIT_ENDOFINIT9:%.*]] = alloca ptr, align 8 +// DEBUG1-NEXT: [[ARRAYINIT_ENDOFINIT7:%.*]] = alloca ptr, align 8 // DEBUG1-NEXT: store ptr [[TMP0]], ptr [[DOTADDR]], align 8 // DEBUG1-NEXT: tail call void @llvm.dbg.declare(metadata ptr [[DOTADDR]], metadata [[META143:![0-9]+]], metadata !DIExpression()), !dbg [[DBG144:![0-9]+]] // DEBUG1-NEXT: [[TMP1:%.*]] = load ptr, ptr [[DOTADDR]], align 8, !dbg [[DBG145:![0-9]+]] -// DEBUG1-NEXT: [[ARRAYINIT_BEGIN:%.*]] = getelementptr inbounds [2 x [3 x %struct.S1]], ptr [[TMP1]], i64 0, i64 0, !dbg [[DBG146:![0-9]+]] -// DEBUG1-NEXT: store ptr [[ARRAYINIT_BEGIN]], ptr [[ARRAYINIT_ENDOFINIT]], align 8, !dbg [[DBG146]] -// DEBUG1-NEXT: [[ARRAYINIT_BEGIN1:%.*]] = getelementptr inbounds [3 x %struct.S1], ptr [[ARRAYINIT_BEGIN]], i64 0, i64 0, !dbg [[DBG147:![0-9]+]] -// DEBUG1-NEXT: store ptr [[ARRAYINIT_BEGIN1]], ptr [[ARRAYINIT_ENDOFINIT2]], align 8, !dbg [[DBG147]] -// DEBUG1-NEXT: invoke void @_ZN2S1C1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_BEGIN1]], i32 noundef 1) +// DEBUG1-NEXT: store ptr [[TMP1]], ptr [[ARRAYINIT_ENDOFINIT]], align 8, !dbg [[DBG146:![0-9]+]] +// DEBUG1-NEXT: store ptr [[TMP1]], ptr [[ARRAYINIT_ENDOFINIT1]], align 8, !dbg [[DBG147:![0-9]+]] +// DEBUG1-NEXT: invoke void @_ZN2S1C1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[TMP1]], i32 noundef 1) // DEBUG1-NEXT: to label [[INVOKE_CONT:%.*]] unwind label [[LPAD:%.*]], !dbg [[DBG148:![0-9]+]] // DEBUG1: invoke.cont: -// DEBUG1-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S1:%.*]], ptr [[ARRAYINIT_BEGIN1]], i64 1, !dbg [[DBG147]] -// DEBUG1-NEXT: store ptr [[ARRAYINIT_ELEMENT]], ptr [[ARRAYINIT_ENDOFINIT2]], align 8, !dbg [[DBG147]] +// DEBUG1-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S1:%.*]], ptr [[TMP1]], i64 1, !dbg [[DBG147]] +// DEBUG1-NEXT: store ptr [[ARRAYINIT_ELEMENT]], ptr [[ARRAYINIT_ENDOFINIT1]], align 8, !dbg [[DBG147]] // DEBUG1-NEXT: invoke void @_ZN2S1C1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_ELEMENT]], i32 noundef 2) -// DEBUG1-NEXT: to label [[INVOKE_CONT3:%.*]] unwind label [[LPAD]], !dbg [[DBG149:![0-9]+]] -// DEBUG1: invoke.cont3: -// DEBUG1-NEXT: [[ARRAYINIT_ELEMENT4:%.*]] = getelementptr inbounds [[STRUCT_S1]], ptr [[ARRAYINIT_ELEMENT]], i64 1, !dbg [[DBG147]] -// DEBUG1-NEXT: store ptr [[ARRAYINIT_ELEMENT4]], ptr [[ARRAYINIT_ENDOFINIT2]], align 8, !dbg [[DBG147]] -// DEBUG1-NEXT: invoke void @_ZN2S1C1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_ELEMENT4]], i32 noundef 3) -// DEBUG1-NEXT: to label [[INVOKE_CONT5:%.*]] unwind label [[LPAD]], !dbg [[DBG150:![0-9]+]] -// DEBUG1: invoke.cont5: -// DEBUG1-NEXT: [[ARRAYINIT_ELEMENT7:%.*]] = getelementptr inbounds [3 x %struct.S1], ptr [[ARRAYINIT_BEGIN]], i64 1, !dbg [[DBG146]] -// DEBUG1-NEXT: store ptr [[ARRAYINIT_ELEMENT7]], ptr [[ARRAYINIT_ENDOFINIT]], align 8, !dbg [[DBG146]] -// DEBUG1-NEXT: [[ARRAYINIT_BEGIN8:%.*]] = getelementptr inbounds [3 x %struct.S1], ptr [[ARRAYINIT_ELEMENT7]], i64 0, i64 0, !dbg [[DBG151:![0-9]+]] -// DEBUG1-NEXT: store ptr [[ARRAYINIT_BEGIN8]], ptr [[ARRAYINIT_ENDOFINIT9]], align 8, !dbg [[DBG151]] -// DEBUG1-NEXT: invoke void @_ZN2S1C1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_BEGIN8]], i32 noundef 4) -// DEBUG1-NEXT: to label [[INVOKE_CONT11:%.*]] unwind label [[LPAD10:%.*]], !dbg [[DBG152:![0-9]+]] +// DEBUG1-NEXT: to label [[INVOKE_CONT2:%.*]] unwind label [[LPAD]], !dbg [[DBG149:![0-9]+]] +// DEBUG1: invoke.cont2: +// DEBUG1-NEXT: [[ARRAYINIT_ELEMENT3:%.*]] = getelementptr inbounds [[STRUCT_S1]], ptr [[TMP1]], i64 2, !dbg [[DBG147]] +// DEBUG1-NEXT: store ptr [[ARRAYINIT_ELEMENT3]], ptr [[ARRAYINIT_ENDOFINIT1]], align 8, !dbg [[DBG147]] +// DEBUG1-NEXT: invoke void @_ZN2S1C1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_ELEMENT3]], i32 noundef 3) +// DEBUG1-NEXT: to label [[INVOKE_CONT4:%.*]] unwind label [[LPAD]], !dbg [[DBG150:![0-9]+]] +// DEBUG1: invoke.cont4: +// DEBUG1-NEXT: [[ARRAYINIT_ELEMENT6:%.*]] = getelementptr inbounds [3 x %struct.S1], ptr [[TMP1]], i64 1, !dbg [[DBG146]] +// DEBUG1-NEXT: store ptr [[ARRAYINIT_ELEMENT6]], ptr [[ARRAYINIT_ENDOFINIT]], align 8, !dbg [[DBG146]] +// DEBUG1-NEXT: store ptr [[ARRAYINIT_ELEMENT6]], ptr [[ARRAYINIT_ENDOFINIT7]], align 8, !dbg [[DBG151:![0-9]+]] +// DEBUG1-NEXT: invoke void @_ZN2S1C1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_ELEMENT6]], i32 noundef 4) +// DEBUG1-NEXT: to label [[INVOKE_CONT9:%.*]] unwind label [[LPAD8:%.*]], !dbg [[DBG152:![0-9]+]] +// DEBUG1: invoke.cont9: +// DEBUG1-NEXT: [[ARRAYINIT_ELEMENT10:%.*]] = getelementptr inbounds [[STRUCT_S1]], ptr [[ARRAYINIT_ELEMENT6]], i64 1, !dbg [[DBG151]] +// DEBUG1-NEXT: store ptr [[ARRAYINIT_ELEMENT10]], ptr [[ARRAYINIT_ENDOFINIT7]], align 8, !dbg [[DBG151]] +// DEBUG1-NEXT: invoke void @_ZN2S1C1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_ELEMENT10]], i32 noundef 5) +// DEBUG1-NEXT: to label [[INVOKE_CONT11:%.*]] unwind label [[LPAD8]], !dbg [[DBG153:![0-9]+]] // DEBUG1: invoke.cont11: -// DEBUG1-NEXT: [[ARRAYINIT_ELEMENT12:%.*]] = getelementptr inbounds [[STRUCT_S1]], ptr [[ARRAYINIT_BEGIN8]], i64 1, !dbg [[DBG151]] -// DEBUG1-NEXT: store ptr [[ARRAYINIT_ELEMENT12]], ptr [[ARRAYINIT_ENDOFINIT9]], align 8, !dbg [[DBG151]] -// DEBUG1-NEXT: invoke void @_ZN2S1C1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_ELEMENT12]], i32 noundef 5) -// DEBUG1-NEXT: to label [[INVOKE_CONT13:%.*]] unwind label [[LPAD10]], !dbg [[DBG153:![0-9]+]] +// DEBUG1-NEXT: [[ARRAYINIT_ELEMENT12:%.*]] = getelementptr inbounds [[STRUCT_S1]], ptr [[ARRAYINIT_ELEMENT6]], i64 2, !dbg [[DBG151]] +// DEBUG1-NEXT: store ptr [[ARRAYINIT_ELEMENT12]], ptr [[ARRAYINIT_ENDOFINIT7]], align 8, !dbg [[DBG151]] +// DEBUG1-NEXT: invoke void @_ZN2S1C1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_ELEMENT12]], i32 noundef 6) +// DEBUG1-NEXT: to label [[INVOKE_CONT13:%.*]] unwind label [[LPAD8]], !dbg [[DBG154:![0-9]+]] // DEBUG1: invoke.cont13: -// DEBUG1-NEXT: [[ARRAYINIT_ELEMENT14:%.*]] = getelementptr inbounds [[STRUCT_S1]], ptr [[ARRAYINIT_ELEMENT12]], i64 1, !dbg [[DBG151]] -// DEBUG1-NEXT: store ptr [[ARRAYINIT_ELEMENT14]], ptr [[ARRAYINIT_ENDOFINIT9]], align 8, !dbg [[DBG151]] -// DEBUG1-NEXT: invoke void @_ZN2S1C1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_ELEMENT14]], i32 noundef 6) -// DEBUG1-NEXT: to label [[INVOKE_CONT15:%.*]] unwind label [[LPAD10]], !dbg [[DBG154:![0-9]+]] -// DEBUG1: invoke.cont15: // DEBUG1-NEXT: [[TMP2:%.*]] = load ptr, ptr [[DOTADDR]], align 8, !dbg [[DBG145]] // DEBUG1-NEXT: ret ptr [[TMP2]], !dbg [[DBG145]] // DEBUG1: lpad: @@ -6555,55 +6546,55 @@ int foobar() { // DEBUG1-NEXT: store ptr [[TMP4]], ptr [[EXN_SLOT]], align 8, !dbg [[DBG144]] // DEBUG1-NEXT: [[TMP5:%.*]] = extractvalue { ptr, i32 } [[TMP3]], 1, !dbg [[DBG144]] // DEBUG1-NEXT: store i32 [[TMP5]], ptr [[EHSELECTOR_SLOT]], align 4, !dbg [[DBG144]] -// DEBUG1-NEXT: [[TMP6:%.*]] = load ptr, ptr [[ARRAYINIT_ENDOFINIT2]], align 8, !dbg [[DBG147]] -// DEBUG1-NEXT: [[ARRAYDESTROY_ISEMPTY:%.*]] = icmp eq ptr [[ARRAYINIT_BEGIN1]], [[TMP6]], !dbg [[DBG147]] -// DEBUG1-NEXT: br i1 [[ARRAYDESTROY_ISEMPTY]], label [[ARRAYDESTROY_DONE6:%.*]], label [[ARRAYDESTROY_BODY:%.*]], !dbg [[DBG147]] +// DEBUG1-NEXT: [[TMP6:%.*]] = load ptr, ptr [[ARRAYINIT_ENDOFINIT1]], align 8, !dbg [[DBG147]] +// DEBUG1-NEXT: [[ARRAYDESTROY_ISEMPTY:%.*]] = icmp eq ptr [[TMP1]], [[TMP6]], !dbg [[DBG147]] +// DEBUG1-NEXT: br i1 [[ARRAYDESTROY_ISEMPTY]], label [[ARRAYDESTROY_DONE5:%.*]], label [[ARRAYDESTROY_BODY:%.*]], !dbg [[DBG147]] // DEBUG1: arraydestroy.body: // DEBUG1-NEXT: [[ARRAYDESTROY_ELEMENTPAST:%.*]] = phi ptr [ [[TMP6]], [[LPAD]] ], [ [[ARRAYDESTROY_ELEMENT:%.*]], [[ARRAYDESTROY_BODY]] ], !dbg [[DBG147]] // DEBUG1-NEXT: [[ARRAYDESTROY_ELEMENT]] = getelementptr inbounds [[STRUCT_S1]], ptr [[ARRAYDESTROY_ELEMENTPAST]], i64 -1, !dbg [[DBG147]] // DEBUG1-NEXT: call void @_ZN2S1D1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYDESTROY_ELEMENT]]) #[[ATTR4]], !dbg [[DBG147]] -// DEBUG1-NEXT: [[ARRAYDESTROY_DONE:%.*]] = icmp eq ptr [[ARRAYDESTROY_ELEMENT]], [[ARRAYINIT_BEGIN1]], !dbg [[DBG147]] -// DEBUG1-NEXT: br i1 [[ARRAYDESTROY_DONE]], label [[ARRAYDESTROY_DONE6]], label [[ARRAYDESTROY_BODY]], !dbg [[DBG147]] -// DEBUG1: arraydestroy.done6: +// DEBUG1-NEXT: [[ARRAYDESTROY_DONE:%.*]] = icmp eq ptr [[ARRAYDESTROY_ELEMENT]], [[TMP1]], !dbg [[DBG147]] +// DEBUG1-NEXT: br i1 [[ARRAYDESTROY_DONE]], label [[ARRAYDESTROY_DONE5]], label [[ARRAYDESTROY_BODY]], !dbg [[DBG147]] +// DEBUG1: arraydestroy.done5: // DEBUG1-NEXT: br label [[EHCLEANUP:%.*]], !dbg [[DBG147]] -// DEBUG1: lpad10: +// DEBUG1: lpad8: // DEBUG1-NEXT: [[TMP7:%.*]] = landingpad { ptr, i32 } // DEBUG1-NEXT: cleanup, !dbg [[DBG144]] // DEBUG1-NEXT: [[TMP8:%.*]] = extractvalue { ptr, i32 } [[TMP7]], 0, !dbg [[DBG144]] // DEBUG1-NEXT: store ptr [[TMP8]], ptr [[EXN_SLOT]], align 8, !dbg [[DBG144]] // DEBUG1-NEXT: [[TMP9:%.*]] = extractvalue { ptr, i32 } [[TMP7]], 1, !dbg [[DBG144]] // DEBUG1-NEXT: store i32 [[TMP9]], ptr [[EHSELECTOR_SLOT]], align 4, !dbg [[DBG144]] -// DEBUG1-NEXT: [[TMP10:%.*]] = load ptr, ptr [[ARRAYINIT_ENDOFINIT9]], align 8, !dbg [[DBG151]] -// DEBUG1-NEXT: [[ARRAYDESTROY_ISEMPTY16:%.*]] = icmp eq ptr [[ARRAYINIT_BEGIN8]], [[TMP10]], !dbg [[DBG151]] -// DEBUG1-NEXT: br i1 [[ARRAYDESTROY_ISEMPTY16]], label [[ARRAYDESTROY_DONE21:%.*]], label [[ARRAYDESTROY_BODY17:%.*]], !dbg [[DBG151]] -// DEBUG1: arraydestroy.body17: -// DEBUG1-NEXT: [[ARRAYDESTROY_ELEMENTPAST18:%.*]] = phi ptr [ [[TMP10]], [[LPAD10]] ], [ [[ARRAYDESTROY_ELEMENT19:%.*]], [[ARRAYDESTROY_BODY17]] ], !dbg [[DBG151]] -// DEBUG1-NEXT: [[ARRAYDESTROY_ELEMENT19]] = getelementptr inbounds [[STRUCT_S1]], ptr [[ARRAYDESTROY_ELEMENTPAST18]], i64 -1, !dbg [[DBG151]] -// DEBUG1-NEXT: call void @_ZN2S1D1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYDESTROY_ELEMENT19]]) #[[ATTR4]], !dbg [[DBG151]] -// DEBUG1-NEXT: [[ARRAYDESTROY_DONE20:%.*]] = icmp eq ptr [[ARRAYDESTROY_ELEMENT19]], [[ARRAYINIT_BEGIN8]], !dbg [[DBG151]] -// DEBUG1-NEXT: br i1 [[ARRAYDESTROY_DONE20]], label [[ARRAYDESTROY_DONE21]], label [[ARRAYDESTROY_BODY17]], !dbg [[DBG151]] -// DEBUG1: arraydestroy.done21: +// DEBUG1-NEXT: [[TMP10:%.*]] = load ptr, ptr [[ARRAYINIT_ENDOFINIT7]], align 8, !dbg [[DBG151]] +// DEBUG1-NEXT: [[ARRAYDESTROY_ISEMPTY14:%.*]] = icmp eq ptr [[ARRAYINIT_ELEMENT6]], [[TMP10]], !dbg [[DBG151]] +// DEBUG1-NEXT: br i1 [[ARRAYDESTROY_ISEMPTY14]], label [[ARRAYDESTROY_DONE19:%.*]], label [[ARRAYDESTROY_BODY15:%.*]], !dbg [[DBG151]] +// DEBUG1: arraydestroy.body15: +// DEBUG1-NEXT: [[ARRAYDESTROY_ELEMENTPAST16:%.*]] = phi ptr [ [[TMP10]], [[LPAD8]] ], [ [[ARRAYDESTROY_ELEMENT17:%.*]], [[ARRAYDESTROY_BODY15]] ], !dbg [[DBG151]] +// DEBUG1-NEXT: [[ARRAYDESTROY_ELEMENT17]] = getelementptr inbounds [[STRUCT_S1]], ptr [[ARRAYDESTROY_ELEMENTPAST16]], i64 -1, !dbg [[DBG151]] +// DEBUG1-NEXT: call void @_ZN2S1D1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYDESTROY_ELEMENT17]]) #[[ATTR4]], !dbg [[DBG151]] +// DEBUG1-NEXT: [[ARRAYDESTROY_DONE18:%.*]] = icmp eq ptr [[ARRAYDESTROY_ELEMENT17]], [[ARRAYINIT_ELEMENT6]], !dbg [[DBG151]] +// DEBUG1-NEXT: br i1 [[ARRAYDESTROY_DONE18]], label [[ARRAYDESTROY_DONE19]], label [[ARRAYDESTROY_BODY15]], !dbg [[DBG151]] +// DEBUG1: arraydestroy.done19: // DEBUG1-NEXT: br label [[EHCLEANUP]], !dbg [[DBG151]] // DEBUG1: ehcleanup: // DEBUG1-NEXT: [[TMP11:%.*]] = load ptr, ptr [[ARRAYINIT_ENDOFINIT]], align 8, !dbg [[DBG146]] -// DEBUG1-NEXT: [[PAD_ARRAYBEGIN:%.*]] = getelementptr inbounds [3 x %struct.S1], ptr [[ARRAYINIT_BEGIN]], i64 0, i64 0, !dbg [[DBG146]] +// DEBUG1-NEXT: [[PAD_ARRAYBEGIN:%.*]] = getelementptr inbounds [3 x %struct.S1], ptr [[TMP1]], i64 0, i64 0, !dbg [[DBG146]] // DEBUG1-NEXT: [[PAD_ARRAYEND:%.*]] = getelementptr inbounds [3 x %struct.S1], ptr [[TMP11]], i64 0, i64 0, !dbg [[DBG146]] -// DEBUG1-NEXT: [[ARRAYDESTROY_ISEMPTY22:%.*]] = icmp eq ptr [[PAD_ARRAYBEGIN]], [[PAD_ARRAYEND]], !dbg [[DBG146]] -// DEBUG1-NEXT: br i1 [[ARRAYDESTROY_ISEMPTY22]], label [[ARRAYDESTROY_DONE27:%.*]], label [[ARRAYDESTROY_BODY23:%.*]], !dbg [[DBG146]] -// DEBUG1: arraydestroy.body23: -// DEBUG1-NEXT: [[ARRAYDESTROY_ELEMENTPAST24:%.*]] = phi ptr [ [[PAD_ARRAYEND]], [[EHCLEANUP]] ], [ [[ARRAYDESTROY_ELEMENT25:%.*]], [[ARRAYDESTROY_BODY23]] ], !dbg [[DBG146]] -// DEBUG1-NEXT: [[ARRAYDESTROY_ELEMENT25]] = getelementptr inbounds [[STRUCT_S1]], ptr [[ARRAYDESTROY_ELEMENTPAST24]], i64 -1, !dbg [[DBG146]] -// DEBUG1-NEXT: call void @_ZN2S1D1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYDESTROY_ELEMENT25]]) #[[ATTR4]], !dbg [[DBG146]] -// DEBUG1-NEXT: [[ARRAYDESTROY_DONE26:%.*]] = icmp eq ptr [[ARRAYDESTROY_ELEMENT25]], [[PAD_ARRAYBEGIN]], !dbg [[DBG146]] -// DEBUG1-NEXT: br i1 [[ARRAYDESTROY_DONE26]], label [[ARRAYDESTROY_DONE27]], label [[ARRAYDESTROY_BODY23]], !dbg [[DBG146]] -// DEBUG1: arraydestroy.done27: +// DEBUG1-NEXT: [[ARRAYDESTROY_ISEMPTY20:%.*]] = icmp eq ptr [[PAD_ARRAYBEGIN]], [[PAD_ARRAYEND]], !dbg [[DBG146]] +// DEBUG1-NEXT: br i1 [[ARRAYDESTROY_ISEMPTY20]], label [[ARRAYDESTROY_DONE25:%.*]], label [[ARRAYDESTROY_BODY21:%.*]], !dbg [[DBG146]] +// DEBUG1: arraydestroy.body21: +// DEBUG1-NEXT: [[ARRAYDESTROY_ELEMENTPAST22:%.*]] = phi ptr [ [[PAD_ARRAYEND]], [[EHCLEANUP]] ], [ [[ARRAYDESTROY_ELEMENT23:%.*]], [[ARRAYDESTROY_BODY21]] ], !dbg [[DBG146]] +// DEBUG1-NEXT: [[ARRAYDESTROY_ELEMENT23]] = getelementptr inbounds [[STRUCT_S1]], ptr [[ARRAYDESTROY_ELEMENTPAST22]], i64 -1, !dbg [[DBG146]] +// DEBUG1-NEXT: call void @_ZN2S1D1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYDESTROY_ELEMENT23]]) #[[ATTR4]], !dbg [[DBG146]] +// DEBUG1-NEXT: [[ARRAYDESTROY_DONE24:%.*]] = icmp eq ptr [[ARRAYDESTROY_ELEMENT23]], [[PAD_ARRAYBEGIN]], !dbg [[DBG146]] +// DEBUG1-NEXT: br i1 [[ARRAYDESTROY_DONE24]], label [[ARRAYDESTROY_DONE25]], label [[ARRAYDESTROY_BODY21]], !dbg [[DBG146]] +// DEBUG1: arraydestroy.done25: // DEBUG1-NEXT: br label [[EH_RESUME:%.*]], !dbg [[DBG146]] // DEBUG1: eh.resume: // DEBUG1-NEXT: [[EXN:%.*]] = load ptr, ptr [[EXN_SLOT]], align 8, !dbg [[DBG146]] // DEBUG1-NEXT: [[SEL:%.*]] = load i32, ptr [[EHSELECTOR_SLOT]], align 4, !dbg [[DBG146]] // DEBUG1-NEXT: [[LPAD_VAL:%.*]] = insertvalue { ptr, i32 } poison, ptr [[EXN]], 0, !dbg [[DBG146]] -// DEBUG1-NEXT: [[LPAD_VAL28:%.*]] = insertvalue { ptr, i32 } [[LPAD_VAL]], i32 [[SEL]], 1, !dbg [[DBG146]] -// DEBUG1-NEXT: resume { ptr, i32 } [[LPAD_VAL28]], !dbg [[DBG146]] +// DEBUG1-NEXT: [[LPAD_VAL26:%.*]] = insertvalue { ptr, i32 } [[LPAD_VAL]], i32 [[SEL]], 1, !dbg [[DBG146]] +// DEBUG1-NEXT: resume { ptr, i32 } [[LPAD_VAL26]], !dbg [[DBG146]] // // // DEBUG1-LABEL: define {{[^@]+}}@.__kmpc_global_dtor_..2 @@ -7375,47 +7366,44 @@ int foobar() { // DEBUG2-NEXT: entry: // DEBUG2-NEXT: [[DOTADDR:%.*]] = alloca ptr, align 8 // DEBUG2-NEXT: [[ARRAYINIT_ENDOFINIT:%.*]] = alloca ptr, align 8 -// DEBUG2-NEXT: [[ARRAYINIT_ENDOFINIT2:%.*]] = alloca ptr, align 8 +// DEBUG2-NEXT: [[ARRAYINIT_ENDOFINIT1:%.*]] = alloca ptr, align 8 // DEBUG2-NEXT: [[EXN_SLOT:%.*]] = alloca ptr, align 8 // DEBUG2-NEXT: [[EHSELECTOR_SLOT:%.*]] = alloca i32, align 4 -// DEBUG2-NEXT: [[ARRAYINIT_ENDOFINIT9:%.*]] = alloca ptr, align 8 +// DEBUG2-NEXT: [[ARRAYINIT_ENDOFINIT7:%.*]] = alloca ptr, align 8 // DEBUG2-NEXT: store ptr [[TMP0]], ptr [[DOTADDR]], align 8 // DEBUG2-NEXT: tail call void @llvm.dbg.declare(metadata ptr [[DOTADDR]], metadata [[META179:![0-9]+]], metadata !DIExpression()), !dbg [[DBG180:![0-9]+]] // DEBUG2-NEXT: [[TMP1:%.*]] = load ptr, ptr [[DOTADDR]], align 8, !dbg [[DBG181:![0-9]+]] -// DEBUG2-NEXT: [[ARRAYINIT_BEGIN:%.*]] = getelementptr inbounds [2 x [3 x %struct.S1]], ptr [[TMP1]], i64 0, i64 0, !dbg [[DBG182:![0-9]+]] -// DEBUG2-NEXT: store ptr [[ARRAYINIT_BEGIN]], ptr [[ARRAYINIT_ENDOFINIT]], align 8, !dbg [[DBG182]] -// DEBUG2-NEXT: [[ARRAYINIT_BEGIN1:%.*]] = getelementptr inbounds [3 x %struct.S1], ptr [[ARRAYINIT_BEGIN]], i64 0, i64 0, !dbg [[DBG183:![0-9]+]] -// DEBUG2-NEXT: store ptr [[ARRAYINIT_BEGIN1]], ptr [[ARRAYINIT_ENDOFINIT2]], align 8, !dbg [[DBG183]] -// DEBUG2-NEXT: invoke void @_ZN2S1C1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_BEGIN1]], i32 noundef 1) +// DEBUG2-NEXT: store ptr [[TMP1]], ptr [[ARRAYINIT_ENDOFINIT]], align 8, !dbg [[DBG182:![0-9]+]] +// DEBUG2-NEXT: store ptr [[TMP1]], ptr [[ARRAYINIT_ENDOFINIT1]], align 8, !dbg [[DBG183:![0-9]+]] +// DEBUG2-NEXT: invoke void @_ZN2S1C1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[TMP1]], i32 noundef 1) // DEBUG2-NEXT: to label [[INVOKE_CONT:%.*]] unwind label [[LPAD:%.*]], !dbg [[DBG184:![0-9]+]] // DEBUG2: invoke.cont: -// DEBUG2-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S1:%.*]], ptr [[ARRAYINIT_BEGIN1]], i64 1, !dbg [[DBG183]] -// DEBUG2-NEXT: store ptr [[ARRAYINIT_ELEMENT]], ptr [[ARRAYINIT_ENDOFINIT2]], align 8, !dbg [[DBG183]] +// DEBUG2-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S1:%.*]], ptr [[TMP1]], i64 1, !dbg [[DBG183]] +// DEBUG2-NEXT: store ptr [[ARRAYINIT_ELEMENT]], ptr [[ARRAYINIT_ENDOFINIT1]], align 8, !dbg [[DBG183]] // DEBUG2-NEXT: invoke void @_ZN2S1C1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_ELEMENT]], i32 noundef 2) -// DEBUG2-NEXT: to label [[INVOKE_CONT3:%.*]] unwind label [[LPAD]], !dbg [[DBG185:![0-9]+]] -// DEBUG2: invoke.cont3: -// DEBUG2-NEXT: [[ARRAYINIT_ELEMENT4:%.*]] = getelementptr inbounds [[STRUCT_S1]], ptr [[ARRAYINIT_ELEMENT]], i64 1, !dbg [[DBG183]] -// DEBUG2-NEXT: store ptr [[ARRAYINIT_ELEMENT4]], ptr [[ARRAYINIT_ENDOFINIT2]], align 8, !dbg [[DBG183]] -// DEBUG2-NEXT: invoke void @_ZN2S1C1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_ELEMENT4]], i32 noundef 3) -// DEBUG2-NEXT: to label [[INVOKE_CONT5:%.*]] unwind label [[LPAD]], !dbg [[DBG186:![0-9]+]] -// DEBUG2: invoke.cont5: -// DEBUG2-NEXT: [[ARRAYINIT_ELEMENT7:%.*]] = getelementptr inbounds [3 x %struct.S1], ptr [[ARRAYINIT_BEGIN]], i64 1, !dbg [[DBG182]] -// DEBUG2-NEXT: store ptr [[ARRAYINIT_ELEMENT7]], ptr [[ARRAYINIT_ENDOFINIT]], align 8, !dbg [[DBG182]] -// DEBUG2-NEXT: [[ARRAYINIT_BEGIN8:%.*]] = getelementptr inbounds [3 x %struct.S1], ptr [[ARRAYINIT_ELEMENT7]], i64 0, i64 0, !dbg [[DBG187:![0-9]+]] -// DEBUG2-NEXT: store ptr [[ARRAYINIT_BEGIN8]], ptr [[ARRAYINIT_ENDOFINIT9]], align 8, !dbg [[DBG187]] -// DEBUG2-NEXT: invoke void @_ZN2S1C1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_BEGIN8]], i32 noundef 4) -// DEBUG2-NEXT: to label [[INVOKE_CONT11:%.*]] unwind label [[LPAD10:%.*]], !dbg [[DBG188:![0-9]+]] +// DEBUG2-NEXT: to label [[INVOKE_CONT2:%.*]] unwind label [[LPAD]], !dbg [[DBG185:![0-9]+]] +// DEBUG2: invoke.cont2: +// DEBUG2-NEXT: [[ARRAYINIT_ELEMENT3:%.*]] = getelementptr inbounds [[STRUCT_S1]], ptr [[TMP1]], i64 2, !dbg [[DBG183]] +// DEBUG2-NEXT: store ptr [[ARRAYINIT_ELEMENT3]], ptr [[ARRAYINIT_ENDOFINIT1]], align 8, !dbg [[DBG183]] +// DEBUG2-NEXT: invoke void @_ZN2S1C1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_ELEMENT3]], i32 noundef 3) +// DEBUG2-NEXT: to label [[INVOKE_CONT4:%.*]] unwind label [[LPAD]], !dbg [[DBG186:![0-9]+]] +// DEBUG2: invoke.cont4: +// DEBUG2-NEXT: [[ARRAYINIT_ELEMENT6:%.*]] = getelementptr inbounds [3 x %struct.S1], ptr [[TMP1]], i64 1, !dbg [[DBG182]] +// DEBUG2-NEXT: store ptr [[ARRAYINIT_ELEMENT6]], ptr [[ARRAYINIT_ENDOFINIT]], align 8, !dbg [[DBG182]] +// DEBUG2-NEXT: store ptr [[ARRAYINIT_ELEMENT6]], ptr [[ARRAYINIT_ENDOFINIT7]], align 8, !dbg [[DBG187:![0-9]+]] +// DEBUG2-NEXT: invoke void @_ZN2S1C1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_ELEMENT6]], i32 noundef 4) +// DEBUG2-NEXT: to label [[INVOKE_CONT9:%.*]] unwind label [[LPAD8:%.*]], !dbg [[DBG188:![0-9]+]] +// DEBUG2: invoke.cont9: +// DEBUG2-NEXT: [[ARRAYINIT_ELEMENT10:%.*]] = getelementptr inbounds [[STRUCT_S1]], ptr [[ARRAYINIT_ELEMENT6]], i64 1, !dbg [[DBG187]] +// DEBUG2-NEXT: store ptr [[ARRAYINIT_ELEMENT10]], ptr [[ARRAYINIT_ENDOFINIT7]], align 8, !dbg [[DBG187]] +// DEBUG2-NEXT: invoke void @_ZN2S1C1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_ELEMENT10]], i32 noundef 5) +// DEBUG2-NEXT: to label [[INVOKE_CONT11:%.*]] unwind label [[LPAD8]], !dbg [[DBG189:![0-9]+]] // DEBUG2: invoke.cont11: -// DEBUG2-NEXT: [[ARRAYINIT_ELEMENT12:%.*]] = getelementptr inbounds [[STRUCT_S1]], ptr [[ARRAYINIT_BEGIN8]], i64 1, !dbg [[DBG187]] -// DEBUG2-NEXT: store ptr [[ARRAYINIT_ELEMENT12]], ptr [[ARRAYINIT_ENDOFINIT9]], align 8, !dbg [[DBG187]] -// DEBUG2-NEXT: invoke void @_ZN2S1C1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_ELEMENT12]], i32 noundef 5) -// DEBUG2-NEXT: to label [[INVOKE_CONT13:%.*]] unwind label [[LPAD10]], !dbg [[DBG189:![0-9]+]] +// DEBUG2-NEXT: [[ARRAYINIT_ELEMENT12:%.*]] = getelementptr inbounds [[STRUCT_S1]], ptr [[ARRAYINIT_ELEMENT6]], i64 2, !dbg [[DBG187]] +// DEBUG2-NEXT: store ptr [[ARRAYINIT_ELEMENT12]], ptr [[ARRAYINIT_ENDOFINIT7]], align 8, !dbg [[DBG187]] +// DEBUG2-NEXT: invoke void @_ZN2S1C1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_ELEMENT12]], i32 noundef 6) +// DEBUG2-NEXT: to label [[INVOKE_CONT13:%.*]] unwind label [[LPAD8]], !dbg [[DBG190:![0-9]+]] // DEBUG2: invoke.cont13: -// DEBUG2-NEXT: [[ARRAYINIT_ELEMENT14:%.*]] = getelementptr inbounds [[STRUCT_S1]], ptr [[ARRAYINIT_ELEMENT12]], i64 1, !dbg [[DBG187]] -// DEBUG2-NEXT: store ptr [[ARRAYINIT_ELEMENT14]], ptr [[ARRAYINIT_ENDOFINIT9]], align 8, !dbg [[DBG187]] -// DEBUG2-NEXT: invoke void @_ZN2S1C1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_ELEMENT14]], i32 noundef 6) -// DEBUG2-NEXT: to label [[INVOKE_CONT15:%.*]] unwind label [[LPAD10]], !dbg [[DBG190:![0-9]+]] -// DEBUG2: invoke.cont15: // DEBUG2-NEXT: [[TMP2:%.*]] = load ptr, ptr [[DOTADDR]], align 8, !dbg [[DBG181]] // DEBUG2-NEXT: ret ptr [[TMP2]], !dbg [[DBG181]] // DEBUG2: lpad: @@ -7425,55 +7413,55 @@ int foobar() { // DEBUG2-NEXT: store ptr [[TMP4]], ptr [[EXN_SLOT]], align 8, !dbg [[DBG180]] // DEBUG2-NEXT: [[TMP5:%.*]] = extractvalue { ptr, i32 } [[TMP3]], 1, !dbg [[DBG180]] // DEBUG2-NEXT: store i32 [[TMP5]], ptr [[EHSELECTOR_SLOT]], align 4, !dbg [[DBG180]] -// DEBUG2-NEXT: [[TMP6:%.*]] = load ptr, ptr [[ARRAYINIT_ENDOFINIT2]], align 8, !dbg [[DBG183]] -// DEBUG2-NEXT: [[ARRAYDESTROY_ISEMPTY:%.*]] = icmp eq ptr [[ARRAYINIT_BEGIN1]], [[TMP6]], !dbg [[DBG183]] -// DEBUG2-NEXT: br i1 [[ARRAYDESTROY_ISEMPTY]], label [[ARRAYDESTROY_DONE6:%.*]], label [[ARRAYDESTROY_BODY:%.*]], !dbg [[DBG183]] +// DEBUG2-NEXT: [[TMP6:%.*]] = load ptr, ptr [[ARRAYINIT_ENDOFINIT1]], align 8, !dbg [[DBG183]] +// DEBUG2-NEXT: [[ARRAYDESTROY_ISEMPTY:%.*]] = icmp eq ptr [[TMP1]], [[TMP6]], !dbg [[DBG183]] +// DEBUG2-NEXT: br i1 [[ARRAYDESTROY_ISEMPTY]], label [[ARRAYDESTROY_DONE5:%.*]], label [[ARRAYDESTROY_BODY:%.*]], !dbg [[DBG183]] // DEBUG2: arraydestroy.body: // DEBUG2-NEXT: [[ARRAYDESTROY_ELEMENTPAST:%.*]] = phi ptr [ [[TMP6]], [[LPAD]] ], [ [[ARRAYDESTROY_ELEMENT:%.*]], [[ARRAYDESTROY_BODY]] ], !dbg [[DBG183]] // DEBUG2-NEXT: [[ARRAYDESTROY_ELEMENT]] = getelementptr inbounds [[STRUCT_S1]], ptr [[ARRAYDESTROY_ELEMENTPAST]], i64 -1, !dbg [[DBG183]] // DEBUG2-NEXT: call void @_ZN2S1D1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYDESTROY_ELEMENT]]) #[[ATTR4]], !dbg [[DBG183]] -// DEBUG2-NEXT: [[ARRAYDESTROY_DONE:%.*]] = icmp eq ptr [[ARRAYDESTROY_ELEMENT]], [[ARRAYINIT_BEGIN1]], !dbg [[DBG183]] -// DEBUG2-NEXT: br i1 [[ARRAYDESTROY_DONE]], label [[ARRAYDESTROY_DONE6]], label [[ARRAYDESTROY_BODY]], !dbg [[DBG183]] -// DEBUG2: arraydestroy.done6: +// DEBUG2-NEXT: [[ARRAYDESTROY_DONE:%.*]] = icmp eq ptr [[ARRAYDESTROY_ELEMENT]], [[TMP1]], !dbg [[DBG183]] +// DEBUG2-NEXT: br i1 [[ARRAYDESTROY_DONE]], label [[ARRAYDESTROY_DONE5]], label [[ARRAYDESTROY_BODY]], !dbg [[DBG183]] +// DEBUG2: arraydestroy.done5: // DEBUG2-NEXT: br label [[EHCLEANUP:%.*]], !dbg [[DBG183]] -// DEBUG2: lpad10: +// DEBUG2: lpad8: // DEBUG2-NEXT: [[TMP7:%.*]] = landingpad { ptr, i32 } // DEBUG2-NEXT: cleanup, !dbg [[DBG180]] // DEBUG2-NEXT: [[TMP8:%.*]] = extractvalue { ptr, i32 } [[TMP7]], 0, !dbg [[DBG180]] // DEBUG2-NEXT: store ptr [[TMP8]], ptr [[EXN_SLOT]], align 8, !dbg [[DBG180]] // DEBUG2-NEXT: [[TMP9:%.*]] = extractvalue { ptr, i32 } [[TMP7]], 1, !dbg [[DBG180]] // DEBUG2-NEXT: store i32 [[TMP9]], ptr [[EHSELECTOR_SLOT]], align 4, !dbg [[DBG180]] -// DEBUG2-NEXT: [[TMP10:%.*]] = load ptr, ptr [[ARRAYINIT_ENDOFINIT9]], align 8, !dbg [[DBG187]] -// DEBUG2-NEXT: [[ARRAYDESTROY_ISEMPTY16:%.*]] = icmp eq ptr [[ARRAYINIT_BEGIN8]], [[TMP10]], !dbg [[DBG187]] -// DEBUG2-NEXT: br i1 [[ARRAYDESTROY_ISEMPTY16]], label [[ARRAYDESTROY_DONE21:%.*]], label [[ARRAYDESTROY_BODY17:%.*]], !dbg [[DBG187]] -// DEBUG2: arraydestroy.body17: -// DEBUG2-NEXT: [[ARRAYDESTROY_ELEMENTPAST18:%.*]] = phi ptr [ [[TMP10]], [[LPAD10]] ], [ [[ARRAYDESTROY_ELEMENT19:%.*]], [[ARRAYDESTROY_BODY17]] ], !dbg [[DBG187]] -// DEBUG2-NEXT: [[ARRAYDESTROY_ELEMENT19]] = getelementptr inbounds [[STRUCT_S1]], ptr [[ARRAYDESTROY_ELEMENTPAST18]], i64 -1, !dbg [[DBG187]] -// DEBUG2-NEXT: call void @_ZN2S1D1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYDESTROY_ELEMENT19]]) #[[ATTR4]], !dbg [[DBG187]] -// DEBUG2-NEXT: [[ARRAYDESTROY_DONE20:%.*]] = icmp eq ptr [[ARRAYDESTROY_ELEMENT19]], [[ARRAYINIT_BEGIN8]], !dbg [[DBG187]] -// DEBUG2-NEXT: br i1 [[ARRAYDESTROY_DONE20]], label [[ARRAYDESTROY_DONE21]], label [[ARRAYDESTROY_BODY17]], !dbg [[DBG187]] -// DEBUG2: arraydestroy.done21: +// DEBUG2-NEXT: [[TMP10:%.*]] = load ptr, ptr [[ARRAYINIT_ENDOFINIT7]], align 8, !dbg [[DBG187]] +// DEBUG2-NEXT: [[ARRAYDESTROY_ISEMPTY14:%.*]] = icmp eq ptr [[ARRAYINIT_ELEMENT6]], [[TMP10]], !dbg [[DBG187]] +// DEBUG2-NEXT: br i1 [[ARRAYDESTROY_ISEMPTY14]], label [[ARRAYDESTROY_DONE19:%.*]], label [[ARRAYDESTROY_BODY15:%.*]], !dbg [[DBG187]] +// DEBUG2: arraydestroy.body15: +// DEBUG2-NEXT: [[ARRAYDESTROY_ELEMENTPAST16:%.*]] = phi ptr [ [[TMP10]], [[LPAD8]] ], [ [[ARRAYDESTROY_ELEMENT17:%.*]], [[ARRAYDESTROY_BODY15]] ], !dbg [[DBG187]] +// DEBUG2-NEXT: [[ARRAYDESTROY_ELEMENT17]] = getelementptr inbounds [[STRUCT_S1]], ptr [[ARRAYDESTROY_ELEMENTPAST16]], i64 -1, !dbg [[DBG187]] +// DEBUG2-NEXT: call void @_ZN2S1D1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYDESTROY_ELEMENT17]]) #[[ATTR4]], !dbg [[DBG187]] +// DEBUG2-NEXT: [[ARRAYDESTROY_DONE18:%.*]] = icmp eq ptr [[ARRAYDESTROY_ELEMENT17]], [[ARRAYINIT_ELEMENT6]], !dbg [[DBG187]] +// DEBUG2-NEXT: br i1 [[ARRAYDESTROY_DONE18]], label [[ARRAYDESTROY_DONE19]], label [[ARRAYDESTROY_BODY15]], !dbg [[DBG187]] +// DEBUG2: arraydestroy.done19: // DEBUG2-NEXT: br label [[EHCLEANUP]], !dbg [[DBG187]] // DEBUG2: ehcleanup: // DEBUG2-NEXT: [[TMP11:%.*]] = load ptr, ptr [[ARRAYINIT_ENDOFINIT]], align 8, !dbg [[DBG182]] -// DEBUG2-NEXT: [[PAD_ARRAYBEGIN:%.*]] = getelementptr inbounds [3 x %struct.S1], ptr [[ARRAYINIT_BEGIN]], i64 0, i64 0, !dbg [[DBG182]] +// DEBUG2-NEXT: [[PAD_ARRAYBEGIN:%.*]] = getelementptr inbounds [3 x %struct.S1], ptr [[TMP1]], i64 0, i64 0, !dbg [[DBG182]] // DEBUG2-NEXT: [[PAD_ARRAYEND:%.*]] = getelementptr inbounds [3 x %struct.S1], ptr [[TMP11]], i64 0, i64 0, !dbg [[DBG182]] -// DEBUG2-NEXT: [[ARRAYDESTROY_ISEMPTY22:%.*]] = icmp eq ptr [[PAD_ARRAYBEGIN]], [[PAD_ARRAYEND]], !dbg [[DBG182]] -// DEBUG2-NEXT: br i1 [[ARRAYDESTROY_ISEMPTY22]], label [[ARRAYDESTROY_DONE27:%.*]], label [[ARRAYDESTROY_BODY23:%.*]], !dbg [[DBG182]] -// DEBUG2: arraydestroy.body23: -// DEBUG2-NEXT: [[ARRAYDESTROY_ELEMENTPAST24:%.*]] = phi ptr [ [[PAD_ARRAYEND]], [[EHCLEANUP]] ], [ [[ARRAYDESTROY_ELEMENT25:%.*]], [[ARRAYDESTROY_BODY23]] ], !dbg [[DBG182]] -// DEBUG2-NEXT: [[ARRAYDESTROY_ELEMENT25]] = getelementptr inbounds [[STRUCT_S1]], ptr [[ARRAYDESTROY_ELEMENTPAST24]], i64 -1, !dbg [[DBG182]] -// DEBUG2-NEXT: call void @_ZN2S1D1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYDESTROY_ELEMENT25]]) #[[ATTR4]], !dbg [[DBG182]] -// DEBUG2-NEXT: [[ARRAYDESTROY_DONE26:%.*]] = icmp eq ptr [[ARRAYDESTROY_ELEMENT25]], [[PAD_ARRAYBEGIN]], !dbg [[DBG182]] -// DEBUG2-NEXT: br i1 [[ARRAYDESTROY_DONE26]], label [[ARRAYDESTROY_DONE27]], label [[ARRAYDESTROY_BODY23]], !dbg [[DBG182]] -// DEBUG2: arraydestroy.done27: +// DEBUG2-NEXT: [[ARRAYDESTROY_ISEMPTY20:%.*]] = icmp eq ptr [[PAD_ARRAYBEGIN]], [[PAD_ARRAYEND]], !dbg [[DBG182]] +// DEBUG2-NEXT: br i1 [[ARRAYDESTROY_ISEMPTY20]], label [[ARRAYDESTROY_DONE25:%.*]], label [[ARRAYDESTROY_BODY21:%.*]], !dbg [[DBG182]] +// DEBUG2: arraydestroy.body21: +// DEBUG2-NEXT: [[ARRAYDESTROY_ELEMENTPAST22:%.*]] = phi ptr [ [[PAD_ARRAYEND]], [[EHCLEANUP]] ], [ [[ARRAYDESTROY_ELEMENT23:%.*]], [[ARRAYDESTROY_BODY21]] ], !dbg [[DBG182]] +// DEBUG2-NEXT: [[ARRAYDESTROY_ELEMENT23]] = getelementptr inbounds [[STRUCT_S1]], ptr [[ARRAYDESTROY_ELEMENTPAST22]], i64 -1, !dbg [[DBG182]] +// DEBUG2-NEXT: call void @_ZN2S1D1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYDESTROY_ELEMENT23]]) #[[ATTR4]], !dbg [[DBG182]] +// DEBUG2-NEXT: [[ARRAYDESTROY_DONE24:%.*]] = icmp eq ptr [[ARRAYDESTROY_ELEMENT23]], [[PAD_ARRAYBEGIN]], !dbg [[DBG182]] +// DEBUG2-NEXT: br i1 [[ARRAYDESTROY_DONE24]], label [[ARRAYDESTROY_DONE25]], label [[ARRAYDESTROY_BODY21]], !dbg [[DBG182]] +// DEBUG2: arraydestroy.done25: // DEBUG2-NEXT: br label [[EH_RESUME:%.*]], !dbg [[DBG182]] // DEBUG2: eh.resume: // DEBUG2-NEXT: [[EXN:%.*]] = load ptr, ptr [[EXN_SLOT]], align 8, !dbg [[DBG182]] // DEBUG2-NEXT: [[SEL:%.*]] = load i32, ptr [[EHSELECTOR_SLOT]], align 4, !dbg [[DBG182]] // DEBUG2-NEXT: [[LPAD_VAL:%.*]] = insertvalue { ptr, i32 } poison, ptr [[EXN]], 0, !dbg [[DBG182]] -// DEBUG2-NEXT: [[LPAD_VAL28:%.*]] = insertvalue { ptr, i32 } [[LPAD_VAL]], i32 [[SEL]], 1, !dbg [[DBG182]] -// DEBUG2-NEXT: resume { ptr, i32 } [[LPAD_VAL28]], !dbg [[DBG182]] +// DEBUG2-NEXT: [[LPAD_VAL26:%.*]] = insertvalue { ptr, i32 } [[LPAD_VAL]], i32 [[SEL]], 1, !dbg [[DBG182]] +// DEBUG2-NEXT: resume { ptr, i32 } [[LPAD_VAL26]], !dbg [[DBG182]] // // // DEBUG2-LABEL: define {{[^@]+}}@.__kmpc_global_dtor_..4 diff --git a/clang/test/PCH/cxx_paren_init.cpp b/clang/test/PCH/cxx_paren_init.cpp index 9731ea7737c198308fec9d4feb86d9f2fedb02d6..298e3161007ce2127fab338ca33e6e265dabd90b 100644 --- a/clang/test/PCH/cxx_paren_init.cpp +++ b/clang/test/PCH/cxx_paren_init.cpp @@ -16,14 +16,13 @@ U u = baz(3); // CHECK-NEXT: [[ARR:%.*]] = alloca [4 x i32], align 16 // CHECK-NEXT: store i32 [[A:%.*]], ptr [[I_ADDR]], align 4 // CHECK-NEXT: store i32 [[B:%.*]], ptr [[J_ADDR]], align 4 -// CHECK-NEXT: [[ARRINIT_BEGIN:%.*]] = getelementptr inbounds [4 x i32], ptr [[ARR]], i64 0, i64 0 // CHECK-NEXT: [[TMP_0:%.*]] = load i32, ptr [[I_ADDR]], align 4 -// CHECK-NEXT: store i32 [[TMP_0]], ptr [[ARRINIT_BEGIN]], align 4 -// CHECK-NEXT: [[ARRINIT_ELEM:%.*]] = getelementptr inbounds i32, ptr [[ARRINIT_BEGIN]], i64 1 +// CHECK-NEXT: store i32 [[TMP_0]], ptr [[ARR]], align 4 +// CHECK-NEXT: [[ARRINIT_ELEM:%.*]] = getelementptr inbounds i32, ptr [[ARR]], i64 1 // CHECK-NEXT: [[TMP_1:%.*]] = load i32, ptr [[J_ADDR]], align 4 // CHECK-NEXT: store i32 [[TMP_1]], ptr [[ARRINIT_ELEM]], align 4 -// CHECK-NEXT: [[ARRINIT_START:%.*]] = getelementptr inbounds i32, ptr [[ARRINIT_ELEM]], i64 1 -// CHECK-NEXT: [[ARRINIT_END:%.*]] = getelementptr inbounds i32, ptr [[ARRINIT_BEGIN]], i64 4 +// CHECK-NEXT: [[ARRINIT_START:%.*]] = getelementptr inbounds i32, ptr [[ARR]], i64 2 +// CHECK-NEXT: [[ARRINIT_END:%.*]] = getelementptr inbounds i32, ptr [[ARR]], i64 4 // CHECK-NEXT: br label [[ARRINIT_BODY:%.*]] // CHECK: [[ARRINIT_CUR:%.*]] = phi ptr [ [[ARRINIT_START]], %entry ], [ [[ARRINIT_NEXT:%.*]], [[ARRINIT_BODY]] ] // CHECK-NEXT: store i32 0, ptr [[ARRINIT_CUR]], align 4 diff --git a/clang/test/ParserOpenACC/parse-clauses.c b/clang/test/ParserOpenACC/parse-clauses.c index 49e749feb2ec7e3df2bfe75640d483fb697ca95d..15c4554a31922a1341b7c99a970a6afe8855f383 100644 --- a/clang/test/ParserOpenACC/parse-clauses.c +++ b/clang/test/ParserOpenACC/parse-clauses.c @@ -23,10 +23,10 @@ void func() { // expected-warning@+1{{OpenACC construct 'enter data' not yet implemented, pragma ignored}} #pragma acc enter data finalize invalid invalid finalize - // expected-warning@+3{{OpenACC clause 'seq' not yet implemented, clause ignored}} + // expected-warning@+3{{OpenACC clause 'wait' not yet implemented, clause ignored}} // expected-warning@+2{{OpenACC clause 'finalize' not yet implemented, clause ignored}} // expected-warning@+1{{OpenACC construct 'enter data' not yet implemented, pragma ignored}} -#pragma acc enter data seq finalize +#pragma acc enter data wait finalize // expected-warning@+2{{OpenACC clause 'if_present' not yet implemented, clause ignored}} // expected-warning@+1{{OpenACC construct 'host_data' not yet implemented, pragma ignored}} @@ -37,23 +37,26 @@ void func() { // expected-warning@+1{{OpenACC construct 'host_data' not yet implemented, pragma ignored}} #pragma acc host_data if_present, if_present - // expected-warning@+4{{OpenACC clause 'seq' not yet implemented, clause ignored}} - // expected-warning@+3{{OpenACC clause 'independent' not yet implemented, clause ignored}} - // expected-warning@+2{{OpenACC clause 'auto' not yet implemented, clause ignored}} - // expected-warning@+1{{OpenACC construct 'loop' not yet implemented, pragma ignored}} + // expected-error@+4{{OpenACC clause 'independent' on 'loop' construct conflicts with previous data dependence clause}} + // expected-note@+3{{previous clause is here}} + // expected-error@+2{{OpenACC clause 'auto' on 'loop' construct conflicts with previous data dependence clause}} + // expected-note@+1{{previous clause is here}} #pragma acc loop seq independent auto + for(;;){} - // expected-warning@+4{{OpenACC clause 'seq' not yet implemented, clause ignored}} - // expected-warning@+3{{OpenACC clause 'independent' not yet implemented, clause ignored}} - // expected-warning@+2{{OpenACC clause 'auto' not yet implemented, clause ignored}} - // expected-warning@+1{{OpenACC construct 'loop' not yet implemented, pragma ignored}} + // expected-error@+4{{OpenACC clause 'independent' on 'loop' construct conflicts with previous data dependence clause}} + // expected-note@+3{{previous clause is here}} + // expected-error@+2{{OpenACC clause 'auto' on 'loop' construct conflicts with previous data dependence clause}} + // expected-note@+1{{previous clause is here}} #pragma acc loop seq, independent auto + for(;;){} - // expected-warning@+4{{OpenACC clause 'seq' not yet implemented, clause ignored}} - // expected-warning@+3{{OpenACC clause 'independent' not yet implemented, clause ignored}} - // expected-warning@+2{{OpenACC clause 'auto' not yet implemented, clause ignored}} - // expected-warning@+1{{OpenACC construct 'loop' not yet implemented, pragma ignored}} + // expected-error@+4{{OpenACC clause 'independent' on 'loop' construct conflicts with previous data dependence clause}} + // expected-note@+3{{previous clause is here}} + // expected-error@+2{{OpenACC clause 'auto' on 'loop' construct conflicts with previous data dependence clause}} + // expected-note@+1{{previous clause is here}} #pragma acc loop seq independent, auto + for(;;){} // expected-warning@+4{{OpenACC clause 'seq' not yet implemented, clause ignored}} // expected-warning@+3{{OpenACC clause 'independent' not yet implemented, clause ignored}} @@ -67,65 +70,56 @@ void func() { // expected-warning@+2{{OpenACC clause 'auto' not yet implemented, clause ignored}} // expected-warning@+1{{OpenACC construct 'serial loop' not yet implemented, pragma ignored}} #pragma acc serial loop seq, independent auto - {} + for(;;){} // expected-warning@+4{{OpenACC clause 'seq' not yet implemented, clause ignored}} // expected-warning@+3{{OpenACC clause 'independent' not yet implemented, clause ignored}} // expected-warning@+2{{OpenACC clause 'auto' not yet implemented, clause ignored}} // expected-warning@+1{{OpenACC construct 'parallel loop' not yet implemented, pragma ignored}} #pragma acc parallel loop seq independent, auto - {} + for(;;){} - // expected-error@+2{{expected identifier}} - // expected-warning@+1{{OpenACC construct 'loop' not yet implemented, pragma ignored}} + // expected-error@+1{{expected identifier}} #pragma acc loop , seq + for(;;){} - // expected-error@+3{{expected identifier}} - // expected-warning@+2{{OpenACC clause 'seq' not yet implemented, clause ignored}} - // expected-warning@+1{{OpenACC construct 'loop' not yet implemented, pragma ignored}} + // expected-error@+1{{expected identifier}} #pragma acc loop seq, + for(;;){} - // expected-error@+2{{expected '('}} - // expected-warning@+1{{OpenACC construct 'loop' not yet implemented, pragma ignored}} + // expected-error@+1{{expected '('}} #pragma acc loop collapse for(;;){} - // expected-error@+2{{expected expression}} - // expected-warning@+1{{OpenACC construct 'loop' not yet implemented, pragma ignored}} + // expected-error@+1{{expected expression}} #pragma acc loop collapse() for(;;){} - // expected-error@+3{{invalid tag 'unknown' on 'collapse' clause}} - // expected-error@+2{{expected expression}} - // expected-warning@+1{{OpenACC construct 'loop' not yet implemented, pragma ignored}} + // expected-error@+2{{invalid tag 'unknown' on 'collapse' clause}} + // expected-error@+1{{expected expression}} #pragma acc loop collapse(unknown:) for(;;){} - // expected-error@+2{{expected expression}} - // expected-warning@+1{{OpenACC construct 'loop' not yet implemented, pragma ignored}} + // expected-error@+1{{expected expression}} #pragma acc loop collapse(force:) for(;;){} - // expected-error@+3{{invalid tag 'unknown' on 'collapse' clause}} - // expected-warning@+2{{OpenACC clause 'collapse' not yet implemented, clause ignored}} - // expected-warning@+1{{OpenACC construct 'loop' not yet implemented, pragma ignored}} + // expected-error@+2{{invalid tag 'unknown' on 'collapse' clause}} + // expected-warning@+1{{OpenACC clause 'collapse' not yet implemented, clause ignored}} #pragma acc loop collapse(unknown:5) for(;;){} - // expected-warning@+2{{OpenACC clause 'collapse' not yet implemented, clause ignored}} - // expected-warning@+1{{OpenACC construct 'loop' not yet implemented, pragma ignored}} + // expected-warning@+1{{OpenACC clause 'collapse' not yet implemented, clause ignored}} #pragma acc loop collapse(force:5) for(;;){} - // expected-warning@+2{{OpenACC clause 'collapse' not yet implemented, clause ignored}} - // expected-warning@+1{{OpenACC construct 'loop' not yet implemented, pragma ignored}} + // expected-warning@+1{{OpenACC clause 'collapse' not yet implemented, clause ignored}} #pragma acc loop collapse(5) for(;;){} - // expected-error@+3{{expected ')'}} - // expected-note@+2{{to match this '('}} - // expected-warning@+1{{OpenACC construct 'loop' not yet implemented, pragma ignored}} + // expected-error@+2{{expected ')'}} + // expected-note@+1{{to match this '('}} #pragma acc loop collapse(5, 6) for(;;){} } @@ -137,12 +131,11 @@ void DefaultClause() { for(;;){} // expected-error@+1{{expected '('}} -#pragma acc serial default seq +#pragma acc serial default self for(;;){} - // expected-error@+2{{expected '('}} - // expected-warning@+1{{OpenACC clause 'seq' not yet implemented, clause ignored}} -#pragma acc serial default, seq + // expected-error@+1{{expected '('}} +#pragma acc serial default, self for(;;){} // expected-error@+3{{expected identifier}} @@ -154,13 +147,13 @@ void DefaultClause() { // expected-error@+3{{invalid value for 'default' clause; expected 'present' or 'none'}} // expected-error@+2{{expected ')'}} // expected-note@+1{{to match this '('}} -#pragma acc serial default( seq +#pragma acc serial default( self for(;;){} // expected-error@+3{{expected identifier}} // expected-error@+2{{expected ')'}} // expected-note@+1{{to match this '('}} -#pragma acc serial default(, seq +#pragma acc serial default(, self for(;;){} // expected-error@+2{{expected '('}} @@ -170,58 +163,53 @@ void DefaultClause() { // expected-error@+2{{expected '('}} // expected-error@+1{{expected identifier}} -#pragma acc serial default), seq +#pragma acc serial default), self for(;;){} // expected-error@+1{{expected identifier}} #pragma acc serial default() for(;;){} - // expected-error@+2{{expected identifier}} - // expected-warning@+1{{OpenACC clause 'seq' not yet implemented, clause ignored}} -#pragma acc serial default() seq + // expected-error@+1{{expected identifier}} +#pragma acc serial default() self for(;;){} - // expected-error@+2{{expected identifier}} - // expected-warning@+1{{OpenACC clause 'seq' not yet implemented, clause ignored}} -#pragma acc serial default(), seq + // expected-error@+1{{expected identifier}} +#pragma acc serial default(), self for(;;){} // expected-error@+1{{invalid value for 'default' clause; expected 'present' or 'none'}} #pragma acc serial default(invalid) for(;;){} - // expected-error@+2{{invalid value for 'default' clause; expected 'present' or 'none'}} - // expected-warning@+1{{OpenACC clause 'seq' not yet implemented, clause ignored}} -#pragma acc serial default(auto) seq + // expected-error@+1{{invalid value for 'default' clause; expected 'present' or 'none'}} +#pragma acc serial default(auto) self for(;;){} - // expected-error@+2{{invalid value for 'default' clause; expected 'present' or 'none'}} - // expected-warning@+1{{OpenACC clause 'seq' not yet implemented, clause ignored}} -#pragma acc serial default(invalid), seq + // expected-error@+1{{invalid value for 'default' clause; expected 'present' or 'none'}} +#pragma acc serial default(invalid), self for(;;){} #pragma acc serial default(none) for(;;){} - // expected-warning@+1{{OpenACC clause 'seq' not yet implemented, clause ignored}} -#pragma acc serial default(present), seq +#pragma acc serial default(present), self for(;;){} } void IfClause() { + int i, j; // expected-error@+2{{expected '('}} // expected-warning@+1{{OpenACC construct 'serial loop' not yet implemented, pragma ignored}} #pragma acc serial loop if for(;;){} // expected-error@+1{{expected '('}} -#pragma acc serial if seq +#pragma acc serial if private(i) for(;;){} - // expected-error@+2{{expected '('}} - // expected-warning@+1{{OpenACC clause 'seq' not yet implemented, clause ignored}} -#pragma acc serial if, seq + // expected-error@+1{{expected '('}} +#pragma acc serial if, private(i) for(;;){} // expected-error@+3{{expected expression}} @@ -230,17 +218,17 @@ void IfClause() { #pragma acc serial if( for(;;){} - // expected-error@+3{{use of undeclared identifier 'seq'}} + // expected-error@+3{{use of undeclared identifier 'self'}} // expected-error@+2{{expected ')'}} // expected-note@+1{{to match this '('}} -#pragma acc serial if( seq +#pragma acc serial if( self for(;;){} // expected-error@+4{{expected expression}} - // expected-error@+3{{use of undeclared identifier 'seq'}} + // expected-error@+3{{use of undeclared identifier 'self'}} // expected-error@+2{{expected ')'}} // expected-note@+1{{to match this '('}} -#pragma acc serial if(, seq +#pragma acc serial if(, self for(;;){} // expected-error@+2{{expected '('}} @@ -250,44 +238,38 @@ void IfClause() { // expected-error@+2{{expected '('}} // expected-error@+1{{expected identifier}} -#pragma acc serial if) seq +#pragma acc serial if) private(i) for(;;){} // expected-error@+2{{expected '('}} // expected-error@+1{{expected identifier}} -#pragma acc serial if), seq +#pragma acc serial if), private(i) for(;;){} // expected-error@+1{{expected expression}} #pragma acc serial if() for(;;){} - // expected-error@+2{{expected expression}} - // expected-warning@+1{{OpenACC clause 'seq' not yet implemented, clause ignored}} -#pragma acc serial if() seq + // expected-error@+1{{expected expression}} +#pragma acc serial if() private(i) for(;;){} - // expected-error@+2{{expected expression}} - // expected-warning@+1{{OpenACC clause 'seq' not yet implemented, clause ignored}} -#pragma acc serial if(), seq + // expected-error@+1{{expected expression}} +#pragma acc serial if(), private(i) for(;;){} // expected-error@+1{{use of undeclared identifier 'invalid_expr'}} #pragma acc serial if(invalid_expr) for(;;){} - // expected-error@+2{{expected expression}} - // expected-warning@+1{{OpenACC clause 'seq' not yet implemented, clause ignored}} -#pragma acc serial if() seq + // expected-error@+1{{expected expression}} +#pragma acc serial if() private(i) for(;;){} - int i, j; - #pragma acc serial if(i > j) for(;;){} - // expected-warning@+1{{OpenACC clause 'seq' not yet implemented, clause ignored}} -#pragma acc serial if(1+5>3), seq +#pragma acc serial if(1+5>3), private(i) for(;;){} } @@ -298,8 +280,8 @@ void SelfClause() { for(;;){} // expected-warning@+3{{OpenACC clause 'self' not yet implemented, clause ignored}} - // expected-warning@+2{{OpenACC clause 'seq' not yet implemented, clause ignored}} - // expected-warning@+1{{OpenACC construct 'serial loop' not yet implemented, pragma ignored}} + // expected-warning@+2{{OpenACC construct 'serial loop' not yet implemented, pragma ignored}} + // expected-warning@+1{{OpenACC clause 'seq' not yet implemented, clause ignored}} #pragma acc serial loop self, seq for(;;){} @@ -345,21 +327,21 @@ void SelfClause() { // expected-error@+3{{expected expression}} - // expected-warning@+2{{OpenACC clause 'seq' not yet implemented, clause ignored}} - // expected-warning@+1{{OpenACC construct 'serial loop' not yet implemented, pragma ignored}} + // expected-warning@+2{{OpenACC construct 'serial loop' not yet implemented, pragma ignored}} + // expected-warning@+1{{OpenACC clause 'seq' not yet implemented, clause ignored}} #pragma acc serial loop self(), seq for(;;){} // expected-error@+4{{expected expression}} // expected-error@+3{{expected expression}} - // expected-warning@+2{{OpenACC clause 'seq' not yet implemented, clause ignored}} - // expected-warning@+1{{OpenACC construct 'serial loop' not yet implemented, pragma ignored}} + // expected-warning@+2{{OpenACC construct 'serial loop' not yet implemented, pragma ignored}} + // expected-warning@+1{{OpenACC clause 'seq' not yet implemented, clause ignored}} #pragma acc serial loop self(,), seq for(;;){} // expected-error@+3{{use of undeclared identifier 'invalid_expr'}} - // expected-warning@+2{{OpenACC clause 'seq' not yet implemented, clause ignored}} - // expected-warning@+1{{OpenACC construct 'serial loop' not yet implemented, pragma ignored}} + // expected-warning@+2{{OpenACC construct 'serial loop' not yet implemented, pragma ignored}} + // expected-warning@+1{{OpenACC clause 'seq' not yet implemented, clause ignored}} #pragma acc serial loop self(invalid_expr), seq for(;;){} @@ -383,8 +365,7 @@ void SelfClause() { #pragma acc serial self(i > j) for(;;){} - // expected-warning@+1{{OpenACC clause 'seq' not yet implemented, clause ignored}} -#pragma acc serial self(1+5>3), seq +#pragma acc serial self(1+5>3), private(i) for(;;){} } @@ -409,15 +390,15 @@ void SelfUpdate() { // expected-error@+5{{expected ','}} // expected-error@+4{{expected expression}} // expected-warning@+3{{OpenACC clause 'self' not yet implemented, clause ignored}} - // expected-warning@+2{{OpenACC clause 'seq' not yet implemented, clause ignored}} + // expected-warning@+2{{OpenACC clause 'if_present' not yet implemented, clause ignored}} // expected-warning@+1{{OpenACC construct 'update' not yet implemented, pragma ignored}} -#pragma acc update self(zero : s.array[s.value : 5], s.value), seq +#pragma acc update self(zero : s.array[s.value : 5], s.value), if_present for(;;){} // expected-warning@+3{{OpenACC clause 'self' not yet implemented, clause ignored}} - // expected-warning@+2{{OpenACC clause 'seq' not yet implemented, clause ignored}} + // expected-warning@+2{{OpenACC clause 'if_present' not yet implemented, clause ignored}} // expected-warning@+1{{OpenACC construct 'update' not yet implemented, pragma ignored}} -#pragma acc update self(s.array[s.value : 5], s.value), seq +#pragma acc update self(s.array[s.value : 5], s.value), if_present for(;;){} } @@ -426,9 +407,8 @@ void VarListClauses() { #pragma acc serial copy for(;;){} - // expected-error@+2{{expected '('}} - // expected-warning@+1{{OpenACC clause 'seq' not yet implemented, clause ignored}} -#pragma acc serial copy, seq + // expected-error@+1{{expected '('}} +#pragma acc serial copy, self for(;;){} // expected-error@+2{{expected '('}} @@ -438,7 +418,7 @@ void VarListClauses() { // expected-error@+2{{expected '('}} // expected-error@+1{{expected identifier}} -#pragma acc serial copy), seq +#pragma acc serial copy), self for(;;){} // expected-error@+3{{expected expression}} @@ -450,65 +430,54 @@ void VarListClauses() { // expected-error@+3{{expected expression}} // expected-error@+2{{expected ')'}} // expected-note@+1{{to match this '('}} -#pragma acc serial copy(, seq +#pragma acc serial copy(, self for(;;){} // expected-error@+1{{expected expression}} #pragma acc serial copy() for(;;){} - // expected-error@+2{{expected expression}} - // expected-warning@+1{{OpenACC clause 'seq' not yet implemented, clause ignored}} -#pragma acc serial copy(), seq + // expected-error@+1{{expected expression}} +#pragma acc serial copy(), self for(;;){} struct Members s; struct HasMembersArray HasMem; - // expected-warning@+1{{OpenACC clause 'seq' not yet implemented, clause ignored}} -#pragma acc serial copy(s.array[s.value]), seq +#pragma acc serial copy(s.array[s.value]), self for(;;){} - // expected-warning@+1{{OpenACC clause 'seq' not yet implemented, clause ignored}} -#pragma acc serial copy(s.array[s.value], s.array[s.value :5] ), seq +#pragma acc serial copy(s.array[s.value], s.array[s.value :5] ), self for(;;){} - // expected-warning@+1{{OpenACC clause 'seq' not yet implemented, clause ignored}} -#pragma acc serial copy(HasMem.MemArr[3].array[1]), seq +#pragma acc serial copy(HasMem.MemArr[3].array[1]), self for(;;){} - // expected-warning@+1{{OpenACC clause 'seq' not yet implemented, clause ignored}} -#pragma acc serial copy(HasMem.MemArr[3].array[1:4]), seq +#pragma acc serial copy(HasMem.MemArr[3].array[1:4]), self for(;;){} - // expected-error@+2{{OpenACC sub-array is not allowed here}} - // expected-warning@+1{{OpenACC clause 'seq' not yet implemented, clause ignored}} -#pragma acc serial copy(HasMem.MemArr[1:3].array[1]), seq + // expected-error@+1{{OpenACC sub-array is not allowed here}} +#pragma acc serial copy(HasMem.MemArr[1:3].array[1]), self for(;;){} - // expected-error@+2{{OpenACC sub-array is not allowed here}} - // expected-warning@+1{{OpenACC clause 'seq' not yet implemented, clause ignored}} -#pragma acc serial copy(HasMem.MemArr[1:3].array[1:2]), seq + // expected-error@+1{{OpenACC sub-array is not allowed here}} +#pragma acc serial copy(HasMem.MemArr[1:3].array[1:2]), self for(;;){} - // expected-warning@+1{{OpenACC clause 'seq' not yet implemented, clause ignored}} -#pragma acc serial copy(HasMem.MemArr[:]), seq +#pragma acc serial copy(HasMem.MemArr[:]), self for(;;){} - // expected-error@+2{{expected expression}} - // expected-warning@+1{{OpenACC clause 'seq' not yet implemented, clause ignored}} -#pragma acc serial copy(HasMem.MemArr[::]), seq + // expected-error@+1{{expected expression}} +#pragma acc serial copy(HasMem.MemArr[::]), self for(;;){} - // expected-error@+4{{expected expression}} - // expected-error@+3{{expected ']'}} - // expected-note@+2{{to match this '['}} - // expected-warning@+1{{OpenACC clause 'seq' not yet implemented, clause ignored}} -#pragma acc serial copy(HasMem.MemArr[: :]), seq + // expected-error@+3{{expected expression}} + // expected-error@+2{{expected ']'}} + // expected-note@+1{{to match this '['}} +#pragma acc serial copy(HasMem.MemArr[: :]), self for(;;){} - // expected-warning@+1{{OpenACC clause 'seq' not yet implemented, clause ignored}} -#pragma acc serial copy(HasMem.MemArr[3:]), seq +#pragma acc serial copy(HasMem.MemArr[3:]), self for(;;){} // expected-warning@+1{{OpenACC clause name 'pcopy' is a deprecated clause name and is now an alias for 'copy'}} @@ -519,167 +488,136 @@ void VarListClauses() { #pragma acc serial present_or_copy(HasMem.MemArr[3:]) for(;;){} - // expected-error@+3{{expected ','}} - // expected-warning@+2{{OpenACC clause 'use_device' not yet implemented, clause ignored}} - // expected-warning@+1{{OpenACC clause 'seq' not yet implemented, clause ignored}} -#pragma acc serial use_device(s.array[s.value] s.array[s.value :5] ), seq + // expected-error@+2{{expected ','}} + // expected-warning@+1{{OpenACC clause 'use_device' not yet implemented, clause ignored}} +#pragma acc serial use_device(s.array[s.value] s.array[s.value :5] ), self for(;;){} - // expected-warning@+2{{OpenACC clause 'use_device' not yet implemented, clause ignored}} - // expected-warning@+1{{OpenACC clause 'seq' not yet implemented, clause ignored}} -#pragma acc serial use_device(s.array[s.value : 5]), seq + // expected-warning@+1{{OpenACC clause 'use_device' not yet implemented, clause ignored}} +#pragma acc serial use_device(s.array[s.value : 5]), self for(;;){} - // expected-error@+2{{expected ','}} - // expected-warning@+1{{OpenACC clause 'seq' not yet implemented, clause ignored}} -#pragma acc serial no_create(s.array[s.value] s.array[s.value :5] ), seq + // expected-error@+1{{expected ','}} +#pragma acc serial no_create(s.array[s.value] s.array[s.value :5] ), self for(;;){} - // expected-warning@+1{{OpenACC clause 'seq' not yet implemented, clause ignored}} -#pragma acc serial no_create(s.array[s.value : 5], s.value), seq +#pragma acc serial no_create(s.array[s.value : 5], s.value), self for(;;){} - // expected-error@+2{{expected ','}} - // expected-warning@+1{{OpenACC clause 'seq' not yet implemented, clause ignored}} -#pragma acc serial present(s.array[s.value] s.array[s.value :5] ), seq + // expected-error@+1{{expected ','}} +#pragma acc serial present(s.array[s.value] s.array[s.value :5] ), self for(;;){} - // expected-warning@+1{{OpenACC clause 'seq' not yet implemented, clause ignored}} -#pragma acc serial present(s.array[s.value : 5], s.value), seq +#pragma acc serial present(s.array[s.value : 5], s.value), self for(;;){} void *IsPointer; - // expected-error@+5{{expected ','}} - // expected-error@+4{{expected pointer in 'deviceptr' clause, type is 'char'}} - // expected-error@+3{{OpenACC sub-array is not allowed here}} - // expected-note@+2{{expected variable of pointer type}} - // expected-warning@+1{{OpenACC clause 'seq' not yet implemented, clause ignored}} -#pragma acc serial deviceptr(s.array[s.value] s.array[s.value :5] ), seq + // expected-error@+4{{expected ','}} + // expected-error@+3{{expected pointer in 'deviceptr' clause, type is 'char'}} + // expected-error@+2{{OpenACC sub-array is not allowed here}} + // expected-note@+1{{expected variable of pointer type}} +#pragma acc serial deviceptr(s.array[s.value] s.array[s.value :5] ), self for(;;){} - // expected-warning@+1{{OpenACC clause 'seq' not yet implemented, clause ignored}} -#pragma acc serial deviceptr(IsPointer), seq +#pragma acc serial deviceptr(IsPointer), self for(;;){} - // expected-error@+5{{expected ','}} - // expected-error@+4{{expected pointer in 'attach' clause, type is 'char'}} - // expected-error@+3{{OpenACC sub-array is not allowed here}} - // expected-note@+2{{expected variable of pointer type}} - // expected-warning@+1{{OpenACC clause 'seq' not yet implemented, clause ignored}} -#pragma acc serial attach(s.array[s.value] s.array[s.value :5] ), seq + // expected-error@+4{{expected ','}} + // expected-error@+3{{expected pointer in 'attach' clause, type is 'char'}} + // expected-error@+2{{OpenACC sub-array is not allowed here}} + // expected-note@+1{{expected variable of pointer type}} +#pragma acc serial attach(s.array[s.value] s.array[s.value :5] ), self for(;;){} - // expected-warning@+1{{OpenACC clause 'seq' not yet implemented, clause ignored}} -#pragma acc serial attach(IsPointer), seq +#pragma acc serial attach(IsPointer), self for(;;){} - // expected-error@+3{{expected ','}} - // expected-warning@+2{{OpenACC clause 'detach' not yet implemented, clause ignored}} - // expected-warning@+1{{OpenACC clause 'seq' not yet implemented, clause ignored}} -#pragma acc serial detach(s.array[s.value] s.array[s.value :5] ), seq + // expected-error@+2{{expected ','}} + // expected-warning@+1{{OpenACC clause 'detach' not yet implemented, clause ignored}} +#pragma acc serial detach(s.array[s.value] s.array[s.value :5] ), self for(;;){} - // expected-warning@+2{{OpenACC clause 'detach' not yet implemented, clause ignored}} - // expected-warning@+1{{OpenACC clause 'seq' not yet implemented, clause ignored}} -#pragma acc serial detach(s.array[s.value : 5], s.value), seq + // expected-warning@+1{{OpenACC clause 'detach' not yet implemented, clause ignored}} +#pragma acc serial detach(s.array[s.value : 5], s.value), self for(;;){} - // expected-error@+2{{expected ','}} - // expected-warning@+1{{OpenACC clause 'seq' not yet implemented, clause ignored}} -#pragma acc serial private(s.array[s.value] s.array[s.value :5] ), seq + // expected-error@+1{{expected ','}} +#pragma acc serial private(s.array[s.value] s.array[s.value :5] ), self for(;;){} - // expected-warning@+1{{OpenACC clause 'seq' not yet implemented, clause ignored}} -#pragma acc serial private(s.array[s.value : 5], s.value), seq +#pragma acc serial private(s.array[s.value : 5], s.value), self for(;;){} - // expected-error@+2{{expected ','}} - // expected-warning@+1{{OpenACC clause 'seq' not yet implemented, clause ignored}} -#pragma acc serial firstprivate(s.array[s.value] s.array[s.value :5] ), seq + // expected-error@+1{{expected ','}} +#pragma acc serial firstprivate(s.array[s.value] s.array[s.value :5] ), self for(;;){} - // expected-warning@+1{{OpenACC clause 'seq' not yet implemented, clause ignored}} -#pragma acc serial firstprivate(s.array[s.value : 5], s.value), seq +#pragma acc serial firstprivate(s.array[s.value : 5], s.value), self for(;;){} - // expected-error@+3{{expected ','}} - // expected-warning@+2{{OpenACC clause 'delete' not yet implemented, clause ignored}} - // expected-warning@+1{{OpenACC clause 'seq' not yet implemented, clause ignored}} -#pragma acc serial delete(s.array[s.value] s.array[s.value :5] ), seq + // expected-error@+2{{expected ','}} + // expected-warning@+1{{OpenACC clause 'delete' not yet implemented, clause ignored}} +#pragma acc serial delete(s.array[s.value] s.array[s.value :5] ), self for(;;){} - // expected-warning@+2{{OpenACC clause 'delete' not yet implemented, clause ignored}} - // expected-warning@+1{{OpenACC clause 'seq' not yet implemented, clause ignored}} -#pragma acc serial delete(s.array[s.value : 5], s.value), seq + // expected-warning@+1{{OpenACC clause 'delete' not yet implemented, clause ignored}} +#pragma acc serial delete(s.array[s.value : 5], s.value), self for(;;){} - // expected-error@+3{{expected ','}} - // expected-warning@+2{{OpenACC clause 'use_device' not yet implemented, clause ignored}} - // expected-warning@+1{{OpenACC clause 'seq' not yet implemented, clause ignored}} -#pragma acc serial use_device(s.array[s.value] s.array[s.value :5] ), seq + // expected-error@+2{{expected ','}} + // expected-warning@+1{{OpenACC clause 'use_device' not yet implemented, clause ignored}} +#pragma acc serial use_device(s.array[s.value] s.array[s.value :5] ), self for(;;){} - // expected-warning@+2{{OpenACC clause 'use_device' not yet implemented, clause ignored}} - // expected-warning@+1{{OpenACC clause 'seq' not yet implemented, clause ignored}} -#pragma acc serial use_device(s.array[s.value : 5], s.value), seq + // expected-warning@+1{{OpenACC clause 'use_device' not yet implemented, clause ignored}} +#pragma acc serial use_device(s.array[s.value : 5], s.value), self for(;;){} - // expected-error@+3{{expected ','}} - // expected-warning@+2{{OpenACC clause 'device_resident' not yet implemented, clause ignored}} - // expected-warning@+1{{OpenACC clause 'seq' not yet implemented, clause ignored}} -#pragma acc serial device_resident(s.array[s.value] s.array[s.value :5] ), seq + // expected-error@+2{{expected ','}} + // expected-warning@+1{{OpenACC clause 'device_resident' not yet implemented, clause ignored}} +#pragma acc serial device_resident(s.array[s.value] s.array[s.value :5] ), self for(;;){} - // expected-warning@+2{{OpenACC clause 'device_resident' not yet implemented, clause ignored}} - // expected-warning@+1{{OpenACC clause 'seq' not yet implemented, clause ignored}} -#pragma acc serial device_resident(s.array[s.value : 5], s.value), seq + // expected-warning@+1{{OpenACC clause 'device_resident' not yet implemented, clause ignored}} +#pragma acc serial device_resident(s.array[s.value : 5], s.value), self for(;;){} - // expected-error@+3{{expected ','}} - // expected-warning@+2{{OpenACC clause 'link' not yet implemented, clause ignored}} - // expected-warning@+1{{OpenACC clause 'seq' not yet implemented, clause ignored}} -#pragma acc serial link(s.array[s.value] s.array[s.value :5] ), seq + // expected-error@+2{{expected ','}} + // expected-warning@+1{{OpenACC clause 'link' not yet implemented, clause ignored}} +#pragma acc serial link(s.array[s.value] s.array[s.value :5] ), self for(;;){} - // expected-warning@+2{{OpenACC clause 'link' not yet implemented, clause ignored}} - // expected-warning@+1{{OpenACC clause 'seq' not yet implemented, clause ignored}} -#pragma acc serial link(s.array[s.value : 5], s.value), seq + // expected-warning@+1{{OpenACC clause 'link' not yet implemented, clause ignored}} +#pragma acc serial link(s.array[s.value : 5], s.value), self for(;;){} - // expected-error@+3{{expected ','}} - // expected-warning@+2{{OpenACC clause 'host' not yet implemented, clause ignored}} - // expected-warning@+1{{OpenACC clause 'seq' not yet implemented, clause ignored}} -#pragma acc serial host(s.array[s.value] s.array[s.value :5] ), seq + // expected-error@+2{{expected ','}} + // expected-warning@+1{{OpenACC clause 'host' not yet implemented, clause ignored}} +#pragma acc serial host(s.array[s.value] s.array[s.value :5] ), self for(;;){} - // expected-warning@+2{{OpenACC clause 'host' not yet implemented, clause ignored}} - // expected-warning@+1{{OpenACC clause 'seq' not yet implemented, clause ignored}} -#pragma acc serial host(s.array[s.value : 5], s.value), seq + // expected-warning@+1{{OpenACC clause 'host' not yet implemented, clause ignored}} +#pragma acc serial host(s.array[s.value : 5], s.value), self for(;;){} - // expected-error@+3{{expected ','}} - // expected-warning@+2{{OpenACC clause 'device' not yet implemented, clause ignored}} - // expected-warning@+1{{OpenACC clause 'seq' not yet implemented, clause ignored}} -#pragma acc serial device(s.array[s.value] s.array[s.value :5] ), seq + // expected-error@+2{{expected ','}} + // expected-warning@+1{{OpenACC clause 'device' not yet implemented, clause ignored}} +#pragma acc serial device(s.array[s.value] s.array[s.value :5] ), self for(;;){} - // expected-warning@+2{{OpenACC clause 'device' not yet implemented, clause ignored}} - // expected-warning@+1{{OpenACC clause 'seq' not yet implemented, clause ignored}} -#pragma acc serial device(s.array[s.value : 5], s.value), seq + // expected-warning@+1{{OpenACC clause 'device' not yet implemented, clause ignored}} +#pragma acc serial device(s.array[s.value : 5], s.value), self for(;;){} - // expected-error@+2{{expected ','}} - // expected-warning@+1{{OpenACC clause 'seq' not yet implemented, clause ignored}} -#pragma acc serial copyout(s.array[s.value] s.array[s.value :5] ), seq + // expected-error@+1{{expected ','}} +#pragma acc serial copyout(s.array[s.value] s.array[s.value :5] ), self for(;;){} - // expected-warning@+1{{OpenACC clause 'seq' not yet implemented, clause ignored}} -#pragma acc serial copyout(s.array[s.value : 5], s.value), seq +#pragma acc serial copyout(s.array[s.value : 5], s.value), self for(;;){} - // expected-warning@+1{{OpenACC clause 'seq' not yet implemented, clause ignored}} -#pragma acc serial copyout(zero:s.array[s.value : 5], s.value), seq +#pragma acc serial copyout(zero:s.array[s.value : 5], s.value), self for(;;){} // expected-warning@+1{{OpenACC clause name 'pcopyout' is a deprecated clause name and is now an alias for 'copyout'}} @@ -690,48 +628,39 @@ void VarListClauses() { #pragma acc serial present_or_copyout(zero:s.array[s.value : 5], s.value) for(;;){} - // expected-warning@+1{{OpenACC clause 'seq' not yet implemented, clause ignored}} -#pragma acc serial copyout(zero : s.array[s.value : 5], s.value), seq +#pragma acc serial copyout(zero : s.array[s.value : 5], s.value), self for(;;){} - // expected-error@+3{{use of undeclared identifier 'zero'}} - // expected-error@+2{{expected ','}} - // expected-warning@+1{{OpenACC clause 'seq' not yet implemented, clause ignored}} -#pragma acc serial copyout(zero s.array[s.value : 5], s.value), seq + // expected-error@+2{{use of undeclared identifier 'zero'}} + // expected-error@+1{{expected ','}} +#pragma acc serial copyout(zero s.array[s.value : 5], s.value), self for(;;){} - // expected-error@+2{{invalid tag 'readonly' on 'copyout' clause}} - // expected-warning@+1{{OpenACC clause 'seq' not yet implemented, clause ignored}} -#pragma acc serial copyout(readonly:s.array[s.value : 5], s.value), seq + // expected-error@+1{{invalid tag 'readonly' on 'copyout' clause}} +#pragma acc serial copyout(readonly:s.array[s.value : 5], s.value), self for(;;){} - // expected-error@+2{{invalid tag 'invalid' on 'copyout' clause}} - // expected-warning@+1{{OpenACC clause 'seq' not yet implemented, clause ignored}} -#pragma acc serial copyout(invalid:s.array[s.value : 5], s.value), seq + // expected-error@+1{{invalid tag 'invalid' on 'copyout' clause}} +#pragma acc serial copyout(invalid:s.array[s.value : 5], s.value), self for(;;){} - // expected-error@+2{{invalid tag 'invalid' on 'copyout' clause}} - // expected-warning@+1{{OpenACC clause 'seq' not yet implemented, clause ignored}} -#pragma acc serial copyout(invalid:s.array[s.value : 5], s.value), seq + // expected-error@+1{{invalid tag 'invalid' on 'copyout' clause}} +#pragma acc serial copyout(invalid:s.array[s.value : 5], s.value), self for(;;){} - // expected-error@+3{{use of undeclared identifier 'invalid'}} - // expected-error@+2{{expected ','}} - // expected-warning@+1{{OpenACC clause 'seq' not yet implemented, clause ignored}} -#pragma acc serial copyout(invalid s.array[s.value : 5], s.value), seq + // expected-error@+2{{use of undeclared identifier 'invalid'}} + // expected-error@+1{{expected ','}} +#pragma acc serial copyout(invalid s.array[s.value : 5], s.value), self for(;;){} - // expected-error@+2{{expected ','}} - // expected-warning@+1{{OpenACC clause 'seq' not yet implemented, clause ignored}} -#pragma acc serial create(s.array[s.value] s.array[s.value :5] ), seq + // expected-error@+1{{expected ','}} +#pragma acc serial create(s.array[s.value] s.array[s.value :5] ), self for(;;){} - // expected-warning@+1{{OpenACC clause 'seq' not yet implemented, clause ignored}} -#pragma acc serial create(s.array[s.value : 5], s.value), seq +#pragma acc serial create(s.array[s.value : 5], s.value), self for(;;){} - // expected-warning@+1{{OpenACC clause 'seq' not yet implemented, clause ignored}} -#pragma acc serial create(zero:s.array[s.value : 5], s.value), seq +#pragma acc serial create(zero:s.array[s.value : 5], s.value), self for(;;){} // expected-warning@+1{{OpenACC clause name 'pcreate' is a deprecated clause name and is now an alias for 'create'}} @@ -742,48 +671,39 @@ void VarListClauses() { #pragma acc serial present_or_create(zero:s.array[s.value : 5], s.value) for(;;){} - // expected-warning@+1{{OpenACC clause 'seq' not yet implemented, clause ignored}} -#pragma acc serial create(zero : s.array[s.value : 5], s.value), seq +#pragma acc serial create(zero : s.array[s.value : 5], s.value), self for(;;){} - // expected-error@+3{{use of undeclared identifier 'zero'}} - // expected-error@+2{{expected ','}} - // expected-warning@+1{{OpenACC clause 'seq' not yet implemented, clause ignored}} -#pragma acc serial create(zero s.array[s.value : 5], s.value), seq + // expected-error@+2{{use of undeclared identifier 'zero'}} + // expected-error@+1{{expected ','}} +#pragma acc serial create(zero s.array[s.value : 5], s.value), self for(;;){} - // expected-error@+2{{invalid tag 'readonly' on 'create' clause}} - // expected-warning@+1{{OpenACC clause 'seq' not yet implemented, clause ignored}} -#pragma acc serial create(readonly:s.array[s.value : 5], s.value), seq + // expected-error@+1{{invalid tag 'readonly' on 'create' clause}} +#pragma acc serial create(readonly:s.array[s.value : 5], s.value), self for(;;){} - // expected-error@+2{{invalid tag 'invalid' on 'create' clause}} - // expected-warning@+1{{OpenACC clause 'seq' not yet implemented, clause ignored}} -#pragma acc serial create(invalid:s.array[s.value : 5], s.value), seq + // expected-error@+1{{invalid tag 'invalid' on 'create' clause}} +#pragma acc serial create(invalid:s.array[s.value : 5], s.value), self for(;;){} - // expected-error@+2{{invalid tag 'invalid' on 'create' clause}} - // expected-warning@+1{{OpenACC clause 'seq' not yet implemented, clause ignored}} -#pragma acc serial create(invalid:s.array[s.value : 5], s.value), seq + // expected-error@+1{{invalid tag 'invalid' on 'create' clause}} +#pragma acc serial create(invalid:s.array[s.value : 5], s.value), self for(;;){} - // expected-error@+3{{use of undeclared identifier 'invalid'}} - // expected-error@+2{{expected ','}} - // expected-warning@+1{{OpenACC clause 'seq' not yet implemented, clause ignored}} -#pragma acc serial create(invalid s.array[s.value : 5], s.value), seq + // expected-error@+2{{use of undeclared identifier 'invalid'}} + // expected-error@+1{{expected ','}} +#pragma acc serial create(invalid s.array[s.value : 5], s.value), self for(;;){} - // expected-error@+2{{expected ','}} - // expected-warning@+1{{OpenACC clause 'seq' not yet implemented, clause ignored}} -#pragma acc serial copyin(s.array[s.value] s.array[s.value :5] ), seq + // expected-error@+1{{expected ','}} +#pragma acc serial copyin(s.array[s.value] s.array[s.value :5] ), self for(;;){} - // expected-warning@+1{{OpenACC clause 'seq' not yet implemented, clause ignored}} -#pragma acc serial copyin(s.array[s.value : 5], s.value), seq +#pragma acc serial copyin(s.array[s.value : 5], s.value), self for(;;){} - // expected-warning@+1{{OpenACC clause 'seq' not yet implemented, clause ignored}} -#pragma acc serial copyin(readonly:s.array[s.value : 5], s.value), seq +#pragma acc serial copyin(readonly:s.array[s.value : 5], s.value), self for(;;){} // expected-warning@+1{{OpenACC clause name 'pcopyin' is a deprecated clause name and is now an alias for 'copyin'}} @@ -794,35 +714,29 @@ void VarListClauses() { #pragma acc serial present_or_copyin(readonly:s.array[s.value : 5], s.value) for(;;){} - // expected-warning@+1{{OpenACC clause 'seq' not yet implemented, clause ignored}} -#pragma acc serial copyin(readonly : s.array[s.value : 5], s.value), seq +#pragma acc serial copyin(readonly : s.array[s.value : 5], s.value), self for(;;){} - // expected-error@+3{{use of undeclared identifier 'readonly'}} - // expected-error@+2{{expected ','}} - // expected-warning@+1{{OpenACC clause 'seq' not yet implemented, clause ignored}} -#pragma acc serial copyin(readonly s.array[s.value : 5], s.value), seq + // expected-error@+2{{use of undeclared identifier 'readonly'}} + // expected-error@+1{{expected ','}} +#pragma acc serial copyin(readonly s.array[s.value : 5], s.value), self for(;;){} - // expected-error@+2{{invalid tag 'zero' on 'copyin' clause}} - // expected-warning@+1{{OpenACC clause 'seq' not yet implemented, clause ignored}} -#pragma acc serial copyin(zero :s.array[s.value : 5], s.value), seq + // expected-error@+1{{invalid tag 'zero' on 'copyin' clause}} +#pragma acc serial copyin(zero :s.array[s.value : 5], s.value), self for(;;){} - // expected-error@+2{{invalid tag 'invalid' on 'copyin' clause}} - // expected-warning@+1{{OpenACC clause 'seq' not yet implemented, clause ignored}} -#pragma acc serial copyin(invalid:s.array[s.value : 5], s.value), seq + // expected-error@+1{{invalid tag 'invalid' on 'copyin' clause}} +#pragma acc serial copyin(invalid:s.array[s.value : 5], s.value), self for(;;){} - // expected-error@+2{{invalid tag 'invalid' on 'copyin' clause}} - // expected-warning@+1{{OpenACC clause 'seq' not yet implemented, clause ignored}} -#pragma acc serial copyin(invalid:s.array[s.value : 5], s.value), seq + // expected-error@+1{{invalid tag 'invalid' on 'copyin' clause}} +#pragma acc serial copyin(invalid:s.array[s.value : 5], s.value), self for(;;){} - // expected-error@+3{{use of undeclared identifier 'invalid'}} - // expected-error@+2{{expected ','}} - // expected-warning@+1{{OpenACC clause 'seq' not yet implemented, clause ignored}} -#pragma acc serial copyin(invalid s.array[s.value : 5], s.value), seq + // expected-error@+2{{use of undeclared identifier 'invalid'}} + // expected-error@+1{{expected ','}} +#pragma acc serial copyin(invalid s.array[s.value : 5], s.value), self for(;;){} } @@ -860,11 +774,9 @@ void ReductionClauseParsing() { for(;;){} #pragma acc serial reduction(^: Begin, End) for(;;){} - // expected-warning@+1{{OpenACC clause 'seq' not yet implemented, clause ignored}} -#pragma acc serial seq, reduction(&&: Begin, End) +#pragma acc serial self, reduction(&&: Begin, End) for(;;){} - // expected-warning@+1{{OpenACC clause 'seq' not yet implemented, clause ignored}} -#pragma acc serial reduction(||: Begin, End), seq +#pragma acc serial reduction(||: Begin, End), self for(;;){} } @@ -989,108 +901,108 @@ void IntExprParsing() { #pragma acc set default_async(returns_int()) - // expected-warning@+2{{OpenACC clause 'vector' not yet implemented, clause ignored}} - // expected-warning@+1{{OpenACC construct 'loop' not yet implemented, pragma ignored}} + // expected-warning@+1{{OpenACC clause 'vector' not yet implemented, clause ignored}} #pragma acc loop vector - // expected-error@+2{{expected expression}} - // expected-warning@+1{{OpenACC construct 'loop' not yet implemented, pragma ignored}} + for(;;); + // expected-error@+1{{expected expression}} #pragma acc loop vector() - // expected-error@+3{{invalid tag 'invalid' on 'vector' clause}} - // expected-error@+2{{expected expression}} - // expected-warning@+1{{OpenACC construct 'loop' not yet implemented, pragma ignored}} + for(;;); + // expected-error@+2{{invalid tag 'invalid' on 'vector' clause}} + // expected-error@+1{{expected expression}} #pragma acc loop vector(invalid:) - // expected-error@+3{{invalid tag 'invalid' on 'vector' clause}} - // expected-warning@+2{{OpenACC clause 'vector' not yet implemented, clause ignored}} - // expected-warning@+1{{OpenACC construct 'loop' not yet implemented, pragma ignored}} + for(;;); + // expected-error@+2{{invalid tag 'invalid' on 'vector' clause}} + // expected-warning@+1{{OpenACC clause 'vector' not yet implemented, clause ignored}} #pragma acc loop vector(invalid:5) - // expected-error@+2{{expected expression}} - // expected-warning@+1{{OpenACC construct 'loop' not yet implemented, pragma ignored}} + for(;;); + // expected-error@+1{{expected expression}} #pragma acc loop vector(length:) - // expected-error@+3{{invalid tag 'num' on 'vector' clause}} - // expected-error@+2{{expected expression}} - // expected-warning@+1{{OpenACC construct 'loop' not yet implemented, pragma ignored}} + for(;;); + // expected-error@+2{{invalid tag 'num' on 'vector' clause}} + // expected-error@+1{{expected expression}} #pragma acc loop vector(num:) - // expected-error@+3{{expected ')'}} - // expected-note@+2{{to match this '('}} - // expected-warning@+1{{OpenACC construct 'loop' not yet implemented, pragma ignored}} + for(;;); + // expected-error@+2{{expected ')'}} + // expected-note@+1{{to match this '('}} #pragma acc loop vector(5, 4) - // expected-error@+3{{expected ')'}} - // expected-note@+2{{to match this '('}} - // expected-warning@+1{{OpenACC construct 'loop' not yet implemented, pragma ignored}} + for(;;); + // expected-error@+2{{expected ')'}} + // expected-note@+1{{to match this '('}} #pragma acc loop vector(length:6,4) - // expected-error@+4{{invalid tag 'num' on 'vector' clause}} - // expected-error@+3{{expected ')'}} - // expected-note@+2{{to match this '('}} - // expected-warning@+1{{OpenACC construct 'loop' not yet implemented, pragma ignored}} + for(;;); + // expected-error@+3{{invalid tag 'num' on 'vector' clause}} + // expected-error@+2{{expected ')'}} + // expected-note@+1{{to match this '('}} #pragma acc loop vector(num:6,4) - // expected-warning@+2{{OpenACC clause 'vector' not yet implemented, clause ignored}} - // expected-warning@+1{{OpenACC construct 'loop' not yet implemented, pragma ignored}} + for(;;); + // expected-warning@+1{{OpenACC clause 'vector' not yet implemented, clause ignored}} #pragma acc loop vector(5) - // expected-error@+3{{invalid tag 'num' on 'vector' clause}} - // expected-warning@+2{{OpenACC clause 'vector' not yet implemented, clause ignored}} - // expected-warning@+1{{OpenACC construct 'loop' not yet implemented, pragma ignored}} + for(;;); + // expected-error@+2{{invalid tag 'num' on 'vector' clause}} + // expected-warning@+1{{OpenACC clause 'vector' not yet implemented, clause ignored}} #pragma acc loop vector(num:5) - // expected-warning@+2{{OpenACC clause 'vector' not yet implemented, clause ignored}} - // expected-warning@+1{{OpenACC construct 'loop' not yet implemented, pragma ignored}} + for(;;); + // expected-warning@+1{{OpenACC clause 'vector' not yet implemented, clause ignored}} #pragma acc loop vector(length:5) - // expected-warning@+2{{OpenACC clause 'vector' not yet implemented, clause ignored}} - // expected-warning@+1{{OpenACC construct 'loop' not yet implemented, pragma ignored}} + for(;;); + // expected-warning@+1{{OpenACC clause 'vector' not yet implemented, clause ignored}} #pragma acc loop vector(returns_int()) - // expected-warning@+2{{OpenACC clause 'vector' not yet implemented, clause ignored}} - // expected-warning@+1{{OpenACC construct 'loop' not yet implemented, pragma ignored}} + for(;;); + // expected-warning@+1{{OpenACC clause 'vector' not yet implemented, clause ignored}} #pragma acc loop vector(length:returns_int()) + for(;;); - // expected-warning@+2{{OpenACC clause 'worker' not yet implemented, clause ignored}} - // expected-warning@+1{{OpenACC construct 'loop' not yet implemented, pragma ignored}} + // expected-warning@+1{{OpenACC clause 'worker' not yet implemented, clause ignored}} #pragma acc loop worker - // expected-error@+2{{expected expression}} - // expected-warning@+1{{OpenACC construct 'loop' not yet implemented, pragma ignored}} + for(;;); + // expected-error@+1{{expected expression}} #pragma acc loop worker() - // expected-error@+3{{invalid tag 'invalid' on 'worker' clause}} - // expected-error@+2{{expected expression}} - // expected-warning@+1{{OpenACC construct 'loop' not yet implemented, pragma ignored}} + for(;;); + // expected-error@+2{{invalid tag 'invalid' on 'worker' clause}} + // expected-error@+1{{expected expression}} #pragma acc loop worker(invalid:) - // expected-error@+3{{invalid tag 'invalid' on 'worker' clause}} - // expected-warning@+2{{OpenACC clause 'worker' not yet implemented, clause ignored}} - // expected-warning@+1{{OpenACC construct 'loop' not yet implemented, pragma ignored}} + for(;;); + // expected-error@+2{{invalid tag 'invalid' on 'worker' clause}} + // expected-warning@+1{{OpenACC clause 'worker' not yet implemented, clause ignored}} #pragma acc loop worker(invalid:5) - // expected-error@+2{{expected expression}} - // expected-warning@+1{{OpenACC construct 'loop' not yet implemented, pragma ignored}} + for(;;); + // expected-error@+1{{expected expression}} #pragma acc loop worker(num:) - // expected-error@+3{{invalid tag 'length' on 'worker' clause}} - // expected-error@+2{{expected expression}} - // expected-warning@+1{{OpenACC construct 'loop' not yet implemented, pragma ignored}} + for(;;); + // expected-error@+2{{invalid tag 'length' on 'worker' clause}} + // expected-error@+1{{expected expression}} #pragma acc loop worker(length:) - // expected-error@+3{{expected ')'}} - // expected-note@+2{{to match this '('}} - // expected-warning@+1{{OpenACC construct 'loop' not yet implemented, pragma ignored}} + for(;;); + // expected-error@+2{{expected ')'}} + // expected-note@+1{{to match this '('}} #pragma acc loop worker(5, 4) - // expected-error@+3{{expected ')'}} - // expected-note@+2{{to match this '('}} - // expected-warning@+1{{OpenACC construct 'loop' not yet implemented, pragma ignored}} + for(;;); + // expected-error@+2{{expected ')'}} + // expected-note@+1{{to match this '('}} #pragma acc loop worker(num:6,4) - // expected-error@+4{{invalid tag 'length' on 'worker' clause}} - // expected-error@+3{{expected ')'}} - // expected-note@+2{{to match this '('}} - // expected-warning@+1{{OpenACC construct 'loop' not yet implemented, pragma ignored}} + for(;;); + // expected-error@+3{{invalid tag 'length' on 'worker' clause}} + // expected-error@+2{{expected ')'}} + // expected-note@+1{{to match this '('}} #pragma acc loop worker(length:6,4) - // expected-warning@+2{{OpenACC clause 'worker' not yet implemented, clause ignored}} - // expected-warning@+1{{OpenACC construct 'loop' not yet implemented, pragma ignored}} + for(;;); + // expected-warning@+1{{OpenACC clause 'worker' not yet implemented, clause ignored}} #pragma acc loop worker(5) - // expected-error@+3{{invalid tag 'length' on 'worker' clause}} - // expected-warning@+2{{OpenACC clause 'worker' not yet implemented, clause ignored}} - // expected-warning@+1{{OpenACC construct 'loop' not yet implemented, pragma ignored}} + for(;;); + // expected-error@+2{{invalid tag 'length' on 'worker' clause}} + // expected-warning@+1{{OpenACC clause 'worker' not yet implemented, clause ignored}} #pragma acc loop worker(length:5) - // expected-warning@+2{{OpenACC clause 'worker' not yet implemented, clause ignored}} - // expected-warning@+1{{OpenACC construct 'loop' not yet implemented, pragma ignored}} + for(;;); + // expected-warning@+1{{OpenACC clause 'worker' not yet implemented, clause ignored}} #pragma acc loop worker(num:5) - // expected-warning@+2{{OpenACC clause 'worker' not yet implemented, clause ignored}} - // expected-warning@+1{{OpenACC construct 'loop' not yet implemented, pragma ignored}} + for(;;); + // expected-warning@+1{{OpenACC clause 'worker' not yet implemented, clause ignored}} #pragma acc loop worker(returns_int()) - // expected-error@+3{{invalid tag 'length' on 'worker' clause}} - // expected-warning@+2{{OpenACC clause 'worker' not yet implemented, clause ignored}} - // expected-warning@+1{{OpenACC construct 'loop' not yet implemented, pragma ignored}} + for(;;); + // expected-error@+2{{invalid tag 'length' on 'worker' clause}} + // expected-warning@+1{{OpenACC clause 'worker' not yet implemented, clause ignored}} #pragma acc loop worker(length:returns_int()) + for(;;); } void device_type() { @@ -1236,238 +1148,196 @@ void AsyncArgument() { void Tile() { int* Foo; - // expected-error@+2{{expected '('}} - // expected-warning@+1{{OpenACC construct 'loop' not yet implemented, pragma ignored}} + // expected-error@+1{{expected '('}} #pragma acc loop tile for(;;){} - // expected-error@+4{{expected expression}} - // expected-error@+3{{expected ')'}} - // expected-note@+2{{to match this '('}} - // expected-warning@+1{{OpenACC construct 'loop' not yet implemented, pragma ignored}} + // expected-error@+3{{expected expression}} + // expected-error@+2{{expected ')'}} + // expected-note@+1{{to match this '('}} #pragma acc loop tile( for(;;){} - // expected-error@+3{{expected expression}} - // expected-warning@+2{{OpenACC clause 'tile' not yet implemented, clause ignored}} - // expected-warning@+1{{OpenACC construct 'loop' not yet implemented, pragma ignored}} + // expected-error@+2{{expected expression}} + // expected-warning@+1{{OpenACC clause 'tile' not yet implemented, clause ignored}} #pragma acc loop tile() for(;;){} - // expected-error@+4{{expected expression}} - // expected-error@+3{{expected ')'}} - // expected-note@+2{{to match this '('}} - // expected-warning@+1{{OpenACC construct 'loop' not yet implemented, pragma ignored}} + // expected-error@+3{{expected expression}} + // expected-error@+2{{expected ')'}} + // expected-note@+1{{to match this '('}} #pragma acc loop tile(, for(;;){} - // expected-error@+3{{expected expression}} - // expected-warning@+2{{OpenACC clause 'tile' not yet implemented, clause ignored}} - // expected-warning@+1{{OpenACC construct 'loop' not yet implemented, pragma ignored}} + // expected-error@+2{{expected expression}} + // expected-warning@+1{{OpenACC clause 'tile' not yet implemented, clause ignored}} #pragma acc loop tile(,) for(;;){} - // expected-error@+3{{use of undeclared identifier 'invalid'}} - // expected-warning@+2{{OpenACC clause 'tile' not yet implemented, clause ignored}} - // expected-warning@+1{{OpenACC construct 'loop' not yet implemented, pragma ignored}} + // expected-error@+2{{use of undeclared identifier 'invalid'}} + // expected-warning@+1{{OpenACC clause 'tile' not yet implemented, clause ignored}} #pragma acc loop tile(returns_int(), *, invalid, *) for(;;){} - // expected-error@+3{{expected expression}} - // expected-warning@+2{{OpenACC clause 'tile' not yet implemented, clause ignored}} - // expected-warning@+1{{OpenACC construct 'loop' not yet implemented, pragma ignored}} + // expected-error@+2{{expected expression}} + // expected-warning@+1{{OpenACC clause 'tile' not yet implemented, clause ignored}} #pragma acc loop tile(returns_int() *, Foo, *) for(;;){} - // expected-error@+3{{indirection requires pointer operand ('int' invalid)}} - // expected-warning@+2{{OpenACC clause 'tile' not yet implemented, clause ignored}} - // expected-warning@+1{{OpenACC construct 'loop' not yet implemented, pragma ignored}} + // expected-error@+2{{indirection requires pointer operand ('int' invalid)}} + // expected-warning@+1{{OpenACC clause 'tile' not yet implemented, clause ignored}} #pragma acc loop tile(* returns_int() , *) for(;;){} - // expected-warning@+2{{OpenACC clause 'tile' not yet implemented, clause ignored}} - // expected-warning@+1{{OpenACC construct 'loop' not yet implemented, pragma ignored}} + // expected-warning@+1{{OpenACC clause 'tile' not yet implemented, clause ignored}} #pragma acc loop tile(*) for(;;){} - // expected-warning@+2{{OpenACC clause 'tile' not yet implemented, clause ignored}} - // expected-warning@+1{{OpenACC construct 'loop' not yet implemented, pragma ignored}} + // expected-warning@+1{{OpenACC clause 'tile' not yet implemented, clause ignored}} #pragma acc loop tile(*Foo, *Foo) for(;;){} - // expected-warning@+2{{OpenACC clause 'tile' not yet implemented, clause ignored}} - // expected-warning@+1{{OpenACC construct 'loop' not yet implemented, pragma ignored}} + // expected-warning@+1{{OpenACC clause 'tile' not yet implemented, clause ignored}} #pragma acc loop tile(5) for(;;){} - // expected-warning@+2{{OpenACC clause 'tile' not yet implemented, clause ignored}} - // expected-warning@+1{{OpenACC construct 'loop' not yet implemented, pragma ignored}} + // expected-warning@+1{{OpenACC clause 'tile' not yet implemented, clause ignored}} #pragma acc loop tile(*, 5) for(;;){} - // expected-warning@+2{{OpenACC clause 'tile' not yet implemented, clause ignored}} - // expected-warning@+1{{OpenACC construct 'loop' not yet implemented, pragma ignored}} + // expected-warning@+1{{OpenACC clause 'tile' not yet implemented, clause ignored}} #pragma acc loop tile(5, *) for(;;){} - // expected-warning@+2{{OpenACC clause 'tile' not yet implemented, clause ignored}} - // expected-warning@+1{{OpenACC construct 'loop' not yet implemented, pragma ignored}} + // expected-warning@+1{{OpenACC clause 'tile' not yet implemented, clause ignored}} #pragma acc loop tile(5, *, 3, *) for(;;){} } void Gang() { - // expected-warning@+2{{OpenACC clause 'gang' not yet implemented, clause ignored}} - // expected-warning@+1{{OpenACC construct 'loop' not yet implemented, pragma ignored}} + // expected-warning@+1{{OpenACC clause 'gang' not yet implemented, clause ignored}} #pragma acc loop gang for(;;){} - // expected-error@+4{{expected expression}} - // expected-error@+3{{expected ')'}} - // expected-note@+2{{to match this '('}} - // expected-warning@+1{{OpenACC construct 'loop' not yet implemented, pragma ignored}} + // expected-error@+3{{expected expression}} + // expected-error@+2{{expected ')'}} + // expected-note@+1{{to match this '('}} #pragma acc loop gang( for(;;){} - // expected-error@+3{{expected expression}} - // expected-warning@+2{{OpenACC clause 'gang' not yet implemented, clause ignored}} - // expected-warning@+1{{OpenACC construct 'loop' not yet implemented, pragma ignored}} + // expected-error@+2{{expected expression}} + // expected-warning@+1{{OpenACC clause 'gang' not yet implemented, clause ignored}} #pragma acc loop gang() for(;;){} - // expected-error@+3{{expected expression}} - // expected-warning@+2{{OpenACC clause 'gang' not yet implemented, clause ignored}} - // expected-warning@+1{{OpenACC construct 'loop' not yet implemented, pragma ignored}} + // expected-error@+2{{expected expression}} + // expected-warning@+1{{OpenACC clause 'gang' not yet implemented, clause ignored}} #pragma acc loop gang(5, *) for(;;){} - // expected-error@+3{{expected expression}} - // expected-warning@+2{{OpenACC clause 'gang' not yet implemented, clause ignored}} - // expected-warning@+1{{OpenACC construct 'loop' not yet implemented, pragma ignored}} + // expected-error@+2{{expected expression}} + // expected-warning@+1{{OpenACC clause 'gang' not yet implemented, clause ignored}} #pragma acc loop gang(*) for(;;){} - // expected-error@+3{{expected expression}} - // expected-warning@+2{{OpenACC clause 'gang' not yet implemented, clause ignored}} - // expected-warning@+1{{OpenACC construct 'loop' not yet implemented, pragma ignored}} + // expected-error@+2{{expected expression}} + // expected-warning@+1{{OpenACC clause 'gang' not yet implemented, clause ignored}} #pragma acc loop gang(5, num:*) for(;;){} - // expected-error@+3{{expected expression}} - // expected-warning@+2{{OpenACC clause 'gang' not yet implemented, clause ignored}} - // expected-warning@+1{{OpenACC construct 'loop' not yet implemented, pragma ignored}} + // expected-error@+2{{expected expression}} + // expected-warning@+1{{OpenACC clause 'gang' not yet implemented, clause ignored}} #pragma acc loop gang(num:5, *) for(;;){} - // expected-error@+3{{expected expression}} - // expected-warning@+2{{OpenACC clause 'gang' not yet implemented, clause ignored}} - // expected-warning@+1{{OpenACC construct 'loop' not yet implemented, pragma ignored}} + // expected-error@+2{{expected expression}} + // expected-warning@+1{{OpenACC clause 'gang' not yet implemented, clause ignored}} #pragma acc loop gang(num:5, num:*) for(;;){} - // expected-error@+3{{expected expression}} - // expected-warning@+2{{OpenACC clause 'gang' not yet implemented, clause ignored}} - // expected-warning@+1{{OpenACC construct 'loop' not yet implemented, pragma ignored}} + // expected-error@+2{{expected expression}} + // expected-warning@+1{{OpenACC clause 'gang' not yet implemented, clause ignored}} #pragma acc loop gang(num:*) for(;;){} - // expected-warning@+2{{OpenACC clause 'gang' not yet implemented, clause ignored}} - // expected-warning@+1{{OpenACC construct 'loop' not yet implemented, pragma ignored}} + // expected-warning@+1{{OpenACC clause 'gang' not yet implemented, clause ignored}} #pragma acc loop gang(dim:5) for(;;){} - // expected-error@+3{{expected expression}} - // expected-warning@+2{{OpenACC clause 'gang' not yet implemented, clause ignored}} - // expected-warning@+1{{OpenACC construct 'loop' not yet implemented, pragma ignored}} + // expected-error@+2{{expected expression}} + // expected-warning@+1{{OpenACC clause 'gang' not yet implemented, clause ignored}} #pragma acc loop gang(dim:5, dim:*) for(;;){} - // expected-error@+3{{expected expression}} - // expected-warning@+2{{OpenACC clause 'gang' not yet implemented, clause ignored}} - // expected-warning@+1{{OpenACC construct 'loop' not yet implemented, pragma ignored}} + // expected-error@+2{{expected expression}} + // expected-warning@+1{{OpenACC clause 'gang' not yet implemented, clause ignored}} #pragma acc loop gang(dim:*) for(;;){} - // expected-warning@+2{{OpenACC clause 'gang' not yet implemented, clause ignored}} - // expected-warning@+1{{OpenACC construct 'loop' not yet implemented, pragma ignored}} + // expected-warning@+1{{OpenACC clause 'gang' not yet implemented, clause ignored}} #pragma acc loop gang(static:*) for(;;){} - // expected-warning@+2{{OpenACC clause 'gang' not yet implemented, clause ignored}} - // expected-warning@+1{{OpenACC construct 'loop' not yet implemented, pragma ignored}} + // expected-warning@+1{{OpenACC clause 'gang' not yet implemented, clause ignored}} #pragma acc loop gang(static:*, static:5) for(;;){} - // expected-warning@+2{{OpenACC clause 'gang' not yet implemented, clause ignored}} - // expected-warning@+1{{OpenACC construct 'loop' not yet implemented, pragma ignored}} + // expected-warning@+1{{OpenACC clause 'gang' not yet implemented, clause ignored}} #pragma acc loop gang(static:*, 5) for(;;){} - // expected-warning@+2{{OpenACC clause 'gang' not yet implemented, clause ignored}} - // expected-warning@+1{{OpenACC construct 'loop' not yet implemented, pragma ignored}} + // expected-warning@+1{{OpenACC clause 'gang' not yet implemented, clause ignored}} #pragma acc loop gang(static:45, 5) for(;;){} - // expected-error@+4{{expected expression}} - // expected-error@+3{{expected ')'}} - // expected-note@+2{{to match this '('}} - // expected-warning@+1{{OpenACC construct 'loop' not yet implemented, pragma ignored}} + // expected-error@+3{{expected expression}} + // expected-error@+2{{expected ')'}} + // expected-note@+1{{to match this '('}} #pragma acc loop gang(static:45, for(;;){} - // expected-error@+3{{expected ')'}} - // expected-note@+2{{to match this '('}} - // expected-warning@+1{{OpenACC construct 'loop' not yet implemented, pragma ignored}} + // expected-error@+2{{expected ')'}} + // expected-note@+1{{to match this '('}} #pragma acc loop gang(static:45 for(;;){} - // expected-error@+4{{expected expression}} - // expected-error@+3{{expected ')'}} - // expected-note@+2{{to match this '('}} - // expected-warning@+1{{OpenACC construct 'loop' not yet implemented, pragma ignored}} + // expected-error@+3{{expected expression}} + // expected-error@+2{{expected ')'}} + // expected-note@+1{{to match this '('}} #pragma acc loop gang(static:*, for(;;){} - // expected-error@+3{{expected ')'}} - // expected-note@+2{{to match this '('}} - // expected-warning@+1{{OpenACC construct 'loop' not yet implemented, pragma ignored}} + // expected-error@+2{{expected ')'}} + // expected-note@+1{{to match this '('}} #pragma acc loop gang(static:* for(;;){} - // expected-error@+4{{expected expression}} - // expected-error@+3{{expected ')'}} - // expected-note@+2{{to match this '('}} - // expected-warning@+1{{OpenACC construct 'loop' not yet implemented, pragma ignored}} + // expected-error@+3{{expected expression}} + // expected-error@+2{{expected ')'}} + // expected-note@+1{{to match this '('}} #pragma acc loop gang(45, for(;;){} - // expected-error@+3{{expected ')'}} - // expected-note@+2{{to match this '('}} - // expected-warning@+1{{OpenACC construct 'loop' not yet implemented, pragma ignored}} + // expected-error@+2{{expected ')'}} + // expected-note@+1{{to match this '('}} #pragma acc loop gang(45 for(;;){} - // expected-error@+4{{expected expression}} - // expected-error@+3{{expected ')'}} - // expected-note@+2{{to match this '('}} - // expected-warning@+1{{OpenACC construct 'loop' not yet implemented, pragma ignored}} + // expected-error@+3{{expected expression}} + // expected-error@+2{{expected ')'}} + // expected-note@+1{{to match this '('}} #pragma acc loop gang(num:45, for(;;){} - // expected-error@+3{{expected ')'}} - // expected-note@+2{{to match this '('}} - // expected-warning@+1{{OpenACC construct 'loop' not yet implemented, pragma ignored}} + // expected-error@+2{{expected ')'}} + // expected-note@+1{{to match this '('}} #pragma acc loop gang(num:45 for(;;){} - // expected-error@+4{{expected expression}} - // expected-error@+3{{expected ')'}} - // expected-note@+2{{to match this '('}} - // expected-warning@+1{{OpenACC construct 'loop' not yet implemented, pragma ignored}} + // expected-error@+3{{expected expression}} + // expected-error@+2{{expected ')'}} + // expected-note@+1{{to match this '('}} #pragma acc loop gang(dim:45, for(;;){} - // expected-error@+3{{expected ')'}} - // expected-note@+2{{to match this '('}} - // expected-warning@+1{{OpenACC construct 'loop' not yet implemented, pragma ignored}} + // expected-error@+2{{expected ')'}} + // expected-note@+1{{to match this '('}} #pragma acc loop gang(dim:45 for(;;){} - // expected-warning@+2{{OpenACC clause 'gang' not yet implemented, clause ignored}} - // expected-warning@+1{{OpenACC construct 'loop' not yet implemented, pragma ignored}} + // expected-warning@+1{{OpenACC clause 'gang' not yet implemented, clause ignored}} #pragma acc loop gang(static:*, dim:returns_int(), 5) for(;;){} - // expected-warning@+2{{OpenACC clause 'gang' not yet implemented, clause ignored}} - // expected-warning@+1{{OpenACC construct 'loop' not yet implemented, pragma ignored}} + // expected-warning@+1{{OpenACC clause 'gang' not yet implemented, clause ignored}} #pragma acc loop gang(num: 32, static:*, dim:returns_int(), 5) for(;;){} diff --git a/clang/test/ParserOpenACC/parse-clauses.cpp b/clang/test/ParserOpenACC/parse-clauses.cpp index 702eb75ca8902d47636455ad90d355e4af74da76..b7e252e892beaba4c1a3f477ccf130978340b3fb 100644 --- a/clang/test/ParserOpenACC/parse-clauses.cpp +++ b/clang/test/ParserOpenACC/parse-clauses.cpp @@ -2,13 +2,11 @@ template void templ() { - // expected-warning@+2{{OpenACC clause 'collapse' not yet implemented, clause ignored}} - // expected-warning@+1{{OpenACC construct 'loop' not yet implemented, pragma ignored}} + // expected-warning@+1{{OpenACC clause 'collapse' not yet implemented, clause ignored}} #pragma acc loop collapse(I) for(;;){} - // expected-warning@+2{{OpenACC clause 'collapse' not yet implemented, clause ignored}} - // expected-warning@+1{{OpenACC construct 'loop' not yet implemented, pragma ignored}} + // expected-warning@+1{{OpenACC clause 'collapse' not yet implemented, clause ignored}} #pragma acc loop collapse(T::value) for(;;){} diff --git a/clang/test/ParserOpenACC/parse-constructs.c b/clang/test/ParserOpenACC/parse-constructs.c index ecedfd9e9e6d6a48314b9b07b008b71d0d94fa3a..ea75360cc135148b2f7c838a8d3c38fd596772ad 100644 --- a/clang/test/ParserOpenACC/parse-constructs.c +++ b/clang/test/ParserOpenACC/parse-constructs.c @@ -82,8 +82,7 @@ void func() { // expected-warning@+1{{OpenACC construct 'host_data' not yet implemented, pragma ignored}} #pragma acc host_data clause list for(;;){} - // expected-error@+2{{invalid OpenACC clause 'clause'}} - // expected-warning@+1{{OpenACC construct 'loop' not yet implemented, pragma ignored}} + // expected-error@+1{{invalid OpenACC clause 'clause'}} #pragma acc loop clause list for(;;){} // expected-error@+1{{invalid OpenACC clause 'invalid'}} diff --git a/clang/test/Preprocessor/aarch64-target-features.c b/clang/test/Preprocessor/aarch64-target-features.c index 82304a15a04a3fac4f192a9cf40631e2d08bda58..c707972fb41d2e69ef3ab842b763b4c1f4d83dcd 100644 --- a/clang/test/Preprocessor/aarch64-target-features.c +++ b/clang/test/Preprocessor/aarch64-target-features.c @@ -335,7 +335,7 @@ // CHECK-MCPU-CARMEL: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-feature" "+v8.2a" "-target-feature" "+aes" "-target-feature" "+crc" "-target-feature" "+fp-armv8" "-target-feature" "+fullfp16" "-target-feature" "+lse" "-target-feature" "+ras" "-target-feature" "+rdm" "-target-feature" "+sha2" "-target-feature" "+neon" // RUN: %clang -target x86_64-apple-macosx -arch arm64 -### -c %s 2>&1 | FileCheck --check-prefix=CHECK-ARCH-ARM64 %s -// CHECK-ARCH-ARM64: "-target-cpu" "apple-m1" "-target-feature" "+zcm" "-target-feature" "+zcz" "-target-feature" "+v8.5a" "-target-feature" "+aes" "-target-feature" "+crc" "-target-feature" "+dotprod" "-target-feature" "+complxnum" "-target-feature" "+fp-armv8" "-target-feature" "+fullfp16" "-target-feature" "+fp16fml" "-target-feature" "+jsconv" "-target-feature" "+lse" "-target-feature" "+pauth" "-target-feature" "+ras" "-target-feature" "+rcpc" "-target-feature" "+rdm" "-target-feature" "+sha2" "-target-feature" "+sha3" "-target-feature" "+neon" +// CHECK-ARCH-ARM64: "-target-cpu" "apple-m1" "-target-feature" "+zcm" "-target-feature" "+zcz" "-target-feature" "+v8.4a" "-target-feature" "+aes" "-target-feature" "+crc" "-target-feature" "+dotprod" "-target-feature" "+complxnum" "-target-feature" "+fp-armv8" "-target-feature" "+fullfp16" "-target-feature" "+fp16fml" "-target-feature" "+jsconv" "-target-feature" "+lse" "-target-feature" "+pauth" "-target-feature" "+ras" "-target-feature" "+rcpc" "-target-feature" "+rdm" "-target-feature" "+sha2" "-target-feature" "+sha3" "-target-feature" "+neon" // RUN: %clang -target x86_64-apple-macosx -arch arm64_32 -### -c %s 2>&1 | FileCheck --check-prefix=CHECK-ARCH-ARM64_32 %s // CHECK-ARCH-ARM64_32: "-target-cpu" "apple-s4" "-target-feature" "+zcm" "-target-feature" "+zcz" "-target-feature" "+v8.3a" "-target-feature" "+aes" "-target-feature" "+crc" "-target-feature" "+complxnum" "-target-feature" "+fp-armv8" "-target-feature" "+fullfp16" "-target-feature" "+jsconv" "-target-feature" "+lse" "-target-feature" "+pauth" "-target-feature" "+ras" "-target-feature" "+rcpc" "-target-feature" "+rdm" "-target-feature" "+sha2" "-target-feature" "+neon" @@ -671,10 +671,15 @@ // CHECK-V83-OR-LATER: __ARM_FEATURE_JCVT 1 // CHECK-V83-OR-LATER: __ARM_FEATURE_PAUTH 1 // CHECK-V81-OR-LATER: __ARM_FEATURE_QRDMX 1 +// CHECK-BEFORE-V85-NOT: __ARM_FEATURE_BTI 1 // CHECK-BEFORE-V83-NOT: __ARM_FEATURE_COMPLEX 1 // CHECK-BEFORE-V83-NOT: __ARM_FEATURE_JCVT 1 // CHECK-BEFORE-V85-NOT: __ARM_FEATURE_FRINT 1 +// RUN: %clang -target aarch64 -mcpu=apple-a14 -x c -E -dM %s -o - | FileCheck --check-prefix=APPLE-A14-M1 %s +// RUN: %clang -target aarch64 -mcpu=apple-m1 -x c -E -dM %s -o - | FileCheck --check-prefix=APPLE-A14-M1 %s +// APPLE-A14-M1-NOT: __ARM_FEATURE_BTI 1 + // RUN: %clang --target=aarch64 -march=armv8.2-a+rcpc -x c -E -dM %s -o - | FileCheck --check-prefix=CHECK-RCPC %s // CHECK-RCPC: __ARM_FEATURE_RCPC 1 diff --git a/clang/test/Preprocessor/hash_builtin.cpp b/clang/test/Preprocessor/hash_builtin.cpp index 77d186c7883f22d14a5e831572da6a24ab0190ea..018b71eca418eb18f088c90d2e2d22cdfc8495aa 100644 --- a/clang/test/Preprocessor/hash_builtin.cpp +++ b/clang/test/Preprocessor/hash_builtin.cpp @@ -1,11 +1,14 @@ // RUN: %clang_cc1 -triple amdgcn -target-cpu gfx906 -E %s -o - | FileCheck %s +// RUN: %clang_cc1 -triple spirv64-amd-amdhsa -E %s -o - | FileCheck %s --check-prefix=SPIRV-AMDGCN // CHECK: has_s_memtime_inst +// SPIRV-AMDGCN: has_s_memtime_inst #if __has_builtin(__builtin_amdgcn_s_memtime) int has_s_memtime_inst; #endif // CHECK-NOT: has_gfx10_inst +// SPIRV-AMDGCN: has_gfx10_inst #if __has_builtin(__builtin_amdgcn_mov_dpp8) int has_gfx10_inst; #endif diff --git a/clang/test/Preprocessor/predefined-macros-no-warnings.c b/clang/test/Preprocessor/predefined-macros-no-warnings.c index e0617f8de4da3856f6248d1dd6e847b72622b99d..722e3e77214b6474888e443cd5bc9ad1cf743f6d 100644 --- a/clang/test/Preprocessor/predefined-macros-no-warnings.c +++ b/clang/test/Preprocessor/predefined-macros-no-warnings.c @@ -173,6 +173,7 @@ // RUN: %clang_cc1 %s -Eonly -Wsystem-headers -Werror -triple spir64 // RUN: %clang_cc1 %s -Eonly -Wsystem-headers -Werror -triple spirv32 // RUN: %clang_cc1 %s -Eonly -Wsystem-headers -Werror -triple spirv64 +// RUN: %clang_cc1 %s -Eonly -Wsystem-headers -Werror -triple spirv64-amd-amdhsa // RUN: %clang_cc1 %s -Eonly -Wsystem-headers -Werror -triple wasm32 // RUN: %clang_cc1 %s -Eonly -Wsystem-headers -Werror -triple wasm32-wasi // RUN: %clang_cc1 %s -Eonly -Wsystem-headers -Werror -triple wasm32-emscripten diff --git a/clang/test/Preprocessor/predefined-macros.c b/clang/test/Preprocessor/predefined-macros.c index c4a9672f0814aad4c0e7506bb33008f7bec51eca..7f036bff401ca09506aae8be9b44c8a20f70c56f 100644 --- a/clang/test/Preprocessor/predefined-macros.c +++ b/clang/test/Preprocessor/predefined-macros.c @@ -236,6 +236,16 @@ // CHECK-SPIRV64-DAG: #define __SPIRV64__ 1 // CHECK-SPIRV64-NOT: #define __SPIRV32__ 1 +// RUN: %clang_cc1 %s -E -dM -o - -x cl -triple spirv64-amd-amdhsa \ +// RUN: | FileCheck -match-full-lines %s --check-prefix=CHECK-SPIRV64-AMDGCN +// CHECK-SPIRV64-AMDGCN-DAG: #define __IMAGE_SUPPORT__ 1 +// CHECK-SPIRV64-AMDGCN-DAG: #define __SPIRV__ 1 +// CHECK-SPIRV64-AMDGCN-DAG: #define __SPIRV64__ 1 +// CHECK-SPIRV64-AMDGCN-DAG: #define __AMD__ 1 +// CHECK-SPIRV64-AMDGCN-DAG: #define __AMDGCN__ 1 +// CHECK-SPIRV64-AMDGCN-DAG: #define __AMDGPU__ 1 +// CHECK-SPIRV64-AMDGCN-NOT: #define __SPIRV32__ 1 + // RUN: %clang_cc1 %s -E -dM -o - -x hip -triple x86_64-unknown-linux-gnu \ // RUN: | FileCheck -match-full-lines %s --check-prefix=CHECK-HIP // CHECK-HIP: #define __HIPCC__ 1 diff --git a/clang/test/Preprocessor/riscv-target-features.c b/clang/test/Preprocessor/riscv-target-features.c index 09b9ad0a160bb1ae2c5e6ff7e3c6cc986be5ca54..91307141e0406b300f9d93ba3e1d884bbf622154 100644 --- a/clang/test/Preprocessor/riscv-target-features.c +++ b/clang/test/Preprocessor/riscv-target-features.c @@ -7,6 +7,7 @@ // CHECK-NOT: __riscv_64e {{.*$}} // CHECK-NOT: __riscv_a {{.*$}} // CHECK-NOT: __riscv_atomic +// CHECK-NOT: __riscv_b {{.*$}} // CHECK-NOT: __riscv_c {{.*$}} // CHECK-NOT: __riscv_compressed {{.*$}} // CHECK-NOT: __riscv_d {{.*$}} @@ -194,6 +195,17 @@ // CHECK-A-EXT: __riscv_a 2001000{{$}} // CHECK-A-EXT: __riscv_atomic 1 +// RUN: %clang --target=riscv32-unknown-linux-gnu \ +// RUN: -march=rv32ib -x c -E -dM %s \ +// RUN: -o - | FileCheck --check-prefix=CHECK-B-EXT %s +// RUN: %clang --target=riscv64-unknown-linux-gnu \ +// RUN: -march=rv64ib -x c -E -dM %s \ +// RUN: -o - | FileCheck --check-prefix=CHECK-B-EXT %s +// CHECK-B-EXT: __riscv_b 1000000{{$}} +// CHECK-B-EXT: __riscv_zba 1000000{{$}} +// CHECK-B-EXT: __riscv_zbb 1000000{{$}} +// CHECK-B-EXT: __riscv_zbs 1000000{{$}} + // RUN: %clang --target=riscv32-unknown-linux-gnu \ // RUN: -march=rv32ic -E -dM %s \ // RUN: -o - | FileCheck --check-prefix=CHECK-C-EXT %s diff --git a/clang/test/Sema/attr-availability-macosx.cpp b/clang/test/Sema/attr-availability-macosx.cpp new file mode 100644 index 0000000000000000000000000000000000000000..52f320d4092815b39abb5dd09ab5d5f35c601c73 --- /dev/null +++ b/clang/test/Sema/attr-availability-macosx.cpp @@ -0,0 +1,17 @@ +// RUN: %clang_cc1 "-triple" "arm64-apple-macosx10.15" -fsyntax-only -verify %s + +__attribute__((availability(macos,introduced=11))) +inline bool try_acquire() { + return true; +} + +template +__attribute__((availability(macos,introduced=11))) +bool try_acquire_for(T duration) { // expected-note{{'try_acquire_for' has been marked as being introduced in macOS 11 here, but the deployment target is macOS 10.15}} + return try_acquire(); +} + +int main() { + try_acquire_for(1); // expected-warning{{'try_acquire_for' is only available on macOS 11 or newer}} + // expected-note@-1{{enclose 'try_acquire_for' in a __builtin_available check to silence this warning}} +} \ No newline at end of file diff --git a/clang/test/Sema/builtin-spirv-amdgcn-atomic-inc-dec-failure.cpp b/clang/test/Sema/builtin-spirv-amdgcn-atomic-inc-dec-failure.cpp new file mode 100644 index 0000000000000000000000000000000000000000..2b8fac72847d6a2d691e82d8d85785912c63a0eb --- /dev/null +++ b/clang/test/Sema/builtin-spirv-amdgcn-atomic-inc-dec-failure.cpp @@ -0,0 +1,25 @@ +// RUN: %clang_cc1 %s -x hip -fcuda-is-device -o - \ +// RUN: -triple=spirv64-amd-amdhsa -fsyntax-only \ +// RUN: -verify=dev +// RUN: %clang_cc1 %s -x hip -triple x86_64 -o - \ +// RUN: -aux-triple spirv64-amd-amdhsa -fsyntax-only \ +// RUN: -verify=host + +// dev-no-diagnostics + +void test_host() { + __UINT32_TYPE__ val32; + __UINT64_TYPE__ val64; + + // host-error@+1 {{reference to __device__ function '__builtin_amdgcn_atomic_inc32' in __host__ function}} + val32 = __builtin_amdgcn_atomic_inc32(&val32, val32, __ATOMIC_SEQ_CST, ""); + + // host-error@+1 {{reference to __device__ function '__builtin_amdgcn_atomic_inc64' in __host__ function}} + val64 = __builtin_amdgcn_atomic_inc64(&val64, val64, __ATOMIC_SEQ_CST, ""); + + // host-error@+1 {{reference to __device__ function '__builtin_amdgcn_atomic_dec32' in __host__ function}} + val32 = __builtin_amdgcn_atomic_dec32(&val32, val32, __ATOMIC_SEQ_CST, ""); + + // host-error@+1 {{reference to __device__ function '__builtin_amdgcn_atomic_dec64' in __host__ function}} + val64 = __builtin_amdgcn_atomic_dec64(&val64, val64, __ATOMIC_SEQ_CST, ""); +} diff --git a/clang/test/Sema/constexpr-void-cast.c b/clang/test/Sema/constexpr-void-cast.c index 91e4027f67fe387850891099e773b490d74e5c26..2ffc59f509b4b72b67a4660ef2e393d1254a573a 100644 --- a/clang/test/Sema/constexpr-void-cast.c +++ b/clang/test/Sema/constexpr-void-cast.c @@ -1,8 +1,12 @@ // 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=c -std=c11 -fexperimental-new-constant-interpreter +// RUN: %clang_cc1 -x c -fsyntax-only %s -pedantic -verify=c-pedantic -std=c11 -fexperimental-new-constant-interpreter // // RUN: %clang_cc1 -x c++ -fsyntax-only %s -verify=cxx // RUN: %clang_cc1 -x c++ -fsyntax-only %s -pedantic -verify=cxx-pedantic +// RUN: %clang_cc1 -x c++ -fsyntax-only %s -verify=cxx -fexperimental-new-constant-interpreter +// RUN: %clang_cc1 -x c++ -fsyntax-only %s -pedantic -verify=cxx-pedantic -fexperimental-new-constant-interpreter // c-no-diagnostics // cxx-no-diagnostics diff --git a/clang/test/Sema/inline-asm-validate-spirv-amdgcn.cl b/clang/test/Sema/inline-asm-validate-spirv-amdgcn.cl new file mode 100644 index 0000000000000000000000000000000000000000..0fb1b5f3672265117fc52cd400898de3c6f9b52d --- /dev/null +++ b/clang/test/Sema/inline-asm-validate-spirv-amdgcn.cl @@ -0,0 +1,111 @@ +// REQUIRES: amdgpu-registered-target +// RUN: %clang_cc1 -triple spirv64-amd-amdhsa -fsyntax-only -verify %s + +#pragma OPENCL EXTENSION cl_khr_fp64 : enable + +kernel void test () { + + int sgpr = 0, vgpr = 0, imm = 0; + + // sgpr constraints + __asm__ ("s_mov_b32 %0, %1" : "=s" (sgpr) : "s" (imm) : ); + + __asm__ ("s_mov_b32 %0, %1" : "={s1}" (sgpr) : "{exec}" (imm) : ); + __asm__ ("s_mov_b32 %0, %1" : "={s1}" (sgpr) : "{exe" (imm) : ); // expected-error {{invalid input constraint '{exe' in asm}} + __asm__ ("s_mov_b32 %0, %1" : "={s1}" (sgpr) : "{exec" (imm) : ); // expected-error {{invalid input constraint '{exec' in asm}} + __asm__ ("s_mov_b32 %0, %1" : "={s1}" (sgpr) : "{exec}a" (imm) : ); // expected-error {{invalid input constraint '{exec}a' in asm}} + + // vgpr constraints + __asm__ ("v_mov_b32 %0, %1" : "=v" (vgpr) : "v" (imm) : ); + + // 'I' constraint (an immediate integer in the range -16 to 64) + __asm__ ("s_mov_b32 %0, %1" : "=s" (sgpr) : "I" (imm) : ); + __asm__ ("s_mov_b32 %0, %1" : "=s" (sgpr) : "I" (-16) : ); + __asm__ ("s_mov_b32 %0, %1" : "=s" (sgpr) : "I" (64) : ); + __asm__ ("s_mov_b32 %0, %1" : "=s" (sgpr) : "I" (-17) : ); // expected-error {{value '-17' out of range for constraint 'I'}} + __asm__ ("s_mov_b32 %0, %1" : "=s" (sgpr) : "I" (65) : ); // expected-error {{value '65' out of range for constraint 'I'}} + + // 'J' constraint (an immediate 16-bit signed integer) + __asm__ ("s_mov_b32 %0, %1" : "=s" (sgpr) : "J" (imm) : ); + __asm__ ("s_mov_b32 %0, %1" : "=s" (sgpr) : "J" (-32768) : ); + __asm__ ("s_mov_b32 %0, %1" : "=s" (sgpr) : "J" (32767) : ); + __asm__ ("s_mov_b32 %0, %1" : "=s" (sgpr) : "J" (-32769) : ); // expected-error {{value '-32769' out of range for constraint 'J'}} + __asm__ ("s_mov_b32 %0, %1" : "=s" (sgpr) : "J" (32768) : ); // expected-error {{value '32768' out of range for constraint 'J'}} + + // 'A' constraint (an immediate constant that can be inlined) + __asm__ ("s_mov_b32 %0, %1" : "=s" (sgpr) : "A" (imm) : ); + + // 'B' constraint (an immediate 32-bit signed integer) + __asm__ ("s_mov_b32 %0, %1" : "=s" (sgpr) : "B" (imm) : ); + + // 'C' constraint (an immediate 32-bit unsigned integer or 'A' constraint) + __asm__ ("s_mov_b32 %0, %1" : "=s" (sgpr) : "C" (imm) : ); + + // 'DA' constraint (an immediate 64-bit constant that can be split into two 'A' constants) + __asm__ ("s_mov_b32 %0, %1" : "=s" (sgpr) : "DA" (imm) : ); + + // 'DB' constraint (an immediate 64-bit constant that can be split into two 'B' constants) + __asm__ ("s_mov_b32 %0, %1" : "=s" (sgpr) : "DB" (imm) : ); + +} + +__kernel void +test_float(const __global float *a, const __global float *b, __global float *c, unsigned i) +{ + float ai = a[i]; + float bi = b[i]; + float ci; + + __asm("v_add_f32_e32 v1, v2, v3" : "={v1}"(ci) : "{v2}"(ai), "{v3}"(bi) : ); + __asm("v_add_f32_e32 v1, v2, v3" : ""(ci) : "{v2}"(ai), "{v3}"(bi) : ); // expected-error {{invalid output constraint '' in asm}} + __asm("v_add_f32_e32 v1, v2, v3" : "="(ci) : "{v2}"(ai), "{v3}"(bi) : ); // expected-error {{invalid output constraint '=' in asm}} + __asm("v_add_f32_e32 v1, v2, v3" : "={a}"(ci) : "{v2}"(ai), "{v3}"(bi) : ); // expected-error {{invalid output constraint '={a}' in asm}} + __asm("v_add_f32_e32 v1, v2, v3" : "={"(ci) : "{v2}"(ai), "{v3}"(bi) : ); // expected-error {{invalid output constraint '={' in asm}} + __asm("v_add_f32_e32 v1, v2, v3" : "={}"(ci) : "{v2}"(ai), "{v3}"(bi) : ); // expected-error {{invalid output constraint '={}' in asm}} + __asm("v_add_f32_e32 v1, v2, v3" : "={v"(ci) : "{v2}"(ai), "{v3}"(bi) : ); // expected-error {{invalid output constraint '={v' in asm}} + __asm("v_add_f32_e32 v1, v2, v3" : "={v1a}"(ci) : "{v2}"(ai), "{v3}"(bi) : ); // expected-error {{invalid output constraint '={v1a}' in asm}} + __asm("v_add_f32_e32 v1, v2, v3" : "={va}"(ci) : "{v2}"(ai), "{v3}"(bi) : ); // expected-error {{invalid output constraint '={va}' in asm}} + __asm("v_add_f32_e32 v1, v2, v3" : "={v1}a"(ci) : "{v2}"(ai), "{v3}"(bi) : ); // expected-error {{invalid output constraint '={v1}a' in asm}} + __asm("v_add_f32_e32 v1, v2, v3" : "={v1"(ci) : "{v2}"(ai), "{v3}"(bi) : ); // expected-error {{invalid output constraint '={v1' in asm}} + __asm("v_add_f32_e32 v1, v2, v3" : "=v1}"(ci) : "{v2}"(ai), "{v3}"(bi) : ); // expected-error {{invalid output constraint '=v1}' in asm}} + + __asm("v_add_f32_e32 v1, v2, v3" : "={v[1]}"(ci) : "{v[2]}"(ai), "{v[3]}"(bi) : ); + __asm("v_add_f32_e32 v1, v2, v3" : "={v[1}"(ci) : "{v[2]}"(ai), "{v[3]}"(bi) : ); // expected-error {{invalid output constraint '={v[1}' in asm}} + __asm("v_add_f32_e32 v1, v2, v3" : "={v[1]"(ci) : "{v[2]}"(ai), "{v[3]}"(bi) : ); // expected-error {{invalid output constraint '={v[1]' in asm}} + __asm("v_add_f32_e32 v1, v2, v3" : "={v[a]}"(ci) : "{v[2]}"(ai), "{v[3]}"(bi) : ); // expected-error {{invalid output constraint '={v[a]}' in asm}} + + __asm("v_add_f32_e32 v1, v2, v3" : "=v"(ci) : "v"(ai), "v"(bi) : ); + __asm("v_add_f32_e32 v1, v2, v3" : "=v1"(ci) : "v2"(ai), "v3"(bi) : ); /// expected-error {{invalid output constraint '=v1' in asm}} + + __asm("v_add_f32_e32 v1, v2, v3" : "={v1}"(ci) : "{a}"(ai), "{v3}"(bi) : ); // expected-error {{invalid input constraint '{a}' in asm}} + __asm("v_add_f32_e32 v1, v2, v3" : "={v1}"(ci) : "{v2}"(ai), "{a}"(bi) : ); // expected-error {{invalid input constraint '{a}' in asm}} + c[i] = ci; +} + +__kernel void +test_double(const __global double *a, const __global double *b, __global double *c, unsigned i) +{ + double ai = a[i]; + double bi = b[i]; + double ci; + + __asm("v_add_f64_e64 v[1:2], v[3:4], v[5:6]" : "={v[1:2]}"(ci) : "{v[3:4]}"(ai), "{v[5:6]}"(bi) : ); + __asm("v_add_f64_e64 v[1:2], v[3:4], v[5:6]" : "=v{[1:2]}"(ci) : "{v[3:4]}"(ai), "{v[5:6]}"(bi) : ); //expected-error {{invalid output constraint '=v{[1:2]}' in asm}} + __asm("v_add_f64_e64 v[1:2], v[3:4], v[5:6]" : "={v[1:2]a}"(ci) : "{v[3:4]}"(ai), "{v[5:6]}"(bi) : ); //expected-error {{invalid output constraint '={v[1:2]a}' in asm}} + __asm("v_add_f64_e64 v[1:2], v[3:4], v[5:6]" : "={v[1:2]}a"(ci) : "{v[3:4]}"(ai), "{v[5:6]}"(bi) : ); //expected-error {{invalid output constraint '={v[1:2]}a' in asm}} + __asm("v_add_f64_e64 v[1:2], v[3:4], v[5:6]" : "={v[1:"(ci) : "{v[3:4]}"(ai), "{v[5:6]}"(bi) : ); //expected-error {{invalid output constraint '={v[1:' in asm}} + __asm("v_add_f64_e64 v[1:2], v[3:4], v[5:6]" : "={v[1:]}"(ci) : "{v[3:4]}"(ai), "{v[5:6]}"(bi) : ); //expected-error {{invalid output constraint '={v[1:]}' in asm}} + __asm("v_add_f64_e64 v[1:2], v[3:4], v[5:6]" : "={v[:2]}"(ci) : "{v[3:4]}"(ai), "{v[5:6]}"(bi) : ); //expected-error {{invalid output constraint '={v[:2]}' in asm}} + __asm("v_add_f64_e64 v[1:2], v[3:4], v[5:6]" : "={v[1:2]"(ci) : "{v[3:4]}"(ai), "{v[5:6]}"(bi) : ); //expected-error {{invalid output constraint '={v[1:2]' in asm}} + __asm("v_add_f64_e64 v[1:2], v[3:4], v[5:6]" : "={v[1:2}"(ci) : "{v[3:4]}"(ai), "{v[5:6]}"(bi) : ); //expected-error {{invalid output constraint '={v[1:2}' in asm}} + __asm("v_add_f64_e64 v[1:2], v[3:4], v[5:6]" : "={v[2:1]}"(ci) : "{v[3:4]}"(ai), "{v[5:6]}"(bi) : ); //expected-error {{invalid output constraint '={v[2:1]}' in asm}} + + __asm("v_add_f64_e64 v[1:2], v[3:4], v[5:6]" : "=v[1:2]"(ci) : "v[3:4]"(ai), "v[5:6]"(bi) : ); //expected-error {{invalid output constraint '=v[1:2]' in asm}} + + c[i] = ci; +} + +void test_long(int arg0) { + long v15_16; + __asm volatile("v_lshlrev_b64 v[15:16], 0, %0" : "={v[15:16]}"(v15_16) : "v"(arg0)); +} diff --git a/clang/test/SemaCUDA/allow-int128.cu b/clang/test/SemaCUDA/allow-int128.cu index eb7b7e7f52862b38acc64d7c364e350041b1e3c3..af3e8c2453ad184d71648ff25cff211668ed3c4f 100644 --- a/clang/test/SemaCUDA/allow-int128.cu +++ b/clang/test/SemaCUDA/allow-int128.cu @@ -1,6 +1,9 @@ // RUN: %clang_cc1 -triple amdgcn-amd-amdhsa \ // RUN: -aux-triple x86_64-unknown-linux-gnu \ // RUN: -fcuda-is-device -verify -fsyntax-only %s +// RUN: %clang_cc1 -triple spirv64-amd-amdhsa \ +// RUN: -aux-triple x86_64-unknown-linux-gnu \ +// RUN: -fcuda-is-device -verify -fsyntax-only %s // RUN: %clang_cc1 -triple nvptx \ // RUN: -aux-triple x86_64-unknown-linux-gnu \ // RUN: -fcuda-is-device -verify -fsyntax-only %s diff --git a/clang/test/SemaCUDA/amdgpu-f128.cu b/clang/test/SemaCUDA/amdgpu-f128.cu index 9a0212cdb93cffa78b0f9bc0d27c547764cabff9..1f5a6553dcc4fdc0f3d6ea10ce5288e652114b1d 100644 --- a/clang/test/SemaCUDA/amdgpu-f128.cu +++ b/clang/test/SemaCUDA/amdgpu-f128.cu @@ -1,4 +1,5 @@ // RUN: %clang_cc1 -triple amdgcn-amd-amdhsa -aux-triple x86_64-unknown-linux-gnu -fcuda-is-device -fsyntax-only -verify %s +// RUN: %clang_cc1 -triple spirv64-amd-amdhsa -aux-triple x86_64-unknown-linux-gnu -fcuda-is-device -fsyntax-only -verify %s // expected-no-diagnostics typedef __float128 f128_t; diff --git a/clang/test/SemaCUDA/float16.cu b/clang/test/SemaCUDA/float16.cu index bb5ed6064384918803db62310f46abb46f6bfa8a..9c7faef284fee76d96107d64d4523ab05d2d6394 100644 --- a/clang/test/SemaCUDA/float16.cu +++ b/clang/test/SemaCUDA/float16.cu @@ -1,4 +1,5 @@ // RUN: %clang_cc1 -fsyntax-only -triple x86_64 -aux-triple amdgcn -verify %s +// RUN: %clang_cc1 -fsyntax-only -triple x86_64 -aux-triple spirv64-amd-amdhsa -verify %s // RUN: %clang_cc1 -fsyntax-only -triple x86_64 -aux-triple nvptx64 -verify %s // expected-no-diagnostics #include "Inputs/cuda.h" diff --git a/clang/test/SemaCUDA/fp16-arg-return.cu b/clang/test/SemaCUDA/fp16-arg-return.cu index 46d543f44445dc8b2cf9c424ca80a6a508e26286..9347491caa97b9e69bac292abf4446b46b4c06a7 100644 --- a/clang/test/SemaCUDA/fp16-arg-return.cu +++ b/clang/test/SemaCUDA/fp16-arg-return.cu @@ -1,4 +1,5 @@ // RUN: %clang_cc1 -o - -triple amdgcn-amd-amdhsa -fcuda-is-device -fsyntax-only -verify %s +// RUN: %clang_cc1 -o - -triple spirv64-amd-amdhsa -fcuda-is-device -fsyntax-only -verify %s // expected-no-diagnostics diff --git a/clang/test/SemaCUDA/function-redclare.cu b/clang/test/SemaCUDA/function-redclare.cu new file mode 100644 index 0000000000000000000000000000000000000000..7cd9bad79ae98872ec8969bbec7b547d7ca025ca --- /dev/null +++ b/clang/test/SemaCUDA/function-redclare.cu @@ -0,0 +1,19 @@ +// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fsyntax-only \ +// RUN: -isystem %S/Inputs -verify %s +// RUN: %clang_cc1 -triple nvptx64-nvidia-cuda -fsyntax-only \ +// RUN: -isystem %S/Inputs -fcuda-is-device -verify %s +// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fsyntax-only \ +// RUN: -isystem %S/Inputs -verify=redecl -Wnvcc-compat %s +// RUN: %clang_cc1 -triple nvptx64-nvidia-cuda -fsyntax-only \ +// RUN: -isystem %S/Inputs -fcuda-is-device -Wnvcc-compat -verify=redecl %s + +// expected-no-diagnostics +#include "cuda.h" + +__device__ void f(); // redecl-note {{previous declaration is here}} + +void f() {} // redecl-warning {{target-attribute based function overloads are not supported by NVCC and will be treated as a function redeclaration:new declaration is __host__ function, old declaration is __device__ function}} + +void g(); // redecl-note {{previous declaration is here}} + +__device__ void g() {} // redecl-warning {{target-attribute based function overloads are not supported by NVCC and will be treated as a function redeclaration:new declaration is __device__ function, old declaration is __host__ function}} diff --git a/clang/test/SemaCUDA/spirv-amdgcn-atomic-ops.cu b/clang/test/SemaCUDA/spirv-amdgcn-atomic-ops.cu new file mode 100644 index 0000000000000000000000000000000000000000..ea1f24670ff9a815c0b84824776dab48ffab1ea6 --- /dev/null +++ b/clang/test/SemaCUDA/spirv-amdgcn-atomic-ops.cu @@ -0,0 +1,86 @@ +// RUN: %clang_cc1 -x hip -std=c++11 -triple spirv64-amd-amdhsa -fcuda-is-device -verify -fsyntax-only %s + +#include "Inputs/cuda.h" + +__device__ int test_hip_atomic_load(int *pi32, unsigned int *pu32, long long *pll, unsigned long long *pull, float *fp, double *dbl) { + int val = __hip_atomic_load(0); // expected-error {{too few arguments to function call, expected 3, have 1}} + val = __hip_atomic_load(0, 0, 0, 0); // expected-error {{too many arguments to function call, expected 3, have 4}} + val = __hip_atomic_load(0, 0, 0); // expected-error {{address argument to atomic builtin must be a pointer ('int' invalid)}} + val = __hip_atomic_load(pi32, 0, 0); // expected-error {{synchronization scope argument to atomic operation is invalid}} + val = __hip_atomic_load(pi32, __ATOMIC_RELAXED, __HIP_MEMORY_SCOPE_SINGLETHREAD); + val = __hip_atomic_load(pi32, __ATOMIC_RELAXED, __HIP_MEMORY_SCOPE_WAVEFRONT); + val = __hip_atomic_load(pi32, __ATOMIC_RELAXED, __HIP_MEMORY_SCOPE_WORKGROUP); + val = __hip_atomic_load(pi32, __ATOMIC_RELAXED, __HIP_MEMORY_SCOPE_AGENT); + val = __hip_atomic_load(pi32, __ATOMIC_RELAXED, __HIP_MEMORY_SCOPE_SYSTEM); + val = __hip_atomic_load(pi32, __ATOMIC_RELAXED, 6); // expected-error {{synchronization scope argument to atomic operation is invalid}} + val = __hip_atomic_load(pi32, __ATOMIC_RELAXED, __HIP_MEMORY_SCOPE_SINGLETHREAD); + val = __hip_atomic_load(pi32, __ATOMIC_SEQ_CST, __HIP_MEMORY_SCOPE_SINGLETHREAD); + val = __hip_atomic_load(pi32, __ATOMIC_CONSUME, __HIP_MEMORY_SCOPE_SINGLETHREAD); + val = __hip_atomic_load(pi32, __ATOMIC_ACQUIRE, __HIP_MEMORY_SCOPE_SINGLETHREAD); + val = __hip_atomic_load(pi32, __ATOMIC_ACQ_REL, __HIP_MEMORY_SCOPE_SINGLETHREAD); // expected-warning{{memory order argument to atomic operation is invalid}} + val = __hip_atomic_load(pu32, __ATOMIC_RELAXED, __HIP_MEMORY_SCOPE_SINGLETHREAD); + val = __hip_atomic_load(pll, __ATOMIC_RELAXED, __HIP_MEMORY_SCOPE_SINGLETHREAD); + val = __hip_atomic_load(pull, __ATOMIC_RELAXED, __HIP_MEMORY_SCOPE_SINGLETHREAD); + val = __hip_atomic_load(fp, __ATOMIC_RELAXED, __HIP_MEMORY_SCOPE_SINGLETHREAD); + val = __hip_atomic_load(dbl, __ATOMIC_RELAXED, __HIP_MEMORY_SCOPE_SINGLETHREAD); + return val; +} + +__device__ int test_hip_atomic_store(int *pi32, unsigned int *pu32, long long *pll, unsigned long long *pull, float *fp, double *dbl, + int i32, unsigned int u32, long long i64, unsigned long long u64, float f32, double f64) { + __hip_atomic_store(0); // expected-error {{too few arguments to function call, expected 4, have 1}} + __hip_atomic_store(0, 0, 0, 0, 0); // expected-error {{too many arguments to function call, expected 4, have 5}} + __hip_atomic_store(0, 0, 0, 0); // expected-error {{address argument to atomic builtin must be a pointer ('int' invalid)}} + __hip_atomic_store(pi32, 0, 0, 0); // expected-error {{synchronization scope argument to atomic operation is invalid}} + __hip_atomic_store(pi32, 0, __ATOMIC_RELAXED, __HIP_MEMORY_SCOPE_SINGLETHREAD); + __hip_atomic_store(pi32, 0, __ATOMIC_RELAXED, __HIP_MEMORY_SCOPE_WAVEFRONT); + __hip_atomic_store(pi32, 0, __ATOMIC_RELAXED, __HIP_MEMORY_SCOPE_WORKGROUP); + __hip_atomic_store(pi32, 0, __ATOMIC_RELAXED, __HIP_MEMORY_SCOPE_AGENT); + __hip_atomic_store(pi32, 0, __ATOMIC_RELAXED, __HIP_MEMORY_SCOPE_SYSTEM); + __hip_atomic_store(pi32, 0, __ATOMIC_RELAXED, 6); // expected-error {{synchronization scope argument to atomic operation is invalid}} + __hip_atomic_store(pi32, 0, __ATOMIC_RELAXED, __HIP_MEMORY_SCOPE_SINGLETHREAD); + __hip_atomic_store(pi32, 0, __ATOMIC_SEQ_CST, __HIP_MEMORY_SCOPE_SINGLETHREAD); + __hip_atomic_store(pi32, 0, __ATOMIC_CONSUME, __HIP_MEMORY_SCOPE_SINGLETHREAD); // expected-warning{{memory order argument to atomic operation is invalid}} + __hip_atomic_store(pi32, 0, __ATOMIC_ACQUIRE, __HIP_MEMORY_SCOPE_SINGLETHREAD); // expected-warning{{memory order argument to atomic operation is invalid}} + __hip_atomic_store(pi32, 0, __ATOMIC_ACQ_REL, __HIP_MEMORY_SCOPE_SINGLETHREAD); // expected-warning{{memory order argument to atomic operation is invalid}} + __hip_atomic_store(pi32, i32, __ATOMIC_RELAXED, __HIP_MEMORY_SCOPE_SINGLETHREAD); + __hip_atomic_store(pi32, i32, __ATOMIC_RELAXED, __HIP_MEMORY_SCOPE_SINGLETHREAD); + __hip_atomic_store(pu32, u32, __ATOMIC_RELAXED, __HIP_MEMORY_SCOPE_SINGLETHREAD); + __hip_atomic_store(pll, i64, __ATOMIC_RELAXED, __HIP_MEMORY_SCOPE_SINGLETHREAD); + __hip_atomic_store(pull, u64, __ATOMIC_RELAXED, __HIP_MEMORY_SCOPE_SINGLETHREAD); + __hip_atomic_store(fp, f32, __ATOMIC_RELAXED, __HIP_MEMORY_SCOPE_SINGLETHREAD); + __hip_atomic_store(dbl, f64, __ATOMIC_RELAXED, __HIP_MEMORY_SCOPE_SINGLETHREAD); + __hip_atomic_store(pi32, u32, __ATOMIC_RELAXED, __HIP_MEMORY_SCOPE_SINGLETHREAD); + __hip_atomic_store(pi32, i64, __ATOMIC_RELAXED, __HIP_MEMORY_SCOPE_SINGLETHREAD); + __hip_atomic_store(pi32, u64, __ATOMIC_RELAXED, __HIP_MEMORY_SCOPE_SINGLETHREAD); + __hip_atomic_store(pll, i32, __ATOMIC_RELAXED, __HIP_MEMORY_SCOPE_SINGLETHREAD); + __hip_atomic_store(fp, i32, __ATOMIC_RELAXED, __HIP_MEMORY_SCOPE_SINGLETHREAD); + __hip_atomic_store(fp, i64, __ATOMIC_RELAXED, __HIP_MEMORY_SCOPE_SINGLETHREAD); + __hip_atomic_store(dbl, i64, __ATOMIC_RELAXED, __HIP_MEMORY_SCOPE_SINGLETHREAD); + __hip_atomic_store(dbl, i32, __ATOMIC_RELAXED, __HIP_MEMORY_SCOPE_SINGLETHREAD); + return 0; +} + +__device__ bool test_hip_atomic_cmpxchg_weak(int *ptr, int val, int desired) { + bool flag = __hip_atomic_compare_exchange_weak(0); // expected-error {{too few arguments to function call, expected 6, have 1}} + flag = __hip_atomic_compare_exchange_weak(0, 0, 0, 0, 0, 0, 0); // expected-error {{too many arguments to function call, expected 6, have 7}} + flag = __hip_atomic_compare_exchange_weak(0, 0, 0, 0, 0, 0); // expected-error {{address argument to atomic builtin must be a pointer ('int' invalid)}} + flag = __hip_atomic_compare_exchange_weak(ptr, 0, 0, 0, 0, 0); // expected-error {{synchronization scope argument to atomic operation is invalid}}, expected-warning {{null passed to a callee that requires a non-null argument}} + flag = __hip_atomic_compare_exchange_weak(ptr, 0, 0, 0, 0, __HIP_MEMORY_SCOPE_SYSTEM); // expected-warning {{null passed to a callee that requires a non-null argument}} + flag = __hip_atomic_compare_exchange_weak(ptr, &val, desired, __ATOMIC_RELAXED, __ATOMIC_RELAXED, __HIP_MEMORY_SCOPE_SYSTEM); + flag = __hip_atomic_compare_exchange_weak(ptr, &val, desired, __ATOMIC_CONSUME, __ATOMIC_RELAXED, __HIP_MEMORY_SCOPE_SINGLETHREAD); + flag = __hip_atomic_compare_exchange_weak(ptr, &val, desired, __ATOMIC_RELAXED, __ATOMIC_RELAXED, __HIP_MEMORY_SCOPE_WAVEFRONT); + flag = __hip_atomic_compare_exchange_weak(ptr, &val, desired, __ATOMIC_RELAXED, __ATOMIC_RELAXED, __HIP_MEMORY_SCOPE_WORKGROUP); + flag = __hip_atomic_compare_exchange_weak(ptr, &val, desired, __ATOMIC_RELAXED, __ATOMIC_RELAXED, __HIP_MEMORY_SCOPE_AGENT); + flag = __hip_atomic_compare_exchange_weak(ptr, &val, desired, __ATOMIC_RELAXED, __ATOMIC_RELAXED, __HIP_MEMORY_SCOPE_SINGLETHREAD); + flag = __hip_atomic_compare_exchange_weak(ptr, &val, desired, __ATOMIC_RELAXED, __ATOMIC_SEQ_CST, __HIP_MEMORY_SCOPE_SINGLETHREAD); + flag = __hip_atomic_compare_exchange_weak(ptr, &val, desired, __ATOMIC_RELAXED, __ATOMIC_CONSUME, __HIP_MEMORY_SCOPE_SINGLETHREAD); + flag = __hip_atomic_compare_exchange_weak(ptr, &val, desired, __ATOMIC_RELAXED, __ATOMIC_ACQUIRE, __HIP_MEMORY_SCOPE_SINGLETHREAD); + flag = __hip_atomic_compare_exchange_weak(ptr, &val, desired, __ATOMIC_RELAXED, __ATOMIC_ACQ_REL, __HIP_MEMORY_SCOPE_SINGLETHREAD); // expected-warning {{failure memory order argument to atomic operation is invalid}} + flag = __hip_atomic_compare_exchange_weak(ptr, &val, desired, __ATOMIC_RELAXED, __ATOMIC_RELAXED, __HIP_MEMORY_SCOPE_SINGLETHREAD); + flag = __hip_atomic_compare_exchange_weak(ptr, &val, desired, __ATOMIC_SEQ_CST, __ATOMIC_RELAXED, __HIP_MEMORY_SCOPE_SINGLETHREAD); + flag = __hip_atomic_compare_exchange_weak(ptr, &val, desired, __ATOMIC_CONSUME, __ATOMIC_RELAXED, __HIP_MEMORY_SCOPE_SINGLETHREAD); + flag = __hip_atomic_compare_exchange_weak(ptr, &val, desired, __ATOMIC_ACQUIRE, __ATOMIC_RELAXED, __HIP_MEMORY_SCOPE_SINGLETHREAD); + flag = __hip_atomic_compare_exchange_weak(ptr, &val, desired, __ATOMIC_ACQ_REL, __ATOMIC_RELAXED, __HIP_MEMORY_SCOPE_SINGLETHREAD); + return flag; +} diff --git a/clang/test/SemaCXX/PR8755.cpp b/clang/test/SemaCXX/PR8755.cpp index 6818f3f0a82276fe4f52794cc82cbe9836ebf5a2..c0bcab3537d654691fbb1070ba147c9285518534 100644 --- a/clang/test/SemaCXX/PR8755.cpp +++ b/clang/test/SemaCXX/PR8755.cpp @@ -7,7 +7,7 @@ struct A { template void f() { - class A ::iterator foo; // expected-error{{typedef 'iterator' cannot be referenced with a class specifier}} + class A ::iterator foo; // expected-error{{typedef 'iterator' cannot be referenced with the 'class' specifier}} } void g() { diff --git a/clang/test/SemaCXX/attr-weak.cpp b/clang/test/SemaCXX/attr-weak.cpp index f065bfd9483f8a127f4add93d6ecf988f4b5d08d..0f9a2975e5f68e8f3167ef3d6dad853febe021a1 100644 --- a/clang/test/SemaCXX/attr-weak.cpp +++ b/clang/test/SemaCXX/attr-weak.cpp @@ -1,4 +1,5 @@ // RUN: %clang_cc1 -triple x86_64-pc-linux-gnu -fsyntax-only -verify -std=c++11 %s +// RUN: %clang_cc1 -triple x86_64-pc-linux-gnu -fsyntax-only -verify -std=c++11 %s -fexperimental-new-constant-interpreter static int test0 __attribute__((weak)); // expected-error {{weak declaration cannot have internal linkage}} static void test1() __attribute__((weak)); // expected-error {{weak declaration cannot have internal linkage}} diff --git a/clang/test/SemaCXX/builtin-is-bitwise-cloneable-fsanitize.cpp b/clang/test/SemaCXX/builtin-is-bitwise-cloneable-fsanitize.cpp new file mode 100644 index 0000000000000000000000000000000000000000..d47a39a0754c54f1f7659304e0affd1747323391 --- /dev/null +++ b/clang/test/SemaCXX/builtin-is-bitwise-cloneable-fsanitize.cpp @@ -0,0 +1,34 @@ +// RUN: %clang_cc1 -triple x86_64-unknown-linux -DSANITIZER_ENABLED -fsanitize=address -fsanitize-address-field-padding=1 %s +// RUN: %clang_cc1 -triple x86_64-unknown-linux %s + +struct S { + ~S() {} + virtual void foo() {} + + int buffer[1]; + int other_field = 0; +}; + +union U { + S s; +}; + +struct Derived : S {}; + +static_assert(!__is_trivially_copyable(S)); +#ifdef SANITIZER_ENABLED +// Don't allow memcpy when the struct has poisoned padding bits. +// The sanitizer adds posion padding bits to struct S. +static_assert(sizeof(S) > 16); +static_assert(!__is_bitwise_cloneable(S)); +static_assert(sizeof(U) == sizeof(S)); // no padding bit for U. +static_assert(!__is_bitwise_cloneable(U)); +static_assert(!__is_bitwise_cloneable(S[2])); +static_assert(!__is_bitwise_cloneable(Derived)); +#else +static_assert(sizeof(S) == 16); +static_assert(__is_bitwise_cloneable(S)); +static_assert(__is_bitwise_cloneable(U)); +static_assert(__is_bitwise_cloneable(S[2])); +static_assert(__is_bitwise_cloneable(Derived)); +#endif diff --git a/clang/test/SemaCXX/builtin-is-bitwise-cloneable.cpp b/clang/test/SemaCXX/builtin-is-bitwise-cloneable.cpp new file mode 100644 index 0000000000000000000000000000000000000000..1781cf48449f6218b7eff0876093a56573c0d0c0 --- /dev/null +++ b/clang/test/SemaCXX/builtin-is-bitwise-cloneable.cpp @@ -0,0 +1,8 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s +// +struct DynamicClass { virtual int Foo(); }; +static_assert(!__is_trivially_copyable(DynamicClass)); +static_assert(__is_bitwise_cloneable(DynamicClass)); + +struct InComplete; // expected-note{{forward declaration}} +static_assert(!__is_bitwise_cloneable(InComplete)); // expected-error{{incomplete type 'InComplete' used in type trait expression}} diff --git a/clang/test/SemaCXX/complex-folding.cpp b/clang/test/SemaCXX/complex-folding.cpp index 054f159e9ce0dd2dd79b00f1a355f78a0b318847..7bfd36f156ea61e1f99d6b01f6bb00fc94876ca3 100644 --- a/clang/test/SemaCXX/complex-folding.cpp +++ b/clang/test/SemaCXX/complex-folding.cpp @@ -59,41 +59,48 @@ static_assert((1.25 / (0.25 - 0.75j)) == (0.5 + 1.5j)); // Test that infinities are preserved, don't turn into NaNs, and do form zeros // when the divisor. +constexpr _Complex float InfC = {1.0, __builtin_inf()}; +constexpr _Complex float InfInf = __builtin_inf() + InfC; +static_assert(__real__(InfInf) == __builtin_inf()); +static_assert(__imag__(InfInf) == __builtin_inf()); +static_assert(__builtin_isnan(__real__(InfInf * InfInf))); +static_assert(__builtin_isinf_sign(__imag__(InfInf * InfInf)) == 1); + static_assert(__builtin_isinf_sign(__real__((__builtin_inf() + 1.0j) * 1.0)) == 1); -static_assert(__builtin_isinf_sign(__imag__((1.0 + __builtin_inf() * 1.0j) * 1.0)) == 1); +static_assert(__builtin_isinf_sign(__imag__((1.0 + InfC) * 1.0)) == 1); static_assert(__builtin_isinf_sign(__real__(1.0 * (__builtin_inf() + 1.0j))) == 1); -static_assert(__builtin_isinf_sign(__imag__(1.0 * (1.0 + __builtin_inf() * 1.0j))) == 1); - +static_assert(__builtin_isinf_sign(__imag__(1.0 * (1.0 + InfC))) == 1); static_assert(__builtin_isinf_sign(__real__((__builtin_inf() + 1.0j) * (1.0 + 1.0j))) == 1); static_assert(__builtin_isinf_sign(__real__((1.0 + 1.0j) * (__builtin_inf() + 1.0j))) == 1); static_assert(__builtin_isinf_sign(__real__((__builtin_inf() + 1.0j) * (__builtin_inf() + 1.0j))) == 1); - -static_assert(__builtin_isinf_sign(__real__((1.0 + __builtin_inf() * 1.0j) * (1.0 + 1.0j))) == -1); -static_assert(__builtin_isinf_sign(__imag__((1.0 + __builtin_inf() * 1.0j) * (1.0 + 1.0j))) == 1); -static_assert(__builtin_isinf_sign(__real__((1.0 + 1.0j) * (1.0 + __builtin_inf() * 1.0j))) == -1); -static_assert(__builtin_isinf_sign(__imag__((1.0 + 1.0j) * (1.0 + __builtin_inf() * 1.0j))) == 1); - -static_assert(__builtin_isinf_sign(__real__((1.0 + __builtin_inf() * 1.0j) * (1.0 + __builtin_inf() * 1.0j))) == -1); -static_assert(__builtin_isinf_sign(__real__((__builtin_inf() + __builtin_inf() * 1.0j) * (__builtin_inf() + __builtin_inf() * 1.0j))) == -1); - +static_assert(__builtin_isinf_sign(__real__((1.0 + InfC) * (1.0 + 1.0j))) == -1); +static_assert(__builtin_isinf_sign(__imag__((1.0 + InfC) * (1.0 + 1.0j))) == 1); +static_assert(__builtin_isinf_sign(__real__((1.0 + 1.0j) * (1.0 + InfC))) == -1); +static_assert(__builtin_isinf_sign(__imag__((1.0 + 1.0j) * (1.0 + InfC))) == 1); +static_assert(__builtin_isinf_sign(__real__((1.0 + InfC) * (1.0 + InfC))) == -1); +static_assert(__builtin_isinf_sign(__real__(InfInf * InfInf)) == 0); static_assert(__builtin_isinf_sign(__real__((__builtin_inf() + 1.0j) / (1.0 + 1.0j))) == 1); -static_assert(__builtin_isinf_sign(__imag__(1.0 + (__builtin_inf() * 1.0j) / (1.0 + 1.0j))) == 1); -static_assert(__builtin_isinf_sign(__imag__((__builtin_inf() + __builtin_inf() * 1.0j) / (1.0 + 1.0j))) == 1); +static_assert(__builtin_isinf_sign(__imag__(1.0 + (InfC) / (1.0 + 1.0j))) == 1); +static_assert(__builtin_isinf_sign(__imag__((InfInf) / (1.0 + 1.0j))) == 0); static_assert(__builtin_isinf_sign(__real__((__builtin_inf() + 1.0j) / 1.0)) == 1); -static_assert(__builtin_isinf_sign(__imag__(1.0 + (__builtin_inf() * 1.0j) / 1.0)) == 1); -static_assert(__builtin_isinf_sign(__imag__((__builtin_inf() + __builtin_inf() * 1.0j) / 1.0)) == 1); - +static_assert(__builtin_isinf_sign(__imag__(1.0 + (InfC) / 1.0)) == 1); +static_assert(__builtin_isinf_sign(__imag__((InfInf) / 1.0)) == 1); static_assert(((1.0 + 1.0j) / (__builtin_inf() + 1.0j)) == (0.0 + 0.0j)); -static_assert(((1.0 + 1.0j) / (1.0 + __builtin_inf() * 1.0j)) == (0.0 + 0.0j)); -static_assert(((1.0 + 1.0j) / (__builtin_inf() + __builtin_inf() * 1.0j)) == (0.0 + 0.0j)); +static_assert(((1.0 + 1.0j) / (1.0 + InfC)) == (0.0 + 0.0j)); +static_assert(((1.0 + 1.0j) / (InfInf)) == (0.0 + 0.0j)); static_assert(((1.0 + 1.0j) / __builtin_inf()) == (0.0 + 0.0j)); - +static_assert(1.0j / 0.0 == 1); // expected-error {{static assertion}} \ + // expected-note {{division by zero}} static_assert(__builtin_isinf_sign(__real__((1.0 + 1.0j) / (0.0 + 0.0j))) == 1); -static_assert(__builtin_isinf_sign(__real__((1.0 + 1.0j) / 0.0)) == 1); - +static_assert(__builtin_isinf_sign(__real__((1.0 + 1.0j) / 0.0)) == 1); // expected-error {{static assertion}} \ + // expected-note {{division by zero}} static_assert(__builtin_isinf_sign(__real__((__builtin_inf() + 1.0j) / (0.0 + 0.0j))) == 1); -static_assert(__builtin_isinf_sign(__imag__((1.0 + __builtin_inf() * 1.0j) / (0.0 + 0.0j))) == 1); -static_assert(__builtin_isinf_sign(__imag__((__builtin_inf() + __builtin_inf() * 1.0j) / (0.0 + 0.0j))) == 1); -static_assert(__builtin_isinf_sign(__real__((__builtin_inf() + 1.0j) / 0.0)) == 1); -static_assert(__builtin_isinf_sign(__imag__((1.0 + __builtin_inf() * 1.0j) / 0.0)) == 1); -static_assert(__builtin_isinf_sign(__imag__((__builtin_inf() + __builtin_inf() * 1.0j) / 0.0)) == 1); +static_assert(__builtin_isinf_sign(__imag__((1.0 + InfC) / (0.0 + 0.0j))) == 1); +static_assert(__builtin_isinf_sign(__imag__((InfInf) / (0.0 + 0.0j))) == 1); +static_assert(__builtin_isinf_sign(__real__((__builtin_inf() + 1.0j) / 0.0)) == 1); // expected-error {{static assertion}} \ + // expected-note {{division by zero}} +static_assert(__builtin_isinf_sign(__imag__((1.0 + InfC) / 0.0)) == 1); // expected-error {{static assertion}} \ + // expected-note {{division by zero}} +static_assert(__builtin_isinf_sign(__imag__((InfInf) / 0.0)) == 1); // expected-error {{static assertion}} \ + // expected-note {{division by zero}} + diff --git a/clang/test/SemaCXX/constant-expression-cxx14.cpp b/clang/test/SemaCXX/constant-expression-cxx14.cpp index 80a7a2dd31531c4fbd933745be3390b36a7af8dc..70ab5dcd357c1caa4d6d6adaf38b74c55b36dea7 100644 --- a/clang/test/SemaCXX/constant-expression-cxx14.cpp +++ b/clang/test/SemaCXX/constant-expression-cxx14.cpp @@ -82,7 +82,7 @@ constexpr void k() { // If the return type is not 'void', no return statements => never a constant // expression, so still diagnose that case. -[[noreturn]] constexpr int fn() { // expected-error {{no return statement in constexpr function}} +[[noreturn]] constexpr int fn() { // cxx14_20-error {{no return statement in constexpr function}} fn(); } diff --git a/clang/test/SemaCXX/constexpr-default-arg.cpp b/clang/test/SemaCXX/constexpr-default-arg.cpp index 901123bfb359ff17bba26b8d4eb7fffe384ed333..ec9b2927880bdfb69c4c71dde805b00fbf26bcf5 100644 --- a/clang/test/SemaCXX/constexpr-default-arg.cpp +++ b/clang/test/SemaCXX/constexpr-default-arg.cpp @@ -32,8 +32,8 @@ void test_default_arg2() { } // Check that multiple CXXDefaultInitExprs don't cause an assertion failure. -struct A { int &&r = 0; }; +struct A { int &&r = 0; }; // expected-note 2{{default member initializer}} struct B { A x, y; }; -B b = {}; // expected-no-diagnostics +B b = {}; // expected-warning 2{{lifetime extension of temporary created by aggregate initialization using a default member initializer is not yet supported}} } diff --git a/clang/test/SemaCXX/constexpr-return-non-void-cxx2b.cpp b/clang/test/SemaCXX/constexpr-return-non-void-cxx2b.cpp new file mode 100644 index 0000000000000000000000000000000000000000..25d1f8df7f71663a99dbacc022e1b9f9db821ff7 --- /dev/null +++ b/clang/test/SemaCXX/constexpr-return-non-void-cxx2b.cpp @@ -0,0 +1,7 @@ +// RUN: %clang_cc1 -std=c++23 -fsyntax-only -verify %s + +constexpr int f() { } // expected-warning {{non-void function does not return a value}} +static_assert(__is_same(decltype([] constexpr -> int { }( )), int)); // expected-warning {{non-void lambda does not return a value}} + +consteval int g() { } // expected-warning {{non-void function does not return a value}} +static_assert(__is_same(decltype([] consteval -> int { }( )), int)); // expected-warning {{non-void lambda does not return a value}} diff --git a/clang/test/SemaCXX/cxx11-default-member-initializers.cpp b/clang/test/SemaCXX/cxx11-default-member-initializers.cpp index 1ea8b98cd86367f41c1927b24e7b523fd07e6835..dd8e9c6b7fc11f0384840513a17afa4723cb484e 100644 --- a/clang/test/SemaCXX/cxx11-default-member-initializers.cpp +++ b/clang/test/SemaCXX/cxx11-default-member-initializers.cpp @@ -27,80 +27,6 @@ class MemInit { C m = s; }; -namespace std { -typedef decltype(sizeof(int)) size_t; - -// libc++'s implementation -template class initializer_list { - const _E *__begin_; - size_t __size_; - - initializer_list(const _E *__b, size_t __s) : __begin_(__b), __size_(__s) {} - -public: - typedef _E value_type; - typedef const _E &reference; - typedef const _E &const_reference; - typedef size_t size_type; - - typedef const _E *iterator; - typedef const _E *const_iterator; - - initializer_list() : __begin_(nullptr), __size_(0) {} - - size_t size() const { return __size_; } - const _E *begin() const { return __begin_; } - const _E *end() const { return __begin_ + __size_; } -}; -} // namespace std - -#if __cplusplus >= 201703L -namespace test_rebuild { -template class C { -public: - C(std::initializer_list); -}; - -template using Ptr = __remove_pointer(T) *; -template C(T) -> C, sizeof(T)>; - -class A { -public: - template T1 *some_func(T2 &&); -}; - -struct B : A { - // Test CXXDefaultInitExpr rebuild issue in - // https://github.com/llvm/llvm-project/pull/87933 - int *ar = some_func(C{some_func(0)}); - B() {} -}; - -int TestBody_got; -template class Vector { -public: - Vector(std::initializer_list); -}; -template Vector(Ts...) -> Vector; -class ProgramBuilder { -public: - template int *create(ARGS); -}; - -struct TypeTest : ProgramBuilder { - int *str_f16 = create(Vector{0}); - TypeTest() {} -}; -class TypeTest_Element_Test : TypeTest { - void TestBody(); -}; -void TypeTest_Element_Test::TestBody() { - int *expect = str_f16; - &TestBody_got != expect; // expected-warning {{inequality comparison result unused}} -} -} // namespace test_rebuild -#endif // __cplusplus >= 201703L - #if __cplusplus >= 202002L // This test ensures cleanup expressions are correctly produced // in the presence of default member initializers. diff --git a/clang/test/SemaCXX/cxx2b-deducing-this.cpp b/clang/test/SemaCXX/cxx2b-deducing-this.cpp index cdb9d1324b974156da967111eccc915cc6c52fc1..2c19b091fabad025930f8cfed694951ebf106a5b 100644 --- a/clang/test/SemaCXX/cxx2b-deducing-this.cpp +++ b/clang/test/SemaCXX/cxx2b-deducing-this.cpp @@ -893,3 +893,28 @@ void g() { a * lval; } } + +namespace P2797 { +struct C { + void c(this const C&); // #first + void c() &; // #second + static void c(int = 0); // #third + + void d() { + c(); // expected-error {{call to member function 'c' is ambiguous}} + // expected-note@#first {{candidate function}} + // expected-note@#second {{candidate function}} + // expected-note@#third {{candidate function}} + + (C::c)(); // expected-error {{call to member function 'c' is ambiguous}} + // expected-note@#first {{candidate function}} + // expected-note@#second {{candidate function}} + // expected-note@#third {{candidate function}} + + (&(C::c))(); // expected-error {{cannot create a non-constant pointer to member function}} + (&C::c)(C{}); + (&C::c)(*this); // expected-error {{call to non-static member function without an object argument}} + (&C::c)(); + } +}; +} diff --git a/clang/test/SemaCXX/eval-crashes.cpp b/clang/test/SemaCXX/eval-crashes.cpp index a06f60f71e9c7ee056a3ccbfdc203778741784b9..017df977b26b7b08637d39c5943ee1634b8d6592 100644 --- a/clang/test/SemaCXX/eval-crashes.cpp +++ b/clang/test/SemaCXX/eval-crashes.cpp @@ -25,9 +25,11 @@ namespace pr33140_0b { } namespace pr33140_2 { - struct A { int &&r = 0; }; + // FIXME: The declaration of 'b' below should lifetime-extend two int + // temporaries. + struct A { int &&r = 0; }; // expected-note 2{{initializing field 'r' with default member initializer}} struct B { A x, y; }; - B b = {}; + B b = {}; // expected-warning 2{{lifetime extension of temporary created by aggregate initialization using a default member initializer is not yet supported}} } namespace pr33140_3 { diff --git a/clang/test/SemaCXX/for-range-examples.cpp b/clang/test/SemaCXX/for-range-examples.cpp index d129d50d673e162da8f4ea6a7316de7d413c1c9f..c06bf0102bcfead12199b0071ed35fa0cc70d515 100644 --- a/clang/test/SemaCXX/for-range-examples.cpp +++ b/clang/test/SemaCXX/for-range-examples.cpp @@ -1,4 +1,5 @@ // RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++11 +// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++11 -fexperimental-new-constant-interpreter namespace value_range_detail { template diff --git a/clang/test/SemaCXX/integer-overflow.cpp b/clang/test/SemaCXX/integer-overflow.cpp index 6049458b93bbd094a10eb60e5d13ca398d706c04..d1cc8bee566f6b0409e75bebcc5c8bdb1e7234d0 100644 --- a/clang/test/SemaCXX/integer-overflow.cpp +++ b/clang/test/SemaCXX/integer-overflow.cpp @@ -1,6 +1,10 @@ // RUN: %clang_cc1 %s -verify -fsyntax-only -std=gnu++98 -triple x86_64-pc-linux-gnu // RUN: %clang_cc1 %s -verify -fsyntax-only -std=gnu++2a -triple x86_64-pc-linux-gnu +// RUN: %clang_cc1 %s -verify -fsyntax-only -std=gnu++98 -triple x86_64-pc-linux-gnu -fexperimental-new-constant-interpreter +// RUN: %clang_cc1 %s -verify -fsyntax-only -std=gnu++2a -triple x86_64-pc-linux-gnu -fexperimental-new-constant-interpreter + + typedef unsigned long long uint64_t; typedef unsigned int uint32_t; diff --git a/clang/test/SemaCXX/nullptr_in_arithmetic_ops.cpp b/clang/test/SemaCXX/nullptr_in_arithmetic_ops.cpp index 6273d9c42e0b153fe319e6d41220fec9f75e1ff6..98bec184164b63b012e933d01439640ec69f8712 100644 --- a/clang/test/SemaCXX/nullptr_in_arithmetic_ops.cpp +++ b/clang/test/SemaCXX/nullptr_in_arithmetic_ops.cpp @@ -1,4 +1,5 @@ // RUN: %clang_cc1 -fsyntax-only -Wno-tautological-pointer-compare -fblocks -std=c++11 -verify %s +// RUN: %clang_cc1 -fsyntax-only -Wno-tautological-pointer-compare -fblocks -std=c++11 -verify %s -fexperimental-new-constant-interpreter void foo() { int a; diff --git a/clang/test/SemaCXX/using-decl-templates.cpp b/clang/test/SemaCXX/using-decl-templates.cpp index 77dc596fdfc9f33fd65b6ff6aed65352e2de8ac8..1cf4caee1c0db0dbeca52090a6917a408bfff486 100644 --- a/clang/test/SemaCXX/using-decl-templates.cpp +++ b/clang/test/SemaCXX/using-decl-templates.cpp @@ -90,7 +90,7 @@ namespace aliastemplateinst { template struct A { }; template using APtr = A; // expected-note{{previous use is here}} - template struct APtr; // expected-error{{type alias template 'APtr' cannot be referenced with a struct specifier}} + template struct APtr; // expected-error{{alias template 'APtr' cannot be referenced with the 'struct' specifier}} } namespace DontDiagnoseInvalidTest { diff --git a/clang/test/SemaObjCXX/arc-type-traits.mm b/clang/test/SemaObjCXX/arc-type-traits.mm index 2d30ae450f3b096090c280e01e4d9786f7206967..25bc8b362140a603c173c1a65ac080b5a2f6c7a3 100644 --- a/clang/test/SemaObjCXX/arc-type-traits.mm +++ b/clang/test/SemaObjCXX/arc-type-traits.mm @@ -221,3 +221,12 @@ TRAIT_IS_TRUE(__is_trivially_relocatable, __unsafe_unretained id); TRAIT_IS_TRUE(__is_trivially_relocatable, HasStrong); TRAIT_IS_FALSE(__is_trivially_relocatable, HasWeak); TRAIT_IS_TRUE(__is_trivially_relocatable, HasUnsafeUnretained); + +// __is_bitwise_cloneable +TRAIT_IS_FALSE(__is_bitwise_cloneable, __strong id); +TRAIT_IS_FALSE(__is_bitwise_cloneable, __weak id); +TRAIT_IS_FALSE(__is_bitwise_cloneable, __autoreleasing id); +TRAIT_IS_TRUE(__is_trivial, __unsafe_unretained id); +TRAIT_IS_FALSE(__is_bitwise_cloneable, HasStrong); +TRAIT_IS_FALSE(__is_bitwise_cloneable, HasWeak); +TRAIT_IS_TRUE(__is_bitwise_cloneable, HasUnsafeUnretained); diff --git a/clang/test/SemaOpenACC/compute-construct-async-clause.c b/clang/test/SemaOpenACC/compute-construct-async-clause.c index 999db74ffbb8bab1d2bae80f3df0ab35c05732eb..fe41c5d0897a49e37e7567d81fcb05ca6f2b2d88 100644 --- a/clang/test/SemaOpenACC/compute-construct-async-clause.c +++ b/clang/test/SemaOpenACC/compute-construct-async-clause.c @@ -39,8 +39,7 @@ void Test() { #pragma acc kernels async(SomeE) while(1); - // expected-error@+2{{OpenACC 'async' clause is not valid on 'loop' directive}} - // expected-warning@+1{{OpenACC construct 'loop' not yet implemented}} + // expected-error@+1{{OpenACC 'async' clause is not valid on 'loop' directive}} #pragma acc loop async(1) for(;;); } diff --git a/clang/test/SemaOpenACC/compute-construct-attach-clause.c b/clang/test/SemaOpenACC/compute-construct-attach-clause.c index 7696620271818cc5c2498b3574bafeaa12b1c607..1d204094de12a4bda931e147ea62ffe18f8b966d 100644 --- a/clang/test/SemaOpenACC/compute-construct-attach-clause.c +++ b/clang/test/SemaOpenACC/compute-construct-attach-clause.c @@ -59,8 +59,7 @@ void uses() { #pragma acc parallel attach(s.PtrMem) while (1); - // expected-error@+2{{OpenACC 'attach' clause is not valid on 'loop' directive}} - // expected-warning@+1{{OpenACC construct 'loop' not yet implemented}} + // expected-error@+1{{OpenACC 'attach' clause is not valid on 'loop' directive}} #pragma acc loop attach(LocalInt) for(;;); } diff --git a/clang/test/SemaOpenACC/compute-construct-copy-clause.c b/clang/test/SemaOpenACC/compute-construct-copy-clause.c index 7adf0e18fa042a0e0cbb8d339baa8d30600cf923..284813f2135296363be438283fad74463e113057 100644 --- a/clang/test/SemaOpenACC/compute-construct-copy-clause.c +++ b/clang/test/SemaOpenACC/compute-construct-copy-clause.c @@ -60,16 +60,13 @@ void uses(int IntParam, short *PointerParam, float ArrayParam[5], Complete Compo #pragma acc parallel copy((float)ArrayParam[2]) while(1); - // expected-error@+2{{OpenACC 'copy' clause is not valid on 'loop' directive}} - // expected-warning@+1{{OpenACC construct 'loop' not yet implemented}} + // expected-error@+1{{OpenACC 'copy' clause is not valid on 'loop' directive}} #pragma acc loop copy(LocalInt) for(;;); - // expected-error@+2{{OpenACC 'pcopy' clause is not valid on 'loop' directive}} - // expected-warning@+1{{OpenACC construct 'loop' not yet implemented}} + // expected-error@+1{{OpenACC 'pcopy' clause is not valid on 'loop' directive}} #pragma acc loop pcopy(LocalInt) for(;;); - // expected-error@+2{{OpenACC 'present_or_copy' clause is not valid on 'loop' directive}} - // expected-warning@+1{{OpenACC construct 'loop' not yet implemented}} + // expected-error@+1{{OpenACC 'present_or_copy' clause is not valid on 'loop' directive}} #pragma acc loop present_or_copy(LocalInt) for(;;); } diff --git a/clang/test/SemaOpenACC/compute-construct-copyin-clause.c b/clang/test/SemaOpenACC/compute-construct-copyin-clause.c index d5573577565687b844f3a267afd50d2f76e72694..d4dda1e16737c008de02647e21a018b49389c78a 100644 --- a/clang/test/SemaOpenACC/compute-construct-copyin-clause.c +++ b/clang/test/SemaOpenACC/compute-construct-copyin-clause.c @@ -66,16 +66,13 @@ void uses(int IntParam, short *PointerParam, float ArrayParam[5], Complete Compo #pragma acc parallel copyin(invalid:(float)ArrayParam[2]) while(1); - // expected-error@+2{{OpenACC 'copyin' clause is not valid on 'loop' directive}} - // expected-warning@+1{{OpenACC construct 'loop' not yet implemented}} + // expected-error@+1{{OpenACC 'copyin' clause is not valid on 'loop' directive}} #pragma acc loop copyin(LocalInt) for(;;); - // expected-error@+2{{OpenACC 'pcopyin' clause is not valid on 'loop' directive}} - // expected-warning@+1{{OpenACC construct 'loop' not yet implemented}} + // expected-error@+1{{OpenACC 'pcopyin' clause is not valid on 'loop' directive}} #pragma acc loop pcopyin(LocalInt) for(;;); - // expected-error@+2{{OpenACC 'present_or_copyin' clause is not valid on 'loop' directive}} - // expected-warning@+1{{OpenACC construct 'loop' not yet implemented}} + // expected-error@+1{{OpenACC 'present_or_copyin' clause is not valid on 'loop' directive}} #pragma acc loop present_or_copyin(LocalInt) for(;;); } diff --git a/clang/test/SemaOpenACC/compute-construct-copyout-clause.c b/clang/test/SemaOpenACC/compute-construct-copyout-clause.c index 432823b6746a3a25d5a3838580338fda320883c7..5692ab0f5660cc6b85d23b1aeb5406c73cf7e6f0 100644 --- a/clang/test/SemaOpenACC/compute-construct-copyout-clause.c +++ b/clang/test/SemaOpenACC/compute-construct-copyout-clause.c @@ -66,16 +66,13 @@ void uses(int IntParam, short *PointerParam, float ArrayParam[5], Complete Compo #pragma acc parallel copyout(invalid:(float)ArrayParam[2]) while(1); - // expected-error@+2{{OpenACC 'copyout' clause is not valid on 'loop' directive}} - // expected-warning@+1{{OpenACC construct 'loop' not yet implemented}} + // expected-error@+1{{OpenACC 'copyout' clause is not valid on 'loop' directive}} #pragma acc loop copyout(LocalInt) for(;;); - // expected-error@+2{{OpenACC 'pcopyout' clause is not valid on 'loop' directive}} - // expected-warning@+1{{OpenACC construct 'loop' not yet implemented}} + // expected-error@+1{{OpenACC 'pcopyout' clause is not valid on 'loop' directive}} #pragma acc loop pcopyout(LocalInt) for(;;); - // expected-error@+2{{OpenACC 'present_or_copyout' clause is not valid on 'loop' directive}} - // expected-warning@+1{{OpenACC construct 'loop' not yet implemented}} + // expected-error@+1{{OpenACC 'present_or_copyout' clause is not valid on 'loop' directive}} #pragma acc loop present_or_copyout(LocalInt) for(;;); } diff --git a/clang/test/SemaOpenACC/compute-construct-create-clause.c b/clang/test/SemaOpenACC/compute-construct-create-clause.c index 319025c9628cfff5f2c1ee9182bd9872429453e6..6ef9551d759ee1896ae1961c2a79eb7b64cf6820 100644 --- a/clang/test/SemaOpenACC/compute-construct-create-clause.c +++ b/clang/test/SemaOpenACC/compute-construct-create-clause.c @@ -67,16 +67,13 @@ void uses(int IntParam, short *PointerParam, float ArrayParam[5], Complete Compo #pragma acc parallel create(invalid:(float)ArrayParam[2]) while(1); - // expected-error@+2{{OpenACC 'create' clause is not valid on 'loop' directive}} - // expected-warning@+1{{OpenACC construct 'loop' not yet implemented}} + // expected-error@+1{{OpenACC 'create' clause is not valid on 'loop' directive}} #pragma acc loop create(LocalInt) for(;;); - // expected-error@+2{{OpenACC 'pcreate' clause is not valid on 'loop' directive}} - // expected-warning@+1{{OpenACC construct 'loop' not yet implemented}} + // expected-error@+1{{OpenACC 'pcreate' clause is not valid on 'loop' directive}} #pragma acc loop pcreate(LocalInt) for(;;); - // expected-error@+2{{OpenACC 'present_or_create' clause is not valid on 'loop' directive}} - // expected-warning@+1{{OpenACC construct 'loop' not yet implemented}} + // expected-error@+1{{OpenACC 'present_or_create' clause is not valid on 'loop' directive}} #pragma acc loop present_or_create(LocalInt) for(;;); } diff --git a/clang/test/SemaOpenACC/compute-construct-default-clause.c b/clang/test/SemaOpenACC/compute-construct-default-clause.c index bcafb02cb4df1fbfabc0865665d029b0d644b002..1fecc3cd830d19f8e731580affef8068f8e41c22 100644 --- a/clang/test/SemaOpenACC/compute-construct-default-clause.c +++ b/clang/test/SemaOpenACC/compute-construct-default-clause.c @@ -4,33 +4,31 @@ void SingleOnly() { #pragma acc parallel default(none) while(0); - // expected-warning@+3{{OpenACC clause 'seq' not yet implemented}} // expected-error@+2{{OpenACC 'default' clause cannot appear more than once on a 'serial' directive}} // expected-note@+1{{previous clause is here}} - #pragma acc serial default(present) seq default(none) + #pragma acc serial default(present) self default(none) while(0); - // expected-warning@+5{{OpenACC clause 'seq' not yet implemented}} - // expected-warning@+4{{OpenACC clause 'seq' not yet implemented}} - // expected-warning@+3{{OpenACC clause 'seq' not yet implemented}} + int i; + // expected-error@+2{{OpenACC 'default' clause cannot appear more than once on a 'kernels' directive}} // expected-note@+1{{previous clause is here}} - #pragma acc kernels seq default(present) seq default(none) seq + #pragma acc kernels self default(present) present(i) default(none) copy(i) while(0); // expected-warning@+6{{OpenACC construct 'parallel loop' not yet implemented}} - // expected-warning@+5{{OpenACC clause 'seq' not yet implemented}} - // expected-warning@+4{{OpenACC clause 'seq' not yet implemented}} - // expected-warning@+3{{OpenACC clause 'seq' not yet implemented}} + // expected-warning@+5{{OpenACC clause 'self' not yet implemented}} + // expected-warning@+4{{OpenACC clause 'default' not yet implemented}} + // expected-warning@+3{{OpenACC clause 'private' not yet implemented}} // expected-warning@+2{{OpenACC clause 'default' not yet implemented}} - // expected-warning@+1{{OpenACC clause 'default' not yet implemented}} - #pragma acc parallel loop seq default(present) seq default(none) seq + // expected-warning@+1{{OpenACC clause 'copy' not yet implemented}} + #pragma acc parallel loop self default(present) private(i) default(none) copy(i) while(0); - // expected-warning@+3{{OpenACC construct 'serial loop' not yet implemented}} - // expected-warning@+2{{OpenACC clause 'seq' not yet implemented}} + // expected-warning@+3{{OpenACC clause 'self' not yet implemented, clause ignored}} + // expected-warning@+2{{OpenACC construct 'serial loop' not yet implemented}} // expected-error@+1{{expected '('}} - #pragma acc serial loop seq default seq default(none) seq + #pragma acc serial loop self default private(i) default(none) if(i) while(0); // expected-warning@+2{{OpenACC construct 'kernels loop' not yet implemented}} @@ -43,18 +41,16 @@ void SingleOnly() { #pragma acc data default(none) while(0); - // expected-warning@+2{{OpenACC construct 'loop' not yet implemented}} // expected-error@+1{{OpenACC 'default' clause is not valid on 'loop' directive}} #pragma acc loop default(none) - while(0); + for(;;); // expected-warning@+2{{OpenACC construct 'wait' not yet implemented}} // expected-error@+1{{OpenACC 'default' clause is not valid on 'wait' directive}} #pragma acc wait default(none) while(0); - // expected-error@+2{{OpenACC 'default' clause is not valid on 'loop' directive}} - // expected-warning@+1{{OpenACC construct 'loop' not yet implemented}} + // expected-error@+1{{OpenACC 'default' clause is not valid on 'loop' directive}} #pragma acc loop default(present) for(;;); } diff --git a/clang/test/SemaOpenACC/compute-construct-default-clause.cpp b/clang/test/SemaOpenACC/compute-construct-default-clause.cpp index 2c3e711ffd08521469b1b9830666658586dfcdad..8a4a79d0eb2dc55fe207b9f103c118949dab59ac 100644 --- a/clang/test/SemaOpenACC/compute-construct-default-clause.cpp +++ b/clang/test/SemaOpenACC/compute-construct-default-clause.cpp @@ -5,32 +5,25 @@ void SingleOnly() { #pragma acc parallel default(none) while(false); - // expected-warning@+3{{OpenACC clause 'seq' not yet implemented}} + int i; + // expected-error@+2{{OpenACC 'default' clause cannot appear more than once on a 'parallel' directive}} // expected-note@+1{{previous clause is here}} - #pragma acc parallel default(present) seq default(none) + #pragma acc parallel default(present) async default(none) while(false); - // expected-warning@+5{{OpenACC clause 'seq' not yet implemented}} - // expected-warning@+4{{OpenACC clause 'seq' not yet implemented}} - // expected-warning@+3{{OpenACC clause 'seq' not yet implemented}} // expected-error@+2{{OpenACC 'default' clause cannot appear more than once on a 'serial' directive}} // expected-note@+1{{previous clause is here}} - #pragma acc serial seq default(present) seq default(none) seq + #pragma acc serial async default(present) copy(i) default(none) self while(false); - // expected-warning@+5{{OpenACC clause 'seq' not yet implemented}} - // expected-warning@+4{{OpenACC clause 'seq' not yet implemented}} - // expected-warning@+3{{OpenACC clause 'seq' not yet implemented}} // expected-error@+2{{OpenACC 'default' clause cannot appear more than once on a 'kernels' directive}} // expected-note@+1{{previous clause is here}} - #pragma acc kernels seq default(present) seq default(none) seq + #pragma acc kernels async default(present) copy(i) default(none) self while(false); - // expected-warning@+3{{OpenACC clause 'seq' not yet implemented}} - // expected-warning@+2{{OpenACC clause 'seq' not yet implemented}} // expected-error@+1{{expected '('}} - #pragma acc parallel seq default(none) seq default seq + #pragma acc parallel async default(none) copy(i) default self while(false); } diff --git a/clang/test/SemaOpenACC/compute-construct-device_type-clause.c b/clang/test/SemaOpenACC/compute-construct-device_type-clause.c index 376a741a2a6b9581f4c4d9532df373f1fc9e4545..b300abe577801c3412448ee4e0cd7d4652ecc0dd 100644 --- a/clang/test/SemaOpenACC/compute-construct-device_type-clause.c +++ b/clang/test/SemaOpenACC/compute-construct-device_type-clause.c @@ -52,16 +52,13 @@ void uses() { // expected-note@+1{{previous clause is here}} #pragma acc kernels device_type(*) if_present while(1); - // expected-error@+2{{OpenACC clause 'seq' may not follow a 'device_type' clause in a compute construct}} - // expected-note@+1{{previous clause is here}} + // expected-error@+1{{OpenACC 'seq' clause is not valid on 'kernels' directive}} #pragma acc kernels device_type(*) seq while(1); - // expected-error@+2{{OpenACC clause 'independent' may not follow a 'device_type' clause in a compute construct}} - // expected-note@+1{{previous clause is here}} + // expected-error@+1{{OpenACC 'independent' clause is not valid on 'kernels' directive}} #pragma acc kernels device_type(*) independent while(1); - // expected-error@+2{{OpenACC clause 'auto' may not follow a 'device_type' clause in a compute construct}} - // expected-note@+1{{previous clause is here}} + // expected-error@+1{{OpenACC 'auto' clause is not valid on 'kernels' directive}} #pragma acc kernels device_type(*) auto while(1); // expected-error@+2{{OpenACC clause 'worker' may not follow a 'device_type' clause in a compute construct}} diff --git a/clang/test/SemaOpenACC/compute-construct-deviceptr-clause.c b/clang/test/SemaOpenACC/compute-construct-deviceptr-clause.c index 8ec911f6dbf1dcb187f01100e78257a90daaaf25..44c4cc4e5ec279f97a083e558e67c06933a9df54 100644 --- a/clang/test/SemaOpenACC/compute-construct-deviceptr-clause.c +++ b/clang/test/SemaOpenACC/compute-construct-deviceptr-clause.c @@ -59,8 +59,7 @@ void uses() { #pragma acc parallel deviceptr(s.PtrMem) while (1); - // expected-error@+2{{OpenACC 'deviceptr' clause is not valid on 'loop' directive}} - // expected-warning@+1{{OpenACC construct 'loop' not yet implemented}} + // expected-error@+1{{OpenACC 'deviceptr' clause is not valid on 'loop' directive}} #pragma acc loop deviceptr(LocalInt) for(;;); } diff --git a/clang/test/SemaOpenACC/compute-construct-firstprivate-clause.c b/clang/test/SemaOpenACC/compute-construct-firstprivate-clause.c index 14f5af60cc855502576699c105a0d8e67e8327ac..0c26a0b4c9b957db7786e6347eb4292897c1ef68 100644 --- a/clang/test/SemaOpenACC/compute-construct-firstprivate-clause.c +++ b/clang/test/SemaOpenACC/compute-construct-firstprivate-clause.c @@ -53,8 +53,7 @@ void uses(int IntParam, short *PointerParam, float ArrayParam[5], Complete Compo #pragma acc parallel firstprivate((float)ArrayParam[2]) while(1); - // expected-error@+2{{OpenACC 'firstprivate' clause is not valid on 'loop' directive}} - // expected-warning@+1{{OpenACC construct 'loop' not yet implemented}} + // expected-error@+1{{OpenACC 'firstprivate' clause is not valid on 'loop' directive}} #pragma acc loop firstprivate(LocalInt) for(;;); } diff --git a/clang/test/SemaOpenACC/compute-construct-if-clause.c b/clang/test/SemaOpenACC/compute-construct-if-clause.c index 21e7ce413e9089ae30f9bd6d6b1cf29eec871684..4629b1b2c2bd0960bbc6778d935deaba243dcfd9 100644 --- a/clang/test/SemaOpenACC/compute-construct-if-clause.c +++ b/clang/test/SemaOpenACC/compute-construct-if-clause.c @@ -60,8 +60,7 @@ void BoolExpr(int *I, float *F) { #pragma acc kernels loop if (*I < *F) while(0); - // expected-error@+2{{OpenACC 'if' clause is not valid on 'loop' directive}} - // expected-warning@+1{{OpenACC construct 'loop' not yet implemented}} + // expected-error@+1{{OpenACC 'if' clause is not valid on 'loop' directive}} #pragma acc loop if(I) for(;;); } diff --git a/clang/test/SemaOpenACC/compute-construct-no_create-clause.c b/clang/test/SemaOpenACC/compute-construct-no_create-clause.c index 5afd6444621473a47c885c0c137a758b999bb10c..6db7d0cca8c3257193ac97743f8a9919debed66c 100644 --- a/clang/test/SemaOpenACC/compute-construct-no_create-clause.c +++ b/clang/test/SemaOpenACC/compute-construct-no_create-clause.c @@ -52,8 +52,7 @@ void uses(int IntParam, short *PointerParam, float ArrayParam[5], Complete Compo #pragma acc parallel no_create((float)ArrayParam[2]) while(1); - // expected-error@+2{{OpenACC 'no_create' clause is not valid on 'loop' directive}} - // expected-warning@+1{{OpenACC construct 'loop' not yet implemented}} + // expected-error@+1{{OpenACC 'no_create' clause is not valid on 'loop' directive}} #pragma acc loop no_create(LocalInt) for(;;); } diff --git a/clang/test/SemaOpenACC/compute-construct-num_gangs-clause.c b/clang/test/SemaOpenACC/compute-construct-num_gangs-clause.c index 9c2a5a781059e8ea57103d69709314a1b0728f58..0a86dee4da04177aded589023c1330b67b66fa8e 100644 --- a/clang/test/SemaOpenACC/compute-construct-num_gangs-clause.c +++ b/clang/test/SemaOpenACC/compute-construct-num_gangs-clause.c @@ -52,8 +52,7 @@ void Test() { #pragma acc parallel num_gangs(getS(), 1, getS(), 1) while(1); - // expected-error@+2{{OpenACC 'num_gangs' clause is not valid on 'loop' directive}} - // expected-warning@+1{{OpenACC construct 'loop' not yet implemented}} + // expected-error@+1{{OpenACC 'num_gangs' clause is not valid on 'loop' directive}} #pragma acc loop num_gangs(1) for(;;); } diff --git a/clang/test/SemaOpenACC/compute-construct-num_workers-clause.c b/clang/test/SemaOpenACC/compute-construct-num_workers-clause.c index a84bd3699536a1d224efbb9dd746f0c3a5668de2..808609cf2a0fbb3a83bd3ccdce1df1917d23fbe3 100644 --- a/clang/test/SemaOpenACC/compute-construct-num_workers-clause.c +++ b/clang/test/SemaOpenACC/compute-construct-num_workers-clause.c @@ -31,8 +31,7 @@ void Test() { #pragma acc kernels num_workers(SomeE) while(1); - // expected-error@+2{{OpenACC 'num_workers' clause is not valid on 'loop' directive}} - // expected-warning@+1{{OpenACC construct 'loop' not yet implemented}} + // expected-error@+1{{OpenACC 'num_workers' clause is not valid on 'loop' directive}} #pragma acc loop num_workers(1) for(;;); } diff --git a/clang/test/SemaOpenACC/compute-construct-present-clause.c b/clang/test/SemaOpenACC/compute-construct-present-clause.c index 5ace750da7efe640f7cee65435f11a54ad88c53c..eea2c77657c8db22e7638e60f74edd0b2a5dc155 100644 --- a/clang/test/SemaOpenACC/compute-construct-present-clause.c +++ b/clang/test/SemaOpenACC/compute-construct-present-clause.c @@ -52,8 +52,7 @@ void uses(int IntParam, short *PointerParam, float ArrayParam[5], Complete Compo #pragma acc parallel present((float)ArrayParam[2]) while(1); - // expected-error@+2{{OpenACC 'present' clause is not valid on 'loop' directive}} - // expected-warning@+1{{OpenACC construct 'loop' not yet implemented}} + // expected-error@+1{{OpenACC 'present' clause is not valid on 'loop' directive}} #pragma acc loop present(LocalInt) for(;;); } diff --git a/clang/test/SemaOpenACC/compute-construct-self-clause.c b/clang/test/SemaOpenACC/compute-construct-self-clause.c index 634a2d8857b7ee46410c7e7b360d14900da66716..c79e7e5d3db6d192383ca6989016deb4df5db94f 100644 --- a/clang/test/SemaOpenACC/compute-construct-self-clause.c +++ b/clang/test/SemaOpenACC/compute-construct-self-clause.c @@ -80,8 +80,7 @@ void WarnMaybeNotUsed(int val1, int val2) { #pragma acc parallel if(invalid) self(val1) while(0); - // expected-error@+2{{OpenACC 'self' clause is not valid on 'loop' directive}} - // expected-warning@+1{{OpenACC construct 'loop' not yet implemented}} + // expected-error@+1{{OpenACC 'self' clause is not valid on 'loop' directive}} #pragma acc loop self for(;;); } diff --git a/clang/test/SemaOpenACC/compute-construct-vector_length-clause.c b/clang/test/SemaOpenACC/compute-construct-vector_length-clause.c index 83055f81fbb2ce49b1dd2d61f429e681784dfbb3..eda2d5e251b25268eae14756d56b57625415b73f 100644 --- a/clang/test/SemaOpenACC/compute-construct-vector_length-clause.c +++ b/clang/test/SemaOpenACC/compute-construct-vector_length-clause.c @@ -31,8 +31,7 @@ void Test() { #pragma acc kernels vector_length(SomeE) while(1); - // expected-error@+2{{OpenACC 'vector_length' clause is not valid on 'loop' directive}} - // expected-warning@+1{{OpenACC construct 'loop' not yet implemented}} + // expected-error@+1{{OpenACC 'vector_length' clause is not valid on 'loop' directive}} #pragma acc loop vector_length(1) for(;;); } diff --git a/clang/test/SemaOpenACC/compute-construct-wait-clause.c b/clang/test/SemaOpenACC/compute-construct-wait-clause.c index 0878288ca4a2c8d2a3fb80fe9b1d5c8b4e62e39e..0d0ab52c31dccc5932c39163ed7612e40df3478c 100644 --- a/clang/test/SemaOpenACC/compute-construct-wait-clause.c +++ b/clang/test/SemaOpenACC/compute-construct-wait-clause.c @@ -36,8 +36,7 @@ void uses() { #pragma acc parallel wait(devnum:arr : queues: arr, NC, 5) while(1); - // expected-error@+2{{OpenACC 'wait' clause is not valid on 'loop' directive}} - // expected-warning@+1{{OpenACC construct 'loop' not yet implemented}} + // expected-error@+1{{OpenACC 'wait' clause is not valid on 'loop' directive}} #pragma acc loop wait for(;;); } diff --git a/clang/test/SemaOpenACC/loop-ast.cpp b/clang/test/SemaOpenACC/loop-ast.cpp new file mode 100644 index 0000000000000000000000000000000000000000..292044f94267b858b1e77dbc1ad58d4276c91081 --- /dev/null +++ b/clang/test/SemaOpenACC/loop-ast.cpp @@ -0,0 +1,182 @@ + +// RUN: %clang_cc1 %s -fopenacc -ast-dump | FileCheck %s + +// Test this with PCH. +// RUN: %clang_cc1 %s -fopenacc -emit-pch -o %t %s +// RUN: %clang_cc1 %s -fopenacc -include-pch %t -ast-dump-all | FileCheck %s + +#ifndef PCH_HELPER +#define PCH_HELPER + +void NormalFunc() { + // CHECK-LABEL: NormalFunc + // CHECK-NEXT: CompoundStmt + +#pragma acc loop + for(;;); + // CHECK-NEXT: OpenACCLoopConstruct{{.*}} + // CHECK-NEXT: ForStmt + // CHECK-NEXT: <<>> + // CHECK-NEXT: <<>> + // CHECK-NEXT: <<>> + // CHECK-NEXT: <<>> + // CHECK-NEXT: NullStmt + + int array[5]; + // CHECK-NEXT: DeclStmt + // CHECK-NEXT: VarDecl +#pragma acc loop + for(auto x : array){} + // CHECK-NEXT: OpenACCLoopConstruct{{.*}} + // CHECK-NEXT: CXXForRangeStmt + // CHECK: CompoundStmt + +#pragma acc parallel + // CHECK-NEXT: OpenACCComputeConstruct {{.*}}parallel + // CHECK-NEXT: CompoundStmt + { +#pragma acc parallel + // CHECK-NEXT: OpenACCComputeConstruct [[PAR_ADDR:[0-9a-fx]+]] {{.*}}parallel + // CHECK-NEXT: CompoundStmt + { +#pragma acc loop + for(;;); + // CHECK-NEXT: OpenACCLoopConstruct{{.*}} parent: [[PAR_ADDR]] + // CHECK-NEXT: ForStmt + // CHECK-NEXT: <<>> + // CHECK-NEXT: <<>> + // CHECK-NEXT: <<>> + // CHECK-NEXT: <<>> + // CHECK-NEXT: NullStmt + } + } +} + +template +void TemplFunc() { + // CHECK-LABEL: FunctionTemplateDecl {{.*}}TemplFunc + // CHECK-NEXT: TemplateTypeParmDecl + // CHECK-NEXT: FunctionDecl{{.*}}TemplFunc + // CHECK-NEXT: CompoundStmt + +#pragma acc loop + // CHECK-NEXT: OpenACCLoopConstruct{{.*}} + for(typename T::type t = 0; t < 5;++t) { + // CHECK-NEXT: ForStmt + // CHECK-NEXT: DeclStmt + // CHECK-NEXT: VarDecl{{.*}} referenced t 'typename T::type' + // CHECK-NEXT: IntegerLiteral {{.*}} 'int' 0 + // CHECK-NEXT: <<> + // CHECK-NEXT: BinaryOperator{{.*}} '' '<' + // CHECK-NEXT: DeclRefExpr {{.*}} 'typename T::type' lvalue Var + // CHECK-NEXT: IntegerLiteral {{.*}} 'int' 5 + // CHECK-NEXT: UnaryOperator{{.*}} '' lvalue prefix '++' + // CHECK-NEXT: DeclRefExpr {{.*}} 'typename T::type' lvalue Var + // CHECK-NEXT: CompoundStmt + typename T::type I; + // CHECK-NEXT: DeclStmt + // CHECK-NEXT: VarDecl{{.*}} I 'typename T::type' + + } + +#pragma acc parallel + { + // CHECK-NEXT: OpenACCComputeConstruct {{.*}}parallel + // CHECK-NEXT: CompoundStmt +#pragma acc parallel + { + // CHECK-NEXT: OpenACCComputeConstruct [[PAR_ADDR_UNINST:[0-9a-fx]+]] {{.*}}parallel + // CHECK-NEXT: CompoundStmt +#pragma acc loop + // CHECK-NEXT: OpenACCLoopConstruct{{.*}} parent: [[PAR_ADDR_UNINST]] + // CHECK-NEXT: ForStmt + // CHECK-NEXT: <<>> + // CHECK-NEXT: <<>> + // CHECK-NEXT: <<>> + // CHECK-NEXT: <<>> + // CHECK-NEXT: NullStmt + for(;;); + +#pragma acc loop + // CHECK-NEXT: OpenACCLoopConstruct{{.*}} parent: [[PAR_ADDR_UNINST]] + // CHECK-NEXT: ForStmt + // CHECK-NEXT: <<>> + // CHECK-NEXT: <<>> + // CHECK-NEXT: <<>> + // CHECK-NEXT: <<>> + // CHECK-NEXT: NullStmt + for(;;); + } + } + + typename T::type array[5]; + // CHECK-NEXT: DeclStmt + // CHECK-NEXT: VarDecl + +#pragma acc loop + for(auto x : array){} + // CHECK-NEXT: OpenACCLoopConstruct{{.*}} + // CHECK-NEXT: CXXForRangeStmt + // CHECK: CompoundStmt + + // Instantiation: + // CHECK-NEXT: FunctionDecl{{.*}} TemplFunc 'void ()' implicit_instantiation + // CHECK-NEXT: TemplateArgument type 'S' + // CHECK-NEXT: RecordType{{.*}} 'S' + // CHECK-NEXT: CXXRecord{{.*}} 'S' + // CHECK-NEXT: CompoundStmt + + // CHECK-NEXT: OpenACCLoopConstruct{{.*}} + // CHECK-NEXT: ForStmt + // CHECK-NEXT: DeclStmt + // CHECK-NEXT: VarDecl{{.*}} used t 'typename S::type':'int' + // CHECK-NEXT: IntegerLiteral {{.*}} 'int' 0 + // CHECK-NEXT: <<> + // CHECK-NEXT: BinaryOperator{{.*}} 'bool' '<' + // CHECK-NEXT: ImplicitCastExpr{{.*}} 'typename S::type':'int' + // CHECK-NEXT: DeclRefExpr {{.*}} 'typename S::type':'int' lvalue Var + // CHECK-NEXT: IntegerLiteral {{.*}} 'int' 5 + // CHECK-NEXT: UnaryOperator{{.*}} 'typename S::type':'int' lvalue prefix '++' + // CHECK-NEXT: DeclRefExpr {{.*}} 'typename S::type':'int' lvalue Var + // CHECK-NEXT: CompoundStmt + // CHECK-NEXT: DeclStmt + // CHECK-NEXT: VarDecl{{.*}} I 'typename S::type':'int' + + // CHECK-NEXT: OpenACCComputeConstruct {{.*}}parallel + // CHECK-NEXT: CompoundStmt + // + // CHECK-NEXT: OpenACCComputeConstruct [[PAR_ADDR_INST:[0-9a-fx]+]] {{.*}}parallel + // CHECK-NEXT: CompoundStmt + + // CHECK-NEXT: OpenACCLoopConstruct{{.*}} parent: [[PAR_ADDR_INST]] + // CHECK-NEXT: ForStmt + // CHECK-NEXT: <<>> + // CHECK-NEXT: <<>> + // CHECK-NEXT: <<>> + // CHECK-NEXT: <<>> + // CHECK-NEXT: NullStmt + + // CHECK-NEXT: OpenACCLoopConstruct{{.*}} parent: [[PAR_ADDR_INST]] + // CHECK-NEXT: ForStmt + // CHECK-NEXT: <<>> + // CHECK-NEXT: <<>> + // CHECK-NEXT: <<>> + // CHECK-NEXT: <<>> + // CHECK-NEXT: NullStmt + + // CHECK-NEXT: DeclStmt + // CHECK-NEXT: VarDecl + // CHECK-NEXT: OpenACCLoopConstruct{{.*}} + // CHECK-NEXT: CXXForRangeStmt + // CHECK: CompoundStmt +} + +struct S { + using type = int; +}; + +void use() { + TemplFunc(); +} +#endif + diff --git a/clang/test/SemaOpenACC/loop-construct-auto_seq_independent-ast.cpp b/clang/test/SemaOpenACC/loop-construct-auto_seq_independent-ast.cpp new file mode 100644 index 0000000000000000000000000000000000000000..3c8f313df5eb2cb938200f6f08b7bfc0e499ee4e --- /dev/null +++ b/clang/test/SemaOpenACC/loop-construct-auto_seq_independent-ast.cpp @@ -0,0 +1,124 @@ +// RUN: %clang_cc1 %s -fopenacc -ast-dump | FileCheck %s + +// Test this with PCH. +// RUN: %clang_cc1 %s -fopenacc -emit-pch -o %t %s +// RUN: %clang_cc1 %s -fopenacc -include-pch %t -ast-dump-all | FileCheck %s +#ifndef PCH_HELPER +#define PCH_HELPER + +void NormalUses() { + // CHECK: FunctionDecl{{.*}}NormalUses + // CHECK-NEXT: CompoundStmt + +#pragma acc loop auto + for(;;){} + // CHECK-NEXT: OpenACCLoopConstruct{{.*}} + // CHECK-NEXT: auto clause + // CHECK-NEXT: ForStmt + // CHECK-NEXT: <<>> + // CHECK-NEXT: <<>> + // CHECK-NEXT: <<>> + // CHECK-NEXT: <<>> + // CHECK-NEXT: CompoundStmt + +#pragma acc loop seq + for(;;){} + // CHECK-NEXT: OpenACCLoopConstruct{{.*}} + // CHECK-NEXT: seq clause + // CHECK-NEXT: ForStmt + // CHECK-NEXT: <<>> + // CHECK-NEXT: <<>> + // CHECK-NEXT: <<>> + // CHECK-NEXT: <<>> + // CHECK-NEXT: CompoundStmt + +#pragma acc loop independent + for(;;){} + // CHECK-NEXT: OpenACCLoopConstruct{{.*}} + // CHECK-NEXT: independent clause + // CHECK-NEXT: ForStmt + // CHECK-NEXT: <<>> + // CHECK-NEXT: <<>> + // CHECK-NEXT: <<>> + // CHECK-NEXT: <<>> + // CHECK-NEXT: CompoundStmt +} + +template +void TemplUses() { + // CHECK: FunctionTemplateDecl{{.*}}TemplUses + // CHECK-NEXT: TemplateTypeParmDecl + // CHECK-NEXT: FunctionDecl{{.*}} TemplUses + // CHECK-NEXT: CompoundStmt + +#pragma acc loop auto + for(;;){} + // CHECK-NEXT: OpenACCLoopConstruct{{.*}} + // CHECK-NEXT: auto clause + // CHECK-NEXT: ForStmt + // CHECK-NEXT: <<>> + // CHECK-NEXT: <<>> + // CHECK-NEXT: <<>> + // CHECK-NEXT: <<>> + // CHECK-NEXT: CompoundStmt + +#pragma acc loop seq + for(;;){} + // CHECK-NEXT: OpenACCLoopConstruct{{.*}} + // CHECK-NEXT: seq clause + // CHECK-NEXT: ForStmt + // CHECK-NEXT: <<>> + // CHECK-NEXT: <<>> + // CHECK-NEXT: <<>> + // CHECK-NEXT: <<>> + // CHECK-NEXT: CompoundStmt + +#pragma acc loop independent + for(;;){} + // CHECK-NEXT: OpenACCLoopConstruct{{.*}} + // CHECK-NEXT: independent clause + // CHECK-NEXT: ForStmt + // CHECK-NEXT: <<>> + // CHECK-NEXT: <<>> + // CHECK-NEXT: <<>> + // CHECK-NEXT: <<>> + // CHECK-NEXT: CompoundStmt + + // Instantiations. + // CHECK-NEXT: FunctionDecl{{.*}}TemplUses 'void ()' implicit_instantiation + // CHECK-NEXT: TemplateArgument + // CHECK-NEXT: BuiltinType + // CHECK-NEXT: CompoundStmt + + // CHECK-NEXT: OpenACCLoopConstruct{{.*}} + // CHECK-NEXT: auto clause + // CHECK-NEXT: ForStmt + // CHECK-NEXT: <<>> + // CHECK-NEXT: <<>> + // CHECK-NEXT: <<>> + // CHECK-NEXT: <<>> + // CHECK-NEXT: CompoundStmt + + // CHECK-NEXT: OpenACCLoopConstruct{{.*}} + // CHECK-NEXT: seq clause + // CHECK-NEXT: ForStmt + // CHECK-NEXT: <<>> + // CHECK-NEXT: <<>> + // CHECK-NEXT: <<>> + // CHECK-NEXT: <<>> + // CHECK-NEXT: CompoundStmt + + // CHECK-NEXT: OpenACCLoopConstruct{{.*}} + // CHECK-NEXT: independent clause + // CHECK-NEXT: ForStmt + // CHECK-NEXT: <<>> + // CHECK-NEXT: <<>> + // CHECK-NEXT: <<>> + // CHECK-NEXT: <<>> + // CHECK-NEXT: CompoundStmt +} + +void Inst() { + TemplUses(); +} +#endif // PCH_HELPER diff --git a/clang/test/SemaOpenACC/loop-construct-auto_seq_independent-clauses.c b/clang/test/SemaOpenACC/loop-construct-auto_seq_independent-clauses.c new file mode 100644 index 0000000000000000000000000000000000000000..ac61976ff620d8a500895e3317d310459c37deab --- /dev/null +++ b/clang/test/SemaOpenACC/loop-construct-auto_seq_independent-clauses.c @@ -0,0 +1,890 @@ +// RUN: %clang_cc1 %s -fopenacc -verify + +void uses() { +#pragma acc loop auto + for(;;); +#pragma acc loop seq + for(;;); +#pragma acc loop independent + for(;;); + + // expected-error@+2{{OpenACC clause 'seq' on 'loop' construct conflicts with previous data dependence clause}} + // expected-note@+1{{previous clause is here}} +#pragma acc loop auto seq + for(;;); + // expected-error@+2{{OpenACC clause 'independent' on 'loop' construct conflicts with previous data dependence clause}} + // expected-note@+1{{previous clause is here}} +#pragma acc loop auto independent + for(;;); + // expected-error@+2{{OpenACC clause 'auto' on 'loop' construct conflicts with previous data dependence clause}} + // expected-note@+1{{previous clause is here}} +#pragma acc loop seq auto + for(;;); + // expected-error@+2{{OpenACC clause 'independent' on 'loop' construct conflicts with previous data dependence clause}} + // expected-note@+1{{previous clause is here}} +#pragma acc loop seq independent + for(;;); + // expected-error@+2{{OpenACC clause 'auto' on 'loop' construct conflicts with previous data dependence clause}} + // expected-note@+1{{previous clause is here}} +#pragma acc loop independent auto + for(;;); + // expected-error@+2{{OpenACC clause 'seq' on 'loop' construct conflicts with previous data dependence clause}} + // expected-note@+1{{previous clause is here}} +#pragma acc loop independent seq + for(;;); + + int Var; + int *VarPtr; + + // 'auto' can combine with any other clause. + // expected-warning@+1{{OpenACC clause 'finalize' not yet implemented}} +#pragma acc loop auto finalize + for(;;); + // expected-warning@+1{{OpenACC clause 'if_present' not yet implemented}} +#pragma acc loop auto if_present + for(;;); + // expected-warning@+1{{OpenACC clause 'worker' not yet implemented}} +#pragma acc loop auto worker + for(;;); + // expected-warning@+1{{OpenACC clause 'vector' not yet implemented}} +#pragma acc loop auto vector + for(;;); + // expected-warning@+1{{OpenACC clause 'nohost' not yet implemented}} +#pragma acc loop auto nohost + for(;;); + // expected-error@+1{{OpenACC 'default' clause is not valid on 'loop' directive}} +#pragma acc loop auto default(none) + for(;;); + // expected-error@+1{{OpenACC 'if' clause is not valid on 'loop' directive}} +#pragma acc loop auto if(1) + for(;;); + // expected-error@+1{{OpenACC 'self' clause is not valid on 'loop' directive}} +#pragma acc loop auto self + for(;;); + // expected-error@+1{{OpenACC 'copy' clause is not valid on 'loop' directive}} +#pragma acc loop auto copy(Var) + for(;;); + // expected-error@+1{{OpenACC 'pcopy' clause is not valid on 'loop' directive}} +#pragma acc loop auto pcopy(Var) + for(;;); + // expected-error@+1{{OpenACC 'present_or_copy' clause is not valid on 'loop' directive}} +#pragma acc loop auto present_or_copy(Var) + for(;;); + // expected-warning@+1{{OpenACC clause 'use_device' not yet implemented}} +#pragma acc loop auto use_device(Var) + for(;;); + // expected-error@+1{{OpenACC 'attach' clause is not valid on 'loop' directive}} +#pragma acc loop auto attach(Var) + for(;;); + // expected-warning@+1{{OpenACC clause 'delete' not yet implemented}} +#pragma acc loop auto delete(Var) + for(;;); + // expected-warning@+1{{OpenACC clause 'detach' not yet implemented}} +#pragma acc loop auto detach(Var) + for(;;); + // expected-warning@+1{{OpenACC clause 'device' not yet implemented}} +#pragma acc loop auto device(VarPtr) + for(;;); + // expected-error@+1{{OpenACC 'deviceptr' clause is not valid on 'loop' directive}} +#pragma acc loop auto deviceptr(VarPtr) + for(;;); + // expected-warning@+1{{OpenACC clause 'device_resident' not yet implemented}} +#pragma acc loop auto device_resident(VarPtr) + for(;;); + // expected-error@+1{{OpenACC 'firstprivate' clause is not valid on 'loop' directive}} +#pragma acc loop auto firstprivate(Var) + for(;;); + // expected-warning@+1{{OpenACC clause 'host' not yet implemented}} +#pragma acc loop auto host(Var) + for(;;); + // expected-warning@+1{{OpenACC clause 'link' not yet implemented}} +#pragma acc loop auto link(Var) + for(;;); + // expected-error@+1{{OpenACC 'no_create' clause is not valid on 'loop' directive}} +#pragma acc loop auto no_create(Var) + for(;;); + // expected-error@+1{{OpenACC 'present' clause is not valid on 'loop' directive}} +#pragma acc loop auto present(Var) + for(;;); +#pragma acc loop auto private(Var) + for(;;); + // expected-error@+1{{OpenACC 'copyout' clause is not valid on 'loop' directive}} +#pragma acc loop auto copyout(Var) + for(;;); + // expected-error@+1{{OpenACC 'pcopyout' clause is not valid on 'loop' directive}} +#pragma acc loop auto pcopyout(Var) + for(;;); + // expected-error@+1{{OpenACC 'present_or_copyout' clause is not valid on 'loop' directive}} +#pragma acc loop auto present_or_copyout(Var) + for(;;); + // expected-error@+1{{OpenACC 'copyin' clause is not valid on 'loop' directive}} +#pragma acc loop auto copyin(Var) + for(;;); + // expected-error@+1{{OpenACC 'pcopyin' clause is not valid on 'loop' directive}} +#pragma acc loop auto pcopyin(Var) + for(;;); + // expected-error@+1{{OpenACC 'present_or_copyin' clause is not valid on 'loop' directive}} +#pragma acc loop auto present_or_copyin(Var) + for(;;); + // expected-error@+1{{OpenACC 'create' clause is not valid on 'loop' directive}} +#pragma acc loop auto create(Var) + for(;;); + // expected-error@+1{{OpenACC 'pcreate' clause is not valid on 'loop' directive}} +#pragma acc loop auto pcreate(Var) + for(;;); + // expected-error@+1{{OpenACC 'present_or_create' clause is not valid on 'loop' directive}} +#pragma acc loop auto present_or_create(Var) + for(;;); + // expected-warning@+1{{OpenACC clause 'reduction' not yet implemented}} +#pragma acc loop auto reduction(+:Var) + for(;;); + // expected-warning@+1{{OpenACC clause 'collapse' not yet implemented}} +#pragma acc loop auto collapse(1) + for(;;); + // expected-warning@+1{{OpenACC clause 'bind' not yet implemented}} +#pragma acc loop auto bind(Var) + for(;;); + // expected-error@+1{{OpenACC 'vector_length' clause is not valid on 'loop' directive}} +#pragma acc loop auto vector_length(1) + for(;;); + // expected-error@+1{{OpenACC 'num_gangs' clause is not valid on 'loop' directive}} +#pragma acc loop auto num_gangs(1) + for(;;); + // expected-error@+1{{OpenACC 'num_workers' clause is not valid on 'loop' directive}} +#pragma acc loop auto num_workers(1) + for(;;); + // expected-warning@+1{{OpenACC clause 'device_num' not yet implemented}} +#pragma acc loop auto device_num(1) + for(;;); + // expected-warning@+1{{OpenACC clause 'default_async' not yet implemented}} +#pragma acc loop auto default_async(1) + for(;;); +#pragma acc loop auto device_type(*) + for(;;); +#pragma acc loop auto dtype(*) + for(;;); + // expected-error@+1{{OpenACC 'async' clause is not valid on 'loop' directive}} +#pragma acc loop auto async + for(;;); + // expected-warning@+1{{OpenACC clause 'tile' not yet implemented}} +#pragma acc loop auto tile(Var, 1) + for(;;); + // expected-warning@+1{{OpenACC clause 'gang' not yet implemented}} +#pragma acc loop auto gang + for(;;); + // expected-error@+1{{OpenACC 'wait' clause is not valid on 'loop' directive}} +#pragma acc loop auto wait + for(;;); + + // expected-warning@+1{{OpenACC clause 'finalize' not yet implemented}} +#pragma acc loop finalize auto + for(;;); + // expected-warning@+1{{OpenACC clause 'if_present' not yet implemented}} +#pragma acc loop if_present auto + for(;;); + // expected-warning@+1{{OpenACC clause 'worker' not yet implemented}} +#pragma acc loop worker auto + for(;;); + // expected-warning@+1{{OpenACC clause 'vector' not yet implemented}} +#pragma acc loop vector auto + for(;;); + // expected-warning@+1{{OpenACC clause 'nohost' not yet implemented}} +#pragma acc loop nohost auto + for(;;); + // expected-error@+1{{OpenACC 'default' clause is not valid on 'loop' directive}} +#pragma acc loop default(none) auto + for(;;); + // expected-error@+1{{OpenACC 'if' clause is not valid on 'loop' directive}} +#pragma acc loop if(1) auto + for(;;); + // expected-error@+1{{OpenACC 'self' clause is not valid on 'loop' directive}} +#pragma acc loop self auto + for(;;); + // expected-error@+1{{OpenACC 'copy' clause is not valid on 'loop' directive}} +#pragma acc loop copy(Var) auto + for(;;); + // expected-error@+1{{OpenACC 'pcopy' clause is not valid on 'loop' directive}} +#pragma acc loop pcopy(Var) auto + for(;;); + // expected-error@+1{{OpenACC 'present_or_copy' clause is not valid on 'loop' directive}} +#pragma acc loop present_or_copy(Var) auto + for(;;); + // expected-warning@+1{{OpenACC clause 'use_device' not yet implemented}} +#pragma acc loop use_device(Var) auto + for(;;); + // expected-error@+1{{OpenACC 'attach' clause is not valid on 'loop' directive}} +#pragma acc loop attach(Var) auto + for(;;); + // expected-warning@+1{{OpenACC clause 'delete' not yet implemented}} +#pragma acc loop delete(Var) auto + for(;;); + // expected-warning@+1{{OpenACC clause 'detach' not yet implemented}} +#pragma acc loop detach(Var) auto + for(;;); + // expected-warning@+1{{OpenACC clause 'device' not yet implemented}} +#pragma acc loop device(VarPtr) auto + for(;;); + // expected-error@+1{{OpenACC 'deviceptr' clause is not valid on 'loop' directive}} +#pragma acc loop deviceptr(VarPtr) auto + for(;;); + // expected-warning@+1{{OpenACC clause 'device_resident' not yet implemented}} +#pragma acc loop device_resident(VarPtr) auto + for(;;); + // expected-error@+1{{OpenACC 'firstprivate' clause is not valid on 'loop' directive}} +#pragma acc loop firstprivate(Var) auto + for(;;); + // expected-warning@+1{{OpenACC clause 'host' not yet implemented}} +#pragma acc loop host(Var) auto + for(;;); + // expected-warning@+1{{OpenACC clause 'link' not yet implemented}} +#pragma acc loop link(Var) auto + for(;;); + // expected-error@+1{{OpenACC 'no_create' clause is not valid on 'loop' directive}} +#pragma acc loop no_create(Var) auto + for(;;); + // expected-error@+1{{OpenACC 'present' clause is not valid on 'loop' directive}} +#pragma acc loop present(Var) auto + for(;;); +#pragma acc loop private(Var) auto + for(;;); + // expected-error@+1{{OpenACC 'copyout' clause is not valid on 'loop' directive}} +#pragma acc loop copyout(Var) auto + for(;;); + // expected-error@+1{{OpenACC 'pcopyout' clause is not valid on 'loop' directive}} +#pragma acc loop pcopyout(Var) auto + for(;;); + // expected-error@+1{{OpenACC 'present_or_copyout' clause is not valid on 'loop' directive}} +#pragma acc loop present_or_copyout(Var) auto + for(;;); + // expected-error@+1{{OpenACC 'copyin' clause is not valid on 'loop' directive}} +#pragma acc loop copyin(Var) auto + for(;;); + // expected-error@+1{{OpenACC 'pcopyin' clause is not valid on 'loop' directive}} +#pragma acc loop pcopyin(Var) auto + for(;;); + // expected-error@+1{{OpenACC 'present_or_copyin' clause is not valid on 'loop' directive}} +#pragma acc loop present_or_copyin(Var) auto + for(;;); + // expected-error@+1{{OpenACC 'create' clause is not valid on 'loop' directive}} +#pragma acc loop create(Var) auto + for(;;); + // expected-error@+1{{OpenACC 'pcreate' clause is not valid on 'loop' directive}} +#pragma acc loop pcreate(Var) auto + for(;;); + // expected-error@+1{{OpenACC 'present_or_create' clause is not valid on 'loop' directive}} +#pragma acc loop present_or_create(Var) auto + for(;;); + // expected-warning@+1{{OpenACC clause 'reduction' not yet implemented}} +#pragma acc loop reduction(+:Var) auto + for(;;); + // expected-warning@+1{{OpenACC clause 'collapse' not yet implemented}} +#pragma acc loop collapse(1) auto + for(;;); + // expected-warning@+1{{OpenACC clause 'bind' not yet implemented}} +#pragma acc loop bind(Var) auto + for(;;); + // expected-error@+1{{OpenACC 'vector_length' clause is not valid on 'loop' directive}} +#pragma acc loop vector_length(1) auto + for(;;); + // expected-error@+1{{OpenACC 'num_gangs' clause is not valid on 'loop' directive}} +#pragma acc loop num_gangs(1) auto + for(;;); + // expected-error@+1{{OpenACC 'num_workers' clause is not valid on 'loop' directive}} +#pragma acc loop num_workers(1) auto + for(;;); + // expected-warning@+1{{OpenACC clause 'device_num' not yet implemented}} +#pragma acc loop device_num(1) auto + for(;;); + // expected-warning@+1{{OpenACC clause 'default_async' not yet implemented}} +#pragma acc loop default_async(1) auto + for(;;); +#pragma acc loop device_type(*) auto + for(;;); +#pragma acc loop dtype(*) auto + for(;;); + // expected-error@+1{{OpenACC 'async' clause is not valid on 'loop' directive}} +#pragma acc loop async auto + for(;;); + // expected-warning@+1{{OpenACC clause 'tile' not yet implemented}} +#pragma acc loop tile(Var, 1) auto + for(;;); + // expected-warning@+1{{OpenACC clause 'gang' not yet implemented}} +#pragma acc loop gang auto + for(;;); + // expected-error@+1{{OpenACC 'wait' clause is not valid on 'loop' directive}} +#pragma acc loop wait auto + for(;;); + + // 'independent' can also be combined with any clauses + // expected-warning@+1{{OpenACC clause 'finalize' not yet implemented}} +#pragma acc loop independent finalize + for(;;); + // expected-warning@+1{{OpenACC clause 'if_present' not yet implemented}} +#pragma acc loop independent if_present + for(;;); + // expected-warning@+1{{OpenACC clause 'worker' not yet implemented}} +#pragma acc loop independent worker + for(;;); + // expected-warning@+1{{OpenACC clause 'vector' not yet implemented}} +#pragma acc loop independent vector + for(;;); + // expected-warning@+1{{OpenACC clause 'nohost' not yet implemented}} +#pragma acc loop independent nohost + for(;;); + // expected-error@+1{{OpenACC 'default' clause is not valid on 'loop' directive}} +#pragma acc loop independent default(none) + for(;;); + // expected-error@+1{{OpenACC 'if' clause is not valid on 'loop' directive}} +#pragma acc loop independent if(1) + for(;;); + // expected-error@+1{{OpenACC 'self' clause is not valid on 'loop' directive}} +#pragma acc loop independent self + for(;;); + // expected-error@+1{{OpenACC 'copy' clause is not valid on 'loop' directive}} +#pragma acc loop independent copy(Var) + for(;;); + // expected-error@+1{{OpenACC 'pcopy' clause is not valid on 'loop' directive}} +#pragma acc loop independent pcopy(Var) + for(;;); + // expected-error@+1{{OpenACC 'present_or_copy' clause is not valid on 'loop' directive}} +#pragma acc loop independent present_or_copy(Var) + for(;;); + // expected-warning@+1{{OpenACC clause 'use_device' not yet implemented}} +#pragma acc loop independent use_device(Var) + for(;;); + // expected-error@+1{{OpenACC 'attach' clause is not valid on 'loop' directive}} +#pragma acc loop independent attach(Var) + for(;;); + // expected-warning@+1{{OpenACC clause 'delete' not yet implemented}} +#pragma acc loop independent delete(Var) + for(;;); + // expected-warning@+1{{OpenACC clause 'detach' not yet implemented}} +#pragma acc loop independent detach(Var) + for(;;); + // expected-warning@+1{{OpenACC clause 'device' not yet implemented}} +#pragma acc loop independent device(VarPtr) + for(;;); + // expected-error@+1{{OpenACC 'deviceptr' clause is not valid on 'loop' directive}} +#pragma acc loop independent deviceptr(VarPtr) + for(;;); + // expected-warning@+1{{OpenACC clause 'device_resident' not yet implemented}} +#pragma acc loop independent device_resident(VarPtr) + for(;;); + // expected-error@+1{{OpenACC 'firstprivate' clause is not valid on 'loop' directive}} +#pragma acc loop independent firstprivate(Var) + for(;;); + // expected-warning@+1{{OpenACC clause 'host' not yet implemented}} +#pragma acc loop independent host(Var) + for(;;); + // expected-warning@+1{{OpenACC clause 'link' not yet implemented}} +#pragma acc loop independent link(Var) + for(;;); + // expected-error@+1{{OpenACC 'no_create' clause is not valid on 'loop' directive}} +#pragma acc loop independent no_create(Var) + for(;;); + // expected-error@+1{{OpenACC 'present' clause is not valid on 'loop' directive}} +#pragma acc loop independent present(Var) + for(;;); +#pragma acc loop independent private(Var) + for(;;); + // expected-error@+1{{OpenACC 'copyout' clause is not valid on 'loop' directive}} +#pragma acc loop independent copyout(Var) + for(;;); + // expected-error@+1{{OpenACC 'pcopyout' clause is not valid on 'loop' directive}} +#pragma acc loop independent pcopyout(Var) + for(;;); + // expected-error@+1{{OpenACC 'present_or_copyout' clause is not valid on 'loop' directive}} +#pragma acc loop independent present_or_copyout(Var) + for(;;); + // expected-error@+1{{OpenACC 'copyin' clause is not valid on 'loop' directive}} +#pragma acc loop independent copyin(Var) + for(;;); + // expected-error@+1{{OpenACC 'pcopyin' clause is not valid on 'loop' directive}} +#pragma acc loop independent pcopyin(Var) + for(;;); + // expected-error@+1{{OpenACC 'present_or_copyin' clause is not valid on 'loop' directive}} +#pragma acc loop independent present_or_copyin(Var) + for(;;); + // expected-error@+1{{OpenACC 'create' clause is not valid on 'loop' directive}} +#pragma acc loop independent create(Var) + for(;;); + // expected-error@+1{{OpenACC 'pcreate' clause is not valid on 'loop' directive}} +#pragma acc loop independent pcreate(Var) + for(;;); + // expected-error@+1{{OpenACC 'present_or_create' clause is not valid on 'loop' directive}} +#pragma acc loop independent present_or_create(Var) + for(;;); + // expected-warning@+1{{OpenACC clause 'reduction' not yet implemented}} +#pragma acc loop independent reduction(+:Var) + for(;;); + // expected-warning@+1{{OpenACC clause 'collapse' not yet implemented}} +#pragma acc loop independent collapse(1) + for(;;); + // expected-warning@+1{{OpenACC clause 'bind' not yet implemented}} +#pragma acc loop independent bind(Var) + for(;;); + // expected-error@+1{{OpenACC 'vector_length' clause is not valid on 'loop' directive}} +#pragma acc loop independent vector_length(1) + for(;;); + // expected-error@+1{{OpenACC 'num_gangs' clause is not valid on 'loop' directive}} +#pragma acc loop independent num_gangs(1) + for(;;); + // expected-error@+1{{OpenACC 'num_workers' clause is not valid on 'loop' directive}} +#pragma acc loop independent num_workers(1) + for(;;); + // expected-warning@+1{{OpenACC clause 'device_num' not yet implemented}} +#pragma acc loop independent device_num(1) + for(;;); + // expected-warning@+1{{OpenACC clause 'default_async' not yet implemented}} +#pragma acc loop independent default_async(1) + for(;;); +#pragma acc loop independent device_type(*) + for(;;); +#pragma acc loop independent dtype(*) + for(;;); + // expected-error@+1{{OpenACC 'async' clause is not valid on 'loop' directive}} +#pragma acc loop independent async + for(;;); + // expected-warning@+1{{OpenACC clause 'tile' not yet implemented}} +#pragma acc loop independent tile(Var, 1) + for(;;); + // expected-warning@+1{{OpenACC clause 'gang' not yet implemented}} +#pragma acc loop independent gang + for(;;); + // expected-error@+1{{OpenACC 'wait' clause is not valid on 'loop' directive}} +#pragma acc loop independent wait + for(;;); + + // expected-warning@+1{{OpenACC clause 'finalize' not yet implemented}} +#pragma acc loop finalize independent + for(;;); + // expected-warning@+1{{OpenACC clause 'if_present' not yet implemented}} +#pragma acc loop if_present independent + for(;;); + // expected-warning@+1{{OpenACC clause 'worker' not yet implemented}} +#pragma acc loop worker independent + for(;;); + // expected-warning@+1{{OpenACC clause 'vector' not yet implemented}} +#pragma acc loop vector independent + for(;;); + // expected-warning@+1{{OpenACC clause 'nohost' not yet implemented}} +#pragma acc loop nohost independent + for(;;); + // expected-error@+1{{OpenACC 'default' clause is not valid on 'loop' directive}} +#pragma acc loop default(none) independent + for(;;); + // expected-error@+1{{OpenACC 'if' clause is not valid on 'loop' directive}} +#pragma acc loop if(1) independent + for(;;); + // expected-error@+1{{OpenACC 'self' clause is not valid on 'loop' directive}} +#pragma acc loop self independent + for(;;); + // expected-error@+1{{OpenACC 'copy' clause is not valid on 'loop' directive}} +#pragma acc loop copy(Var) independent + for(;;); + // expected-error@+1{{OpenACC 'pcopy' clause is not valid on 'loop' directive}} +#pragma acc loop pcopy(Var) independent + for(;;); + // expected-error@+1{{OpenACC 'present_or_copy' clause is not valid on 'loop' directive}} +#pragma acc loop present_or_copy(Var) independent + for(;;); + // expected-warning@+1{{OpenACC clause 'use_device' not yet implemented}} +#pragma acc loop use_device(Var) independent + for(;;); + // expected-error@+1{{OpenACC 'attach' clause is not valid on 'loop' directive}} +#pragma acc loop attach(Var) independent + for(;;); + // expected-warning@+1{{OpenACC clause 'delete' not yet implemented}} +#pragma acc loop delete(Var) independent + for(;;); + // expected-warning@+1{{OpenACC clause 'detach' not yet implemented}} +#pragma acc loop detach(Var) independent + for(;;); + // expected-warning@+1{{OpenACC clause 'device' not yet implemented}} +#pragma acc loop device(VarPtr) independent + for(;;); + // expected-error@+1{{OpenACC 'deviceptr' clause is not valid on 'loop' directive}} +#pragma acc loop deviceptr(VarPtr) independent + for(;;); + // expected-warning@+1{{OpenACC clause 'device_resident' not yet implemented}} +#pragma acc loop device_resident(VarPtr) independent + for(;;); + // expected-error@+1{{OpenACC 'firstprivate' clause is not valid on 'loop' directive}} +#pragma acc loop firstprivate(Var) independent + for(;;); + // expected-warning@+1{{OpenACC clause 'host' not yet implemented}} +#pragma acc loop host(Var) independent + for(;;); + // expected-warning@+1{{OpenACC clause 'link' not yet implemented}} +#pragma acc loop link(Var) independent + for(;;); + // expected-error@+1{{OpenACC 'no_create' clause is not valid on 'loop' directive}} +#pragma acc loop no_create(Var) independent + for(;;); + // expected-error@+1{{OpenACC 'present' clause is not valid on 'loop' directive}} +#pragma acc loop present(Var) independent + for(;;); +#pragma acc loop private(Var) independent + for(;;); + // expected-error@+1{{OpenACC 'copyout' clause is not valid on 'loop' directive}} +#pragma acc loop copyout(Var) independent + for(;;); + // expected-error@+1{{OpenACC 'pcopyout' clause is not valid on 'loop' directive}} +#pragma acc loop pcopyout(Var) independent + for(;;); + // expected-error@+1{{OpenACC 'present_or_copyout' clause is not valid on 'loop' directive}} +#pragma acc loop present_or_copyout(Var) independent + for(;;); + // expected-error@+1{{OpenACC 'copyin' clause is not valid on 'loop' directive}} +#pragma acc loop copyin(Var) independent + for(;;); + // expected-error@+1{{OpenACC 'pcopyin' clause is not valid on 'loop' directive}} +#pragma acc loop pcopyin(Var) independent + for(;;); + // expected-error@+1{{OpenACC 'present_or_copyin' clause is not valid on 'loop' directive}} +#pragma acc loop present_or_copyin(Var) independent + for(;;); + // expected-error@+1{{OpenACC 'create' clause is not valid on 'loop' directive}} +#pragma acc loop create(Var) independent + for(;;); + // expected-error@+1{{OpenACC 'pcreate' clause is not valid on 'loop' directive}} +#pragma acc loop pcreate(Var) independent + for(;;); + // expected-error@+1{{OpenACC 'present_or_create' clause is not valid on 'loop' directive}} +#pragma acc loop present_or_create(Var) independent + for(;;); + // expected-warning@+1{{OpenACC clause 'reduction' not yet implemented}} +#pragma acc loop reduction(+:Var) independent + for(;;); + // expected-warning@+1{{OpenACC clause 'collapse' not yet implemented}} +#pragma acc loop collapse(1) independent + for(;;); + // expected-warning@+1{{OpenACC clause 'bind' not yet implemented}} +#pragma acc loop bind(Var) independent + for(;;); + // expected-error@+1{{OpenACC 'vector_length' clause is not valid on 'loop' directive}} +#pragma acc loop vector_length(1) independent + for(;;); + // expected-error@+1{{OpenACC 'num_gangs' clause is not valid on 'loop' directive}} +#pragma acc loop num_gangs(1) independent + for(;;); + // expected-error@+1{{OpenACC 'num_workers' clause is not valid on 'loop' directive}} +#pragma acc loop num_workers(1) independent + for(;;); + // expected-warning@+1{{OpenACC clause 'device_num' not yet implemented}} +#pragma acc loop device_num(1) independent + for(;;); + // expected-warning@+1{{OpenACC clause 'default_async' not yet implemented}} +#pragma acc loop default_async(1) independent + for(;;); +#pragma acc loop device_type(*) independent + for(;;); +#pragma acc loop dtype(*) independent + for(;;); + // expected-error@+1{{OpenACC 'async' clause is not valid on 'loop' directive}} +#pragma acc loop async independent + for(;;); + // expected-warning@+1{{OpenACC clause 'tile' not yet implemented}} +#pragma acc loop tile(Var, 1) independent + for(;;); + // expected-warning@+1{{OpenACC clause 'gang' not yet implemented}} +#pragma acc loop gang independent + for(;;); + // expected-error@+1{{OpenACC 'wait' clause is not valid on 'loop' directive}} +#pragma acc loop wait independent + for(;;); + + // 'seq' cannot be combined with 'gang', 'worker' or 'vector' + // expected-error@+3{{OpenACC clause 'gang' may not appear on the same construct as a 'seq' clause on a 'loop' construct}} + // expected-note@+2{{previous clause is here}} + // expected-warning@+1{{OpenACC clause 'gang' not yet implemented}} +#pragma acc loop seq gang + for(;;); + // expected-error@+3{{OpenACC clause 'worker' may not appear on the same construct as a 'seq' clause on a 'loop' construct}} + // expected-note@+2{{previous clause is here}} + // expected-warning@+1{{OpenACC clause 'worker' not yet implemented}} +#pragma acc loop seq worker + for(;;); + // expected-error@+3{{OpenACC clause 'vector' may not appear on the same construct as a 'seq' clause on a 'loop' construct}} + // expected-note@+2{{previous clause is here}} + // expected-warning@+1{{OpenACC clause 'vector' not yet implemented}} +#pragma acc loop seq vector + for(;;); + // expected-warning@+1{{OpenACC clause 'finalize' not yet implemented}} +#pragma acc loop seq finalize + for(;;); + // expected-warning@+1{{OpenACC clause 'if_present' not yet implemented}} +#pragma acc loop seq if_present + for(;;); + // expected-warning@+1{{OpenACC clause 'nohost' not yet implemented}} +#pragma acc loop seq nohost + for(;;); + // expected-error@+1{{OpenACC 'default' clause is not valid on 'loop' directive}} +#pragma acc loop seq default(none) + for(;;); + // expected-error@+1{{OpenACC 'if' clause is not valid on 'loop' directive}} +#pragma acc loop seq if(1) + for(;;); + // expected-error@+1{{OpenACC 'self' clause is not valid on 'loop' directive}} +#pragma acc loop seq self + for(;;); + // expected-error@+1{{OpenACC 'copy' clause is not valid on 'loop' directive}} +#pragma acc loop seq copy(Var) + for(;;); + // expected-error@+1{{OpenACC 'pcopy' clause is not valid on 'loop' directive}} +#pragma acc loop seq pcopy(Var) + for(;;); + // expected-error@+1{{OpenACC 'present_or_copy' clause is not valid on 'loop' directive}} +#pragma acc loop seq present_or_copy(Var) + for(;;); + // expected-warning@+1{{OpenACC clause 'use_device' not yet implemented}} +#pragma acc loop seq use_device(Var) + for(;;); + // expected-error@+1{{OpenACC 'attach' clause is not valid on 'loop' directive}} +#pragma acc loop seq attach(Var) + for(;;); + // expected-warning@+1{{OpenACC clause 'delete' not yet implemented}} +#pragma acc loop seq delete(Var) + for(;;); + // expected-warning@+1{{OpenACC clause 'detach' not yet implemented}} +#pragma acc loop seq detach(Var) + for(;;); + // expected-warning@+1{{OpenACC clause 'device' not yet implemented}} +#pragma acc loop seq device(VarPtr) + for(;;); + // expected-error@+1{{OpenACC 'deviceptr' clause is not valid on 'loop' directive}} +#pragma acc loop seq deviceptr(VarPtr) + for(;;); + // expected-warning@+1{{OpenACC clause 'device_resident' not yet implemented}} +#pragma acc loop seq device_resident(VarPtr) + for(;;); + // expected-error@+1{{OpenACC 'firstprivate' clause is not valid on 'loop' directive}} +#pragma acc loop seq firstprivate(Var) + for(;;); + // expected-warning@+1{{OpenACC clause 'host' not yet implemented}} +#pragma acc loop seq host(Var) + for(;;); + // expected-warning@+1{{OpenACC clause 'link' not yet implemented}} +#pragma acc loop seq link(Var) + for(;;); + // expected-error@+1{{OpenACC 'no_create' clause is not valid on 'loop' directive}} +#pragma acc loop seq no_create(Var) + for(;;); + // expected-error@+1{{OpenACC 'present' clause is not valid on 'loop' directive}} +#pragma acc loop seq present(Var) + for(;;); +#pragma acc loop seq private(Var) + for(;;); + // expected-error@+1{{OpenACC 'copyout' clause is not valid on 'loop' directive}} +#pragma acc loop seq copyout(Var) + for(;;); + // expected-error@+1{{OpenACC 'pcopyout' clause is not valid on 'loop' directive}} +#pragma acc loop seq pcopyout(Var) + for(;;); + // expected-error@+1{{OpenACC 'present_or_copyout' clause is not valid on 'loop' directive}} +#pragma acc loop seq present_or_copyout(Var) + for(;;); + // expected-error@+1{{OpenACC 'copyin' clause is not valid on 'loop' directive}} +#pragma acc loop seq copyin(Var) + for(;;); + // expected-error@+1{{OpenACC 'pcopyin' clause is not valid on 'loop' directive}} +#pragma acc loop seq pcopyin(Var) + for(;;); + // expected-error@+1{{OpenACC 'present_or_copyin' clause is not valid on 'loop' directive}} +#pragma acc loop seq present_or_copyin(Var) + for(;;); + // expected-error@+1{{OpenACC 'create' clause is not valid on 'loop' directive}} +#pragma acc loop seq create(Var) + for(;;); + // expected-error@+1{{OpenACC 'pcreate' clause is not valid on 'loop' directive}} +#pragma acc loop seq pcreate(Var) + for(;;); + // expected-error@+1{{OpenACC 'present_or_create' clause is not valid on 'loop' directive}} +#pragma acc loop seq present_or_create(Var) + for(;;); + // expected-warning@+1{{OpenACC clause 'reduction' not yet implemented}} +#pragma acc loop seq reduction(+:Var) + for(;;); + // expected-warning@+1{{OpenACC clause 'collapse' not yet implemented}} +#pragma acc loop seq collapse(1) + for(;;); + // expected-warning@+1{{OpenACC clause 'bind' not yet implemented}} +#pragma acc loop seq bind(Var) + for(;;); + // expected-error@+1{{OpenACC 'vector_length' clause is not valid on 'loop' directive}} +#pragma acc loop seq vector_length(1) + for(;;); + // expected-error@+1{{OpenACC 'num_gangs' clause is not valid on 'loop' directive}} +#pragma acc loop seq num_gangs(1) + for(;;); + // expected-error@+1{{OpenACC 'num_workers' clause is not valid on 'loop' directive}} +#pragma acc loop seq num_workers(1) + for(;;); + // expected-warning@+1{{OpenACC clause 'device_num' not yet implemented}} +#pragma acc loop seq device_num(1) + for(;;); + // expected-warning@+1{{OpenACC clause 'default_async' not yet implemented}} +#pragma acc loop seq default_async(1) + for(;;); +#pragma acc loop seq device_type(*) + for(;;); +#pragma acc loop seq dtype(*) + for(;;); + // expected-error@+1{{OpenACC 'async' clause is not valid on 'loop' directive}} +#pragma acc loop seq async + for(;;); + // expected-warning@+1{{OpenACC clause 'tile' not yet implemented}} +#pragma acc loop seq tile(Var, 1) + for(;;); + // expected-error@+1{{OpenACC 'wait' clause is not valid on 'loop' directive}} +#pragma acc loop seq wait + for(;;); + + // TODO OpenACC: when 'gang' is implemented and makes it to the AST, this should diagnose because of a conflict with 'seq'. + // TODOexpected-error@+3{{OpenACC clause 'gang' may not appear on the same construct as a 'seq' clause on a 'loop' construct}} + // TODOexpected-note@+2{{previous clause is here}} + // expected-warning@+1{{OpenACC clause 'gang' not yet implemented}} +#pragma acc loop gang seq + for(;;); + // TODO OpenACC: when 'worker' is implemented and makes it to the AST, this should diagnose because of a conflict with 'seq'. + // TODOexpected-error@+3{{OpenACC clause 'worker' may not appear on the same construct as a 'seq' clause on a 'loop' construct}} + // TODOexpected-note@+2{{previous clause is here}} + // expected-warning@+1{{OpenACC clause 'worker' not yet implemented}} +#pragma acc loop worker seq + for(;;); + // TODO OpenACC: when 'vector' is implemented and makes it to the AST, this should diagnose because of a conflict with 'seq'. + // TODOexpected-error@+3{{OpenACC clause 'vector' may not appear on the same construct as a 'seq' clause on a 'loop' construct}} + // TODOexpected-note@+2{{previous clause is here}} + // expected-warning@+1{{OpenACC clause 'vector' not yet implemented}} +#pragma acc loop vector seq + for(;;); + // expected-warning@+1{{OpenACC clause 'finalize' not yet implemented}} +#pragma acc loop finalize seq + for(;;); + // expected-warning@+1{{OpenACC clause 'if_present' not yet implemented}} +#pragma acc loop if_present seq + for(;;); + // expected-warning@+1{{OpenACC clause 'nohost' not yet implemented}} +#pragma acc loop nohost seq + for(;;); + // expected-error@+1{{OpenACC 'default' clause is not valid on 'loop' directive}} +#pragma acc loop default(none) seq + for(;;); + // expected-error@+1{{OpenACC 'if' clause is not valid on 'loop' directive}} +#pragma acc loop if(1) seq + for(;;); + // expected-error@+1{{OpenACC 'self' clause is not valid on 'loop' directive}} +#pragma acc loop self seq + for(;;); + // expected-error@+1{{OpenACC 'copy' clause is not valid on 'loop' directive}} +#pragma acc loop copy(Var) seq + for(;;); + // expected-error@+1{{OpenACC 'pcopy' clause is not valid on 'loop' directive}} +#pragma acc loop pcopy(Var) seq + for(;;); + // expected-error@+1{{OpenACC 'present_or_copy' clause is not valid on 'loop' directive}} +#pragma acc loop present_or_copy(Var) seq + for(;;); + // expected-warning@+1{{OpenACC clause 'use_device' not yet implemented}} +#pragma acc loop use_device(Var) seq + for(;;); + // expected-error@+1{{OpenACC 'attach' clause is not valid on 'loop' directive}} +#pragma acc loop attach(Var) seq + for(;;); + // expected-warning@+1{{OpenACC clause 'delete' not yet implemented}} +#pragma acc loop delete(Var) seq + for(;;); + // expected-warning@+1{{OpenACC clause 'detach' not yet implemented}} +#pragma acc loop detach(Var) seq + for(;;); + // expected-warning@+1{{OpenACC clause 'device' not yet implemented}} +#pragma acc loop device(VarPtr) seq + for(;;); + // expected-error@+1{{OpenACC 'deviceptr' clause is not valid on 'loop' directive}} +#pragma acc loop deviceptr(VarPtr) seq + for(;;); + // expected-warning@+1{{OpenACC clause 'device_resident' not yet implemented}} +#pragma acc loop device_resident(VarPtr) seq + for(;;); + // expected-error@+1{{OpenACC 'firstprivate' clause is not valid on 'loop' directive}} +#pragma acc loop firstprivate(Var) seq + for(;;); + // expected-warning@+1{{OpenACC clause 'host' not yet implemented}} +#pragma acc loop host(Var) seq + for(;;); + // expected-warning@+1{{OpenACC clause 'link' not yet implemented}} +#pragma acc loop link(Var) seq + for(;;); + // expected-error@+1{{OpenACC 'no_create' clause is not valid on 'loop' directive}} +#pragma acc loop no_create(Var) seq + for(;;); + // expected-error@+1{{OpenACC 'present' clause is not valid on 'loop' directive}} +#pragma acc loop present(Var) seq + for(;;); +#pragma acc loop private(Var) seq + for(;;); + // expected-error@+1{{OpenACC 'copyout' clause is not valid on 'loop' directive}} +#pragma acc loop copyout(Var) seq + for(;;); + // expected-error@+1{{OpenACC 'pcopyout' clause is not valid on 'loop' directive}} +#pragma acc loop pcopyout(Var) seq + for(;;); + // expected-error@+1{{OpenACC 'present_or_copyout' clause is not valid on 'loop' directive}} +#pragma acc loop present_or_copyout(Var) seq + for(;;); + // expected-error@+1{{OpenACC 'copyin' clause is not valid on 'loop' directive}} +#pragma acc loop copyin(Var) seq + for(;;); + // expected-error@+1{{OpenACC 'pcopyin' clause is not valid on 'loop' directive}} +#pragma acc loop pcopyin(Var) seq + for(;;); + // expected-error@+1{{OpenACC 'present_or_copyin' clause is not valid on 'loop' directive}} +#pragma acc loop present_or_copyin(Var) seq + for(;;); + // expected-error@+1{{OpenACC 'create' clause is not valid on 'loop' directive}} +#pragma acc loop create(Var) seq + for(;;); + // expected-error@+1{{OpenACC 'pcreate' clause is not valid on 'loop' directive}} +#pragma acc loop pcreate(Var) seq + for(;;); + // expected-error@+1{{OpenACC 'present_or_create' clause is not valid on 'loop' directive}} +#pragma acc loop present_or_create(Var) seq + for(;;); + // expected-warning@+1{{OpenACC clause 'reduction' not yet implemented}} +#pragma acc loop reduction(+:Var) seq + for(;;); + // expected-warning@+1{{OpenACC clause 'collapse' not yet implemented}} +#pragma acc loop collapse(1) seq + for(;;); + // expected-warning@+1{{OpenACC clause 'bind' not yet implemented}} +#pragma acc loop bind(Var) seq + for(;;); + // expected-error@+1{{OpenACC 'vector_length' clause is not valid on 'loop' directive}} +#pragma acc loop vector_length(1) seq + for(;;); + // expected-error@+1{{OpenACC 'num_gangs' clause is not valid on 'loop' directive}} +#pragma acc loop num_gangs(1) seq + for(;;); + // expected-error@+1{{OpenACC 'num_workers' clause is not valid on 'loop' directive}} +#pragma acc loop num_workers(1) seq + for(;;); + // expected-warning@+1{{OpenACC clause 'device_num' not yet implemented}} +#pragma acc loop device_num(1) seq + for(;;); + // expected-warning@+1{{OpenACC clause 'default_async' not yet implemented}} +#pragma acc loop default_async(1) seq + for(;;); +#pragma acc loop device_type(*) seq + for(;;); +#pragma acc loop dtype(*) seq + for(;;); + // expected-error@+1{{OpenACC 'async' clause is not valid on 'loop' directive}} +#pragma acc loop async seq + for(;;); + // expected-warning@+1{{OpenACC clause 'tile' not yet implemented}} +#pragma acc loop tile(Var, 1) seq + for(;;); + // expected-error@+1{{OpenACC 'wait' clause is not valid on 'loop' directive}} +#pragma acc loop wait seq + for(;;); +} diff --git a/clang/test/SemaOpenACC/loop-construct-device_type-ast.cpp b/clang/test/SemaOpenACC/loop-construct-device_type-ast.cpp new file mode 100644 index 0000000000000000000000000000000000000000..537eae09083581de83a004dc5ae70b6d359d8c8e --- /dev/null +++ b/clang/test/SemaOpenACC/loop-construct-device_type-ast.cpp @@ -0,0 +1,129 @@ +// RUN: %clang_cc1 %s -fopenacc -ast-dump | FileCheck %s + +// Test this with PCH. +// RUN: %clang_cc1 %s -fopenacc -emit-pch -o %t %s +// RUN: %clang_cc1 %s -fopenacc -include-pch %t -ast-dump-all | FileCheck %s +#ifndef PCH_HELPER +#define PCH_HELPER + +struct SomeS{}; +void NormalUses() { + // CHECK: FunctionDecl{{.*}}NormalUses + // CHECK-NEXT: CompoundStmt + + SomeS SomeImpl; + // CHECK-NEXT: DeclStmt + // CHECK-NEXT: VarDecl{{.*}} SomeImpl 'SomeS' + // CHECK-NEXT: CXXConstructExpr + bool SomeVar; + // CHECK-NEXT: DeclStmt + // CHECK-NEXT: VarDecl{{.*}} SomeVar 'bool' + +#pragma acc loop device_type(SomeS) dtype(SomeImpl) + for(;;){} + // CHECK-NEXT: OpenACCLoopConstruct{{.*}} + // CHECK-NEXT: device_type(SomeS) + // CHECK-NEXT: dtype(SomeImpl) + // CHECK-NEXT: ForStmt + // CHECK-NEXT: <<>> + // CHECK-NEXT: <<>> + // CHECK-NEXT: <<>> + // CHECK-NEXT: <<>> + // CHECK-NEXT: CompoundStmt +#pragma acc loop device_type(SomeVar) dtype(int) + for(;;){} + // CHECK-NEXT: OpenACCLoopConstruct{{.*}} + // CHECK-NEXT: device_type(SomeVar) + // CHECK-NEXT: dtype(int) + // CHECK-NEXT: ForStmt + // CHECK-NEXT: <<>> + // CHECK-NEXT: <<>> + // CHECK-NEXT: <<>> + // CHECK-NEXT: <<>> + // CHECK-NEXT: CompoundStmt +#pragma acc loop device_type(private) dtype(struct) + for(;;){} + // CHECK-NEXT: OpenACCLoopConstruct{{.*}} + // CHECK-NEXT: device_type(private) + // CHECK-NEXT: dtype(struct) + // CHECK-NEXT: ForStmt + // CHECK-NEXT: <<>> + // CHECK-NEXT: <<>> + // CHECK-NEXT: <<>> + // CHECK-NEXT: <<>> + // CHECK-NEXT: CompoundStmt +#pragma acc loop device_type(private) dtype(class) + for(;;){} + // CHECK-NEXT: OpenACCLoopConstruct{{.*}} + // CHECK-NEXT: device_type(private) + // CHECK-NEXT: dtype(class) + // CHECK-NEXT: ForStmt + // CHECK-NEXT: <<>> + // CHECK-NEXT: <<>> + // CHECK-NEXT: <<>> + // CHECK-NEXT: <<>> + // CHECK-NEXT: CompoundStmt +#pragma acc loop device_type(float) dtype(*) + for(;;){} + // CHECK-NEXT: OpenACCLoopConstruct{{.*}} + // CHECK-NEXT: device_type(float) + // CHECK-NEXT: dtype(*) + // CHECK-NEXT: ForStmt + // CHECK-NEXT: <<>> + // CHECK-NEXT: <<>> + // CHECK-NEXT: <<>> + // CHECK-NEXT: <<>> + // CHECK-NEXT: CompoundStmt +#pragma acc loop device_type(float, int) dtype(*) + for(;;){} + // CHECK-NEXT: OpenACCLoopConstruct{{.*}} + // CHECK-NEXT: device_type(float, int) + // CHECK-NEXT: dtype(*) + // CHECK-NEXT: ForStmt + // CHECK-NEXT: <<>> + // CHECK-NEXT: <<>> + // CHECK-NEXT: <<>> + // CHECK-NEXT: <<>> + // CHECK-NEXT: CompoundStmt +} + +template +void TemplUses() { + // CHECK-NEXT: FunctionTemplateDecl{{.*}}TemplUses + // CHECK-NEXT: TemplateTypeParmDecl{{.*}}T + // CHECK-NEXT: FunctionDecl{{.*}}TemplUses + // CHECK-NEXT: CompoundStmt +#pragma acc loop device_type(T) dtype(T) + for(;;){} + // CHECK-NEXT: OpenACCLoopConstruct{{.*}} + // CHECK-NEXT: device_type(T) + // CHECK-NEXT: dtype(T) + // CHECK-NEXT: ForStmt + // CHECK-NEXT: <<>> + // CHECK-NEXT: <<>> + // CHECK-NEXT: <<>> + // CHECK-NEXT: <<>> + // CHECK-NEXT: CompoundStmt + + + // Instantiations + // CHECK-NEXT: FunctionDecl{{.*}} TemplUses 'void ()' implicit_instantiation + // CHECK-NEXT: TemplateArgument type 'int' + // CHECK-NEXT: BuiltinType{{.*}} 'int' + // CHECK-NEXT: CompoundStmt + + // CHECK-NEXT: OpenACCLoopConstruct{{.*}} + // CHECK-NEXT: device_type(T) + // CHECK-NEXT: dtype(T) + // CHECK-NEXT: ForStmt + // CHECK-NEXT: <<>> + // CHECK-NEXT: <<>> + // CHECK-NEXT: <<>> + // CHECK-NEXT: <<>> + // CHECK-NEXT: CompoundStmt +} + +void Inst() { + TemplUses(); +} +#endif // PCH_HELPER diff --git a/clang/test/SemaOpenACC/loop-construct-device_type-clause.c b/clang/test/SemaOpenACC/loop-construct-device_type-clause.c new file mode 100644 index 0000000000000000000000000000000000000000..520ba45aaebf4f662b803d0acce467db10bb7764 --- /dev/null +++ b/clang/test/SemaOpenACC/loop-construct-device_type-clause.c @@ -0,0 +1,201 @@ +// RUN: %clang_cc1 %s -fopenacc -verify + +#define MACRO +FOO + +void uses() { + typedef struct S{} STy; + STy SImpl; + +#pragma acc loop device_type(I) + for(;;); +#pragma acc loop device_type(S) dtype(STy) + for(;;); +#pragma acc loop dtype(SImpl) + for(;;); +#pragma acc loop dtype(int) device_type(*) + for(;;); +#pragma acc loop dtype(true) device_type(false) + for(;;); + + // expected-error@+1{{expected identifier}} +#pragma acc loop dtype(int, *) + for(;;); + +#pragma acc loop device_type(I, int) + for(;;); + // expected-error@+2{{expected ','}} + // expected-error@+1{{expected identifier}} +#pragma acc loop dtype(int{}) + for(;;); + // expected-error@+1{{expected identifier}} +#pragma acc loop dtype(5) + for(;;); + // expected-error@+1{{expected identifier}} +#pragma acc loop dtype(MACRO) + for(;;); + + + // Only 'collapse', 'gang', 'worker', 'vector', 'seq', 'independent', 'auto', + // and 'tile' allowed after 'device_type'. + + // expected-warning@+1{{OpenACC clause 'vector' not yet implemented, clause ignored}} +#pragma acc loop device_type(*) vector + for(;;); + + // expected-error@+2{{OpenACC clause 'finalize' may not follow a 'device_type' clause in a 'loop' construct}} + // expected-note@+1{{previous clause is here}} +#pragma acc loop device_type(*) finalize + for(;;); + // expected-error@+2{{OpenACC clause 'if_present' may not follow a 'device_type' clause in a 'loop' construct}} + // expected-note@+1{{previous clause is here}} +#pragma acc loop device_type(*) if_present + for(;;); +#pragma acc loop device_type(*) seq + for(;;); +#pragma acc loop device_type(*) independent + for(;;); +#pragma acc loop device_type(*) auto + for(;;); + // expected-warning@+1{{OpenACC clause 'worker' not yet implemented, clause ignored}} +#pragma acc loop device_type(*) worker + for(;;); + // expected-error@+2{{OpenACC clause 'nohost' may not follow a 'device_type' clause in a 'loop' construct}} + // expected-note@+1{{previous clause is here}} +#pragma acc loop device_type(*) nohost + for(;;); + // expected-error@+1{{OpenACC 'default' clause is not valid on 'loop' directive}} +#pragma acc loop device_type(*) default(none) + for(;;); + // expected-error@+1{{OpenACC 'if' clause is not valid on 'loop' directive}} +#pragma acc loop device_type(*) if(1) + for(;;); + // expected-error@+1{{OpenACC 'self' clause is not valid on 'loop' directive}} +#pragma acc loop device_type(*) self + for(;;); + + int Var; + int *VarPtr; + // expected-error@+1{{OpenACC 'copy' clause is not valid on 'loop' directive}} +#pragma acc loop device_type(*) copy(Var) + for(;;); + // expected-error@+1{{OpenACC 'pcopy' clause is not valid on 'loop' directive}} +#pragma acc loop device_type(*) pcopy(Var) + for(;;); + // expected-error@+1{{OpenACC 'present_or_copy' clause is not valid on 'loop' directive}} +#pragma acc loop device_type(*) present_or_copy(Var) + for(;;); + // expected-error@+2{{OpenACC clause 'use_device' may not follow a 'device_type' clause in a 'loop' construct}} + // expected-note@+1{{previous clause is here}} +#pragma acc loop device_type(*) use_device(Var) + for(;;); + // expected-error@+1{{OpenACC 'attach' clause is not valid on 'loop' directive}} +#pragma acc loop device_type(*) attach(Var) + for(;;); + // expected-error@+2{{OpenACC clause 'delete' may not follow a 'device_type' clause in a 'loop' construct}} + // expected-note@+1{{previous clause is here}} +#pragma acc loop device_type(*) delete(Var) + for(;;); + // expected-error@+2{{OpenACC clause 'detach' may not follow a 'device_type' clause in a 'loop' construct}} + // expected-note@+1{{previous clause is here}} +#pragma acc loop device_type(*) detach(Var) + for(;;); + // expected-error@+2{{OpenACC clause 'device' may not follow a 'device_type' clause in a 'loop' construct}} + // expected-note@+1{{previous clause is here}} +#pragma acc loop device_type(*) device(VarPtr) + for(;;); + // expected-error@+1{{OpenACC 'deviceptr' clause is not valid on 'loop' directive}} +#pragma acc loop device_type(*) deviceptr(VarPtr) + for(;;); + // expected-error@+2{{OpenACC clause 'device_resident' may not follow a 'device_type' clause in a 'loop' construct}} + // expected-note@+1{{previous clause is here}} +#pragma acc loop device_type(*) device_resident(VarPtr) + for(;;); + // expected-error@+1{{OpenACC 'firstprivate' clause is not valid on 'loop' directive}} +#pragma acc loop device_type(*) firstprivate(Var) + for(;;); + // expected-error@+2{{OpenACC clause 'host' may not follow a 'device_type' clause in a 'loop' construct}} + // expected-note@+1{{previous clause is here}} +#pragma acc loop device_type(*) host(Var) + for(;;); + // expected-error@+2{{OpenACC clause 'link' may not follow a 'device_type' clause in a 'loop' construct}} + // expected-note@+1{{previous clause is here}} +#pragma acc loop device_type(*) link(Var) + for(;;); + // expected-error@+1{{OpenACC 'no_create' clause is not valid on 'loop' directive}} +#pragma acc loop device_type(*) no_create(Var) + for(;;); + // expected-error@+1{{OpenACC 'present' clause is not valid on 'loop' directive}} +#pragma acc loop device_type(*) present(Var) + for(;;); + // expected-error@+2{{OpenACC clause 'private' may not follow a 'device_type' clause in a 'loop' construct}} + // expected-note@+1{{previous clause is here}} +#pragma acc loop device_type(*) private(Var) + for(;;); + // expected-error@+1{{OpenACC 'copyout' clause is not valid on 'loop' directive}} +#pragma acc loop device_type(*) copyout(Var) + for(;;); + // expected-error@+1{{OpenACC 'pcopyout' clause is not valid on 'loop' directive}} +#pragma acc loop device_type(*) pcopyout(Var) + for(;;); + // expected-error@+1{{OpenACC 'present_or_copyout' clause is not valid on 'loop' directive}} +#pragma acc loop device_type(*) present_or_copyout(Var) + for(;;); + // expected-error@+1{{OpenACC 'copyin' clause is not valid on 'loop' directive}} +#pragma acc loop device_type(*) copyin(Var) + for(;;); + // expected-error@+1{{OpenACC 'pcopyin' clause is not valid on 'loop' directive}} +#pragma acc loop device_type(*) pcopyin(Var) + for(;;); + // expected-error@+1{{OpenACC 'present_or_copyin' clause is not valid on 'loop' directive}} +#pragma acc loop device_type(*) present_or_copyin(Var) + for(;;); + // expected-error@+1{{OpenACC 'create' clause is not valid on 'loop' directive}} +#pragma acc loop device_type(*) create(Var) + for(;;); + // expected-error@+1{{OpenACC 'pcreate' clause is not valid on 'loop' directive}} +#pragma acc loop device_type(*) pcreate(Var) + for(;;); + // expected-error@+1{{OpenACC 'present_or_create' clause is not valid on 'loop' directive}} +#pragma acc loop device_type(*) present_or_create(Var) + for(;;); + // expected-error@+2{{OpenACC clause 'reduction' may not follow a 'device_type' clause in a 'loop' construct}} + // expected-note@+1{{previous clause is here}} +#pragma acc loop device_type(*) reduction(+:Var) + for(;;); + // expected-warning@+1{{OpenACC clause 'collapse' not yet implemented, clause ignored}} +#pragma acc loop device_type(*) collapse(1) + for(;;); + // expected-error@+2{{OpenACC clause 'bind' may not follow a 'device_type' clause in a 'loop' construct}} + // expected-note@+1{{previous clause is here}} +#pragma acc loop device_type(*) bind(Var) + for(;;); + // expected-error@+1{{OpenACC 'vector_length' clause is not valid on 'loop' directive}} +#pragma acc loop device_type(*) vector_length(1) + for(;;); + // expected-error@+1{{OpenACC 'num_gangs' clause is not valid on 'loop' directive}} +#pragma acc loop device_type(*) num_gangs(1) + for(;;); + // expected-error@+1{{OpenACC 'num_workers' clause is not valid on 'loop' directive}} +#pragma acc loop device_type(*) num_workers(1) + for(;;); + // expected-error@+2{{OpenACC clause 'device_num' may not follow a 'device_type' clause in a 'loop' construct}} + // expected-note@+1{{previous clause is here}} +#pragma acc loop device_type(*) device_num(1) + for(;;); + // expected-error@+2{{OpenACC clause 'default_async' may not follow a 'device_type' clause in a 'loop' construct}} + // expected-note@+1{{previous clause is here}} +#pragma acc loop device_type(*) default_async(1) + for(;;); + // expected-error@+1{{OpenACC 'async' clause is not valid on 'loop' directive}} +#pragma acc loop device_type(*) async + for(;;); + // expected-warning@+1{{OpenACC clause 'tile' not yet implemented, clause ignored}} +#pragma acc loop device_type(*) tile(Var, 1) + for(;;); + // expected-warning@+1{{OpenACC clause 'gang' not yet implemented, clause ignored}} +#pragma acc loop dtype(*) gang + for(;;); + // expected-error@+1{{OpenACC 'wait' clause is not valid on 'loop' directive}} +#pragma acc loop device_type(*) wait + for(;;); +} diff --git a/clang/test/SemaOpenACC/loop-construct-device_type-clause.cpp b/clang/test/SemaOpenACC/loop-construct-device_type-clause.cpp new file mode 100644 index 0000000000000000000000000000000000000000..b8d8d6de4dcf6010867e1914e49c9ed81c8d6f63 --- /dev/null +++ b/clang/test/SemaOpenACC/loop-construct-device_type-clause.cpp @@ -0,0 +1,25 @@ +// RUN: %clang_cc1 %s -fopenacc -verify + +template +void TemplUses() { +#pragma acc loop device_type(I) + for(;;); +#pragma acc loop dtype(*) + for(;;); +#pragma acc loop device_type(class) + for(;;); +#pragma acc loop device_type(private) + for(;;); +#pragma acc loop device_type(bool) + for(;;); +#pragma acc kernels dtype(true) device_type(false) + for(;;); + // expected-error@+2{{expected ','}} + // expected-error@+1{{expected identifier}} +#pragma acc loop device_type(T::value) + for(;;); +} + +void Inst() { + TemplUses(); // #INST +} diff --git a/clang/test/SemaOpenACC/loop-construct-private-clause.c b/clang/test/SemaOpenACC/loop-construct-private-clause.c new file mode 100644 index 0000000000000000000000000000000000000000..f3ffdfbe3984c82959e15ec8937818d255cbda82 --- /dev/null +++ b/clang/test/SemaOpenACC/loop-construct-private-clause.c @@ -0,0 +1,132 @@ +// RUN: %clang_cc1 %s -fopenacc -verify + +struct Incomplete; +enum SomeE{ A }; +typedef struct IsComplete { + struct S { int A; } CompositeMember; + int ScalarMember; + float ArrayMember[5]; + enum SomeE EnumMember; + void *PointerMember; +} Complete; + +int GlobalInt; +float GlobalArray[5]; +short *GlobalPointer; +Complete GlobalComposite; + +void uses(int IntParam, short *PointerParam, float ArrayParam[5], Complete CompositeParam) { + int LocalInt; + short *LocalPointer; + float LocalArray[5]; + Complete LocalComposite; + + // Check Appertainment: +#pragma acc loop private(LocalInt) + for(;;); + + // Valid cases: +#pragma acc loop private(LocalInt, LocalPointer, LocalArray) + for(;;); +#pragma acc loop private(LocalArray) + for(;;); +#pragma acc loop private(LocalArray[:]) + for(;;); +#pragma acc loop private(LocalArray[:5]) + for(;;); +#pragma acc loop private(LocalArray[2:]) + for(;;); +#pragma acc loop private(LocalArray[2:1]) + for(;;); +#pragma acc loop private(LocalArray[2]) + for(;;); +#pragma acc loop private(LocalComposite) + for(;;); +#pragma acc loop private(LocalComposite.EnumMember) + for(;;); +#pragma acc loop private(LocalComposite.ScalarMember) + for(;;); +#pragma acc loop private(LocalComposite.ArrayMember) + for(;;); +#pragma acc loop private(LocalComposite.ArrayMember[5]) + for(;;); +#pragma acc loop private(LocalComposite.PointerMember) + for(;;); +#pragma acc loop private(GlobalInt, GlobalArray, GlobalPointer, GlobalComposite) + for(;;); +#pragma acc loop private(GlobalArray[2], GlobalPointer[2], GlobalComposite.CompositeMember.A) + for(;;); +#pragma acc loop private(LocalComposite, GlobalComposite) + for(;;); +#pragma acc loop private(IntParam, PointerParam, ArrayParam, CompositeParam) + for(;;); +#pragma acc loop private(PointerParam[IntParam], ArrayParam[IntParam], CompositeParam.CompositeMember.A) + for(;;); + +#pragma acc loop private(LocalArray) private(LocalArray[2]) + for(;;); + +#pragma acc loop private(LocalArray, LocalArray[2]) + for(;;); + +#pragma acc loop private(LocalComposite, LocalComposite.ScalarMember) + for(;;); + +#pragma acc loop private(LocalComposite.CompositeMember.A, LocalComposite.ScalarMember) + for(;;); + +#pragma acc loop private(LocalComposite.CompositeMember.A) private(LocalComposite.ScalarMember) + for(;;); + + Complete LocalComposite2; +#pragma acc loop private(LocalComposite2.ScalarMember, LocalComposite2.ScalarMember) + for(;;); + + // Invalid cases, arbitrary expressions. + struct Incomplete *I; + // expected-error@+1{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}} +#pragma acc loop private(*I) + for(;;); + // expected-error@+1{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}} +#pragma acc loop private(GlobalInt + IntParam) + for(;;); + // expected-error@+1{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}} +#pragma acc loop private(+GlobalInt) + for(;;); + + // expected-error@+1{{OpenACC sub-array length is unspecified and cannot be inferred because the subscripted value is not an array}} +#pragma acc loop private(PointerParam[:]) + for(;;); +#pragma acc loop private(PointerParam[:5]) + for(;;); +#pragma acc loop private(PointerParam[:IntParam]) + for(;;); + // expected-error@+1{{OpenACC sub-array length is unspecified and cannot be inferred because the subscripted value is not an array}} +#pragma acc loop private(PointerParam[2:]) + for(;;); +#pragma acc loop private(PointerParam[2:5]) + for(;;); +#pragma acc loop private(PointerParam[2]) + for(;;); +#pragma acc loop private(ArrayParam[:]) + for(;;); +#pragma acc loop private(ArrayParam[:5]) + for(;;); +#pragma acc loop private(ArrayParam[:IntParam]) + for(;;); +#pragma acc loop private(ArrayParam[2:]) + for(;;); + // expected-error@+1{{OpenACC sub-array specified range [2:5] would be out of the range of the subscripted array size of 5}} +#pragma acc loop private(ArrayParam[2:5]) + for(;;); +#pragma acc loop private(ArrayParam[2]) + for(;;); + + // expected-error@+2{{OpenACC sub-array specified range [2:5] would be out of the range of the subscripted array size of 5}} + // expected-error@+1{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}} +#pragma acc loop private((float*)ArrayParam[2:5]) + for(;;); + // expected-error@+1{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}} +#pragma acc loop private((float)ArrayParam[2]) + for(;;); +} diff --git a/clang/test/SemaOpenACC/loop-construct-private-clause.cpp b/clang/test/SemaOpenACC/loop-construct-private-clause.cpp new file mode 100644 index 0000000000000000000000000000000000000000..b5d3fc9e7f222f4a8ac106d3b7ef31b3e8a169d3 --- /dev/null +++ b/clang/test/SemaOpenACC/loop-construct-private-clause.cpp @@ -0,0 +1,155 @@ +// RUN: %clang_cc1 %s -fopenacc -verify + +struct Incomplete; +enum SomeE{}; +typedef struct IsComplete { + struct S { int A; } CompositeMember; + int ScalarMember; + float ArrayMember[5]; + SomeE EnumMember; + char *PointerMember; +} Complete; + +int GlobalInt; +float GlobalArray[5]; +char *GlobalPointer; +Complete GlobalComposite; + +void uses(int IntParam, char *PointerParam, float ArrayParam[5], Complete CompositeParam, int &IntParamRef) { + int LocalInt; + char *LocalPointer; + float LocalArray[5]; + Complete LocalComposite; + + // Check Appertainment: + +#pragma acc loop private(LocalInt) + for(;;); + + // Valid cases: +#pragma acc loop private(LocalInt, LocalPointer, LocalArray) + for(;;); +#pragma acc loop private(LocalArray) + for(;;); +#pragma acc loop private(LocalArray[2]) + for(;;); +#pragma acc loop private(LocalComposite) + for(;;); +#pragma acc loop private(LocalComposite.EnumMember) + for(;;); +#pragma acc loop private(LocalComposite.ScalarMember) + for(;;); +#pragma acc loop private(LocalComposite.ArrayMember) + for(;;); +#pragma acc loop private(LocalComposite.ArrayMember[5]) + for(;;); +#pragma acc loop private(LocalComposite.PointerMember) + for(;;); +#pragma acc loop private(GlobalInt, GlobalArray, GlobalPointer, GlobalComposite) + for(;;); +#pragma acc loop private(GlobalArray[2], GlobalPointer[2], GlobalComposite.CompositeMember.A) + for(;;); +#pragma acc loop private(LocalComposite, GlobalComposite) + for(;;); +#pragma acc loop private(IntParam, PointerParam, ArrayParam, CompositeParam) private(IntParamRef) + for(;;); +#pragma acc loop private(PointerParam[IntParam], ArrayParam[IntParam], CompositeParam.CompositeMember.A) + for(;;); + + + // Invalid cases, arbitrary expressions. + Incomplete *I; + // expected-error@+1{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}} +#pragma acc loop private(*I) + for(;;); + // expected-error@+1{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}} +#pragma acc loop private(GlobalInt + IntParam) + for(;;); + // expected-error@+1{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}} +#pragma acc loop private(+GlobalInt) + for(;;); +} + +template +void TemplUses(T t, T (&arrayT)[I], V TemplComp) { + // expected-error@+1{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}} +#pragma acc loop private(+t) + for(;;); + + // expected-error@+1{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}} +#pragma acc loop private(+I) + for(;;); + + // NTTP's are only valid if it is a reference to something. + // expected-error@+2{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}} + // expected-note@#TEMPL_USES_INST{{in instantiation of}} +#pragma acc loop private(I) + for(;;); + + // expected-error@+1{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}} +#pragma acc loop private(t, I) + for(;;); + +#pragma acc loop private(arrayT) + for(;;); + +#pragma acc loop private(TemplComp) + for(;;); + +#pragma acc loop private(TemplComp.PointerMember[5]) + for(;;); + +#pragma acc loop private(TemplComp.PointerMember[5]) private(TemplComp) + for(;;); + + int *Pointer; +#pragma acc loop private(Pointer[:I]) + for(;;); +#pragma acc loop private(Pointer[:t]) + for(;;); + // expected-error@+1{{OpenACC sub-array length is unspecified and cannot be inferred because the subscripted value is not an array}} +#pragma acc loop private(Pointer[1:]) + for(;;); +} + +template +void NTTP() { + // NTTP's are only valid if it is a reference to something. + // expected-error@+2{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}} + // expected-note@#NTTP_INST{{in instantiation of}} +#pragma acc loop private(I) + for(;;); + +#pragma acc loop private(NTTP_REF) + for(;;); +} + +struct S { + int ThisMember; + int ThisMemberArray[5]; + + void foo(); +}; + +void S::foo() { +#pragma acc loop private(ThisMember, this->ThisMemberArray[1]) + for(;;); + +#pragma acc loop private(ThisMemberArray[1:2]) + for(;;); + +#pragma acc loop private(this) + for(;;); + +#pragma acc loop private(ThisMember, this->ThisMember) + for(;;); +} + +void Inst() { + static constexpr int NTTP_REFed = 1; + int i; + int Arr[5]; + Complete C; + TemplUses(i, Arr, C); // #TEMPL_USES_INST + NTTP<5, NTTP_REFed>(); // #NTTP_INST +} diff --git a/clang/test/SemaOpenACC/loop-loc-and-stmt.c b/clang/test/SemaOpenACC/loop-loc-and-stmt.c new file mode 100644 index 0000000000000000000000000000000000000000..36c6743f9843b844f2f3efa5ca4edd399aafddef --- /dev/null +++ b/clang/test/SemaOpenACC/loop-loc-and-stmt.c @@ -0,0 +1,38 @@ +// RUN: %clang_cc1 %s -verify -fopenacc + +// expected-error@+1{{OpenACC construct 'loop' cannot be used here; it can only be used in a statement context}} +#pragma acc loop + +// expected-error@+1{{OpenACC construct 'loop' cannot be used here; it can only be used in a statement context}} +#pragma acc loop +int foo; + +struct S { +// expected-error@+1{{OpenACC construct 'loop' cannot be used here; it can only be used in a statement context}} +#pragma acc loop + int i; +}; + +void func() { + // expected-error@+2{{expected expression}} +#pragma acc loop + int foo; + + // expected-error@+3{{OpenACC 'loop' construct can only be applied to a 'for' loop}} + // expected-note@+1{{'loop' construct is here}} +#pragma acc loop + while(0); + + // expected-error@+3{{OpenACC 'loop' construct can only be applied to a 'for' loop}} + // expected-note@+1{{'loop' construct is here}} +#pragma acc loop + do{}while(0); + + // expected-error@+3{{OpenACC 'loop' construct can only be applied to a 'for' loop}} + // expected-note@+1{{'loop' construct is here}} +#pragma acc loop + {} + +#pragma acc loop + for(;;); +} diff --git a/clang/test/SemaOpenACC/loop-loc-and-stmt.cpp b/clang/test/SemaOpenACC/loop-loc-and-stmt.cpp new file mode 100644 index 0000000000000000000000000000000000000000..5d50145b7c882543cc38765d16d76969188c0aab --- /dev/null +++ b/clang/test/SemaOpenACC/loop-loc-and-stmt.cpp @@ -0,0 +1,80 @@ +// RUN: %clang_cc1 %s -verify -fopenacc +// +// expected-error@+1{{OpenACC construct 'loop' cannot be used here; it can only be used in a statement context}} +#pragma acc loop + +// expected-error@+1{{OpenACC construct 'loop' cannot be used here; it can only be used in a statement context}} +#pragma acc loop +int foo; + +struct S { +// expected-error@+1{{OpenACC construct 'loop' cannot be used here; it can only be used in a statement context}} +#pragma acc loop + int i; + + void mem_func() { + // expected-error@+3{{OpenACC 'loop' construct can only be applied to a 'for' loop}} + // expected-note@+1{{'loop' construct is here}} +#pragma acc loop + int foo; + + // expected-error@+3{{OpenACC 'loop' construct can only be applied to a 'for' loop}} + // expected-note@+1{{'loop' construct is here}} +#pragma acc loop + while(0); + + // expected-error@+3{{OpenACC 'loop' construct can only be applied to a 'for' loop}} + // expected-note@+1{{'loop' construct is here}} +#pragma acc loop + do{}while(0); + + // expected-error@+3{{OpenACC 'loop' construct can only be applied to a 'for' loop}} + // expected-note@+1{{'loop' construct is here}} +#pragma acc loop + {} + +#pragma acc loop + for(;;); + + int array[5]; + +#pragma acc loop + for(auto X : array){} +} +}; + +template +void templ_func() { + // expected-error@+3{{OpenACC 'loop' construct can only be applied to a 'for' loop}} + // expected-note@+1{{'loop' construct is here}} +#pragma acc loop + int foo; + + // expected-error@+3{{OpenACC 'loop' construct can only be applied to a 'for' loop}} + // expected-note@+1{{'loop' construct is here}} +#pragma acc loop + while(T{}); + + // expected-error@+3{{OpenACC 'loop' construct can only be applied to a 'for' loop}} + // expected-note@+1{{'loop' construct is here}} +#pragma acc loop + do{}while(0); + + // expected-error@+3{{OpenACC 'loop' construct can only be applied to a 'for' loop}} + // expected-note@+1{{'loop' construct is here}} +#pragma acc loop + {} + +#pragma acc loop + for(T i;;); + + T array[5]; + +#pragma acc loop + for(auto X : array){} +} + +void use() { + templ_func(); +} + diff --git a/clang/test/SemaOpenCL/builtins-amdgcn-error-gfx908-param.cl b/clang/test/SemaOpenCL/builtins-amdgcn-error-gfx908-param.cl index bb949c0ddd10df152c07682b7ffa2905c2230633..969ff4ba9c9203fff97ae033bafc69b0416ab16a 100644 --- a/clang/test/SemaOpenCL/builtins-amdgcn-error-gfx908-param.cl +++ b/clang/test/SemaOpenCL/builtins-amdgcn-error-gfx908-param.cl @@ -1,4 +1,5 @@ // RUN: %clang_cc1 -triple amdgcn-- -target-cpu gfx908 -verify -S -o - %s +// RUN: %clang_cc1 -triple spirv64-amd-amdhsa -verify -S -o - %s #pragma OPENCL EXTENSION cl_khr_fp64:enable diff --git a/clang/test/SemaOpenCL/builtins-amdgcn-error-gfx90a-param.cl b/clang/test/SemaOpenCL/builtins-amdgcn-error-gfx90a-param.cl index 701016148a893cd110d3d9fb3fc86560b1f0cac1..235fa8263140258a8d8586499c80d761e004a8ba 100644 --- a/clang/test/SemaOpenCL/builtins-amdgcn-error-gfx90a-param.cl +++ b/clang/test/SemaOpenCL/builtins-amdgcn-error-gfx90a-param.cl @@ -1,4 +1,5 @@ // RUN: %clang_cc1 -triple amdgcn-- -target-cpu gfx90a -verify -S -o - %s +// RUN: %clang_cc1 -triple spirv64-amd-amdhsa -verify -S -o - %s #pragma OPENCL EXTENSION cl_khr_fp64:enable diff --git a/clang/test/SemaOpenCL/builtins-amdgcn-error-gfx940-param.cl b/clang/test/SemaOpenCL/builtins-amdgcn-error-gfx940-param.cl index b177b93938e46e52fb813b5809673459b99fbd7d..0fc2304d51ce0571285478bf342faafb0a37e1e8 100644 --- a/clang/test/SemaOpenCL/builtins-amdgcn-error-gfx940-param.cl +++ b/clang/test/SemaOpenCL/builtins-amdgcn-error-gfx940-param.cl @@ -1,4 +1,5 @@ // RUN: %clang_cc1 -triple amdgcn-- -target-cpu gfx940 -verify -S -o - %s +// RUN: %clang_cc1 -triple spirv64-amd-amdhsa -verify -S -o - %s typedef float v2f __attribute__((ext_vector_type(2))); typedef float v4f __attribute__((ext_vector_type(4))); diff --git a/clang/test/SemaOpenCL/builtins-amdgcn-gfx940-err.cl b/clang/test/SemaOpenCL/builtins-amdgcn-gfx940-err.cl index 487cc53e8ad8a375d2486d54a6bbdb9761aebc71..2a1ba4300864cb4325181bcc8f813a0985c4b792 100644 --- a/clang/test/SemaOpenCL/builtins-amdgcn-gfx940-err.cl +++ b/clang/test/SemaOpenCL/builtins-amdgcn-gfx940-err.cl @@ -3,8 +3,10 @@ typedef unsigned int u32; -void test_global_load_lds_unsupported_size(global u32* src, local u32 *dst, u32 size) { - __builtin_amdgcn_global_load_lds(src, dst, size, /*offset=*/0, /*aux=*/0); // expected-error{{expression is not an integer constant expression}} +void test_global_load_lds_unsupported_size(global u32* src, local u32 *dst, u32 size, u32 offset, u32 aux) { + __builtin_amdgcn_global_load_lds(src, dst, size, /*offset=*/0, /*aux=*/0); // expected-error{{argument to '__builtin_amdgcn_global_load_lds' must be a constant integer}} + __builtin_amdgcn_global_load_lds(src, dst, /*size=*/4, offset, /*aux=*/0); // expected-error{{argument to '__builtin_amdgcn_global_load_lds' must be a constant integer}} + __builtin_amdgcn_global_load_lds(src, dst, /*size=*/4, /*offset=*/0, aux); // expected-error{{argument to '__builtin_amdgcn_global_load_lds' must be a constant integer}} __builtin_amdgcn_global_load_lds(src, dst, /*size=*/5, /*offset=*/0, /*aux=*/0); // expected-error{{invalid size value}} expected-note {{size must be 1, 2, or 4}} __builtin_amdgcn_global_load_lds(src, dst, /*size=*/0, /*offset=*/0, /*aux=*/0); // expected-error{{invalid size value}} expected-note {{size must be 1, 2, or 4}} __builtin_amdgcn_global_load_lds(src, dst, /*size=*/3, /*offset=*/0, /*aux=*/0); // expected-error{{invalid size value}} expected-note {{size must be 1, 2, or 4}} diff --git a/clang/test/SemaTemplate/cwg2398.cpp b/clang/test/SemaTemplate/cwg2398.cpp index 45e74cce3a98c851bc3bd9d279a719d0c159ad95..7675d4287cb88a49654f1966115d95440cfbe20f 100644 --- a/clang/test/SemaTemplate/cwg2398.cpp +++ b/clang/test/SemaTemplate/cwg2398.cpp @@ -200,4 +200,132 @@ namespace consistency { template struct A, B, B>; // new-error@-1 {{ambiguous partial specializations}} } // namespace t2 + namespace t3 { + template struct A; + + template class TT1, + class T1, class T2, class T3, class T4> + struct A, TT1, typename nondeduced>::type> {}; + // new-note@-1 {{partial specialization matches}} + + template class UU1, + class U1, class U2> + struct A, UU1, typename nondeduced>::type>; + // new-note@-1 {{partial specialization matches}} + + template struct A, B, B>; + // new-error@-1 {{ambiguous partial specializations}} + } // namespace t3 + namespace t4 { + template struct A; + + template class TT1, + class T1, class T2, class T3, class T4> + struct A, TT1, typename nondeduced>::type> {}; + // new-note@-1 {{partial specialization matches}} + + template class UU1, + class U1, class U2> + struct A, UU1, typename nondeduced>::type>; + // new-note@-1 {{partial specialization matches}} + + template struct A, B, B>; + // new-error@-1 {{ambiguous partial specializations}} + } // namespace t4 + namespace t5 { + template struct A; + + template class TT1, + class T1, class T2, class T3, class T4> + struct A, TT1> {}; + // new-note@-1 {{partial specialization matches}} + + template class UU1, + class U1, class U2> + struct A, UU1>; + // new-note@-1 {{partial specialization matches}} + + template struct A, B>; + // new-error@-1 {{ambiguous partial specializations}} + } // namespace t5 + namespace t6 { + template struct A; + + template class TT1, + class T1, class T2, class T3> + struct A, TT1> {}; + // new-note@-1 {{partial specialization matches}} + + template class UU1, + class U1, class U2> + struct A, UU1>; + // new-note@-1 {{partial specialization matches}} + + template struct A, B>; + // new-error@-1 {{ambiguous partial specializations}} + } // namespace t6 } // namespace consistency + +namespace classes { + namespace canon { + template struct A {}; + + template class TT> auto f(TT a) { return a; } + // old-note@-1 2{{template template argument has different template parameters}} + // new-note@-2 2{{substitution failure: too few template arguments}} + + A v1; + A v2; + + using X = decltype(f(v1)); + // expected-error@-1 {{no matching function for call}} + + using X = decltype(f(v2)); + // expected-error@-1 {{no matching function for call}} + } // namespace canon + namespace expr { + template struct A { + static constexpr auto val = E1; + }; + template