diff --git a/external/llvm-project/.ci/compute_projects.py b/external/llvm-project/.ci/compute_projects.py index 40dd0507a9ea..80e4e0221b3d 100644 --- a/external/llvm-project/.ci/compute_projects.py +++ b/external/llvm-project/.ci/compute_projects.py @@ -49,12 +49,22 @@ }, "lld": {"bolt", "cross-project-tests"}, # TODO(issues/132795): LLDB should be enabled on clang changes. - "clang": {"clang-tools-extra", "compiler-rt", "cross-project-tests"}, - "clang-tools-extra": {"libc"}, + "clang": {"clang-tools-extra", "cross-project-tests"}, "mlir": {"flang"}, # Test everything if ci scripts are changed. - # FIXME: Figure out what is missing and add here. - ".ci": {"llvm", "clang", "lld", "lldb"}, + ".ci": { + "llvm", + "clang", + "lld", + "lldb", + "bolt", + "clang-tools-extra", + "mlir", + "polly", + "flang", + "libclc", + "openmp", + }, } # This mapping describes runtimes that should be enabled for a specific project, @@ -64,7 +74,16 @@ # This mapping describes runtimes that should be tested when the key project is # touched. -DEPENDENT_RUNTIMES_TO_TEST = {"clang": {"libcxx", "libcxxabi", "libunwind"}} +DEPENDENT_RUNTIMES_TO_TEST = { + "clang": {"compiler-rt"}, + "clang-tools-extra": {"libc"}, + ".ci": {"compiler-rt", "libc"}, +} +DEPENDENT_RUNTIMES_TO_TEST_NEEDS_RECONFIG = { + "llvm": {"libcxx", "libcxxabi", "libunwind"}, + "clang": {"libcxx", "libcxxabi", "libunwind"}, + ".ci": {"libcxx", "libcxxabi", "libunwind"}, +} EXCLUDE_LINUX = { "cross-project-tests", # TODO(issues/132796): Tests are failing. @@ -93,9 +112,6 @@ "cross-project-tests", "flang", "libc", - "libcxx", - "libcxxabi", - "libunwind", "lldb", "openmp", "polly", @@ -122,21 +138,35 @@ "polly": "check-polly", } -RUNTIMES = {"libcxx", "libcxxabi", "libunwind"} +RUNTIMES = {"libcxx", "libcxxabi", "libunwind", "compiler-rt", "libc"} -def _add_dependencies(projects: Set[str]) -> Set[str]: +def _add_dependencies(projects: Set[str], runtimes: Set[str]) -> Set[str]: projects_with_dependents = set(projects) current_projects_count = 0 while current_projects_count != len(projects_with_dependents): current_projects_count = len(projects_with_dependents) for project in list(projects_with_dependents): - if project not in PROJECT_DEPENDENCIES: - continue - projects_with_dependents.update(PROJECT_DEPENDENCIES[project]) + if project in PROJECT_DEPENDENCIES: + projects_with_dependents.update(PROJECT_DEPENDENCIES[project]) + for runtime in runtimes: + if runtime in PROJECT_DEPENDENCIES: + projects_with_dependents.update(PROJECT_DEPENDENCIES[runtime]) return projects_with_dependents +def _exclude_projects(current_projects: Set[str], platform: str) -> Set[str]: + if platform == "Linux": + to_exclude = EXCLUDE_LINUX + elif platform == "Windows": + to_exclude = EXCLUDE_WINDOWS + elif platform == "Darwin": + to_exclude = EXCLUDE_MAC + else: + raise ValueError(f"Unexpected platform: {platform}") + return current_projects.difference(to_exclude) + + def _compute_projects_to_test(modified_projects: Set[str], platform: str) -> Set[str]: projects_to_test = set() for modified_project in modified_projects: @@ -154,54 +184,52 @@ def _compute_projects_to_test(modified_projects: Set[str], platform: str) -> Set ): continue projects_to_test.add(dependent_project) - if platform == "Linux": - for to_exclude in EXCLUDE_LINUX: - if to_exclude in projects_to_test: - projects_to_test.remove(to_exclude) - elif platform == "Windows": - for to_exclude in EXCLUDE_WINDOWS: - if to_exclude in projects_to_test: - projects_to_test.remove(to_exclude) - elif platform == "Darwin": - for to_exclude in EXCLUDE_MAC: - if to_exclude in projects_to_test: - projects_to_test.remove(to_exclude) - else: - raise ValueError("Unexpected platform.") + projects_to_test = _exclude_projects(projects_to_test, platform) return projects_to_test -def _compute_projects_to_build(projects_to_test: Set[str]) -> Set[str]: - return _add_dependencies(projects_to_test) +def _compute_projects_to_build( + projects_to_test: Set[str], runtimes: Set[str] +) -> Set[str]: + return _add_dependencies(projects_to_test, runtimes) def _compute_project_check_targets(projects_to_test: Set[str]) -> Set[str]: check_targets = set() for project_to_test in projects_to_test: - if project_to_test not in PROJECT_CHECK_TARGETS: - continue - check_targets.add(PROJECT_CHECK_TARGETS[project_to_test]) + if project_to_test in PROJECT_CHECK_TARGETS: + check_targets.add(PROJECT_CHECK_TARGETS[project_to_test]) return check_targets -def _compute_runtimes_to_test(projects_to_test: Set[str]) -> Set[str]: +def _compute_runtimes_to_test(modified_projects: Set[str], platform: str) -> Set[str]: runtimes_to_test = set() - for project_to_test in projects_to_test: - if project_to_test in DEPENDENT_RUNTIMES_TO_TEST: - runtimes_to_test.update(DEPENDENT_RUNTIMES_TO_TEST[project_to_test]) - if project_to_test in DEPENDENT_RUNTIMES_TO_BUILD: - runtimes_to_test.update(DEPENDENT_RUNTIMES_TO_BUILD[project_to_test]) - return runtimes_to_test + for modified_project in modified_projects: + if modified_project in DEPENDENT_RUNTIMES_TO_TEST: + runtimes_to_test.update(DEPENDENT_RUNTIMES_TO_TEST[modified_project]) + return _exclude_projects(runtimes_to_test, platform) -def _compute_runtime_check_targets(projects_to_test: Set[str]) -> Set[str]: - check_targets = set() - for project_to_test in projects_to_test: - if project_to_test not in DEPENDENT_RUNTIMES_TO_TEST: - continue - for runtime_to_test in DEPENDENT_RUNTIMES_TO_TEST[project_to_test]: - check_targets.add(PROJECT_CHECK_TARGETS[runtime_to_test]) - return check_targets +def _compute_runtimes_to_test_needs_reconfig( + modified_projects: Set[str], platform: str +) -> Set[str]: + runtimes_to_test = set() + for modified_project in modified_projects: + if modified_project in DEPENDENT_RUNTIMES_TO_TEST_NEEDS_RECONFIG: + runtimes_to_test.update( + DEPENDENT_RUNTIMES_TO_TEST_NEEDS_RECONFIG[modified_project] + ) + return _exclude_projects(runtimes_to_test, platform) + + +def _compute_runtimes_to_build( + runtimes_to_test: Set[str], modified_projects: Set[str], platform: str +) -> Set[str]: + runtimes_to_build = set(runtimes_to_test) + for modified_project in modified_projects: + if modified_project in DEPENDENT_RUNTIMES_TO_BUILD: + runtimes_to_build.update(DEPENDENT_RUNTIMES_TO_BUILD[modified_project]) + return _exclude_projects(runtimes_to_build, platform) def _get_modified_projects(modified_files: list[str]) -> Set[str]: @@ -225,10 +253,19 @@ def _get_modified_projects(modified_files: list[str]) -> Set[str]: def get_env_variables(modified_files: list[str], platform: str) -> Set[str]: modified_projects = _get_modified_projects(modified_files) projects_to_test = _compute_projects_to_test(modified_projects, platform) - projects_to_build = _compute_projects_to_build(projects_to_test) + runtimes_to_test = _compute_runtimes_to_test(modified_projects, platform) + runtimes_to_test_needs_reconfig = _compute_runtimes_to_test_needs_reconfig( + modified_projects, platform + ) + runtimes_to_build = _compute_runtimes_to_build( + runtimes_to_test | runtimes_to_test_needs_reconfig, modified_projects, platform + ) + projects_to_build = _compute_projects_to_build(projects_to_test, runtimes_to_build) projects_check_targets = _compute_project_check_targets(projects_to_test) - runtimes_to_build = _compute_runtimes_to_test(projects_to_test) - runtimes_check_targets = _compute_runtime_check_targets(projects_to_test) + runtimes_check_targets = _compute_project_check_targets(runtimes_to_test) + runtimes_check_targets_needs_reconfig = _compute_project_check_targets( + runtimes_to_test_needs_reconfig + ) # We use a semicolon to separate the projects/runtimes as they get passed # to the CMake invocation and thus we need to use the CMake list separator # (;). We use spaces to separate the check targets as they end up getting @@ -238,6 +275,9 @@ def get_env_variables(modified_files: list[str], platform: str) -> Set[str]: "project_check_targets": " ".join(sorted(projects_check_targets)), "runtimes_to_build": ";".join(sorted(runtimes_to_build)), "runtimes_check_targets": " ".join(sorted(runtimes_check_targets)), + "runtimes_check_targets_needs_reconfig": " ".join( + sorted(runtimes_check_targets_needs_reconfig) + ), } diff --git a/external/llvm-project/.ci/compute_projects_test.py b/external/llvm-project/.ci/compute_projects_test.py index ae376ea6a43c..5efac2636698 100644 --- a/external/llvm-project/.ci/compute_projects_test.py +++ b/external/llvm-project/.ci/compute_projects_test.py @@ -26,6 +26,10 @@ def test_llvm(self): ) self.assertEqual( env_variables["runtimes_check_targets"], + "", + ) + self.assertEqual( + env_variables["runtimes_check_targets_needs_reconfig"], "check-cxx check-cxxabi check-unwind", ) @@ -46,6 +50,10 @@ def test_llvm_windows(self): ) self.assertEqual( env_variables["runtimes_check_targets"], + "", + ) + self.assertEqual( + env_variables["runtimes_check_targets_needs_reconfig"], "check-cxx check-cxxabi check-unwind", ) @@ -66,6 +74,10 @@ def test_llvm_mac(self): ) self.assertEqual( env_variables["runtimes_check_targets"], + "", + ) + self.assertEqual( + env_variables["runtimes_check_targets_needs_reconfig"], "check-cxx check-cxxabi check-unwind", ) @@ -75,17 +87,21 @@ def test_clang(self): ) self.assertEqual( env_variables["projects_to_build"], - "clang;clang-tools-extra;compiler-rt;lld;llvm", + "clang;clang-tools-extra;lld;llvm", ) self.assertEqual( env_variables["project_check_targets"], - "check-clang check-clang-tools check-compiler-rt", + "check-clang check-clang-tools", ) self.assertEqual( - env_variables["runtimes_to_build"], "libcxx;libcxxabi;libunwind" + env_variables["runtimes_to_build"], "compiler-rt;libcxx;libcxxabi;libunwind" ) self.assertEqual( env_variables["runtimes_check_targets"], + "check-compiler-rt", + ) + self.assertEqual( + env_variables["runtimes_check_targets_needs_reconfig"], "check-cxx check-cxxabi check-unwind", ) @@ -104,6 +120,10 @@ def test_clang_windows(self): ) self.assertEqual( env_variables["runtimes_check_targets"], + "", + ) + self.assertEqual( + env_variables["runtimes_check_targets_needs_reconfig"], "check-cxx check-cxxabi check-unwind", ) @@ -115,6 +135,7 @@ def test_bolt(self): self.assertEqual(env_variables["project_check_targets"], "check-bolt") self.assertEqual(env_variables["runtimes_to_build"], "") self.assertEqual(env_variables["runtimes_check_targets"], "") + self.assertEqual(env_variables["runtimes_check_targets_needs_reconfig"], "") def test_lldb(self): env_variables = compute_projects.get_env_variables( @@ -124,6 +145,7 @@ def test_lldb(self): self.assertEqual(env_variables["project_check_targets"], "check-lldb") self.assertEqual(env_variables["runtimes_to_build"], "") self.assertEqual(env_variables["runtimes_check_targets"], "") + self.assertEqual(env_variables["runtimes_check_targets_needs_reconfig"], "") def test_mlir(self): env_variables = compute_projects.get_env_variables( @@ -135,6 +157,7 @@ def test_mlir(self): ) self.assertEqual(env_variables["runtimes_to_build"], "") self.assertEqual(env_variables["runtimes_check_targets"], "") + self.assertEqual(env_variables["runtimes_check_targets_needs_reconfig"], "") def test_flang(self): env_variables = compute_projects.get_env_variables( @@ -144,6 +167,7 @@ def test_flang(self): self.assertEqual(env_variables["project_check_targets"], "check-flang") self.assertEqual(env_variables["runtimes_to_build"], "") self.assertEqual(env_variables["runtimes_check_targets"], "") + self.assertEqual(env_variables["runtimes_check_targets_needs_reconfig"], "") def test_invalid_subproject(self): env_variables = compute_projects.get_env_variables( @@ -153,6 +177,7 @@ def test_invalid_subproject(self): self.assertEqual(env_variables["project_check_targets"], "") self.assertEqual(env_variables["runtimes_to_build"], "") self.assertEqual(env_variables["runtimes_check_targets"], "") + self.assertEqual(env_variables["runtimes_check_targets_needs_reconfig"], "") def test_top_level_file(self): env_variables = compute_projects.get_env_variables(["README.md"], "Linux") @@ -160,6 +185,7 @@ def test_top_level_file(self): self.assertEqual(env_variables["project_check_targets"], "") self.assertEqual(env_variables["runtimes_to_build"], "") self.assertEqual(env_variables["runtimes_check_targets"], "") + self.assertEqual(env_variables["runtimes_check_targets_needs_reconfig"], "") def test_exclude_runtiems_in_projects(self): env_variables = compute_projects.get_env_variables( @@ -169,6 +195,7 @@ def test_exclude_runtiems_in_projects(self): self.assertEqual(env_variables["project_check_targets"], "") self.assertEqual(env_variables["runtimes_to_build"], "") self.assertEqual(env_variables["runtimes_check_targets"], "") + self.assertEqual(env_variables["runtimes_check_targets_needs_reconfig"], "") def test_exclude_docs(self): env_variables = compute_projects.get_env_variables( @@ -178,6 +205,7 @@ def test_exclude_docs(self): self.assertEqual(env_variables["project_check_targets"], "") self.assertEqual(env_variables["runtimes_to_build"], "") self.assertEqual(env_variables["runtimes_check_targets"], "") + self.assertEqual(env_variables["runtimes_check_targets_needs_reconfig"], "") def test_exclude_gn(self): env_variables = compute_projects.get_env_variables( @@ -187,21 +215,30 @@ def test_exclude_gn(self): self.assertEqual(env_variables["project_check_targets"], "") self.assertEqual(env_variables["runtimes_to_build"], "") self.assertEqual(env_variables["runtimes_check_targets"], "") + self.assertEqual(env_variables["runtimes_check_targets_needs_reconfig"], "") def test_ci(self): env_variables = compute_projects.get_env_variables( [".ci/compute_projects.py"], "Linux" ) - self.assertEqual(env_variables["projects_to_build"], "clang;lld;lldb;llvm") + self.assertEqual( + env_variables["projects_to_build"], + "bolt;clang;clang-tools-extra;flang;libclc;lld;lldb;llvm;mlir;polly", + ) self.assertEqual( env_variables["project_check_targets"], - "check-clang check-lld check-lldb check-llvm", + "check-bolt check-clang check-clang-tools check-flang check-lld check-lldb check-llvm check-mlir check-polly", ) self.assertEqual( - env_variables["runtimes_to_build"], "libcxx;libcxxabi;libunwind" + env_variables["runtimes_to_build"], + "compiler-rt;libc;libcxx;libcxxabi;libunwind", ) self.assertEqual( env_variables["runtimes_check_targets"], + "check-compiler-rt check-libc", + ) + self.assertEqual( + env_variables["runtimes_check_targets_needs_reconfig"], "check-cxx check-cxxabi check-unwind", ) @@ -215,6 +252,19 @@ def test_lldb(self): env_variables["runtimes_to_build"], "libcxx;libcxxabi;libunwind" ) self.assertEqual(env_variables["runtimes_check_targets"], "") + self.assertEqual(env_variables["runtimes_check_targets_needs_reconfig"], "") + + def test_clang_tools_extra(self): + env_variables = compute_projects.get_env_variables( + ["clang-tools-extra/CMakeLists.txt"], "Linux" + ) + self.assertEqual( + env_variables["projects_to_build"], "clang;clang-tools-extra;lld;llvm" + ) + self.assertEqual(env_variables["project_check_targets"], "check-clang-tools") + self.assertEqual(env_variables["runtimes_to_build"], "libc") + self.assertEqual(env_variables["runtimes_check_targets"], "check-libc") + self.assertEqual(env_variables["runtimes_check_targets_needs_reconfig"], "") if __name__ == "__main__": diff --git a/external/llvm-project/.ci/generate-buildkite-pipeline-premerge b/external/llvm-project/.ci/generate-buildkite-pipeline-premerge deleted file mode 100755 index 5e5f916f35b7..000000000000 --- a/external/llvm-project/.ci/generate-buildkite-pipeline-premerge +++ /dev/null @@ -1,131 +0,0 @@ -#!/usr/bin/env bash -#===----------------------------------------------------------------------===## -# -# 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 generates a Buildkite pipeline that triggers the various CI jobs for -# the LLVM project during pre-commit CI. -# -# See https://buildkite.com/docs/agent/v3/cli-pipeline#pipeline-format. -# -# As this outputs a yaml file, it's possible to log messages to stderr or -# prefix with "#". - - -set -eu -set -o pipefail - -# Environment variables script works with: - -# Set by buildkite -: ${BUILDKITE_PULL_REQUEST_BASE_BRANCH:=} -: ${BUILDKITE_COMMIT:=} -: ${BUILDKITE_BRANCH:=} -# Fetch origin to have an up to date merge base for the diff. -git fetch origin -# List of files affected by this commit -: ${MODIFIED_FILES:=$(git diff --name-only origin/${BUILDKITE_PULL_REQUEST_BASE_BRANCH}...HEAD)} -# Filter rules for generic windows tests -: ${WINDOWS_AGENTS:='{"queue": "windows"}'} -# Filter rules for generic linux tests -: ${LINUX_AGENTS:='{"queue": "linux"}'} - -reviewID="$(git log --format=%B -n 1 | sed -nE 's/^Review-ID:[[:space:]]*(.+)$/\1/p')" -if [[ "${reviewID}" != "" ]]; then - buildMessage="https://llvm.org/${reviewID}" -else - buildMessage="Push to branch ${BUILDKITE_BRANCH}" -fi - -cat <&2 -echo "$MODIFIED_FILES" >&2 -modified_dirs=$(echo "$MODIFIED_FILES" | cut -d'/' -f1 | sort -u) -echo "Directories modified:" >&2 -echo "$modified_dirs" >&2 - -# Project specific pipelines. - -# If libc++ or one of the runtimes directories changed. -if echo "$modified_dirs" | grep -q -E "^(libcxx|libcxxabi|libunwind|runtimes|cmake)$"; then - cat <&1 >/dev/null - then - python3 "${MONOREPO_ROOT}"/.ci/generate_test_report_buildkite.py ":linux: Linux x64 Test Results" \ - "linux-x64-test-results" $retcode "${BUILD_DIR}"/test-results.*.xml - else - python3 "${MONOREPO_ROOT}"/.ci/generate_test_report_github.py ":penguin: Linux x64 Test Results" \ - $retcode "${BUILD_DIR}"/test-results.*.xml >> $GITHUB_STEP_SUMMARY - fi + + python3 "${MONOREPO_ROOT}"/.ci/generate_test_report_github.py ":penguin: Linux x64 Test Results" \ + $retcode "${BUILD_DIR}"/test-results.*.xml >> $GITHUB_STEP_SUMMARY } trap at-exit EXIT @@ -57,6 +52,7 @@ projects="${1}" targets="${2}" runtimes="${3}" runtime_targets="${4}" +runtime_targets_needs_reconfig="${5}" lit_args="-v --xunit-xml-output ${BUILD_DIR}/test-results.xml --use-unique-output-file-name --timeout=1200 --time-tests" @@ -93,9 +89,15 @@ echo "--- ninja" # Targets are not escaped as they are passed as separate arguments. ninja -C "${BUILD_DIR}" -k 0 ${targets} +if [[ "${runtime_targets}" != "" ]]; then + echo "--- ninja runtimes" + + ninja -C "${BUILD_DIR}" ${runtime_targets} +fi + # Compiling runtimes with just-built Clang and running their tests # as an additional testing for Clang. -if [[ "${runtimes_targets}" != "" ]]; then +if [[ "${runtime_targets_needs_reconfig}" != "" ]]; then echo "--- cmake runtimes C++26" cmake \ @@ -105,7 +107,7 @@ if [[ "${runtimes_targets}" != "" ]]; then echo "--- ninja runtimes C++26" - ninja -C "${BUILD_DIR}" ${runtime_targets} + ninja -C "${BUILD_DIR}" ${runtime_targets_needs_reconfig} echo "--- cmake runtimes clang modules" @@ -116,5 +118,5 @@ if [[ "${runtimes_targets}" != "" ]]; then echo "--- ninja runtimes clang modules" - ninja -C "${BUILD_DIR}" ${runtime_targets} + ninja -C "${BUILD_DIR}" ${runtime_targets_needs_reconfig} fi diff --git a/external/llvm-project/.ci/monolithic-windows.sh b/external/llvm-project/.ci/monolithic-windows.sh index a0997420b0d3..dc2913830e92 100755 --- a/external/llvm-project/.ci/monolithic-windows.sh +++ b/external/llvm-project/.ci/monolithic-windows.sh @@ -37,14 +37,9 @@ function at-exit { # If building fails there will be no results files. shopt -s nullglob - if command -v buildkite-agent 2>&1 >/dev/null - then - python "${MONOREPO_ROOT}"/.ci/generate_test_report_buildkite.py ":windows: Windows x64 Test Results" \ - "windows-x64-test-results" $retcode "${BUILD_DIR}"/test-results.*.xml - else - python "${MONOREPO_ROOT}"/.ci/generate_test_report_github.py ":window: Windows x64 Test Results" \ - $retcode "${BUILD_DIR}"/test-results.*.xml >> $GITHUB_STEP_SUMMARY - fi + + python "${MONOREPO_ROOT}"/.ci/generate_test_report_github.py ":window: Windows x64 Test Results" \ + $retcode "${BUILD_DIR}"/test-results.*.xml >> $GITHUB_STEP_SUMMARY } trap at-exit EXIT diff --git a/external/llvm-project/.github/new-prs-labeler.yml b/external/llvm-project/.github/new-prs-labeler.yml index 162161ff13fb..2f8d5745668d 100644 --- a/external/llvm-project/.github/new-prs-labeler.yml +++ b/external/llvm-project/.github/new-prs-labeler.yml @@ -777,6 +777,10 @@ backend:NVPTX: - 'llvm/**/*nvptx*/**' - 'llvm/**/*NVPTX*/**' +backend:MIPS: + - '**/*mips*' + - '**/*Mips*' + backend:RISC-V: - clang/**/*riscv* - clang/**/*RISCV* diff --git a/external/llvm-project/.github/workflows/libcxx-restart-preempted-jobs.yaml b/external/llvm-project/.github/workflows/libcxx-restart-preempted-jobs.yaml index 7b341d7f22e4..9706f0459922 100644 --- a/external/llvm-project/.github/workflows/libcxx-restart-preempted-jobs.yaml +++ b/external/llvm-project/.github/workflows/libcxx-restart-preempted-jobs.yaml @@ -33,7 +33,7 @@ jobs: with: script: | const failure_regex = /Process completed with exit code 1./ - const preemption_regex = /The runner has received a shutdown signal/ + const preemption_regex = /(The runner has received a shutdown signal)|(The operation was canceled)/ const wf_run = context.payload.workflow_run core.notice(`Running on "${wf_run.display_title}" by @${wf_run.actor.login} (event: ${wf_run.event})\nWorkflow run URL: ${wf_run.html_url}`) diff --git a/external/llvm-project/.github/workflows/premerge.yaml b/external/llvm-project/.github/workflows/premerge.yaml index 709b6d03d94c..4435a3e90576 100644 --- a/external/llvm-project/.github/workflows/premerge.yaml +++ b/external/llvm-project/.github/workflows/premerge.yaml @@ -56,11 +56,12 @@ jobs: echo "Running project checks targets: ${project_check_targets}" echo "Building runtimes: ${runtimes_to_build}" echo "Running runtimes checks targets: ${runtimes_check_targets}" + echo "Running runtimes checks requiring reconfiguring targets: ${runtimes_check_targets_needs_reconfig}" export CC=/opt/llvm/bin/clang export CXX=/opt/llvm/bin/clang++ - ./.ci/monolithic-linux.sh "${projects_to_build}" "${project_check_targets}" "${runtimes_to_build}" "${runtimes_check_targets}" + ./.ci/monolithic-linux.sh "${projects_to_build}" "${project_check_targets}" "${runtimes_to_build}" "${runtimes_check_targets}" "${runtimes_check_targets_needs_reconfig}" - name: Upload Artifacts uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 # v4.6.0 with: diff --git a/external/llvm-project/amd/comgr/README.md b/external/llvm-project/amd/comgr/README.md index 1e3056378698..6a478338e385 100644 --- a/external/llvm-project/amd/comgr/README.md +++ b/external/llvm-project/amd/comgr/README.md @@ -152,6 +152,7 @@ Comgr supports an environment variable to help locate LLVM: installation, which is currently used to locate the clang resource directory and clang binary path, allowing for additional optimizations. +### Caching Comgr utilizes a cache to preserve the results of compilations between executions. The cache's status (enabled/disabled), storage location for its results, and eviction policy can be manipulated through specific environment variables. @@ -172,6 +173,7 @@ By default, the cache is enabled. termination. The string format aligns with [Clang's ThinLTO cache pruning policy](https://clang.llvm.org/docs/ThinLTO.html#cache-pruning). The default policy is set as: "prune_interval=1h:prune_expiration=0h:cache_size=75%:cache_size_bytes=30g:cache_size_files=0". +### Debugging Comgr supports some environment variables to aid in debugging. These include: @@ -192,6 +194,7 @@ include: * `AMD_COMGR_TIME_STATISTICS`: If this is set, and is not "0", logs will include additional Comgr-specific timing information for compilation actions. +### VFS Comgr implements support for an in-memory, virtual filesystem (VFS) for storing temporaries generated during intermediate compilation steps. This is aimed at improving performance by reducing on-disk file I/O. Currently, VFS is only supported diff --git a/external/llvm-project/amd/comgr/src/comgr.cpp b/external/llvm-project/amd/comgr/src/comgr.cpp index e0be20fe1252..9e1d6aba2c8d 100644 --- a/external/llvm-project/amd/comgr/src/comgr.cpp +++ b/external/llvm-project/amd/comgr/src/comgr.cpp @@ -308,8 +308,16 @@ amd_comgr_status_t COMGR::parseTargetIdentifier(StringRef IdentStr, Ident.Processor = Ident.Features[0]; Ident.Features.erase(Ident.Features.begin()); - size_t IsaIndex; + // TODO: Add a LIT test for this + if (IdentStr == "amdgcn-amd-amdhsa--amdgcnspirv") { + // Features not supported for SPIR-V + if (!Ident.Features.empty()) + return AMD_COMGR_STATUS_ERROR_INVALID_ARGUMENT; + return AMD_COMGR_STATUS_SUCCESS; + } + + size_t IsaIndex; amd_comgr_status_t Status = metadata::getIsaIndex(IdentStr, IsaIndex); if (Status != AMD_COMGR_STATUS_SUCCESS) { return Status; @@ -981,6 +989,10 @@ amd_comgr_status_t AMD_COMGR_API return AMD_COMGR_STATUS_SUCCESS; } + if (StringRef(IsaName) == "amdgcn-amd-amdhsa--amdgcnspirv") { + return ActionP->setIsaName(IsaName); + } + if (!metadata::isValidIsaName(IsaName)) { return AMD_COMGR_STATUS_ERROR_INVALID_ARGUMENT; } diff --git a/external/llvm-project/amd/comgr/test-lit/cache-tests/spirv-translator-cached.cl b/external/llvm-project/amd/comgr/test-lit/cache-tests/spirv-translator-cached.cl index 5b79e2b31a70..b90821f283bb 100644 --- a/external/llvm-project/amd/comgr/test-lit/cache-tests/spirv-translator-cached.cl +++ b/external/llvm-project/amd/comgr/test-lit/cache-tests/spirv-translator-cached.cl @@ -3,7 +3,7 @@ // RUN: rm -fr %t.cache // COM: Generate a spirv-targeted LLVM IR file from an OpenCL kernel -// RUN: clang -c -emit-llvm --target=spirv64 %S/../spirv-translator.cl -o %t.bc +// RUN: clang -c -emit-llvm --target=spirv64 %S/../spirv-tests/spirv-translator.cl -o %t.bc // COM: Translate LLVM IR to SPIRV format // RUN: amd-llvm-spirv --spirv-target-env=CL2.0 %t.bc -o %t.spv @@ -21,4 +21,4 @@ // RUN: [ 2 -eq $COUNT ] // COM: Dissasemble LLVM IR bitcode to LLVM IR text -// RUN: llvm-dis %t.translated.bc -o - | FileCheck %S/../spirv-translator.cl +// RUN: llvm-dis %t.translated.bc -o - | FileCheck %S/../spirv-tests/spirv-translator.cl diff --git a/external/llvm-project/amd/comgr/test-lit/spirv-to-reloc-debuginfo.hip b/external/llvm-project/amd/comgr/test-lit/spirv-tests/spirv-to-reloc-debuginfo.hip similarity index 100% rename from external/llvm-project/amd/comgr/test-lit/spirv-to-reloc-debuginfo.hip rename to external/llvm-project/amd/comgr/test-lit/spirv-tests/spirv-to-reloc-debuginfo.hip diff --git a/external/llvm-project/amd/comgr/test-lit/spirv-to-reloc.hip b/external/llvm-project/amd/comgr/test-lit/spirv-tests/spirv-to-reloc.hip similarity index 100% rename from external/llvm-project/amd/comgr/test-lit/spirv-to-reloc.hip rename to external/llvm-project/amd/comgr/test-lit/spirv-tests/spirv-to-reloc.hip diff --git a/external/llvm-project/amd/comgr/test-lit/spirv-translator.cl b/external/llvm-project/amd/comgr/test-lit/spirv-tests/spirv-translator.cl similarity index 100% rename from external/llvm-project/amd/comgr/test-lit/spirv-translator.cl rename to external/llvm-project/amd/comgr/test-lit/spirv-tests/spirv-translator.cl diff --git a/external/llvm-project/amd/comgr/test-lit/spirv-translator.hip b/external/llvm-project/amd/comgr/test-lit/spirv-tests/spirv-translator.hip similarity index 100% rename from external/llvm-project/amd/comgr/test-lit/spirv-translator.hip rename to external/llvm-project/amd/comgr/test-lit/spirv-tests/spirv-translator.hip diff --git a/external/llvm-project/amd/comgr/test-lit/time-statistics.cl b/external/llvm-project/amd/comgr/test-lit/time-statistics.cl new file mode 100644 index 000000000000..5881e3787984 --- /dev/null +++ b/external/llvm-project/amd/comgr/test-lit/time-statistics.cl @@ -0,0 +1,7 @@ +// COM: Check for any runtime errors with the Comgr Profilier +// RUN: AMD_COMGR_TIME_STATISTICS=1 compile-minimal-test %s %t.bin +// RUN: test -f PerfStatsLog.txt + +void kernel add(__global float *A, __global float *B, __global float *C) { + *C = *A + *B; +} diff --git a/external/llvm-project/amd/hipcc/CMakeLists.txt b/external/llvm-project/amd/hipcc/CMakeLists.txt index 7512aa93baaa..b39bcbcc4829 100755 --- a/external/llvm-project/amd/hipcc/CMakeLists.txt +++ b/external/llvm-project/amd/hipcc/CMakeLists.txt @@ -1,16 +1,13 @@ cmake_minimum_required(VERSION 3.13.4) +if(POLICY CMP0177) + cmake_policy(SET CMP0177 NEW) +endif() project(hipcc VERSION "1.1.1" LANGUAGES C CXX) include(CMakePackageConfigHelpers) include(GNUInstallDirs) -find_package(ROCM QUIET) -if(ROCM_FOUND) - include(ROCMSetupVersion) - rocm_setup_version(VERSION "${hipcc_VERSION}") -endif() - # Generate static package, when BUILD_SHARED_LIBS is set to OFF. # Default to ON option(BUILD_SHARED_LIBS "Build using shared libraries" ON) diff --git a/external/llvm-project/bolt/include/bolt/Passes/PAuthGadgetScanner.h b/external/llvm-project/bolt/include/bolt/Passes/PAuthGadgetScanner.h index c6b9cc2eb4b9..721fd664a325 100644 --- a/external/llvm-project/bolt/include/bolt/Passes/PAuthGadgetScanner.h +++ b/external/llvm-project/bolt/include/bolt/Passes/PAuthGadgetScanner.h @@ -199,8 +199,7 @@ namespace PAuthGadgetScanner { // to distinguish intermediate and final results at the type level. // // Here is an overview of issue life-cycle: -// * an analysis (SrcSafetyAnalysis at now, DstSafetyAnalysis will be added -// later to support the detection of authentication oracles) computes register +// * an analysis (SrcSafetyAnalysis or DstSafetyAnalysis) computes register // state for each instruction in the function. // * for each instruction, it is checked whether it is a gadget of some kind, // taking the computed state into account. If a gadget is found, its kind @@ -273,6 +272,11 @@ class ExtraInfo { virtual ~ExtraInfo() {} }; +/// The set of instructions writing to the affected register in an unsafe +/// manner. +/// +/// This is a hint to be printed alongside the report. It should be further +/// analyzed by the user. class ClobberingInfo : public ExtraInfo { SmallVector ClobberingInstrs; @@ -282,6 +286,20 @@ class ClobberingInfo : public ExtraInfo { void print(raw_ostream &OS, const MCInstReference Location) const override; }; +/// The set of instructions leaking the authenticated pointer before the +/// result of authentication was checked. +/// +/// This is a hint to be printed alongside the report. It should be further +/// analyzed by the user. +class LeakageInfo : public ExtraInfo { + SmallVector LeakingInstrs; + +public: + LeakageInfo(ArrayRef Instrs) : LeakingInstrs(Instrs) {} + + void print(raw_ostream &OS, const MCInstReference Location) const override; +}; + /// A brief version of a report that can be further augmented with the details. /// /// A half-baked report produced on the first run of the analysis. An extra, @@ -322,6 +340,9 @@ class FunctionAnalysisContext { void findUnsafeUses(SmallVector> &Reports); void augmentUnsafeUseReports(ArrayRef> Reports); + void findUnsafeDefs(SmallVector> &Reports); + void augmentUnsafeDefReports(ArrayRef> Reports); + /// Process the reports which do not have to be augmented, and remove them /// from Reports. void handleSimpleReports(SmallVector> &Reports); diff --git a/external/llvm-project/bolt/include/bolt/Profile/DataAggregator.h b/external/llvm-project/bolt/include/bolt/Profile/DataAggregator.h index 3f07a6dc03a4..cc28a06c151e 100644 --- a/external/llvm-project/bolt/include/bolt/Profile/DataAggregator.h +++ b/external/llvm-project/bolt/include/bolt/Profile/DataAggregator.h @@ -85,6 +85,8 @@ class DataAggregator : public DataReader { }; friend raw_ostream &operator<<(raw_ostream &OS, const LBREntry &); + friend struct PerfSpeEventsTestHelper; + struct PerfBranchSample { SmallVector LBR; }; @@ -99,24 +101,29 @@ class DataAggregator : public DataReader { uint64_t Addr; }; + /// Container for the unit of branch data, matching pre-aggregated trace type. + /// Backwards compatible with branch and fall-through types: + /// - if \p To is < 0, the trace only contains branch data (BR_ONLY), + /// - if \p Branch is < 0, the trace only contains fall-through data + /// (FT_ONLY, FT_EXTERNAL_ORIGIN, or FT_EXTERNAL_RETURN). struct Trace { + static constexpr const uint64_t EXTERNAL = 0ULL; + static constexpr const uint64_t BR_ONLY = -1ULL; + static constexpr const uint64_t FT_ONLY = -1ULL; + static constexpr const uint64_t FT_EXTERNAL_ORIGIN = -2ULL; + static constexpr const uint64_t FT_EXTERNAL_RETURN = -3ULL; + + uint64_t Branch; uint64_t From; uint64_t To; - Trace(uint64_t From, uint64_t To) : From(From), To(To) {} - bool operator==(const Trace &Other) const { - return From == Other.From && To == Other.To; - } + auto tie() const { return std::tie(Branch, From, To); } + bool operator==(const Trace &Other) const { return tie() == Other.tie(); } + bool operator<(const Trace &Other) const { return tie() < Other.tie(); } }; + friend raw_ostream &operator<<(raw_ostream &OS, const Trace &); struct TraceHash { - size_t operator()(const Trace &L) const { - return std::hash()(L.From << 32 | L.To); - } - }; - - struct FTInfo { - uint64_t InternCount{0}; - uint64_t ExternCount{0}; + size_t operator()(const Trace &L) const { return hash_combine(L.tie()); } }; struct TakenBranchInfo { @@ -126,8 +133,11 @@ class DataAggregator : public DataReader { /// Intermediate storage for profile data. We save the results of parsing /// and use them later for processing and assigning profile. - std::unordered_map BranchLBRs; - std::unordered_map FallthroughLBRs; + std::unordered_map TraceMap; + std::vector> Traces; + /// Pre-populated addresses of returns, coming from pre-aggregated data or + /// disassembly. Used to disambiguate call-continuation fall-throughs. + std::unordered_set Returns; std::unordered_map BasicSamples; std::vector MemSamples; @@ -200,8 +210,8 @@ class DataAggregator : public DataReader { /// Return a vector of offsets corresponding to a trace in a function /// if the trace is valid, std::nullopt otherwise. std::optional, 16>> - getFallthroughsInTrace(BinaryFunction &BF, const LBREntry &First, - const LBREntry &Second, uint64_t Count = 1) const; + getFallthroughsInTrace(BinaryFunction &BF, const Trace &Trace, uint64_t Count, + bool IsReturn) const; /// Record external entry into the function \p BF. /// @@ -261,12 +271,14 @@ class DataAggregator : public DataReader { uint64_t From, uint64_t To, uint64_t Count, uint64_t Mispreds); + /// Checks if \p Addr corresponds to a return instruction. + bool checkReturn(uint64_t Addr); + /// Register a \p Branch. bool doBranch(uint64_t From, uint64_t To, uint64_t Count, uint64_t Mispreds); /// Register a trace between two LBR entries supplied in execution order. - bool doTrace(const LBREntry &First, const LBREntry &Second, - uint64_t Count = 1); + bool doTrace(const Trace &Trace, uint64_t Count, bool IsReturn); /// Parser helpers /// Return false if we exhausted our parser buffer and finished parsing @@ -379,9 +391,9 @@ class DataAggregator : public DataReader { /// File format syntax: /// E /// S - /// T + /// [TR] /// B - /// [Ff] + /// [Ffr] /// /// where , , have the format [:] /// @@ -392,8 +404,11 @@ class DataAggregator : public DataReader { /// f - an aggregated fall-through with external origin - used to disambiguate /// between a return hitting a basic block head and a regular internal /// jump to the block + /// r - an aggregated fall-through originating at an external return, no + /// checks are performed for a fallthrough start /// T - an aggregated trace: branch from to with a fall-through /// to + /// R - an aggregated trace originating at a return /// /// - build id of the object containing the address. We can skip it for /// the main binary and use "X" for an unknown object. This will save some @@ -516,6 +531,26 @@ inline raw_ostream &operator<<(raw_ostream &OS, OS << formatv("{0:x} -> {1:x}/{2}", L.From, L.To, L.Mispred ? 'M' : 'P'); return OS; } + +inline raw_ostream &operator<<(raw_ostream &OS, + const DataAggregator::Trace &T) { + switch (T.Branch) { + case DataAggregator::Trace::FT_ONLY: + break; + case DataAggregator::Trace::FT_EXTERNAL_ORIGIN: + OS << "X:0 -> "; + break; + case DataAggregator::Trace::FT_EXTERNAL_RETURN: + OS << "X:R -> "; + break; + default: + OS << Twine::utohexstr(T.Branch) << " -> "; + } + OS << Twine::utohexstr(T.From); + if (T.To != DataAggregator::Trace::BR_ONLY) + OS << " ... " << Twine::utohexstr(T.To); + return OS; +} } // namespace bolt } // namespace llvm diff --git a/external/llvm-project/bolt/include/bolt/Utils/CommandLineOpts.h b/external/llvm-project/bolt/include/bolt/Utils/CommandLineOpts.h index 4acce5a3e832..a75b6bf720ec 100644 --- a/external/llvm-project/bolt/include/bolt/Utils/CommandLineOpts.h +++ b/external/llvm-project/bolt/include/bolt/Utils/CommandLineOpts.h @@ -48,6 +48,7 @@ extern llvm::cl::OptionCategory BinaryAnalysisCategory; extern llvm::cl::opt AlignText; extern llvm::cl::opt AlignFunctions; extern llvm::cl::opt AggregateOnly; +extern llvm::cl::opt ArmSPE; extern llvm::cl::opt BucketsPerLine; extern llvm::cl::opt CompactCodeModel; extern llvm::cl::opt DiffOnly; diff --git a/external/llvm-project/bolt/lib/Passes/PAuthGadgetScanner.cpp b/external/llvm-project/bolt/lib/Passes/PAuthGadgetScanner.cpp index 971ea5fdef42..95e831fe9c8c 100644 --- a/external/llvm-project/bolt/lib/Passes/PAuthGadgetScanner.cpp +++ b/external/llvm-project/bolt/lib/Passes/PAuthGadgetScanner.cpp @@ -152,6 +152,8 @@ class TrackedRegisters { // in the gadgets to be reported. This information is used in the second run // to also track which instructions last wrote to those registers. +typedef SmallPtrSet SetOfRelatedInsts; + /// A state representing which registers are safe to use by an instruction /// at a given program point. /// @@ -195,7 +197,7 @@ struct SrcState { /// pac-ret analysis, the expectation is that almost all return instructions /// only use register `X30`, and therefore, this vector will probably have /// length 1 in the second run. - std::vector> LastInstWritingReg; + std::vector LastInstWritingReg; /// Construct an empty state. SrcState() {} @@ -230,12 +232,11 @@ struct SrcState { bool operator!=(const SrcState &RHS) const { return !((*this) == RHS); } }; -static void -printLastInsts(raw_ostream &OS, - ArrayRef> LastInstWritingReg) { +static void printInstsShort(raw_ostream &OS, + ArrayRef Insts) { OS << "Insts: "; - for (unsigned I = 0; I < LastInstWritingReg.size(); ++I) { - auto &Set = LastInstWritingReg[I]; + for (unsigned I = 0; I < Insts.size(); ++I) { + auto &Set = Insts[I]; OS << "[" << I << "]("; for (const MCInst *MCInstP : Set) OS << MCInstP << " "; @@ -243,14 +244,14 @@ printLastInsts(raw_ostream &OS, } } -raw_ostream &operator<<(raw_ostream &OS, const SrcState &S) { +static raw_ostream &operator<<(raw_ostream &OS, const SrcState &S) { OS << "src-state<"; if (S.empty()) { OS << "empty"; } else { OS << "SafeToDerefRegs: " << S.SafeToDerefRegs << ", "; OS << "TrustedRegs: " << S.TrustedRegs << ", "; - printLastInsts(OS, S.LastInstWritingReg); + printInstsShort(OS, S.LastInstWritingReg); } OS << ">"; return OS; @@ -279,7 +280,7 @@ void SrcStatePrinter::print(raw_ostream &OS, const SrcState &S) const { OS << ", TrustedRegs: "; RegStatePrinter.print(OS, S.TrustedRegs); OS << ", "; - printLastInsts(OS, S.LastInstWritingReg); + printInstsShort(OS, S.LastInstWritingReg); } OS << ">"; } @@ -323,13 +324,12 @@ class SrcSafetyAnalysis { DenseMap> CheckerSequenceInfo; - SmallPtrSet &lastWritingInsts(SrcState &S, - MCPhysReg Reg) const { + SetOfRelatedInsts &lastWritingInsts(SrcState &S, MCPhysReg Reg) const { unsigned Index = RegsToTrackInstsFor.getIndex(Reg); return S.LastInstWritingReg[Index]; } - const SmallPtrSet &lastWritingInsts(const SrcState &S, - MCPhysReg Reg) const { + const SetOfRelatedInsts &lastWritingInsts(const SrcState &S, + MCPhysReg Reg) const { unsigned Index = RegsToTrackInstsFor.getIndex(Reg); return S.LastInstWritingReg[Index]; } @@ -430,11 +430,13 @@ class SrcSafetyAnalysis { } SrcState computeNext(const MCInst &Point, const SrcState &Cur) { + if (BC.MIB->isCFI(Point)) + return Cur; + SrcStatePrinter P(BC); LLVM_DEBUG({ dbgs() << " SrcSafetyAnalysis::ComputeNext("; - BC.InstPrinter->printInst(&const_cast(Point), 0, "", *BC.STI, - dbgs()); + BC.InstPrinter->printInst(&Point, 0, "", *BC.STI, dbgs()); dbgs() << ", "; P.print(dbgs(), Cur); dbgs() << ")\n"; @@ -612,6 +614,42 @@ class DataflowSrcSafetyAnalysis StringRef getAnnotationName() const { return "DataflowSrcSafetyAnalysis"; } }; +/// A helper base class for implementing a simplified counterpart of a dataflow +/// analysis for functions without CFG information. +template class CFGUnawareAnalysis { + BinaryContext &BC; + BinaryFunction &BF; + MCPlusBuilder::AllocatorIdTy AllocId; + unsigned StateAnnotationIndex; + + void cleanStateAnnotations() { + for (auto &I : BF.instrs()) + BC.MIB->removeAnnotation(I.second, StateAnnotationIndex); + } + +protected: + CFGUnawareAnalysis(BinaryFunction &BF, MCPlusBuilder::AllocatorIdTy AllocId, + StringRef AnnotationName) + : BC(BF.getBinaryContext()), BF(BF), AllocId(AllocId) { + StateAnnotationIndex = BC.MIB->getOrCreateAnnotationIndex(AnnotationName); + } + + void setState(MCInst &Inst, const StateTy &S) { + // Check if we need to remove an old annotation (this is the case if + // this is the second, detailed run of the analysis). + if (BC.MIB->hasAnnotation(Inst, StateAnnotationIndex)) + BC.MIB->removeAnnotation(Inst, StateAnnotationIndex); + // Attach the state. + BC.MIB->addAnnotation(Inst, StateAnnotationIndex, S, AllocId); + } + + const StateTy &getState(const MCInst &Inst) const { + return BC.MIB->getAnnotationAs(Inst, StateAnnotationIndex); + } + + virtual ~CFGUnawareAnalysis() { cleanStateAnnotations(); } +}; + // A simplified implementation of DataflowSrcSafetyAnalysis for functions // lacking CFG information. // @@ -646,15 +684,10 @@ class DataflowSrcSafetyAnalysis // of instructions without labels in between. These sequences can be processed // the same way basic blocks are processed by data-flow analysis, assuming // pessimistically that all registers are unsafe at the start of each sequence. -class CFGUnawareSrcSafetyAnalysis : public SrcSafetyAnalysis { +class CFGUnawareSrcSafetyAnalysis : public SrcSafetyAnalysis, + public CFGUnawareAnalysis { + using SrcSafetyAnalysis::BC; BinaryFunction &BF; - MCPlusBuilder::AllocatorIdTy AllocId; - unsigned StateAnnotationIndex; - - void cleanStateAnnotations() { - for (auto &I : BF.instrs()) - BC.MIB->removeAnnotation(I.second, StateAnnotationIndex); - } /// Creates a state with all registers marked unsafe (not to be confused /// with empty state). @@ -666,15 +699,16 @@ class CFGUnawareSrcSafetyAnalysis : public SrcSafetyAnalysis { CFGUnawareSrcSafetyAnalysis(BinaryFunction &BF, MCPlusBuilder::AllocatorIdTy AllocId, ArrayRef RegsToTrackInstsFor) - : SrcSafetyAnalysis(BF, RegsToTrackInstsFor), BF(BF), AllocId(AllocId) { - StateAnnotationIndex = - BC.MIB->getOrCreateAnnotationIndex("CFGUnawareSrcSafetyAnalysis"); + : SrcSafetyAnalysis(BF, RegsToTrackInstsFor), + CFGUnawareAnalysis(BF, AllocId, "CFGUnawareSrcSafetyAnalysis"), BF(BF) { } void run() override { SrcState S = createEntryState(); for (auto &I : BF.instrs()) { MCInst &Inst = I.second; + if (BC.MIB->isCFI(Inst)) + continue; // If there is a label before this instruction, it is possible that it // can be jumped-to, thus conservatively resetting S. As an exception, @@ -687,12 +721,8 @@ class CFGUnawareSrcSafetyAnalysis : public SrcSafetyAnalysis { S = createUnsafeState(); } - // Check if we need to remove an old annotation (this is the case if - // this is the second, detailed, run of the analysis). - if (BC.MIB->hasAnnotation(Inst, StateAnnotationIndex)) - BC.MIB->removeAnnotation(Inst, StateAnnotationIndex); // Attach the state *before* this instruction executes. - BC.MIB->addAnnotation(Inst, StateAnnotationIndex, S, AllocId); + setState(Inst, S); // Compute the state after this instruction executes. S = computeNext(Inst, S); @@ -700,10 +730,8 @@ class CFGUnawareSrcSafetyAnalysis : public SrcSafetyAnalysis { } const SrcState &getStateBefore(const MCInst &Inst) const override { - return BC.MIB->getAnnotationAs(Inst, StateAnnotationIndex); + return getState(Inst); } - - ~CFGUnawareSrcSafetyAnalysis() { cleanStateAnnotations(); } }; std::shared_ptr @@ -717,6 +745,483 @@ SrcSafetyAnalysis::create(BinaryFunction &BF, RegsToTrackInstsFor); } +/// A state representing which registers are safe to be used as the destination +/// operand of an authentication instruction. +/// +/// Similar to SrcState, it is the responsibility of the analysis to take +/// register aliasing into account. +/// +/// Depending on the implementation (such as whether FEAT_FPAC is implemented +/// by an AArch64 CPU or not), it may be possible that an authentication +/// instruction returns an invalid pointer on failure instead of terminating +/// the program immediately (assuming the program will crash as soon as that +/// pointer is dereferenced). Since few bits are usually allocated for the PAC +/// field (such as less than 16 bits on a typical AArch64 system), an attacker +/// can try every possible signature and guess the correct one if there is a +/// gadget that tells whether the particular pointer has a correct signature +/// (a so called "authentication oracle"). For that reason, it should be +/// impossible for an attacker to test if a pointer is correctly signed - +/// either the program should be terminated on authentication failure or +/// the result of authentication should not be accessible to an attacker. +/// +/// Considering the instructions in forward order as they are executed, a +/// restricted set of operations can be allowed on any register containing a +/// value derived from the result of an authentication instruction until that +/// value is checked not to contain the result of a failed authentication. +/// In DstSafetyAnalysis, these rules are adapted, so that the safety property +/// for a register is computed by iterating the instructions in backward order. +/// Then the resulting properties are used at authentication instruction sites +/// to check output registers and report the particular instruction if it writes +/// to an unsafe register. +/// +/// Another approach would be to simulate the above rules as-is, iterating over +/// the instructions in forward direction. To make it possible to report the +/// particular instructions as oracles, this would probably require tracking +/// references to these instructions for each register currently containing +/// sensitive data. +/// +/// In DstSafetyAnalysis, the source register Xn of an instruction Inst is safe +/// if at least one of the following is true: +/// * Inst checks if Xn contains the result of a successful authentication and +/// terminates the program on failure. Note that Inst can either naturally +/// dereference Xn (load, branch, return, etc. instructions) or be the first +/// instruction of an explicit checking sequence. +/// * Inst performs safe address arithmetic AND both source and result +/// registers, as well as any temporary registers, must be safe after +/// execution of Inst (temporaries are not used on AArch64 and thus not +/// currently supported/allowed). +/// See MCPlusBuilder::analyzeAddressArithmeticsForPtrAuth for the details. +/// * Inst fully overwrites Xn with a constant. +struct DstState { + /// The set of registers whose values cannot be inspected by an attacker in + /// a way usable as an authentication oracle. The results of authentication + /// instructions should only be written to such registers. + BitVector CannotEscapeUnchecked; + + /// A vector of sets, only used on the second analysis run. + /// Each element in this vector represents one of the tracked registers. + /// For each such register we track the set of first instructions that leak + /// the authenticated pointer before it was checked. This is intended to + /// provide clues on which instruction made the particular register unsafe. + /// + /// Please note that the mapping from MCPhysReg values to indexes in this + /// vector is provided by RegsToTrackInstsFor field of DstSafetyAnalysis. + std::vector FirstInstLeakingReg; + + /// Constructs an empty state. + DstState() {} + + DstState(unsigned NumRegs, unsigned NumRegsToTrack) + : CannotEscapeUnchecked(NumRegs), FirstInstLeakingReg(NumRegsToTrack) {} + + DstState &merge(const DstState &StateIn) { + if (StateIn.empty()) + return *this; + if (empty()) + return (*this = StateIn); + + CannotEscapeUnchecked &= StateIn.CannotEscapeUnchecked; + for (unsigned I = 0; I < FirstInstLeakingReg.size(); ++I) + for (const MCInst *J : StateIn.FirstInstLeakingReg[I]) + FirstInstLeakingReg[I].insert(J); + return *this; + } + + /// Returns true if this object does not store state of any registers - + /// neither safe, nor unsafe ones. + bool empty() const { return CannotEscapeUnchecked.empty(); } + + bool operator==(const DstState &RHS) const { + return CannotEscapeUnchecked == RHS.CannotEscapeUnchecked && + FirstInstLeakingReg == RHS.FirstInstLeakingReg; + } + bool operator!=(const DstState &RHS) const { return !((*this) == RHS); } +}; + +static raw_ostream &operator<<(raw_ostream &OS, const DstState &S) { + OS << "dst-state<"; + if (S.empty()) { + OS << "empty"; + } else { + OS << "CannotEscapeUnchecked: " << S.CannotEscapeUnchecked << ", "; + printInstsShort(OS, S.FirstInstLeakingReg); + } + OS << ">"; + return OS; +} + +class DstStatePrinter { +public: + void print(raw_ostream &OS, const DstState &S) const; + explicit DstStatePrinter(const BinaryContext &BC) : BC(BC) {} + +private: + const BinaryContext &BC; +}; + +void DstStatePrinter::print(raw_ostream &OS, const DstState &S) const { + RegStatePrinter RegStatePrinter(BC); + OS << "dst-state<"; + if (S.empty()) { + assert(S.CannotEscapeUnchecked.empty()); + assert(S.FirstInstLeakingReg.empty()); + OS << "empty"; + } else { + OS << "CannotEscapeUnchecked: "; + RegStatePrinter.print(OS, S.CannotEscapeUnchecked); + OS << ", "; + printInstsShort(OS, S.FirstInstLeakingReg); + } + OS << ">"; +} + +/// Computes which registers are safe to be written to by auth instructions. +/// +/// This is the base class for two implementations: a dataflow-based analysis +/// which is intended to be used for most functions and a simplified CFG-unaware +/// version for functions without reconstructed CFG. +class DstSafetyAnalysis { +public: + DstSafetyAnalysis(BinaryFunction &BF, ArrayRef RegsToTrackInstsFor) + : BC(BF.getBinaryContext()), NumRegs(BC.MRI->getNumRegs()), + RegsToTrackInstsFor(RegsToTrackInstsFor) {} + + virtual ~DstSafetyAnalysis() {} + + static std::shared_ptr + create(BinaryFunction &BF, MCPlusBuilder::AllocatorIdTy AllocId, + ArrayRef RegsToTrackInstsFor); + + virtual void run() = 0; + virtual const DstState &getStateAfter(const MCInst &Inst) const = 0; + +protected: + BinaryContext &BC; + const unsigned NumRegs; + + const TrackedRegisters RegsToTrackInstsFor; + + /// Stores information about the detected instruction sequences emitted to + /// check an authenticated pointer. Specifically, if such sequence is detected + /// in a basic block, it maps the first instruction of that sequence to the + /// register being checked. + /// + /// As the detection of such sequences requires iterating over the adjacent + /// instructions, it should be done before calling computeNext(), which + /// operates on separate instructions. + DenseMap RegCheckedAt; + + SetOfRelatedInsts &firstLeakingInsts(DstState &S, MCPhysReg Reg) const { + unsigned Index = RegsToTrackInstsFor.getIndex(Reg); + return S.FirstInstLeakingReg[Index]; + } + const SetOfRelatedInsts &firstLeakingInsts(const DstState &S, + MCPhysReg Reg) const { + unsigned Index = RegsToTrackInstsFor.getIndex(Reg); + return S.FirstInstLeakingReg[Index]; + } + + /// Creates a state with all registers marked unsafe (not to be confused + /// with empty state). + DstState createUnsafeState() { + return DstState(NumRegs, RegsToTrackInstsFor.getNumTrackedRegisters()); + } + + /// Returns the set of registers that can be leaked by this instruction. + /// A register is considered leaked if it has any intersection with any + /// register read by Inst. This is similar to how the set of clobbered + /// registers is computed, but taking input operands instead of outputs. + BitVector getLeakedRegs(const MCInst &Inst) const { + BitVector Leaked(NumRegs); + + // Assume a call can read all registers. + if (BC.MIB->isCall(Inst)) { + Leaked.set(); + return Leaked; + } + + // Compute the set of registers overlapping with any register used by + // this instruction. + + const MCInstrDesc &Desc = BC.MII->get(Inst.getOpcode()); + + for (MCPhysReg Reg : Desc.implicit_uses()) + Leaked |= BC.MIB->getAliases(Reg, /*OnlySmaller=*/false); + + for (const MCOperand &Op : BC.MIB->useOperands(Inst)) { + if (Op.isReg()) + Leaked |= BC.MIB->getAliases(Op.getReg(), /*OnlySmaller=*/false); + } + + return Leaked; + } + + SmallVector getRegsMadeProtected(const MCInst &Inst, + const BitVector &LeakedRegs, + const DstState &Cur) const { + SmallVector Regs; + + // A pointer can be checked, or + if (auto CheckedReg = + BC.MIB->getAuthCheckedReg(Inst, /*MayOverwrite=*/true)) + Regs.push_back(*CheckedReg); + if (RegCheckedAt.contains(&Inst)) + Regs.push_back(RegCheckedAt.at(&Inst)); + + // ... it can be used as a branch target, or + if (BC.MIB->isIndirectBranch(Inst) || BC.MIB->isIndirectCall(Inst)) { + bool IsAuthenticated; + MCPhysReg BranchDestReg = + BC.MIB->getRegUsedAsIndirectBranchDest(Inst, IsAuthenticated); + assert(BranchDestReg != BC.MIB->getNoRegister()); + if (!IsAuthenticated) + Regs.push_back(BranchDestReg); + } + + // ... it can be used as a return target, or + if (BC.MIB->isReturn(Inst)) { + bool IsAuthenticated = false; + std::optional RetReg = + BC.MIB->getRegUsedAsRetDest(Inst, IsAuthenticated); + if (RetReg && !IsAuthenticated) + Regs.push_back(*RetReg); + } + + // ... an address can be updated in a safe manner, or + if (auto DstAndSrc = BC.MIB->analyzeAddressArithmeticsForPtrAuth(Inst)) { + MCPhysReg DstReg, SrcReg; + std::tie(DstReg, SrcReg) = *DstAndSrc; + // Note that *all* registers containing the derived values must be safe, + // both source and destination ones. No temporaries are supported at now. + if (Cur.CannotEscapeUnchecked[SrcReg] && + Cur.CannotEscapeUnchecked[DstReg]) + Regs.push_back(SrcReg); + } + + // ... the register can be overwritten in whole with a constant: for that + // purpose, look for the instructions with no register inputs (neither + // explicit nor implicit ones) and no side effects (to rule out reading + // not modelled locations). + const MCInstrDesc &Desc = BC.MII->get(Inst.getOpcode()); + bool HasExplicitSrcRegs = llvm::any_of(BC.MIB->useOperands(Inst), + [](auto Op) { return Op.isReg(); }); + if (!Desc.hasUnmodeledSideEffects() && !HasExplicitSrcRegs && + Desc.implicit_uses().empty()) { + for (const MCOperand &Def : BC.MIB->defOperands(Inst)) + Regs.push_back(Def.getReg()); + } + + return Regs; + } + + DstState computeNext(const MCInst &Point, const DstState &Cur) { + if (BC.MIB->isCFI(Point)) + return Cur; + + DstStatePrinter P(BC); + LLVM_DEBUG({ + dbgs() << " DstSafetyAnalysis::ComputeNext("; + BC.InstPrinter->printInst(&Point, 0, "", *BC.STI, dbgs()); + dbgs() << ", "; + P.print(dbgs(), Cur); + dbgs() << ")\n"; + }); + + // If this instruction is reachable by the analysis, a non-empty state will + // be propagated to it sooner or later. Until then, skip computeNext(). + if (Cur.empty()) { + LLVM_DEBUG( + { dbgs() << "Skipping computeNext(Point, Cur) as Cur is empty.\n"; }); + return DstState(); + } + + // First, compute various properties of the instruction, taking the state + // after its execution into account, if necessary. + + BitVector LeakedRegs = getLeakedRegs(Point); + SmallVector NewProtectedRegs = + getRegsMadeProtected(Point, LeakedRegs, Cur); + + // Then, compute the state before this instruction is executed. + DstState Next = Cur; + + Next.CannotEscapeUnchecked.reset(LeakedRegs); + for (MCPhysReg Reg : RegsToTrackInstsFor.getRegisters()) { + if (LeakedRegs[Reg]) + firstLeakingInsts(Next, Reg) = {&Point}; + } + + BitVector NewProtectedSubregs(NumRegs); + for (MCPhysReg Reg : NewProtectedRegs) + NewProtectedSubregs |= BC.MIB->getAliases(Reg, /*OnlySmaller=*/true); + Next.CannotEscapeUnchecked |= NewProtectedSubregs; + for (MCPhysReg Reg : RegsToTrackInstsFor.getRegisters()) { + if (NewProtectedSubregs[Reg]) + firstLeakingInsts(Next, Reg).clear(); + } + + LLVM_DEBUG({ + dbgs() << " .. result: ("; + P.print(dbgs(), Next); + dbgs() << ")\n"; + }); + + return Next; + } + +public: + std::vector getLeakingInsts(const MCInst &Inst, + BinaryFunction &BF, + MCPhysReg LeakedReg) const { + const DstState &S = getStateAfter(Inst); + + std::vector Result; + for (const MCInst *Inst : firstLeakingInsts(S, LeakedReg)) { + MCInstReference Ref = MCInstReference::get(Inst, BF); + assert(Ref && "Expected Inst to be found"); + Result.push_back(Ref); + } + return Result; + } +}; + +class DataflowDstSafetyAnalysis + : public DstSafetyAnalysis, + public DataflowAnalysis { + using DFParent = DataflowAnalysis; + friend DFParent; + + using DstSafetyAnalysis::BC; + using DstSafetyAnalysis::computeNext; + +public: + DataflowDstSafetyAnalysis(BinaryFunction &BF, + MCPlusBuilder::AllocatorIdTy AllocId, + ArrayRef RegsToTrackInstsFor) + : DstSafetyAnalysis(BF, RegsToTrackInstsFor), DFParent(BF, AllocId) {} + + const DstState &getStateAfter(const MCInst &Inst) const override { + // The dataflow analysis base class iterates backwards over the + // instructions, thus "after" vs. "before" difference. + return DFParent::getStateBefore(Inst).get(); + } + + void run() override { + for (BinaryBasicBlock &BB : Func) { + if (auto CheckerInfo = BC.MIB->getAuthCheckedReg(BB)) { + LLVM_DEBUG({ + dbgs() << "Found pointer checking sequence in " << BB.getName() + << ":\n"; + traceReg(BC, "Checked register", CheckerInfo->first); + traceInst(BC, "First instruction", *CheckerInfo->second); + }); + RegCheckedAt[CheckerInfo->second] = CheckerInfo->first; + } + } + DFParent::run(); + } + +protected: + void preflight() {} + + DstState getStartingStateAtBB(const BinaryBasicBlock &BB) { + // In general, the initial state should be empty, not everything-is-unsafe, + // to give a chance for some meaningful state to be propagated to BB from + // an indirectly reachable "exit basic block" ending with a return or tail + // call instruction. + // + // A basic block without any successors, on the other hand, can be + // pessimistically initialized to everything-is-unsafe: this will naturally + // handle both return and tail call instructions and is harmless for + // internal indirect branch instructions (such as computed gotos). + if (BB.succ_empty()) + return createUnsafeState(); + + return DstState(); + } + + DstState getStartingStateAtPoint(const MCInst &Point) { return DstState(); } + + void doConfluence(DstState &StateOut, const DstState &StateIn) { + DstStatePrinter P(BC); + LLVM_DEBUG({ + dbgs() << " DataflowDstSafetyAnalysis::Confluence(\n"; + dbgs() << " State 1: "; + P.print(dbgs(), StateOut); + dbgs() << "\n"; + dbgs() << " State 2: "; + P.print(dbgs(), StateIn); + dbgs() << ")\n"; + }); + + StateOut.merge(StateIn); + + LLVM_DEBUG({ + dbgs() << " merged state: "; + P.print(dbgs(), StateOut); + dbgs() << "\n"; + }); + } + + StringRef getAnnotationName() const { return "DataflowDstSafetyAnalysis"; } +}; + +class CFGUnawareDstSafetyAnalysis : public DstSafetyAnalysis, + public CFGUnawareAnalysis { + using DstSafetyAnalysis::BC; + BinaryFunction &BF; + +public: + CFGUnawareDstSafetyAnalysis(BinaryFunction &BF, + MCPlusBuilder::AllocatorIdTy AllocId, + ArrayRef RegsToTrackInstsFor) + : DstSafetyAnalysis(BF, RegsToTrackInstsFor), + CFGUnawareAnalysis(BF, AllocId, "CFGUnawareDstSafetyAnalysis"), BF(BF) { + } + + void run() override { + DstState S = createUnsafeState(); + for (auto &I : llvm::reverse(BF.instrs())) { + MCInst &Inst = I.second; + if (BC.MIB->isCFI(Inst)) + continue; + + // If Inst can change the control flow, we cannot be sure that the next + // instruction (to be executed in analyzed program) is the one processed + // on the previous iteration, thus pessimistically reset S before + // starting to analyze Inst. + if (BC.MIB->isCall(Inst) || BC.MIB->isBranch(Inst) || + BC.MIB->isReturn(Inst)) { + LLVM_DEBUG({ traceInst(BC, "Control flow instruction", Inst); }); + S = createUnsafeState(); + } + + // Attach the state *after* this instruction executes. + setState(Inst, S); + + // Compute the next state. + S = computeNext(Inst, S); + } + } + + const DstState &getStateAfter(const MCInst &Inst) const override { + return getState(Inst); + } +}; + +std::shared_ptr +DstSafetyAnalysis::create(BinaryFunction &BF, + MCPlusBuilder::AllocatorIdTy AllocId, + ArrayRef RegsToTrackInstsFor) { + if (BF.hasCFG()) + return std::make_shared(BF, AllocId, + RegsToTrackInstsFor); + return std::make_shared(BF, AllocId, + RegsToTrackInstsFor); +} + // This function could return PartialReport, but currently T is always // MCPhysReg, even though it is an implementation detail. static PartialReport make_generic_report(MCInstReference Location, @@ -808,6 +1313,37 @@ shouldReportSigningOracle(const BinaryContext &BC, const MCInstReference &Inst, return make_gadget_report(SigningOracleKind, Inst, *SignedReg); } +static std::optional> +shouldReportAuthOracle(const BinaryContext &BC, const MCInstReference &Inst, + const DstState &S) { + static const GadgetKind AuthOracleKind("authentication oracle found"); + + bool IsChecked = false; + std::optional AuthReg = + BC.MIB->getWrittenAuthenticatedReg(Inst, IsChecked); + if (!AuthReg || IsChecked) + return std::nullopt; + + LLVM_DEBUG({ + traceInst(BC, "Found auth inst", Inst); + traceReg(BC, "Authenticated reg", *AuthReg); + }); + + if (S.empty()) { + LLVM_DEBUG({ dbgs() << " DstState is empty!\n"; }); + return make_generic_report( + Inst, "Warning: no state computed for an authentication instruction " + "(possibly unreachable)"); + } + + LLVM_DEBUG( + { traceRegMask(BC, "safe output registers", S.CannotEscapeUnchecked); }); + if (S.CannotEscapeUnchecked[*AuthReg]) + return std::nullopt; + + return make_gadget_report(AuthOracleKind, Inst, *AuthReg); +} + template static void iterateOverInstrs(BinaryFunction &BF, T Fn) { if (BF.hasCFG()) { for (BinaryBasicBlock &BB : BF) @@ -840,6 +1376,9 @@ void FunctionAnalysisContext::findUnsafeUses( }); iterateOverInstrs(BF, [&](MCInstReference Inst) { + if (BC.MIB->isCFI(Inst)) + return; + const SrcState &S = Analysis->getStateBefore(Inst); // If non-empty state was never propagated from the entry basic block @@ -889,6 +1428,55 @@ void FunctionAnalysisContext::augmentUnsafeUseReports( } } +void FunctionAnalysisContext::findUnsafeDefs( + SmallVector> &Reports) { + if (PacRetGadgetsOnly) + return; + + auto Analysis = DstSafetyAnalysis::create(BF, AllocatorId, {}); + LLVM_DEBUG({ dbgs() << "Running dst register safety analysis...\n"; }); + Analysis->run(); + LLVM_DEBUG({ + dbgs() << "After dst register safety analysis:\n"; + BF.dump(); + }); + + iterateOverInstrs(BF, [&](MCInstReference Inst) { + if (BC.MIB->isCFI(Inst)) + return; + + const DstState &S = Analysis->getStateAfter(Inst); + + if (auto Report = shouldReportAuthOracle(BC, Inst, S)) + Reports.push_back(*Report); + }); +} + +void FunctionAnalysisContext::augmentUnsafeDefReports( + ArrayRef> Reports) { + SmallVector RegsToTrack = collectRegsToTrack(Reports); + // Re-compute the analysis with register tracking. + auto Analysis = DstSafetyAnalysis::create(BF, AllocatorId, RegsToTrack); + LLVM_DEBUG( + { dbgs() << "\nRunning detailed dst register safety analysis...\n"; }); + Analysis->run(); + LLVM_DEBUG({ + dbgs() << "After detailed dst register safety analysis:\n"; + BF.dump(); + }); + + // Augment gadget reports. + for (auto &Report : Reports) { + MCInstReference Location = Report.Issue->Location; + LLVM_DEBUG({ traceInst(BC, "Attaching leakage info to", Location); }); + assert(Report.RequestedDetails && + "Should be removed by handleSimpleReports"); + auto DetailedInfo = std::make_shared( + Analysis->getLeakingInsts(Location, BF, *Report.RequestedDetails)); + Result.Diagnostics.emplace_back(Report.Issue, DetailedInfo); + } +} + void FunctionAnalysisContext::handleSimpleReports( SmallVector> &Reports) { // Before re-running the detailed analysis, process the reports which do not @@ -912,6 +1500,12 @@ void FunctionAnalysisContext::run() { handleSimpleReports(UnsafeUses); if (!UnsafeUses.empty()) augmentUnsafeUseReports(UnsafeUses); + + SmallVector> UnsafeDefs; + findUnsafeDefs(UnsafeDefs); + handleSimpleReports(UnsafeDefs); + if (!UnsafeDefs.empty()) + augmentUnsafeDefReports(UnsafeDefs); } void Analysis::runOnFunction(BinaryFunction &BF, @@ -1015,6 +1609,12 @@ void ClobberingInfo::print(raw_ostream &OS, printRelatedInstrs(OS, Location, ClobberingInstrs); } +void LeakageInfo::print(raw_ostream &OS, const MCInstReference Location) const { + OS << " The " << LeakingInstrs.size() + << " instructions that leak the affected registers are:\n"; + printRelatedInstrs(OS, Location, LeakingInstrs); +} + void GenericDiagnostic::generateReport(raw_ostream &OS, const BinaryContext &BC) const { printBasicInfo(OS, BC, Text); diff --git a/external/llvm-project/bolt/lib/Profile/BoltAddressTranslation.cpp b/external/llvm-project/bolt/lib/Profile/BoltAddressTranslation.cpp index a253522e4fb1..7ad4e6a2e141 100644 --- a/external/llvm-project/bolt/lib/Profile/BoltAddressTranslation.cpp +++ b/external/llvm-project/bolt/lib/Profile/BoltAddressTranslation.cpp @@ -546,7 +546,7 @@ BoltAddressTranslation::getFallthroughsInTrace(uint64_t FuncAddress, return Res; for (auto Iter = FromIter; Iter != ToIter;) { - const uint32_t Src = Iter->first; + const uint32_t Src = Iter->second >> 1; if (Iter->second & BRANCHENTRY) { ++Iter; continue; @@ -557,7 +557,7 @@ BoltAddressTranslation::getFallthroughsInTrace(uint64_t FuncAddress, ++Iter; if (Iter->second & BRANCHENTRY) break; - Res.emplace_back(Src, Iter->first); + Res.emplace_back(Src, Iter->second >> 1); } return Res; diff --git a/external/llvm-project/bolt/lib/Profile/DataAggregator.cpp b/external/llvm-project/bolt/lib/Profile/DataAggregator.cpp index ade8478f556e..5c8af3710720 100644 --- a/external/llvm-project/bolt/lib/Profile/DataAggregator.cpp +++ b/external/llvm-project/bolt/lib/Profile/DataAggregator.cpp @@ -49,6 +49,9 @@ static cl::opt cl::desc("aggregate basic samples (without LBR info)"), cl::cat(AggregatorCategory)); +cl::opt ArmSPE("spe", cl::desc("Enable Arm SPE mode."), + cl::cat(AggregatorCategory)); + static cl::opt ITraceAggregation("itrace", cl::desc("Generate LBR info with perf itrace argument"), @@ -181,11 +184,21 @@ void DataAggregator::start() { findPerfExecutable(); + if (opts::ArmSPE) { + // pid from_ip to_ip flags + // where flags could be: + // P/M: whether branch was Predicted or Mispredicted. + // N: optionally appears when the branch was Not-Taken (ie fall-through) + // 12345 0x123/0x456/PN/-/-/8/RET/- + opts::ITraceAggregation = "bl"; + opts::ParseMemProfile = true; + opts::BasicAggregation = false; + } + if (opts::BasicAggregation) { - launchPerfProcess("events without LBR", - MainEventsPPI, + launchPerfProcess("events without LBR", MainEventsPPI, "script -F pid,event,ip", - /*Wait = */false); + /*Wait = */ false); } else if (!opts::ITraceAggregation.empty()) { // Disable parsing memory profile from trace data, unless requested by user. if (!opts::ParseMemProfile.getNumOccurrences()) @@ -523,6 +536,9 @@ Error DataAggregator::preprocessProfile(BinaryContext &BC) { deleteTempFiles(); heatmap: + // Sort parsed traces for faster processing. + llvm::sort(Traces, llvm::less_first()); + if (!opts::HeatmapMode) return Error::success(); @@ -598,8 +614,7 @@ void DataAggregator::processProfile(BinaryContext &BC) { llvm::stable_sort(MemEvents.second.Data); // Release intermediate storage. - clear(BranchLBRs); - clear(FallthroughLBRs); + clear(Traces); clear(BasicSamples); clear(MemSamples); } @@ -727,50 +742,54 @@ bool DataAggregator::doInterBranch(BinaryFunction *FromFunc, return true; } +bool DataAggregator::checkReturn(uint64_t Addr) { + auto isReturn = [&](auto MI) { return MI && BC->MIB->isReturn(*MI); }; + if (llvm::is_contained(Returns, Addr)) + return true; + + BinaryFunction *Func = getBinaryFunctionContainingAddress(Addr); + if (!Func) + return false; + + const uint64_t Offset = Addr - Func->getAddress(); + if (Func->hasInstructions() + ? isReturn(Func->getInstructionAtOffset(Offset)) + : isReturn(Func->disassembleInstructionAtOffset(Offset))) { + Returns.emplace(Addr); + return true; + } + return false; +} + bool DataAggregator::doBranch(uint64_t From, uint64_t To, uint64_t Count, uint64_t Mispreds) { - // Returns whether \p Offset in \p Func contains a return instruction. - auto checkReturn = [&](const BinaryFunction &Func, const uint64_t Offset) { - auto isReturn = [&](auto MI) { return MI && BC->MIB->isReturn(*MI); }; - return Func.hasInstructions() - ? isReturn(Func.getInstructionAtOffset(Offset)) - : isReturn(Func.disassembleInstructionAtOffset(Offset)); - }; - // Mutates \p Addr to an offset into the containing function, performing BAT // offset translation and parent lookup. // - // Returns the containing function (or BAT parent) and whether the address - // corresponds to a return (if \p IsFrom) or a call continuation (otherwise). + // Returns the containing function (or BAT parent). auto handleAddress = [&](uint64_t &Addr, bool IsFrom) { BinaryFunction *Func = getBinaryFunctionContainingAddress(Addr); if (!Func) { Addr = 0; - return std::pair{Func, false}; + return Func; } Addr -= Func->getAddress(); - bool IsRet = IsFrom && checkReturn(*Func, Addr); - if (BAT) Addr = BAT->translate(Func->getAddress(), Addr, IsFrom); if (BinaryFunction *ParentFunc = getBATParentFunction(*Func)) - Func = ParentFunc; + return ParentFunc; - return std::pair{Func, IsRet}; + return Func; }; - auto [FromFunc, IsReturn] = handleAddress(From, /*IsFrom*/ true); - auto [ToFunc, _] = handleAddress(To, /*IsFrom*/ false); + BinaryFunction *FromFunc = handleAddress(From, /*IsFrom*/ true); + BinaryFunction *ToFunc = handleAddress(To, /*IsFrom*/ false); if (!FromFunc && !ToFunc) return false; - // Ignore returns. - if (IsReturn) - return true; - // Treat recursive control transfers as inter-branches. if (FromFunc == ToFunc && To != 0) { recordBranch(*FromFunc, From, To, Count, Mispreds); @@ -780,37 +799,20 @@ bool DataAggregator::doBranch(uint64_t From, uint64_t To, uint64_t Count, return doInterBranch(FromFunc, ToFunc, From, To, Count, Mispreds); } -bool DataAggregator::doTrace(const LBREntry &First, const LBREntry &Second, - uint64_t Count) { - BinaryFunction *FromFunc = getBinaryFunctionContainingAddress(First.To); - BinaryFunction *ToFunc = getBinaryFunctionContainingAddress(Second.From); +bool DataAggregator::doTrace(const Trace &Trace, uint64_t Count, + bool IsReturn) { + const uint64_t From = Trace.From, To = Trace.To; + BinaryFunction *FromFunc = getBinaryFunctionContainingAddress(From); + BinaryFunction *ToFunc = getBinaryFunctionContainingAddress(To); + NumTraces += Count; if (!FromFunc || !ToFunc) { - LLVM_DEBUG({ - dbgs() << "Out of range trace starting in "; - if (FromFunc) - dbgs() << formatv("{0} @ {1:x}", *FromFunc, - First.To - FromFunc->getAddress()); - else - dbgs() << Twine::utohexstr(First.To); - dbgs() << " and ending in "; - if (ToFunc) - dbgs() << formatv("{0} @ {1:x}", *ToFunc, - Second.From - ToFunc->getAddress()); - else - dbgs() << Twine::utohexstr(Second.From); - dbgs() << '\n'; - }); + LLVM_DEBUG(dbgs() << "Out of range trace " << Trace << '\n'); NumLongRangeTraces += Count; return false; } if (FromFunc != ToFunc) { + LLVM_DEBUG(dbgs() << "Invalid trace " << Trace << '\n'); NumInvalidTraces += Count; - LLVM_DEBUG({ - dbgs() << "Invalid trace starting in " << FromFunc->getPrintName() - << formatv(" @ {0:x}", First.To - FromFunc->getAddress()) - << " and ending in " << ToFunc->getPrintName() - << formatv(" @ {0:x}\n", Second.From - ToFunc->getAddress()); - }); return false; } @@ -818,51 +820,37 @@ bool DataAggregator::doTrace(const LBREntry &First, const LBREntry &Second, BinaryFunction *ParentFunc = getBATParentFunction(*FromFunc); if (!ParentFunc) ParentFunc = FromFunc; - ParentFunc->SampleCountInBytes += Count * (Second.From - First.To); + ParentFunc->SampleCountInBytes += Count * (To - From); const uint64_t FuncAddress = FromFunc->getAddress(); std::optional FTs = BAT && BAT->isBATFunction(FuncAddress) - ? BAT->getFallthroughsInTrace(FuncAddress, First.To, Second.From) - : getFallthroughsInTrace(*FromFunc, First, Second, Count); + ? BAT->getFallthroughsInTrace(FuncAddress, From - IsReturn, To) + : getFallthroughsInTrace(*FromFunc, Trace, Count, IsReturn); if (!FTs) { - LLVM_DEBUG( - dbgs() << "Invalid trace starting in " << FromFunc->getPrintName() - << " @ " << Twine::utohexstr(First.To - FromFunc->getAddress()) - << " and ending in " << ToFunc->getPrintName() << " @ " - << ToFunc->getPrintName() << " @ " - << Twine::utohexstr(Second.From - ToFunc->getAddress()) << '\n'); + LLVM_DEBUG(dbgs() << "Invalid trace " << Trace << '\n'); NumInvalidTraces += Count; return false; } LLVM_DEBUG(dbgs() << "Processing " << FTs->size() << " fallthroughs for " - << FromFunc->getPrintName() << ":" - << Twine::utohexstr(First.To) << " to " - << Twine::utohexstr(Second.From) << ".\n"); - for (auto [From, To] : *FTs) { - if (BAT) { - From = BAT->translate(FromFunc->getAddress(), From, /*IsBranchSrc=*/true); - To = BAT->translate(FromFunc->getAddress(), To, /*IsBranchSrc=*/false); - } + << FromFunc->getPrintName() << ":" << Trace << '\n'); + for (const auto &[From, To] : *FTs) doIntraBranch(*ParentFunc, From, To, Count, false); - } return true; } std::optional, 16>> -DataAggregator::getFallthroughsInTrace(BinaryFunction &BF, - const LBREntry &FirstLBR, - const LBREntry &SecondLBR, - uint64_t Count) const { +DataAggregator::getFallthroughsInTrace(BinaryFunction &BF, const Trace &Trace, + uint64_t Count, bool IsReturn) const { SmallVector, 16> Branches; BinaryContext &BC = BF.getBinaryContext(); // Offsets of the trace within this function. - const uint64_t From = FirstLBR.To - BF.getAddress(); - const uint64_t To = SecondLBR.From - BF.getAddress(); + const uint64_t From = Trace.From - BF.getAddress(); + const uint64_t To = Trace.To - BF.getAddress(); if (From > To) return std::nullopt; @@ -889,8 +877,9 @@ DataAggregator::getFallthroughsInTrace(BinaryFunction &BF, // Adjust FromBB if the first LBR is a return from the last instruction in // the previous block (that instruction should be a call). - if (From == FromBB->getOffset() && !BF.containsAddress(FirstLBR.From) && - !FromBB->isEntryPoint() && !FromBB->isLandingPad()) { + if (Trace.Branch != Trace::FT_ONLY && !BF.containsAddress(Trace.Branch) && + From == FromBB->getOffset() && + (IsReturn ? From : !(FromBB->isEntryPoint() || FromBB->isLandingPad()))) { const BinaryBasicBlock *PrevBB = BF.getLayout().getBlock(FromBB->getIndex() - 1); if (PrevBB->getSuccessor(FromBB->getLabel())) { @@ -898,10 +887,9 @@ DataAggregator::getFallthroughsInTrace(BinaryFunction &BF, if (Instr && BC.MIB->isCall(*Instr)) FromBB = PrevBB; else - LLVM_DEBUG(dbgs() << "invalid incoming LBR (no call): " << FirstLBR - << '\n'); + LLVM_DEBUG(dbgs() << "invalid trace (no call): " << Trace << '\n'); } else { - LLVM_DEBUG(dbgs() << "invalid incoming LBR: " << FirstLBR << '\n'); + LLVM_DEBUG(dbgs() << "invalid trace: " << Trace << '\n'); } } @@ -920,9 +908,7 @@ DataAggregator::getFallthroughsInTrace(BinaryFunction &BF, // Check for bad LBRs. if (!BB->getSuccessor(NextBB->getLabel())) { - LLVM_DEBUG(dbgs() << "no fall-through for the trace:\n" - << " " << FirstLBR << '\n' - << " " << SecondLBR << '\n'); + LLVM_DEBUG(dbgs() << "no fall-through for the trace: " << Trace << '\n'); return std::nullopt; } @@ -1011,9 +997,22 @@ ErrorOr DataAggregator::parseLBREntry() { if (std::error_code EC = MispredStrRes.getError()) return EC; StringRef MispredStr = MispredStrRes.get(); - if (MispredStr.size() != 1 || - (MispredStr[0] != 'P' && MispredStr[0] != 'M' && MispredStr[0] != '-')) { - reportError("expected single char for mispred bit"); + // SPE brstack mispredicted flags might be up to two characters long: + // 'PN' or 'MN'. Where 'N' optionally appears. + bool ValidStrSize = opts::ArmSPE + ? MispredStr.size() >= 1 && MispredStr.size() <= 2 + : MispredStr.size() == 1; + bool SpeTakenBitErr = + (opts::ArmSPE && MispredStr.size() == 2 && MispredStr[1] != 'N'); + bool PredictionBitErr = + !ValidStrSize || + (MispredStr[0] != 'P' && MispredStr[0] != 'M' && MispredStr[0] != '-'); + if (SpeTakenBitErr) + reportError("expected 'N' as SPE prediction bit for a not-taken branch"); + if (PredictionBitErr) + reportError("expected 'P', 'M' or '-' char as a prediction bit"); + + if (SpeTakenBitErr || PredictionBitErr) { Diag << "Found: " << MispredStr << "\n"; return make_error_code(llvm::errc::io_error); } @@ -1219,22 +1218,25 @@ ErrorOr DataAggregator::parseLocationOrOffset() { std::error_code DataAggregator::parseAggregatedLBREntry() { enum AggregatedLBREntry : char { INVALID = 0, - EVENT_NAME, // E - TRACE, // T - SAMPLE, // S - BRANCH, // B - FT, // F - FT_EXTERNAL_ORIGIN // f + EVENT_NAME, // E + TRACE, // T + RETURN, // R + SAMPLE, // S + BRANCH, // B + FT, // F + FT_EXTERNAL_ORIGIN, // f + FT_EXTERNAL_RETURN // r } Type = INVALID; - // The number of fields to parse, set based on Type. + /// The number of fields to parse, set based on \p Type. int AddrNum = 0; int CounterNum = 0; - // Storage for parsed fields. + /// Storage for parsed fields. StringRef EventName; std::optional Addr[3]; int64_t Counters[2] = {0}; + /// Parse strings: record type and optionally an event name. while (Type == INVALID || Type == EVENT_NAME) { while (checkAndConsumeFS()) { } @@ -1251,23 +1253,26 @@ std::error_code DataAggregator::parseAggregatedLBREntry() { Type = StringSwitch(Str) .Case("T", TRACE) + .Case("R", RETURN) .Case("S", SAMPLE) .Case("E", EVENT_NAME) .Case("B", BRANCH) .Case("F", FT) .Case("f", FT_EXTERNAL_ORIGIN) + .Case("r", FT_EXTERNAL_RETURN) .Default(INVALID); if (Type == INVALID) { - reportError("expected T, S, E, B, F or f"); + reportError("expected T, R, S, E, B, F, f or r"); return make_error_code(llvm::errc::io_error); } using SSI = StringSwitch; - AddrNum = SSI(Str).Case("T", 3).Case("S", 1).Case("E", 0).Default(2); + AddrNum = SSI(Str).Cases("T", "R", 3).Case("S", 1).Case("E", 0).Default(2); CounterNum = SSI(Str).Case("B", 2).Case("E", 0).Default(1); } + /// Parse locations depending on entry type, recording them in \p Addr array. for (int I = 0; I < AddrNum; ++I) { while (checkAndConsumeFS()) { } @@ -1277,6 +1282,7 @@ std::error_code DataAggregator::parseAggregatedLBREntry() { Addr[I] = AddrOrErr.get(); } + /// Parse counters depending on entry type. for (int I = 0; I < CounterNum; ++I) { while (checkAndConsumeFS()) { } @@ -1287,11 +1293,13 @@ std::error_code DataAggregator::parseAggregatedLBREntry() { Counters[I] = CountOrErr.get(); } + /// Expect end of line here. if (!checkAndConsumeNewLine()) { reportError("expected end of line"); return make_error_code(llvm::errc::io_error); } + /// Record event name into \p EventNames and return. if (Type == EVENT_NAME) { EventNames.insert(EventName); return std::error_code(); @@ -1305,6 +1313,7 @@ std::error_code DataAggregator::parseAggregatedLBREntry() { int64_t Count = Counters[0]; int64_t Mispreds = Counters[1]; + /// Record basic IP sample into \p BasicSamples and return. if (Type == SAMPLE) { BasicSamples[FromOffset] += Count; NumTotalSamples += Count; @@ -1316,30 +1325,39 @@ std::error_code DataAggregator::parseAggregatedLBREntry() { if (ToFunc) ToFunc->setHasProfileAvailable(); - Trace Trace(FromOffset, ToOffset); - // Taken trace - if (Type == TRACE || Type == BRANCH) { - TakenBranchInfo &Info = BranchLBRs[Trace]; - Info.TakenCount += Count; - Info.MispredCount += Mispreds; - - NumTotalSamples += Count; - } - // Construct fallthrough part of the trace - if (Type == TRACE) { - const uint64_t TraceFtEndOffset = Addr[2]->Offset; - Trace.From = ToOffset; - Trace.To = TraceFtEndOffset; - Type = FromFunc == ToFunc ? FT : FT_EXTERNAL_ORIGIN; + /// For fall-through types, adjust locations to match Trace container. + if (Type == FT || Type == FT_EXTERNAL_ORIGIN || Type == FT_EXTERNAL_RETURN) { + Addr[2] = Location(Addr[1]->Offset); // Trace To + Addr[1] = Location(Addr[0]->Offset); // Trace From + // Put a magic value into Trace Branch to differentiate from a full trace: + if (Type == FT) + Addr[0] = Location(Trace::FT_ONLY); + else if (Type == FT_EXTERNAL_ORIGIN) + Addr[0] = Location(Trace::FT_EXTERNAL_ORIGIN); + else if (Type == FT_EXTERNAL_RETURN) + Addr[0] = Location(Trace::FT_EXTERNAL_RETURN); + else + llvm_unreachable("Unexpected fall-through type"); } - // Add fallthrough trace - if (Type != BRANCH) { - FTInfo &Info = FallthroughLBRs[Trace]; - (Type == FT ? Info.InternCount : Info.ExternCount) += Count; - NumTraces += Count; + /// For branch type, mark Trace To to differentiate from a full trace. + if (Type == BRANCH) + Addr[2] = Location(Trace::BR_ONLY); + + if (Type == RETURN) { + if (!Addr[0]->Offset) + Addr[0]->Offset = Trace::FT_EXTERNAL_RETURN; + else + Returns.emplace(Addr[0]->Offset); } + /// Record a trace. + Trace T{Addr[0]->Offset, Addr[1]->Offset, Addr[2]->Offset}; + TakenBranchInfo TI{(uint64_t)Count, (uint64_t)Mispreds}; + Traces.emplace_back(T, TI); + + NumTotalSamples += Count; + return std::error_code(); } @@ -1350,7 +1368,7 @@ bool DataAggregator::ignoreKernelInterrupt(LBREntry &LBR) const { std::error_code DataAggregator::printLBRHeatMap() { outs() << "PERF2BOLT: parse branch events...\n"; - NamedRegionTimer T("parseBranch", "Parsing branch events", TimerGroupName, + NamedRegionTimer T("buildHeatmap", "Building heatmap", TimerGroupName, TimerGroupDesc, opts::TimeAggregator); if (BC->IsLinuxKernel) { @@ -1386,12 +1404,9 @@ std::error_code DataAggregator::printLBRHeatMap() { // Register basic samples and perf LBR addresses not covered by fallthroughs. for (const auto &[PC, Hits] : BasicSamples) HM.registerAddress(PC, Hits); - for (const auto &LBR : FallthroughLBRs) { - const Trace &Trace = LBR.first; - const FTInfo &Info = LBR.second; - HM.registerAddressRange(Trace.From, Trace.To, - Info.InternCount + Info.ExternCount); - } + for (const auto &[Trace, Info] : Traces) + if (Trace.To != Trace::BR_ONLY) + HM.registerAddressRange(Trace.From, Trace.To, Info.TakenCount); if (HM.getNumInvalidRanges()) outs() << "HEATMAP: invalid traces: " << HM.getNumInvalidRanges() << '\n'; @@ -1437,22 +1452,10 @@ void DataAggregator::parseLBRSample(const PerfBranchSample &Sample, // chronological order) if (NeedsSkylakeFix && NumEntry <= 2) continue; - if (NextLBR) { - // Record fall-through trace. - const uint64_t TraceFrom = LBR.To; - const uint64_t TraceTo = NextLBR->From; - const BinaryFunction *TraceBF = - getBinaryFunctionContainingAddress(TraceFrom); - FTInfo &Info = FallthroughLBRs[Trace(TraceFrom, TraceTo)]; - if (TraceBF && TraceBF->containsAddress(LBR.From)) - ++Info.InternCount; - else - ++Info.ExternCount; - ++NumTraces; - } + uint64_t TraceTo = NextLBR ? NextLBR->From : Trace::BR_ONLY; NextLBR = &LBR; - TakenBranchInfo &Info = BranchLBRs[Trace(LBR.From, LBR.To)]; + TakenBranchInfo &Info = TraceMap[Trace{LBR.From, LBR.To, TraceTo}]; ++Info.TakenCount; Info.MispredCount += LBR.Mispred; } @@ -1527,7 +1530,9 @@ void DataAggregator::printBranchStacksDiagnostics( } std::error_code DataAggregator::parseBranchEvents() { - outs() << "PERF2BOLT: parse branch events...\n"; + std::string BranchEventTypeStr = + opts::ArmSPE ? "SPE branch events in LBR-format" : "branch events"; + outs() << "PERF2BOLT: parse " << BranchEventTypeStr << "...\n"; NamedRegionTimer T("parseBranch", "Parsing branch events", TimerGroupName, TimerGroupDesc, opts::TimeAggregator); @@ -1555,7 +1560,8 @@ std::error_code DataAggregator::parseBranchEvents() { } NumEntries += Sample.LBR.size(); - if (BAT && Sample.LBR.size() == 32 && !NeedsSkylakeFix) { + if (this->BC->isX86() && BAT && Sample.LBR.size() == 32 && + !NeedsSkylakeFix) { errs() << "PERF2BOLT-WARNING: using Intel Skylake bug workaround\n"; NeedsSkylakeFix = true; } @@ -1563,10 +1569,14 @@ std::error_code DataAggregator::parseBranchEvents() { parseLBRSample(Sample, NeedsSkylakeFix); } - for (const Trace &Trace : llvm::make_first_range(BranchLBRs)) - for (const uint64_t Addr : {Trace.From, Trace.To}) + Traces.reserve(TraceMap.size()); + for (const auto &[Trace, Info] : TraceMap) { + Traces.emplace_back(Trace, Info); + for (const uint64_t Addr : {Trace.Branch, Trace.From}) if (BinaryFunction *BF = getBinaryFunctionContainingAddress(Addr)) BF->setHasProfileAvailable(); + } + clear(TraceMap); outs() << "PERF2BOLT: read " << NumSamples << " samples and " << NumEntries << " LBR entries\n"; @@ -1574,10 +1584,18 @@ std::error_code DataAggregator::parseBranchEvents() { if (NumSamples && NumSamplesNoLBR == NumSamples) { // Note: we don't know if perf2bolt is being used to parse memory samples // at this point. In this case, it is OK to parse zero LBRs. - errs() << "PERF2BOLT-WARNING: all recorded samples for this binary lack " - "LBR. Record profile with perf record -j any or run perf2bolt " - "in no-LBR mode with -nl (the performance improvement in -nl " - "mode may be limited)\n"; + if (!opts::ArmSPE) + errs() + << "PERF2BOLT-WARNING: all recorded samples for this binary lack " + "LBR. Record profile with perf record -j any or run perf2bolt " + "in no-LBR mode with -nl (the performance improvement in -nl " + "mode may be limited)\n"; + else + errs() + << "PERF2BOLT-WARNING: All recorded samples for this binary lack " + "SPE brstack entries. Make sure you are running Linux perf 6.14 " + "or later, otherwise you get zero samples. Record the profile " + "with: perf record -e 'arm_spe_0/branch_filter=1/'."; } else { printBranchStacksDiagnostics(NumTotalSamples - NumSamples); } @@ -1591,23 +1609,15 @@ void DataAggregator::processBranchEvents() { NamedRegionTimer T("processBranch", "Processing branch events", TimerGroupName, TimerGroupDesc, opts::TimeAggregator); - for (const auto &AggrLBR : FallthroughLBRs) { - const Trace &Loc = AggrLBR.first; - const FTInfo &Info = AggrLBR.second; - LBREntry First{Loc.From, Loc.From, false}; - LBREntry Second{Loc.To, Loc.To, false}; - if (Info.InternCount) - doTrace(First, Second, Info.InternCount); - if (Info.ExternCount) { - First.From = 0; - doTrace(First, Second, Info.ExternCount); - } - } - - for (const auto &AggrLBR : BranchLBRs) { - const Trace &Loc = AggrLBR.first; - const TakenBranchInfo &Info = AggrLBR.second; - doBranch(Loc.From, Loc.To, Info.TakenCount, Info.MispredCount); + Returns.emplace(Trace::FT_EXTERNAL_RETURN); + for (const auto &[Trace, Info] : Traces) { + bool IsReturn = checkReturn(Trace.Branch); + // Ignore returns. + if (!IsReturn && Trace.Branch != Trace::FT_ONLY && + Trace.Branch != Trace::FT_EXTERNAL_ORIGIN) + doBranch(Trace.Branch, Trace.From, Info.TakenCount, Info.MispredCount); + if (Trace.To != Trace::BR_ONLY) + doTrace(Trace, Info.TakenCount, IsReturn); } printBranchSamplesDiagnostics(); } diff --git a/external/llvm-project/bolt/lib/Rewrite/LinuxKernelRewriter.cpp b/external/llvm-project/bolt/lib/Rewrite/LinuxKernelRewriter.cpp index 5a5e044184d0..174721a3a053 100644 --- a/external/llvm-project/bolt/lib/Rewrite/LinuxKernelRewriter.cpp +++ b/external/llvm-project/bolt/lib/Rewrite/LinuxKernelRewriter.cpp @@ -432,25 +432,33 @@ class LinuxKernelRewriter final : public MetadataRewriter { }; Error LinuxKernelRewriter::detectLinuxKernelVersion() { - if (BinaryData *BD = BC.getBinaryDataByName("linux_banner")) { - const BinarySection &Section = BD->getSection(); - const std::string S = - Section.getContents().substr(BD->getOffset(), BD->getSize()).str(); - - const std::regex Re(R"---(Linux version ((\d+)\.(\d+)(\.(\d+))?))---"); - std::smatch Match; - if (std::regex_search(S, Match, Re)) { - const unsigned Major = std::stoi(Match[2].str()); - const unsigned Minor = std::stoi(Match[3].str()); - const unsigned Rev = Match[5].matched ? std::stoi(Match[5].str()) : 0; - LinuxKernelVersion = LKVersion(Major, Minor, Rev); - BC.outs() << "BOLT-INFO: Linux kernel version is " << Match[1].str() - << "\n"; - return Error::success(); - } + // Check for global and local linux_banner symbol. + BinaryData *BD = BC.getBinaryDataByName("linux_banner"); + if (!BD) + BD = BC.getBinaryDataByName("linux_banner/1"); + + if (!BD) + return createStringError(errc::executable_format_error, + "unable to locate linux_banner"); + + const BinarySection &Section = BD->getSection(); + const std::string S = + Section.getContents().substr(BD->getOffset(), BD->getSize()).str(); + + const std::regex Re(R"---(Linux version ((\d+)\.(\d+)(\.(\d+))?))---"); + std::smatch Match; + if (std::regex_search(S, Match, Re)) { + const unsigned Major = std::stoi(Match[2].str()); + const unsigned Minor = std::stoi(Match[3].str()); + const unsigned Rev = Match[5].matched ? std::stoi(Match[5].str()) : 0; + LinuxKernelVersion = LKVersion(Major, Minor, Rev); + BC.outs() << "BOLT-INFO: Linux kernel version is " << Match[1].str() + << "\n"; + return Error::success(); } + return createStringError(errc::executable_format_error, - "Linux kernel version is unknown"); + "Linux kernel version is unknown: " + S); } void LinuxKernelRewriter::processLKSections() { diff --git a/external/llvm-project/bolt/lib/Rewrite/RewriteInstance.cpp b/external/llvm-project/bolt/lib/Rewrite/RewriteInstance.cpp index e1aa00a3d749..93bd93b6cb98 100644 --- a/external/llvm-project/bolt/lib/Rewrite/RewriteInstance.cpp +++ b/external/llvm-project/bolt/lib/Rewrite/RewriteInstance.cpp @@ -780,14 +780,6 @@ void RewriteInstance::discoverFileObjects() { // For local symbols we want to keep track of associated FILE symbol name for // disambiguation by combined name. - StringRef FileSymbolName; - bool SeenFileName = false; - struct SymbolRefHash { - size_t operator()(SymbolRef const &S) const { - return std::hash{}(S.getRawDataRefImpl().p); - } - }; - std::unordered_map SymbolToFileName; for (const ELFSymbolRef &Symbol : InputFile->symbols()) { Expected NameOrError = Symbol.getName(); if (NameOrError && NameOrError->starts_with("__asan_init")) { @@ -806,21 +798,8 @@ void RewriteInstance::discoverFileObjects() { if (cantFail(Symbol.getFlags()) & SymbolRef::SF_Undefined) continue; - if (cantFail(Symbol.getType()) == SymbolRef::ST_File) { + if (cantFail(Symbol.getType()) == SymbolRef::ST_File) FileSymbols.emplace_back(Symbol); - StringRef Name = - cantFail(std::move(NameOrError), "cannot get symbol name for file"); - // Ignore Clang LTO artificial FILE symbol as it is not always generated, - // and this uncertainty is causing havoc in function name matching. - if (Name == "ld-temp.o") - continue; - FileSymbolName = Name; - SeenFileName = true; - continue; - } - if (!FileSymbolName.empty() && - !(cantFail(Symbol.getFlags()) & SymbolRef::SF_Global)) - SymbolToFileName[Symbol] = FileSymbolName; } // Sort symbols in the file by value. Ignore symbols from non-allocatable @@ -1028,14 +1007,14 @@ void RewriteInstance::discoverFileObjects() { // The field is used for disambiguation of local symbols since there // could be identical function names coming from identical file names // (e.g. from different directories). - std::string AltPrefix; - auto SFI = SymbolToFileName.find(Symbol); - if (SymbolType == SymbolRef::ST_Function && SFI != SymbolToFileName.end()) - AltPrefix = Name + "/" + std::string(SFI->second); + auto SFI = llvm::upper_bound(FileSymbols, ELFSymbolRef(Symbol)); + if (SymbolType == SymbolRef::ST_Function && SFI != FileSymbols.begin()) { + StringRef FileSymbolName = cantFail(SFI[-1].getName()); + if (!FileSymbolName.empty()) + AlternativeName = NR.uniquify(Name + "/" + FileSymbolName.str()); + } UniqueName = NR.uniquify(Name); - if (!AltPrefix.empty()) - AlternativeName = NR.uniquify(AltPrefix); } uint64_t SymbolSize = ELFSymbolRef(Symbol).getSize(); @@ -1294,7 +1273,7 @@ void RewriteInstance::discoverFileObjects() { FDE->getAddressRange()); } - BC->setHasSymbolsWithFileName(SeenFileName); + BC->setHasSymbolsWithFileName(FileSymbols.size()); // Now that all the functions were created - adjust their boundaries. adjustFunctionBoundaries(); @@ -1567,6 +1546,11 @@ void RewriteInstance::registerFragments() { uint64_t ParentAddress{0}; + // Check if containing FILE symbol is BOLT emitted synthetic symbol marking + // local fragments of global parents. + if (cantFail(FSI[-1].getName()) == getBOLTFileSymbolName()) + goto registerParent; + // BOLT split fragment symbols are emitted just before the main function // symbol. for (ELFSymbolRef NextSymbol = Symbol; NextSymbol < StopSymbol; diff --git a/external/llvm-project/bolt/lib/Target/AArch64/AArch64MCPlusBuilder.cpp b/external/llvm-project/bolt/lib/Target/AArch64/AArch64MCPlusBuilder.cpp index eb1d9d8a1951..e6e0aeba3457 100644 --- a/external/llvm-project/bolt/lib/Target/AArch64/AArch64MCPlusBuilder.cpp +++ b/external/llvm-project/bolt/lib/Target/AArch64/AArch64MCPlusBuilder.cpp @@ -14,7 +14,7 @@ #include "AArch64MCSymbolizer.h" #include "MCTargetDesc/AArch64AddressingModes.h" #include "MCTargetDesc/AArch64FixupKinds.h" -#include "MCTargetDesc/AArch64MCExpr.h" +#include "MCTargetDesc/AArch64MCAsmInfo.h" #include "MCTargetDesc/AArch64MCTargetDesc.h" #include "Utils/AArch64BaseInfo.h" #include "bolt/Core/BinaryBasicBlock.h" @@ -179,13 +179,10 @@ class AArch64MCPlusBuilder : public MCPlusBuilder { bool equals(const MCSpecifierExpr &A, const MCSpecifierExpr &B, CompFuncTy Comp) const override { - const auto &AArch64ExprA = cast(A); - const auto &AArch64ExprB = cast(B); - if (AArch64ExprA.getKind() != AArch64ExprB.getKind()) + if (A.getSpecifier() != B.getSpecifier()) return false; - return MCPlusBuilder::equals(*AArch64ExprA.getSubExpr(), - *AArch64ExprB.getSubExpr(), Comp); + return MCPlusBuilder::equals(*A.getSubExpr(), *B.getSubExpr(), Comp); } bool shortenInstruction(MCInst &, const MCSubtargetInfo &) const override { @@ -1084,7 +1081,7 @@ class AArch64MCPlusBuilder : public MCPlusBuilder { if (isADR(Inst) || RelType == ELF::R_AARCH64_ADR_PREL_LO21 || RelType == ELF::R_AARCH64_TLSDESC_ADR_PREL21) { - return AArch64MCExpr::create(Expr, AArch64MCExpr::VK_ABS, Ctx); + return MCSpecifierExpr::create(Expr, AArch64MCExpr::VK_ABS, Ctx); } else if (isADRP(Inst) || RelType == ELF::R_AARCH64_ADR_PREL_PG_HI21 || RelType == ELF::R_AARCH64_ADR_PREL_PG_HI21_NC || RelType == ELF::R_AARCH64_TLSDESC_ADR_PAGE21 || @@ -1092,7 +1089,7 @@ class AArch64MCPlusBuilder : public MCPlusBuilder { RelType == ELF::R_AARCH64_ADR_GOT_PAGE) { // Never emit a GOT reloc, we handled this in // RewriteInstance::readRelocations(). - return AArch64MCExpr::create(Expr, AArch64MCExpr::VK_ABS_PAGE, Ctx); + return MCSpecifierExpr::create(Expr, AArch64MCExpr::VK_ABS_PAGE, Ctx); } else { switch (RelType) { case ELF::R_AARCH64_ADD_ABS_LO12_NC: @@ -1106,18 +1103,18 @@ class AArch64MCPlusBuilder : public MCPlusBuilder { case ELF::R_AARCH64_TLSDESC_LD64_LO12: case ELF::R_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC: case ELF::R_AARCH64_TLSLE_ADD_TPREL_LO12_NC: - return AArch64MCExpr::create(Expr, AArch64MCExpr::VK_LO12, Ctx); + return MCSpecifierExpr::create(Expr, AArch64MCExpr::VK_LO12, Ctx); case ELF::R_AARCH64_MOVW_UABS_G3: - return AArch64MCExpr::create(Expr, AArch64MCExpr::VK_ABS_G3, Ctx); + return MCSpecifierExpr::create(Expr, AArch64MCExpr::VK_ABS_G3, Ctx); case ELF::R_AARCH64_MOVW_UABS_G2: case ELF::R_AARCH64_MOVW_UABS_G2_NC: - return AArch64MCExpr::create(Expr, AArch64MCExpr::VK_ABS_G2_NC, Ctx); + return MCSpecifierExpr::create(Expr, AArch64MCExpr::VK_ABS_G2_NC, Ctx); case ELF::R_AARCH64_MOVW_UABS_G1: case ELF::R_AARCH64_MOVW_UABS_G1_NC: - return AArch64MCExpr::create(Expr, AArch64MCExpr::VK_ABS_G1_NC, Ctx); + return MCSpecifierExpr::create(Expr, AArch64MCExpr::VK_ABS_G1_NC, Ctx); case ELF::R_AARCH64_MOVW_UABS_G0: case ELF::R_AARCH64_MOVW_UABS_G0_NC: - return AArch64MCExpr::create(Expr, AArch64MCExpr::VK_ABS_G0_NC, Ctx); + return MCSpecifierExpr::create(Expr, AArch64MCExpr::VK_ABS_G0_NC, Ctx); default: break; } @@ -1142,7 +1139,7 @@ class AArch64MCPlusBuilder : public MCPlusBuilder { } const MCSymbol *getTargetSymbol(const MCExpr *Expr) const override { - auto *AArchExpr = dyn_cast(Expr); + auto *AArchExpr = dyn_cast(Expr); if (AArchExpr && AArchExpr->getSubExpr()) return getTargetSymbol(AArchExpr->getSubExpr()); @@ -1162,7 +1159,7 @@ class AArch64MCPlusBuilder : public MCPlusBuilder { } int64_t getTargetAddend(const MCExpr *Expr) const override { - auto *AArchExpr = dyn_cast(Expr); + auto *AArchExpr = dyn_cast(Expr); if (AArchExpr && AArchExpr->getSubExpr()) return getTargetAddend(AArchExpr->getSubExpr()); @@ -2030,9 +2027,8 @@ class AArch64MCPlusBuilder : public MCPlusBuilder { MCInst Inst; Inst.setOpcode(AArch64::MOVZXi); Inst.addOperand(MCOperand::createReg(AArch64::X16)); - Inst.addOperand(MCOperand::createExpr(AArch64MCExpr::create( - MCSymbolRefExpr::create(Target, MCSymbolRefExpr::VK_None, *Ctx), - AArch64MCExpr::VK_ABS_G3, *Ctx))); + Inst.addOperand(MCOperand::createExpr( + MCSpecifierExpr::create(Target, AArch64MCExpr::VK_ABS_G3, *Ctx))); Inst.addOperand(MCOperand::createImm(0x30)); Seq.emplace_back(Inst); @@ -2040,9 +2036,8 @@ class AArch64MCPlusBuilder : public MCPlusBuilder { Inst.setOpcode(AArch64::MOVKXi); Inst.addOperand(MCOperand::createReg(AArch64::X16)); Inst.addOperand(MCOperand::createReg(AArch64::X16)); - Inst.addOperand(MCOperand::createExpr(AArch64MCExpr::create( - MCSymbolRefExpr::create(Target, MCSymbolRefExpr::VK_None, *Ctx), - AArch64MCExpr::VK_ABS_G2_NC, *Ctx))); + Inst.addOperand(MCOperand::createExpr( + MCSpecifierExpr::create(Target, AArch64MCExpr::VK_ABS_G2_NC, *Ctx))); Inst.addOperand(MCOperand::createImm(0x20)); Seq.emplace_back(Inst); @@ -2050,9 +2045,8 @@ class AArch64MCPlusBuilder : public MCPlusBuilder { Inst.setOpcode(AArch64::MOVKXi); Inst.addOperand(MCOperand::createReg(AArch64::X16)); Inst.addOperand(MCOperand::createReg(AArch64::X16)); - Inst.addOperand(MCOperand::createExpr(AArch64MCExpr::create( - MCSymbolRefExpr::create(Target, MCSymbolRefExpr::VK_None, *Ctx), - AArch64MCExpr::VK_ABS_G1_NC, *Ctx))); + Inst.addOperand(MCOperand::createExpr( + MCSpecifierExpr::create(Target, AArch64MCExpr::VK_ABS_G1_NC, *Ctx))); Inst.addOperand(MCOperand::createImm(0x10)); Seq.emplace_back(Inst); @@ -2060,9 +2054,8 @@ class AArch64MCPlusBuilder : public MCPlusBuilder { Inst.setOpcode(AArch64::MOVKXi); Inst.addOperand(MCOperand::createReg(AArch64::X16)); Inst.addOperand(MCOperand::createReg(AArch64::X16)); - Inst.addOperand(MCOperand::createExpr(AArch64MCExpr::create( - MCSymbolRefExpr::create(Target, MCSymbolRefExpr::VK_None, *Ctx), - AArch64MCExpr::VK_ABS_G0_NC, *Ctx))); + Inst.addOperand(MCOperand::createExpr( + MCSpecifierExpr::create(Target, AArch64MCExpr::VK_ABS_G0_NC, *Ctx))); Inst.addOperand(MCOperand::createImm(0)); Seq.emplace_back(Inst); diff --git a/external/llvm-project/bolt/test/AArch64/r_aarch64_prelxx.s b/external/llvm-project/bolt/test/AArch64/r_aarch64_prelxx.s index 5cbe2c50b294..39f74301cedf 100644 --- a/external/llvm-project/bolt/test/AArch64/r_aarch64_prelxx.s +++ b/external/llvm-project/bolt/test/AArch64/r_aarch64_prelxx.s @@ -5,7 +5,7 @@ // REQUIRES: system-linux // RUN: %clang %cflags -nostartfiles -nostdlib %s -o %t.exe -mlittle-endian \ -// RUN: -Wl,-q -Wl,-z,max-page-size=4 +// RUN: -Wl,-q -Wl,-z,max-page-size=4 -Wl,--no-relax // RUN: llvm-readelf -Wa %t.exe | FileCheck %s -check-prefix=CHECKPREL // CHECKPREL: R_AARCH64_PREL16 {{.*}} .dummy + 0 @@ -36,9 +36,9 @@ .type _start, %function _start: adrp x0, datatable - add x0, x0, :lo12:datable + add x0, x0, :lo12:datatable mov x0, #0 - ret + ret .section .dummy, "a", @progbits dummy: diff --git a/external/llvm-project/bolt/test/X86/callcont-fallthru.s b/external/llvm-project/bolt/test/X86/callcont-fallthru.s index 4994cfb541ee..8c05491e7bca 100644 --- a/external/llvm-project/bolt/test/X86/callcont-fallthru.s +++ b/external/llvm-project/bolt/test/X86/callcont-fallthru.s @@ -4,29 +4,62 @@ # RUN: %clang %cflags -fpic -shared -xc /dev/null -o %t.so ## Link against a DSO to ensure PLT entries. # RUN: %clangxx %cxxflags %s %t.so -o %t -Wl,-q -nostdlib -# RUN: link_fdata %s %t %t.pat PREAGGT1 -# RUN: link_fdata %s %t %t.pat2 PREAGGT2 -# RUN-DISABLED: link_fdata %s %t %t.patplt PREAGGPLT +# Trace to a call continuation, not a landing pad/entry point +# RUN: link_fdata %s %t %t.pa-base PREAGG-BASE +# Trace from a return to a landing pad/entry point call continuation +# RUN: link_fdata %s %t %t.pa-ret PREAGG-RET +# Trace from an external location to a landing pad/entry point call continuation +# RUN: link_fdata %s %t %t.pa-ext PREAGG-EXT +# Return trace to a landing pad/entry point call continuation +# RUN: link_fdata %s %t %t.pa-pret PREAGG-PRET +# External return to a landing pad/entry point call continuation +# RUN: link_fdata %s %t %t.pa-eret PREAGG-ERET +# RUN-DISABLED: link_fdata %s %t %t.pa-plt PREAGG-PLT # RUN: llvm-strip --strip-unneeded %t -o %t.strip # RUN: llvm-objcopy --remove-section=.eh_frame %t.strip %t.noeh ## Check pre-aggregated traces attach call continuation fallthrough count -# RUN: llvm-bolt %t.noeh --pa -p %t.pat -o %t.out \ -# RUN: --print-cfg --print-only=main | FileCheck %s - -## Check pre-aggregated traces don't attach call continuation fallthrough count -## to secondary entry point (unstripped) -# RUN: llvm-bolt %t --pa -p %t.pat2 -o %t.out \ -# RUN: --print-cfg --print-only=main | FileCheck %s --check-prefix=CHECK3 -## Check pre-aggregated traces don't attach call continuation fallthrough count -## to landing pad (stripped, LP) -# RUN: llvm-bolt %t.strip --pa -p %t.pat2 -o %t.out \ -# RUN: --print-cfg --print-only=main | FileCheck %s --check-prefix=CHECK3 +## in the basic case (not an entry point, not a landing pad). +# RUN: llvm-bolt %t.noeh --pa -p %t.pa-base -o %t.out \ +# RUN: --print-cfg --print-only=main | FileCheck %s --check-prefix=CHECK-BASE + +## Check pre-aggregated traces from a return attach call continuation +## fallthrough count to secondary entry point (unstripped) +# RUN: llvm-bolt %t --pa -p %t.pa-ret -o %t.out \ +# RUN: --print-cfg --print-only=main | FileCheck %s --check-prefix=CHECK-ATTACH +## Check pre-aggregated traces from a return attach call continuation +## fallthrough count to landing pad (stripped, landing pad) +# RUN: llvm-bolt %t.strip --pa -p %t.pa-ret -o %t.out \ +# RUN: --print-cfg --print-only=main | FileCheck %s --check-prefix=CHECK-ATTACH + +## Check pre-aggregated traces from external location don't attach call +## continuation fallthrough count to secondary entry point (unstripped) +# RUN: llvm-bolt %t --pa -p %t.pa-ext -o %t.out \ +# RUN: --print-cfg --print-only=main | FileCheck %s --check-prefix=CHECK-SKIP +## Check pre-aggregated traces from external location don't attach call +## continuation fallthrough count to landing pad (stripped, landing pad) +# RUN: llvm-bolt %t.strip --pa -p %t.pa-ext -o %t.out \ +# RUN: --print-cfg --print-only=main | FileCheck %s --check-prefix=CHECK-SKIP + +## Check pre-aggregated return traces from external location attach call +## continuation fallthrough count to secondary entry point (unstripped) +# RUN: llvm-bolt %t --pa -p %t.pa-pret -o %t.out \ +# RUN: --print-cfg --print-only=main | FileCheck %s --check-prefix=CHECK-ATTACH +## Check pre-aggregated return traces from external location attach call +## continuation fallthrough count to landing pad (stripped, landing pad) +# RUN: llvm-bolt %t.strip --pa -p %t.pa-pret -o %t.out \ +# RUN: --print-cfg --print-only=main | FileCheck %s --check-prefix=CHECK-ATTACH + +## Same for external return type +# RUN: llvm-bolt %t --pa -p %t.pa-eret -o %t.out \ +# RUN: --print-cfg --print-only=main | FileCheck %s --check-prefix=CHECK-ATTACH +# RUN: llvm-bolt %t.strip --pa -p %t.pa-eret -o %t.out \ +# RUN: --print-cfg --print-only=main | FileCheck %s --check-prefix=CHECK-ATTACH ## Check pre-aggregated traces don't report zero-sized PLT fall-through as ## invalid trace -# RUN-DISABLED: llvm-bolt %t.strip --pa -p %t.patplt -o %t.out | FileCheck %s \ +# RUN-DISABLED: llvm-bolt %t.strip --pa -p %t.pa-plt -o %t.out | FileCheck %s \ # RUN-DISABLED: --check-prefix=CHECK-PLT # CHECK-PLT: traces mismatching disassembled function contents: 0 @@ -56,11 +89,11 @@ main: Ltmp0_br: callq puts@PLT ## Check PLT traces are accepted -# PREAGGPLT: T #Ltmp0_br# #puts@plt# #puts@plt# 3 +# PREAGG-PLT: T #Ltmp0_br# #puts@plt# #puts@plt# 3 ## Target is an external-origin call continuation -# PREAGGT1: T X:0 #Ltmp1# #Ltmp4_br# 2 -# CHECK: callq puts@PLT -# CHECK-NEXT: count: 2 +# PREAGG-BASE: T X:0 #Ltmp1# #Ltmp4_br# 2 +# CHECK-BASE: callq puts@PLT +# CHECK-BASE-NEXT: count: 2 Ltmp1: movq -0x10(%rbp), %rax @@ -71,24 +104,22 @@ Ltmp4: cmpl $0x0, -0x14(%rbp) Ltmp4_br: je Ltmp0 -# CHECK2: je .Ltmp0 -# CHECK2-NEXT: count: 3 movl $0xa, -0x18(%rbp) callq foo ## Target is a binary-local call continuation -# PREAGGT1: T #Lfoo_ret# #Ltmp3# #Ltmp3_br# 1 -# CHECK: callq foo -# CHECK-NEXT: count: 1 - -## PLT call continuation fallthrough spanning the call -# CHECK2: callq foo -# CHECK2-NEXT: count: 3 - +# PREAGG-RET: T #Lfoo_ret# #Ltmp3# #Ltmp3_br# 1 ## Target is a secondary entry point (unstripped) or a landing pad (stripped) -# PREAGGT2: T X:0 #Ltmp3# #Ltmp3_br# 2 -# CHECK3: callq foo -# CHECK3-NEXT: count: 0 +# PREAGG-EXT: T X:0 #Ltmp3# #Ltmp3_br# 1 +## Pre-aggregated return trace +# PREAGG-PRET: R X:0 #Ltmp3# #Ltmp3_br# 1 +## External return +# PREAGG-ERET: r #Ltmp3# #Ltmp3_br# 1 + +# CHECK-ATTACH: callq foo +# CHECK-ATTACH-NEXT: count: 1 +# CHECK-SKIP: callq foo +# CHECK-SKIP-NEXT: count: 0 Ltmp3: cmpl $0x0, -0x18(%rbp) diff --git a/external/llvm-project/bolt/test/X86/linux-version.S b/external/llvm-project/bolt/test/X86/linux-version.S index e680d0d64a21..a3d7f365304a 100644 --- a/external/llvm-project/bolt/test/X86/linux-version.S +++ b/external/llvm-project/bolt/test/X86/linux-version.S @@ -17,6 +17,11 @@ # RUN: -Wl,--image-base=0xffffffff80000000,--no-dynamic-linker,--no-eh-frame-hdr # RUN: llvm-bolt %t.exe -o %t.out 2>&1 | FileCheck --check-prefix=CHECK-C %s +# RUN: %clang -DD -target x86_64-unknown-unknown \ +# RUN: %cflags -nostdlib %s -o %t.exe \ +# RUN: -Wl,--image-base=0xffffffff80000000,--no-dynamic-linker,--no-eh-frame-hdr +# RUN: llvm-bolt %t.exe -o %t.out 2>&1 | FileCheck --check-prefix=CHECK-D %s + .text .globl foo .type foo, %function @@ -46,6 +51,12 @@ linux_banner: #endif # CHECK-C: BOLT-INFO: Linux kernel version is 6.6 +#ifdef D + .hidden linux_banner + .string "Linux version 6.6.15.2-2-xxx\n" +#endif +# CHECK-D: BOLT-INFO: Linux kernel version is 6.6 + .size linux_banner, . - linux_banner ## Fake Linux Kernel sections. diff --git a/external/llvm-project/bolt/test/X86/register-fragments-bolt-symbols.s b/external/llvm-project/bolt/test/X86/register-fragments-bolt-symbols.s index c9f1859c4e8a..20e7345541d9 100644 --- a/external/llvm-project/bolt/test/X86/register-fragments-bolt-symbols.s +++ b/external/llvm-project/bolt/test/X86/register-fragments-bolt-symbols.s @@ -29,6 +29,7 @@ # RUN: link_fdata %s %t.bolt %t.preagg PREAGG # PREAGG: B X:0 #chain.cold.0# 1 0 +# PREAGG: B X:0 #dummy# 1 0 # RUN: perf2bolt %t.bolt -p %t.preagg --pa -o %t.bat.fdata -w %t.bat.yaml -v=1 \ # RUN: | FileCheck %s --check-prefix=CHECK-REGISTER # RUN: FileCheck --input-file %t.bat.fdata --check-prefix=CHECK-FDATA %s @@ -44,7 +45,13 @@ # CHECK-SYMS: l F .text.cold [[#]] chain.cold.0 # CHECK-SYMS: l F .text [[#]] chain # CHECK-SYMS: l df *ABS* [[#]] bolt-pseudo.o +# CHECK-SYMS: l F .text.cold [[#]] dummy.cold.0 +# CHECK-SYMS: l F .text.cold.1 [[#]] dummy.cold.1 +# CHECK-SYMS: l F .text.cold.2 [[#]] dummy.cold.2 +# CHECK-REGISTER: BOLT-INFO: marking dummy.cold.0/1(*2) as a fragment of dummy +# CHECK-REGISTER: BOLT-INFO: marking dummy.cold.1/1(*2) as a fragment of dummy +# CHECK-REGISTER: BOLT-INFO: marking dummy.cold.2/1(*2) as a fragment of dummy # CHECK-REGISTER: BOLT-INFO: marking chain.cold.0/1(*2) as a fragment of chain/2(*2) # CHECK-FDATA: 0 [unknown] 0 1 chain/chain.s/2 10 0 1 diff --git a/external/llvm-project/bolt/test/binary-analysis/AArch64/gs-pauth-authentication-oracles.s b/external/llvm-project/bolt/test/binary-analysis/AArch64/gs-pauth-authentication-oracles.s new file mode 100644 index 000000000000..717bf40df3d0 --- /dev/null +++ b/external/llvm-project/bolt/test/binary-analysis/AArch64/gs-pauth-authentication-oracles.s @@ -0,0 +1,812 @@ +// RUN: %clang %cflags -march=armv8.3-a %s -o %t.exe +// RUN: llvm-bolt-binary-analysis --scanners=pacret %t.exe 2>&1 | FileCheck -check-prefix=PACRET %s +// RUN: llvm-bolt-binary-analysis --scanners=pauth %t.exe 2>&1 | FileCheck %s + +// The detection of compiler-generated explicit pointer checks is tested in +// gs-pauth-address-checks.s, for that reason only test here "dummy-load" and +// "high-bits-notbi" checkers, as the shortest examples of checkers that are +// detected per-instruction and per-BB. + +// PACRET-NOT: authentication oracle found in function + + .text + + .type sym,@function +sym: + ret + .size sym, .-sym + + .globl callee + .type callee,@function +callee: + ret + .size callee, .-callee + + .globl good_ret + .type good_ret,@function +good_ret: +// CHECK-NOT: good_ret + autia x0, x1 + ret x0 + .size good_ret, .-good_ret + + .globl good_call + .type good_call,@function +good_call: +// CHECK-NOT: good_call + paciasp + stp x29, x30, [sp, #-16]! + mov x29, sp + + autia x0, x1 + blr x0 + + ldp x29, x30, [sp], #16 + autiasp + ret + .size good_call, .-good_call + + .globl good_branch + .type good_branch,@function +good_branch: +// CHECK-NOT: good_branch + autia x0, x1 + br x0 + .size good_branch, .-good_branch + + .globl good_load_other_reg + .type good_load_other_reg,@function +good_load_other_reg: +// CHECK-NOT: good_load_other_reg + autia x0, x1 + ldr x2, [x0] + ret + .size good_load_other_reg, .-good_load_other_reg + + .globl good_load_same_reg + .type good_load_same_reg,@function +good_load_same_reg: +// CHECK-NOT: good_load_same_reg + autia x0, x1 + ldr x0, [x0] + ret + .size good_load_same_reg, .-good_load_same_reg + + .globl good_explicit_check + .type good_explicit_check,@function +good_explicit_check: +// CHECK-NOT: good_explicit_check + autia x0, x1 + eor x16, x0, x0, lsl #1 + tbz x16, #62, 1f + brk 0x1234 +1: + ret + .size good_explicit_check, .-good_explicit_check + + .globl bad_unchecked + .type bad_unchecked,@function +bad_unchecked: +// CHECK-LABEL: GS-PAUTH: authentication oracle found in function bad_unchecked, basic block {{[^,]+}}, at address +// CHECK-NEXT: The instruction is {{[0-9a-f]+}}: autia x0, x1 +// CHECK-NEXT: The 0 instructions that leak the affected registers are: + autia x0, x1 + ret + .size bad_unchecked, .-bad_unchecked + + .globl bad_leaked_to_subroutine + .type bad_leaked_to_subroutine,@function +bad_leaked_to_subroutine: +// CHECK-LABEL: GS-PAUTH: authentication oracle found in function bad_leaked_to_subroutine, basic block {{[^,]+}}, at address +// CHECK-NEXT: The instruction is {{[0-9a-f]+}}: autia x0, x1 +// CHECK-NEXT: The 1 instructions that leak the affected registers are: +// CHECK-NEXT: 1. {{[0-9a-f]+}}: bl callee +// CHECK-NEXT: This happens in the following basic block: +// CHECK-NEXT: {{[0-9a-f]+}}: paciasp +// CHECK-NEXT: {{[0-9a-f]+}}: stp x29, x30, [sp, #-0x10]! +// CHECK-NEXT: {{[0-9a-f]+}}: mov x29, sp +// CHECK-NEXT: {{[0-9a-f]+}}: autia x0, x1 +// CHECK-NEXT: {{[0-9a-f]+}}: bl callee +// CHECK-NEXT: {{[0-9a-f]+}}: ldr x2, [x0] +// CHECK-NEXT: {{[0-9a-f]+}}: ldp x29, x30, [sp], #0x10 +// CHECK-NEXT: {{[0-9a-f]+}}: autiasp +// CHECK-NEXT: {{[0-9a-f]+}}: ret + paciasp + stp x29, x30, [sp, #-16]! + mov x29, sp + + autia x0, x1 + bl callee + ldr x2, [x0] + + ldp x29, x30, [sp], #16 + autiasp + ret + .size bad_leaked_to_subroutine, .-bad_leaked_to_subroutine + + .globl bad_unknown_usage_read + .type bad_unknown_usage_read,@function +bad_unknown_usage_read: +// CHECK-LABEL: GS-PAUTH: authentication oracle found in function bad_unknown_usage_read, basic block {{[^,]+}}, at address +// CHECK-NEXT: The instruction is {{[0-9a-f]+}}: autia x0, x1 +// CHECK-NEXT: The 1 instructions that leak the affected registers are: +// CHECK-NEXT: 1. {{[0-9a-f]+}}: mul x3, x0, x1 +// CHECK-NEXT: This happens in the following basic block: +// CHECK-NEXT: {{[0-9a-f]+}}: autia x0, x1 +// CHECK-NEXT: {{[0-9a-f]+}}: mul x3, x0, x1 +// CHECK-NEXT: {{[0-9a-f]+}}: ldr x2, [x0] +// CHECK-NEXT: {{[0-9a-f]+}}: ret + autia x0, x1 + // Registers are not accessible to an attacker under Pointer + // Authentication threat model, until spilled to memory. + // Thus, reporting the below MUL instruction is a false positive, since + // the next LDR instruction prevents any possible spilling of x3 unless + // the authentication succeeded. Though, rejecting anything except for + // a closed list of instruction types is the intended behavior of the + // analysis, so this false positive is by design. + mul x3, x0, x1 + ldr x2, [x0] + ret + .size bad_unknown_usage_read, .-bad_unknown_usage_read + + .globl bad_store_to_memory_and_wait + .type bad_store_to_memory_and_wait,@function +bad_store_to_memory_and_wait: +// CHECK-LABEL: GS-PAUTH: authentication oracle found in function bad_store_to_memory_and_wait, basic block {{[^,]+}}, at address +// CHECK-NEXT: The instruction is {{[0-9a-f]+}}: autia x0, x1 +// CHECK-NEXT: The 1 instructions that leak the affected registers are: +// CHECK-NEXT: 1. {{[0-9a-f]+}}: str x0, [x3] + autia x0, x1 + cbz x3, 2f + str x0, [x3] +1: + // The thread performs a time-consuming computation while the result of + // authentication is accessible in memory. + nop +2: + ldr x2, [x0] + ret + .size bad_store_to_memory_and_wait, .-bad_store_to_memory_and_wait + +// FIXME: Known false negative: if no return instruction is reachable from a +// program point (this probably implies an infinite loop), such +// instruction cannot be detected as an authentication oracle. + .globl bad_store_to_memory_and_hang + .type bad_store_to_memory_and_hang,@function +bad_store_to_memory_and_hang: +// CHECK-NOT: bad_store_to_memory_and_hang + autia x0, x1 + cbz x3, 2f + str x0, [x3] +1: + // The thread loops indefinitely while the result of authentication + // is accessible in memory. + b 1b +2: + ldr x2, [x0] + ret + .size bad_store_to_memory_and_hang, .-bad_store_to_memory_and_hang + + .globl bad_unknown_usage_subreg_read + .type bad_unknown_usage_subreg_read,@function +bad_unknown_usage_subreg_read: +// CHECK-LABEL: GS-PAUTH: authentication oracle found in function bad_unknown_usage_subreg_read, basic block {{[^,]+}}, at address +// CHECK-NEXT: The instruction is {{[0-9a-f]+}}: autia x0, x1 +// CHECK-NEXT: The 1 instructions that leak the affected registers are: +// CHECK-NEXT: 1. {{[0-9a-f]+}}: mul w3, w0, w1 +// CHECK-NEXT: This happens in the following basic block: +// CHECK-NEXT: {{[0-9a-f]+}}: autia x0, x1 +// CHECK-NEXT: {{[0-9a-f]+}}: mul w3, w0, w1 +// CHECK-NEXT: {{[0-9a-f]+}}: ldr x2, [x0] +// CHECK-NEXT: {{[0-9a-f]+}}: ret + autia x0, x1 + mul w3, w0, w1 + ldr x2, [x0] + ret + .size bad_unknown_usage_subreg_read, .-bad_unknown_usage_subreg_read + + .globl bad_unknown_usage_update + .type bad_unknown_usage_update,@function +bad_unknown_usage_update: +// CHECK-LABEL: GS-PAUTH: authentication oracle found in function bad_unknown_usage_update, basic block {{[^,]+}}, at address +// CHECK-NEXT: The instruction is {{[0-9a-f]+}}: autia x0, x1 +// CHECK-NEXT: The 1 instructions that leak the affected registers are: +// CHECK-NEXT: 1. {{[0-9a-f]+}}: movk x0, #0x2a, lsl #16 +// CHECK-NEXT: This happens in the following basic block: +// CHECK-NEXT: {{[0-9a-f]+}}: autia x0, x1 +// CHECK-NEXT: {{[0-9a-f]+}}: movk x0, #0x2a, lsl #16 +// CHECK-NEXT: {{[0-9a-f]+}}: ldr x2, [x0] +// CHECK-NEXT: {{[0-9a-f]+}}: ret + autia x0, x1 + movk x0, #42, lsl #16 // does not overwrite x0 completely + ldr x2, [x0] + ret + .size bad_unknown_usage_update, .-bad_unknown_usage_update + + .globl good_overwrite_with_constant + .type good_overwrite_with_constant,@function +good_overwrite_with_constant: +// CHECK-NOT: good_overwrite_with_constant + autia x0, x1 + mov x0, #42 + ret + .size good_overwrite_with_constant, .-good_overwrite_with_constant + +// Overwriting sensitive data by instructions with unmodelled side-effects is +// explicitly rejected, even though this particular MRS is safe. + .globl bad_overwrite_with_side_effects + .type bad_overwrite_with_side_effects,@function +bad_overwrite_with_side_effects: +// CHECK-LABEL: GS-PAUTH: authentication oracle found in function bad_overwrite_with_side_effects, basic block {{[^,]+}}, at address +// CHECK-NEXT: The instruction is {{[0-9a-f]+}}: autia x0, x1 +// CHECK-NEXT: The 0 instructions that leak the affected registers are: + autia x0, x1 + mrs x0, CTR_EL0 + ret + .size bad_overwrite_with_side_effects, .-bad_overwrite_with_side_effects + +// Here the new value written by MUL to x0 is completely unrelated to the result +// of authentication, so this is a false positive. +// FIXME: Can/should we generalize overwriting by constant to handle such cases? + .globl good_unknown_overwrite + .type good_unknown_overwrite,@function +good_unknown_overwrite: +// CHECK-LABEL: GS-PAUTH: authentication oracle found in function good_unknown_overwrite, basic block {{[^,]+}}, at address +// CHECK-NEXT: The instruction is {{[0-9a-f]+}}: autia x0, x1 +// CHECK-NEXT: The 0 instructions that leak the affected registers are: + autia x0, x1 + mul x0, x1, x2 + ret + .size good_unknown_overwrite, .-good_unknown_overwrite + +// This is a false positive: when a general-purpose register is written to as +// a 32-bit register, its top 32 bits are zeroed, but according to LLVM +// representation, the instruction only overwrites the Wn register. + .globl good_wreg_overwrite + .type good_wreg_overwrite,@function +good_wreg_overwrite: +// CHECK-LABEL: GS-PAUTH: authentication oracle found in function good_wreg_overwrite, basic block {{[^,]+}}, at address +// CHECK-NEXT: The instruction is {{[0-9a-f]+}}: autia x0, x1 + autia x0, x1 + mov w0, #42 + ret + .size good_wreg_overwrite, .-good_wreg_overwrite + + .globl good_address_arith + .type good_address_arith,@function +good_address_arith: +// CHECK-NOT: good_address_arith + autia x0, x1 + + add x1, x0, #8 + sub x2, x1, #16 + mov x3, x2 + + ldr x4, [x3] + mov x0, #0 + mov x1, #0 + mov x2, #0 + + ret + .size good_address_arith, .-good_address_arith + + .globl good_ret_multi_bb + .type good_ret_multi_bb,@function +good_ret_multi_bb: +// CHECK-NOT: good_ret_multi_bb + autia x0, x1 + cbz x1, 1f + nop +1: + ret x0 + .size good_ret_multi_bb, .-good_ret_multi_bb + + .globl good_call_multi_bb + .type good_call_multi_bb,@function +good_call_multi_bb: +// CHECK-NOT: good_call_multi_bb + paciasp + stp x29, x30, [sp, #-16]! + mov x29, sp + + autia x0, x1 + cbz x1, 1f + nop +1: + blr x0 + cbz x1, 2f + nop +2: + ldp x29, x30, [sp], #16 + autiasp + ret + .size good_call_multi_bb, .-good_call_multi_bb + + .globl good_branch_multi_bb + .type good_branch_multi_bb,@function +good_branch_multi_bb: +// CHECK-NOT: good_branch_multi_bb + autia x0, x1 + cbz x1, 1f + nop +1: + br x0 + .size good_branch_multi_bb, .-good_branch_multi_bb + + .globl good_load_other_reg_multi_bb + .type good_load_other_reg_multi_bb,@function +good_load_other_reg_multi_bb: +// CHECK-NOT: good_load_other_reg_multi_bb + autia x0, x1 + cbz x1, 1f + nop +1: + ldr x2, [x0] + cbz x1, 2f + nop +2: + ret + .size good_load_other_reg_multi_bb, .-good_load_other_reg_multi_bb + + .globl good_load_same_reg_multi_bb + .type good_load_same_reg_multi_bb,@function +good_load_same_reg_multi_bb: +// CHECK-NOT: good_load_same_reg_multi_bb + autia x0, x1 + cbz x1, 1f + nop +1: + ldr x0, [x0] + cbz x1, 2f + nop +2: + ret + .size good_load_same_reg_multi_bb, .-good_load_same_reg_multi_bb + + .globl good_explicit_check_multi_bb + .type good_explicit_check_multi_bb,@function +good_explicit_check_multi_bb: +// CHECK-NOT: good_explicit_check_multi_bb + autia x0, x1 + cbz x1, 1f + nop +1: + eor x16, x0, x0, lsl #1 + tbz x16, #62, 2f + brk 0x1234 +2: + cbz x1, 3f + nop +3: + ret + .size good_explicit_check_multi_bb, .-good_explicit_check_multi_bb + + .globl bad_unchecked_multi_bb + .type bad_unchecked_multi_bb,@function +bad_unchecked_multi_bb: +// CHECK-LABEL: GS-PAUTH: authentication oracle found in function bad_unchecked_multi_bb, basic block {{[^,]+}}, at address +// CHECK-NEXT: The instruction is {{[0-9a-f]+}}: autia x0, x1 +// CHECK-NEXT: The 0 instructions that leak the affected registers are: + autia x0, x1 + cbz x1, 1f + ldr x2, [x0] +1: + ret + .size bad_unchecked_multi_bb, .-bad_unchecked_multi_bb + + .globl bad_leaked_to_subroutine_multi_bb + .type bad_leaked_to_subroutine_multi_bb,@function +bad_leaked_to_subroutine_multi_bb: +// CHECK-LABEL: GS-PAUTH: authentication oracle found in function bad_leaked_to_subroutine_multi_bb, basic block {{[^,]+}}, at address +// CHECK-NEXT: The instruction is {{[0-9a-f]+}}: autia x0, x1 +// CHECK-NEXT: The 1 instructions that leak the affected registers are: +// CHECK-NEXT: 1. {{[0-9a-f]+}}: bl callee + paciasp + stp x29, x30, [sp, #-16]! + mov x29, sp + + autia x0, x1 + cbz x1, 1f + ldr x2, [x0] +1: + bl callee + ldr x2, [x0] + + ldp x29, x30, [sp], #16 + autiasp + ret + .size bad_leaked_to_subroutine_multi_bb, .-bad_leaked_to_subroutine_multi_bb + + .globl bad_unknown_usage_read_multi_bb + .type bad_unknown_usage_read_multi_bb,@function +bad_unknown_usage_read_multi_bb: +// CHECK-LABEL: GS-PAUTH: authentication oracle found in function bad_unknown_usage_read_multi_bb, basic block {{[^,]+}}, at address +// CHECK-NEXT: The instruction is {{[0-9a-f]+}}: autia x0, x1 +// CHECK-NEXT: The 1 instructions that leak the affected registers are: +// CHECK-NEXT: 1. {{[0-9a-f]+}}: mul x3, x0, x1 + autia x0, x1 + cbz x3, 1f + mul x3, x0, x1 +1: + ldr x2, [x0] + ret + .size bad_unknown_usage_read_multi_bb, .-bad_unknown_usage_read_multi_bb + + .globl bad_unknown_usage_subreg_read_multi_bb + .type bad_unknown_usage_subreg_read_multi_bb,@function +bad_unknown_usage_subreg_read_multi_bb: +// CHECK-LABEL: GS-PAUTH: authentication oracle found in function bad_unknown_usage_subreg_read_multi_bb, basic block {{[^,]+}}, at address +// CHECK-NEXT: The instruction is {{[0-9a-f]+}}: autia x0, x1 +// CHECK-NEXT: The 1 instructions that leak the affected registers are: +// CHECK-NEXT: 1. {{[0-9a-f]+}}: mul w3, w0, w1 + autia x0, x1 + cbz x3, 1f + mul w3, w0, w1 +1: + ldr x2, [x0] + ret + .size bad_unknown_usage_subreg_read_multi_bb, .-bad_unknown_usage_subreg_read_multi_bb + + .globl bad_unknown_usage_update_multi_bb + .type bad_unknown_usage_update_multi_bb,@function +bad_unknown_usage_update_multi_bb: +// CHECK-LABEL: GS-PAUTH: authentication oracle found in function bad_unknown_usage_update_multi_bb, basic block {{[^,]+}}, at address +// CHECK-NEXT: The instruction is {{[0-9a-f]+}}: autia x0, x1 +// CHECK-NEXT: The 1 instructions that leak the affected registers are: +// CHECK-NEXT: 1. {{[0-9a-f]+}}: movk x0, #0x2a, lsl #16 + autia x0, x1 + cbz x3, 1f + movk x0, #42, lsl #16 // does not overwrite x0 completely +1: + ldr x2, [x0] + ret + .size bad_unknown_usage_update_multi_bb, .-bad_unknown_usage_update_multi_bb + + .globl good_overwrite_with_constant_multi_bb + .type good_overwrite_with_constant_multi_bb,@function +good_overwrite_with_constant_multi_bb: +// CHECK-NOT: good_overwrite_with_constant_multi_bb + autia x0, x1 + cbz x3, 1f +1: + mov x0, #42 + ret + .size good_overwrite_with_constant_multi_bb, .-good_overwrite_with_constant_multi_bb + + .globl good_address_arith_multi_bb + .type good_address_arith_multi_bb,@function +good_address_arith_multi_bb: +// CHECK-NOT: good_address_arith_multi_bb + autia x0, x1 + cbz x3, 1f + + add x1, x0, #8 + sub x2, x1, #16 + mov x0, x2 + + mov x1, #0 + mov x2, #0 +1: + ldr x3, [x0] + ret + .size good_address_arith_multi_bb, .-good_address_arith_multi_bb + +// FIXME: Most *_nocfg test cases contain paciasp+autiasp instructions even if +// LR is not spilled - this is a workaround for RET instructions being +// reported as non-protected, because LR state is reset at every label. + + .globl good_ret_nocfg + .type good_ret_nocfg,@function +good_ret_nocfg: +// CHECK-NOT: good_ret_nocfg + adr x2, 1f + br x2 +1: + autia x0, x1 + + ret x0 + .size good_ret_nocfg, .-good_ret_nocfg + + .globl good_call_nocfg + .type good_call_nocfg,@function +good_call_nocfg: +// CHECK-NOT: good_call_nocfg + paciasp + stp x29, x30, [sp, #-16]! + mov x29, sp + + adr x2, 1f + br x2 +1: + autia x0, x1 + blr x0 + + ldp x29, x30, [sp], #16 + autiasp + ret + .size good_call_nocfg, .-good_call_nocfg + + .globl good_branch_nocfg + .type good_branch_nocfg,@function +good_branch_nocfg: +// CHECK-NOT: good_branch_nocfg + adr x2, 1f + br x2 +1: + autia x0, x1 + br x0 + .size good_branch_nocfg, .-good_branch_nocfg + + .globl good_load_other_reg_nocfg + .type good_load_other_reg_nocfg,@function +good_load_other_reg_nocfg: +// CHECK-NOT: good_load_other_reg_nocfg + paciasp + adr x2, 1f + br x2 +1: + autia x0, x1 + ldr x2, [x0] + + autiasp + ret + .size good_load_other_reg_nocfg, .-good_load_other_reg_nocfg + + .globl good_load_same_reg_nocfg + .type good_load_same_reg_nocfg,@function +good_load_same_reg_nocfg: +// CHECK-NOT: good_load_same_reg_nocfg + paciasp + adr x2, 1f + br x2 +1: + autia x0, x1 + ldr x0, [x0] + + autiasp + ret + .size good_load_same_reg_nocfg, .-good_load_same_reg_nocfg + +// FIXME: Multi-instruction checker sequences are not supported without CFG. + + .globl bad_unchecked_nocfg + .type bad_unchecked_nocfg,@function +bad_unchecked_nocfg: +// CHECK-LABEL: GS-PAUTH: authentication oracle found in function bad_unchecked_nocfg, at address +// CHECK-NEXT: The instruction is {{[0-9a-f]+}}: autia x0, x1 +// CHECK-NEXT: The 0 instructions that leak the affected registers are: + paciasp + adr x2, 1f + br x2 +1: + autia x0, x1 + + autiasp + ret + .size bad_unchecked_nocfg, .-bad_unchecked_nocfg + + .globl bad_leaked_to_subroutine_nocfg + .type bad_leaked_to_subroutine_nocfg,@function +bad_leaked_to_subroutine_nocfg: +// CHECK-LABEL: GS-PAUTH: authentication oracle found in function bad_leaked_to_subroutine_nocfg, at address +// CHECK-NEXT: The instruction is {{[0-9a-f]+}}: autia x0, x1 +// CHECK-NEXT: The 1 instructions that leak the affected registers are: +// CHECK-NEXT: 1. {{[0-9a-f]+}}: bl callee # Offset: 24 + paciasp + stp x29, x30, [sp, #-16]! + mov x29, sp + + adr x2, 1f + br x2 +1: + autia x0, x1 + bl callee + ldr x2, [x0] + + ldp x29, x30, [sp], #16 + autiasp + ret + .size bad_leaked_to_subroutine_nocfg, .-bad_leaked_to_subroutine_nocfg + + .globl bad_unknown_usage_read_nocfg + .type bad_unknown_usage_read_nocfg,@function +bad_unknown_usage_read_nocfg: +// CHECK-LABEL: GS-PAUTH: authentication oracle found in function bad_unknown_usage_read_nocfg, at address +// CHECK-NEXT: The instruction is {{[0-9a-f]+}}: autia x0, x1 +// CHECK-NEXT: The 1 instructions that leak the affected registers are: +// CHECK-NEXT: 1. {{[0-9a-f]+}}: mul x3, x0, x1 + paciasp + adr x2, 1f + br x2 +1: + autia x0, x1 + mul x3, x0, x1 + ldr x2, [x0] + + autiasp + ret + .size bad_unknown_usage_read_nocfg, .-bad_unknown_usage_read_nocfg + + .globl bad_unknown_usage_subreg_read_nocfg + .type bad_unknown_usage_subreg_read_nocfg,@function +bad_unknown_usage_subreg_read_nocfg: +// CHECK-LABEL: GS-PAUTH: authentication oracle found in function bad_unknown_usage_subreg_read_nocfg, at address +// CHECK-NEXT: The instruction is {{[0-9a-f]+}}: autia x0, x1 +// CHECK-NEXT: The 1 instructions that leak the affected registers are: +// CHECK-NEXT: 1. {{[0-9a-f]+}}: mul w3, w0, w1 + paciasp + adr x2, 1f + br x2 +1: + autia x0, x1 + mul w3, w0, w1 + ldr x2, [x0] + + autiasp + ret + .size bad_unknown_usage_subreg_read_nocfg, .-bad_unknown_usage_subreg_read_nocfg + + .globl bad_unknown_usage_update_nocfg + .type bad_unknown_usage_update_nocfg,@function +bad_unknown_usage_update_nocfg: +// CHECK-LABEL: GS-PAUTH: authentication oracle found in function bad_unknown_usage_update_nocfg, at address +// CHECK-NEXT: The instruction is {{[0-9a-f]+}}: autia x0, x1 +// CHECK-NEXT: The 1 instructions that leak the affected registers are: +// CHECK-NEXT: 1. {{[0-9a-f]+}}: movk x0, #0x2a, lsl #16 + paciasp + adr x2, 1f + br x2 +1: + autia x0, x1 + movk x0, #42, lsl #16 // does not overwrite x0 completely + ldr x2, [x0] + + autiasp + ret + .size bad_unknown_usage_update_nocfg, .-bad_unknown_usage_update_nocfg + + .globl good_overwrite_with_constant_nocfg + .type good_overwrite_with_constant_nocfg,@function +good_overwrite_with_constant_nocfg: +// CHECK-NOT: good_overwrite_with_constant_nocfg + paciasp + adr x2, 1f + br x2 +1: + autia x0, x1 + mov x0, #42 + + autiasp + ret + .size good_overwrite_with_constant_nocfg, .-good_overwrite_with_constant_nocfg + + .globl good_address_arith_nocfg + .type good_address_arith_nocfg,@function +good_address_arith_nocfg: +// CHECK-NOT: good_address_arith_nocfg + paciasp + adr x2, 1f + br x2 +1: + autia x0, x1 + add x1, x0, #8 + sub x2, x1, #16 + mov x3, x2 + + ldr x4, [x3] + mov x0, #0 + mov x1, #0 + mov x2, #0 + + autiasp + ret + .size good_address_arith_nocfg, .-good_address_arith_nocfg + + .globl good_explicit_check_unrelated_reg + .type good_explicit_check_unrelated_reg,@function +good_explicit_check_unrelated_reg: +// CHECK-LABEL: GS-PAUTH: authentication oracle found in function good_explicit_check_unrelated_reg, basic block {{[^,]+}}, at address + // FIXME: The below instruction is not an authentication oracle + autia x2, x3 // One of possible execution paths after this instruction + // ends at BRK below, thus BRK used as a trap instruction + // should formally "check everything" not to introduce + // false-positive here. + autia x0, x1 + eor x16, x0, x0, lsl #1 + tbz x16, #62, 1f + brk 0x1234 +1: + ldr x4, [x2] // Right before this instruction X2 is checked - this + // should be propagated to the basic block ending with + // TBZ instruction above. + ret + .size good_explicit_check_unrelated_reg, .-good_explicit_check_unrelated_reg + +// The last BB (in layout order) is processed first by the data-flow analysis. +// Its initial state is usually filled in a special way (because it ends with +// `ret` instruction), and then affects the state propagated to the other BBs +// Thus, the case of the last instruction in a function being a jump somewhere +// in the middle is special. + + .globl good_no_ret_from_last_bb + .type good_no_ret_from_last_bb,@function +good_no_ret_from_last_bb: +// CHECK-NOT: good_no_ret_from_last_bb + paciasp + autiasp // authenticates LR + b 2f +1: + ret +2: + b 1b // LR is dereferenced by `ret`, which is executed next + .size good_no_ret_from_last_bb, .-good_no_ret_from_last_bb + + .globl bad_no_ret_from_last_bb + .type bad_no_ret_from_last_bb,@function +bad_no_ret_from_last_bb: +// CHECK-LABEL: GS-PAUTH: authentication oracle found in function bad_no_ret_from_last_bb, basic block {{[^,]+}}, at address +// CHECK-NEXT: The instruction is {{[0-9a-f]+}}: autiasp +// CHECK-NEXT: The 0 instructions that leak the affected registers are: + paciasp + autiasp // authenticates LR + b 2f +1: + ret x0 +2: + b 1b // X0 (but not LR) is dereferenced by `ret x0` + .size bad_no_ret_from_last_bb, .-bad_no_ret_from_last_bb + +// Test that combined auth+something instructions are not reported as +// authentication oracles. + + .globl inst_retaa + .type inst_retaa,@function +inst_retaa: +// CHECK-NOT: inst_retaa + paciasp + retaa + .size inst_retaa, .-inst_retaa + + .globl inst_blraa + .type inst_blraa,@function +inst_blraa: +// CHECK-NOT: inst_blraa + paciasp + stp x29, x30, [sp, #-16]! + mov x29, sp + + blraa x0, x1 + + ldp x29, x30, [sp], #16 + retaa + .size inst_blraa, .-inst_blraa + + .globl inst_braa + .type inst_braa,@function +inst_braa: +// CHECK-NOT: inst_braa + braa x0, x1 + .size inst_braa, .-inst_braa + + .globl inst_ldraa_no_wb + .type inst_ldraa_no_wb,@function +inst_ldraa_no_wb: +// CHECK-NOT: inst_ldraa_no_wb + ldraa x1, [x0] + ret + .size inst_ldraa_no_wb, .-inst_ldraa_no_wb + + .globl inst_ldraa_wb + .type inst_ldraa_wb,@function +inst_ldraa_wb: +// CHECK-NOT: inst_ldraa_wb + ldraa x1, [x0]! + ret + .size inst_ldraa_wb, .-inst_ldraa_wb + + .globl main + .type main,@function +main: + mov x0, 0 + ret + .size main, .-main diff --git a/external/llvm-project/bolt/test/binary-analysis/AArch64/gs-pauth-debug-output.s b/external/llvm-project/bolt/test/binary-analysis/AArch64/gs-pauth-debug-output.s index 82494d834a15..fbb96a63d41e 100644 --- a/external/llvm-project/bolt/test/binary-analysis/AArch64/gs-pauth-debug-output.s +++ b/external/llvm-project/bolt/test/binary-analysis/AArch64/gs-pauth-debug-output.s @@ -113,7 +113,7 @@ simple: // CHECK-EMPTY: // PAUTH-NEXT: Found sign inst: 00000000: paciasp # DataflowSrcSafetyAnalysis: src-state // PAUTH-NEXT: Signed reg: LR -// PAUTH-NEXT: TrustedRegs: LR W30 W30_HI +// PAUTH-NEXT: TrustedRegs: LR W30 W30_HI{{[ \t]*$}} // PAUTH-NEXT: Found call inst: 00000000: blr x0 # DataflowSrcSafetyAnalysis: src-state // PAUTH-NEXT: Call destination reg: X0 // PAUTH-NEXT: SafeToDerefRegs: W0 X0 W0_HI{{[ \t]*$}} @@ -220,10 +220,10 @@ nocfg: // CHECK-EMPTY: // PAUTH-NEXT: Found call inst: 00000000: br x0 # UNKNOWN CONTROL FLOW # Offset: 4 # CFGUnawareSrcSafetyAnalysis: src-state // PAUTH-NEXT: Call destination reg: X0 -// PAUTH-NEXT: SafeToDerefRegs: LR W0 W30 X0 W0_HI W30_HI +// PAUTH-NEXT: SafeToDerefRegs: LR W0 W30 X0 W0_HI W30_HI{{[ \t]*$}} // CHECK-NEXT: Found RET inst: 00000000: ret # Offset: 8 # CFGUnawareSrcSafetyAnalysis: src-state // CHECK-NEXT: RetReg: LR -// CHECK-NEXT: SafeToDerefRegs: +// CHECK-NEXT: SafeToDerefRegs:{{[ \t]*$}} // CHECK-EMPTY: // CHECK-NEXT: Running detailed src register safety analysis... // CHECK-NEXT: SrcSafetyAnalysis::ComputeNext( adr x0, __ENTRY_nocfg@0x[[ENTRY_ADDR]], src-state) @@ -251,6 +251,116 @@ nocfg: // CHECK-EMPTY: // CHECK-NEXT: Attaching clobbering info to: 00000000: ret # Offset: 8 # CFGUnawareSrcSafetyAnalysis: src-state + .globl auth_oracle + .type auth_oracle,@function +auth_oracle: + autia x0, x1 + ret + .size auth_oracle, .-auth_oracle + +// CHECK-LABEL:Analyzing function auth_oracle, AllocatorId = 1 +// CHECK-NEXT: Binary Function "auth_oracle" { +// CHECK-NEXT: Number : 4 +// CHECK-NEXT: State : CFG constructed +// ... +// CHECK: BB Layout : [[BB0:[0-9a-zA-Z.]+]] +// CHECK-NEXT: } +// CHECK-NEXT: [[BB0]] (2 instructions, align : 1) +// CHECK-NEXT: Entry Point +// CHECK-NEXT: 00000000: autia x0, x1 +// CHECK-NEXT: 00000004: ret +// CHECK-EMPTY: +// CHECK-NEXT: DWARF CFI Instructions: +// CHECK-NEXT: +// CHECK-NEXT: End of Function "auth_oracle" +// CHECK-EMPTY: +// CHECK-NEXT: Running src register safety analysis... +// ... +// CHECK: After src register safety analysis: +// CHECK-NEXT: Binary Function "auth_oracle" { +// ... +// CHECK: End of Function "auth_oracle" +// ... +// PAUTH: Running dst register safety analysis... +// PAUTH-NEXT: DstSafetyAnalysis::ComputeNext( ret x30, dst-state) +// PAUTH-NEXT: .. result: (dst-state) +// PAUTH-NEXT: DstSafetyAnalysis::ComputeNext( autia x0, x1, dst-state) +// PAUTH-NEXT: .. result: (dst-state) +// PAUTH-NEXT: After dst register safety analysis: +// PAUTH-NEXT: Binary Function "auth_oracle" { +// PAUTH-NEXT: Number : 4 +// PAUTH-NEXT: State : CFG constructed +// ... +// PAUTH: BB Layout : [[BB0]] +// PAUTH-NEXT: } +// PAUTH-NEXT: [[BB0]] (2 instructions, align : 1) +// PAUTH-NEXT: Entry Point +// PAUTH-NEXT: 00000000: autia x0, x1 # DataflowDstSafetyAnalysis: dst-state +// PAUTH-NEXT: 00000004: ret # DataflowDstSafetyAnalysis: dst-state +// PAUTH-EMPTY: +// PAUTH-NEXT: DWARF CFI Instructions: +// PAUTH-NEXT: +// PAUTH-NEXT: End of Function "auth_oracle" +// PAUTH-EMPTY: +// PAUTH-NEXT: Found auth inst: 00000000: autia x0, x1 # DataflowDstSafetyAnalysis: dst-state +// PAUTH-NEXT: Authenticated reg: X0 +// PAUTH-NEXT: safe output registers: LR W30 W30_HI{{[ \t]*$}} +// PAUTH-EMPTY: +// PAUTH-NEXT: Running detailed dst register safety analysis... +// PAUTH-NEXT: DstSafetyAnalysis::ComputeNext( ret x30, dst-state) +// PAUTH-NEXT: .. result: (dst-state) +// PAUTH-NEXT: DstSafetyAnalysis::ComputeNext( autia x0, x1, dst-state) +// PAUTH-NEXT: .. result: (dst-state) +// PAUTH-NEXT: After detailed dst register safety analysis: +// PAUTH-NEXT: Binary Function "auth_oracle" { +// PAUTH-NEXT: Number : 4 +// PAUTH-NEXT: State : CFG constructed +// ... +// PAUTH: BB Layout : [[BB0]] +// PAUTH-NEXT: } +// PAUTH-NEXT: [[BB0]] (2 instructions, align : 1) +// PAUTH-NEXT: Entry Point +// PAUTH-NEXT: 00000000: autia x0, x1 # DataflowDstSafetyAnalysis: dst-state +// PAUTH-NEXT: 00000004: ret # DataflowDstSafetyAnalysis: dst-state +// PAUTH-EMPTY: +// PAUTH-NEXT: DWARF CFI Instructions: +// PAUTH-NEXT: +// PAUTH-NEXT: End of Function "auth_oracle" +// PAUTH-EMPTY: +// PAUTH-NEXT: Attaching leakage info to: 00000000: autia x0, x1 # DataflowDstSafetyAnalysis: dst-state + +// Gadget scanner should not crash on CFI instructions, including when debug-printing them. +// Note that the particular debug output is not checked, but BOLT should be +// compiled with assertions enabled to support -debug-only argument. + + .globl cfi_inst_df + .type cfi_inst_df,@function +cfi_inst_df: + .cfi_startproc + sub sp, sp, #16 + .cfi_def_cfa_offset 16 + add sp, sp, #16 + .cfi_def_cfa_offset 0 + ret + .size cfi_inst_df, .-cfi_inst_df + .cfi_endproc + + .globl cfi_inst_nocfg + .type cfi_inst_nocfg,@function +cfi_inst_nocfg: + .cfi_startproc + sub sp, sp, #16 + .cfi_def_cfa_offset 16 + + adr x0, 1f + br x0 +1: + add sp, sp, #16 + .cfi_def_cfa_offset 0 + ret + .size cfi_inst_nocfg, .-cfi_inst_nocfg + .cfi_endproc + // CHECK-LABEL:Analyzing function main, AllocatorId = 1 .globl main .type main,@function diff --git a/external/llvm-project/bolt/test/link_fdata.py b/external/llvm-project/bolt/test/link_fdata.py index 5a9752068bb9..898dce8e3fb5 100755 --- a/external/llvm-project/bolt/test/link_fdata.py +++ b/external/llvm-project/bolt/test/link_fdata.py @@ -36,9 +36,9 @@ fdata_pat = re.compile(r"([01].*) (?P\d+) (?P\d+)") # Pre-aggregated profile: -# {T|S|E|B|F|f} [] [] [] +# {T|R|S|E|B|F|f|r} [] [] [] # : [:] -preagg_pat = re.compile(r"(?P[TSBFf]) (?P.*)") +preagg_pat = re.compile(r"(?P[TRSBFfr]) (?P.*)") # No-LBR profile: # diff --git a/external/llvm-project/bolt/test/lit.local.cfg b/external/llvm-project/bolt/test/lit.local.cfg index d5a6849b27a7..8a61d11f5825 100644 --- a/external/llvm-project/bolt/test/lit.local.cfg +++ b/external/llvm-project/bolt/test/lit.local.cfg @@ -1,6 +1,11 @@ -host_linux_triple = config.target_triple.split("-")[0] + "-unknown-linux-gnu" +host_triple = config.target_triple + +# Force triple on non-linux hosts to get ELF binaries on all platforms. +if not "linux" in host_triple: + host_triple = host_triple.split("-")[0] + "-unknown-linux-gnu" + common_linker_flags = "-fuse-ld=lld -Wl,--unresolved-symbols=ignore-all -Wl,--build-id=none -pie" -flags = f"--target={host_linux_triple} -fPIE {common_linker_flags}" +flags = f"--target={host_triple} -fPIE {common_linker_flags}" config.substitutions.insert(0, ("%cflags", f"%cflags {flags}")) config.substitutions.insert(0, ("%cxxflags", f"%cxxflags {flags}")) diff --git a/external/llvm-project/bolt/test/perf2bolt/AArch64/perf2bolt-spe.test b/external/llvm-project/bolt/test/perf2bolt/AArch64/perf2bolt-spe.test new file mode 100644 index 000000000000..91f5c857fbab --- /dev/null +++ b/external/llvm-project/bolt/test/perf2bolt/AArch64/perf2bolt-spe.test @@ -0,0 +1,12 @@ +## Check that Arm SPE mode is available on AArch64. + +REQUIRES: system-linux,perf,target=aarch64{{.*}} + +RUN: %clang %cflags %p/../../Inputs/asm_foo.s %p/../../Inputs/asm_main.c -o %t.exe + +RUN: perf record -e cycles -q -o %t.perf.data -- %t.exe 2> /dev/null + +RUN: (perf2bolt -p %t.perf.data -o %t.perf.boltdata --spe %t.exe 2> /dev/null; exit 0) | FileCheck %s --check-prefix=CHECK-SPE-LBR + +CHECK-SPE-LBR: PERF2BOLT: parse SPE branch events in LBR-format + diff --git a/external/llvm-project/bolt/test/perf2bolt/X86/perf2bolt-spe.test b/external/llvm-project/bolt/test/perf2bolt/X86/perf2bolt-spe.test new file mode 100644 index 000000000000..101bd3789a18 --- /dev/null +++ b/external/llvm-project/bolt/test/perf2bolt/X86/perf2bolt-spe.test @@ -0,0 +1,9 @@ +## Check that Arm SPE mode is unavailable on X86. + +REQUIRES: system-linux,x86_64-linux + +RUN: %clang %cflags %p/../../Inputs/asm_foo.s %p/../../Inputs/asm_main.c -o %t.exe +RUN: touch %t.empty.perf.data +RUN: not perf2bolt -p %t.empty.perf.data -o %t.perf.boltdata --spe --pa %t.exe 2>&1 | FileCheck %s + +CHECK: perf2bolt{{.*}} -spe is available only on AArch64. diff --git a/external/llvm-project/bolt/tools/driver/llvm-bolt.cpp b/external/llvm-project/bolt/tools/driver/llvm-bolt.cpp index b9836c2397b6..cf1b31f8c0c6 100644 --- a/external/llvm-project/bolt/tools/driver/llvm-bolt.cpp +++ b/external/llvm-project/bolt/tools/driver/llvm-bolt.cpp @@ -237,6 +237,13 @@ int main(int argc, char **argv) { if (Error E = RIOrErr.takeError()) report_error(opts::InputFilename, std::move(E)); RewriteInstance &RI = *RIOrErr.get(); + + if (opts::AggregateOnly && !RI.getBinaryContext().isAArch64() && + opts::ArmSPE) { + errs() << ToolName << ": -spe is available only on AArch64.\n"; + exit(1); + } + if (!opts::PerfData.empty()) { if (!opts::AggregateOnly) { errs() << ToolName diff --git a/external/llvm-project/bolt/unittests/Profile/CMakeLists.txt b/external/llvm-project/bolt/unittests/Profile/CMakeLists.txt index e0aa0926b49c..ce01c6c4b949 100644 --- a/external/llvm-project/bolt/unittests/Profile/CMakeLists.txt +++ b/external/llvm-project/bolt/unittests/Profile/CMakeLists.txt @@ -1,11 +1,25 @@ +set(LLVM_LINK_COMPONENTS + DebugInfoDWARF + Object + ${LLVM_TARGETS_TO_BUILD} + ) + add_bolt_unittest(ProfileTests DataAggregator.cpp + PerfSpeEvents.cpp DISABLE_LLVM_LINK_LLVM_DYLIB ) target_link_libraries(ProfileTests PRIVATE + LLVMBOLTCore LLVMBOLTProfile + LLVMTargetParser + LLVMTestingSupport ) +foreach (tgt ${BOLT_TARGETS_TO_BUILD}) + string(TOUPPER "${tgt}" upper) + target_compile_definitions(ProfileTests PRIVATE "${upper}_AVAILABLE") +endforeach() diff --git a/external/llvm-project/bolt/unittests/Profile/PerfSpeEvents.cpp b/external/llvm-project/bolt/unittests/Profile/PerfSpeEvents.cpp new file mode 100644 index 000000000000..8d023cd7b7e7 --- /dev/null +++ b/external/llvm-project/bolt/unittests/Profile/PerfSpeEvents.cpp @@ -0,0 +1,164 @@ +//===- bolt/unittests/Profile/PerfSpeEvents.cpp ---------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifdef AARCH64_AVAILABLE + +#include "bolt/Core/BinaryContext.h" +#include "bolt/Profile/DataAggregator.h" +#include "llvm/BinaryFormat/ELF.h" +#include "llvm/DebugInfo/DWARF/DWARFContext.h" +#include "llvm/Support/CommandLine.h" +#include "llvm/Support/TargetSelect.h" +#include "gtest/gtest.h" + +using namespace llvm; +using namespace llvm::bolt; +using namespace llvm::object; +using namespace llvm::ELF; + +namespace opts { +extern cl::opt ReadPerfEvents; +extern cl::opt ArmSPE; +} // namespace opts + +namespace llvm { +namespace bolt { + +/// Perform checks on perf SPE branch events. +struct PerfSpeEventsTestHelper : public testing::Test { + void SetUp() override { + initalizeLLVM(); + prepareElf(); + initializeBOLT(); + } + +protected: + using Trace = DataAggregator::Trace; + using TakenBranchInfo = DataAggregator::TakenBranchInfo; + + void initalizeLLVM() { + llvm::InitializeAllTargetInfos(); + llvm::InitializeAllTargetMCs(); + llvm::InitializeAllAsmParsers(); + llvm::InitializeAllDisassemblers(); + llvm::InitializeAllTargets(); + llvm::InitializeAllAsmPrinters(); + } + + void prepareElf() { + memcpy(ElfBuf, "\177ELF", 4); + ELF64LE::Ehdr *EHdr = reinterpret_cast(ElfBuf); + EHdr->e_ident[llvm::ELF::EI_CLASS] = llvm::ELF::ELFCLASS64; + EHdr->e_ident[llvm::ELF::EI_DATA] = llvm::ELF::ELFDATA2LSB; + EHdr->e_machine = llvm::ELF::EM_AARCH64; + MemoryBufferRef Source(StringRef(ElfBuf, sizeof(ElfBuf)), "ELF"); + ObjFile = cantFail(ObjectFile::createObjectFile(Source)); + } + + void initializeBOLT() { + Relocation::Arch = ObjFile->makeTriple().getArch(); + BC = cantFail(BinaryContext::createBinaryContext( + ObjFile->makeTriple(), std::make_shared(), + ObjFile->getFileName(), nullptr, /*IsPIC*/ false, + DWARFContext::create(*ObjFile), {llvm::outs(), llvm::errs()})); + ASSERT_FALSE(!BC); + } + + char ElfBuf[sizeof(typename ELF64LE::Ehdr)] = {}; + std::unique_ptr ObjFile; + std::unique_ptr BC; + + /// Helper function to export lists to show the mismatch. + void reportBrStackEventMismatch( + const std::vector> &Traces, + const std::vector> &ExpectedSamples) { + llvm::errs() << "Traces items: \n"; + for (const auto &[Trace, BI] : Traces) + llvm::errs() << "{" << Trace.Branch << ", " << Trace.From << "," + << Trace.To << ", " << BI.TakenCount << ", " + << BI.MispredCount << "}" << "\n"; + + llvm::errs() << "Expected items: \n"; + for (const auto &[Trace, BI] : ExpectedSamples) + llvm::errs() << "{" << Trace.Branch << ", " << Trace.From << ", " + << Trace.To << ", " << BI.TakenCount << ", " + << BI.MispredCount << "}" << "\n"; + } + + /// Parse and check SPE brstack as LBR. + void parseAndCheckBrstackEvents( + uint64_t PID, + const std::vector> &ExpectedSamples) { + DataAggregator DA(""); + DA.ParsingBuf = opts::ReadPerfEvents; + DA.BC = BC.get(); + DataAggregator::MMapInfo MMap; + DA.BinaryMMapInfo.insert(std::make_pair(PID, MMap)); + + DA.parseBranchEvents(); + + EXPECT_EQ(DA.Traces.size(), ExpectedSamples.size()); + if (DA.Traces.size() != ExpectedSamples.size()) + reportBrStackEventMismatch(DA.Traces, ExpectedSamples); + + const auto TracesBegin = DA.Traces.begin(); + const auto TracesEnd = DA.Traces.end(); + for (const auto &BI : ExpectedSamples) { + auto it = find_if(TracesBegin, TracesEnd, + [&BI](const auto &Tr) { return Tr.first == BI.first; }); + + EXPECT_NE(it, TracesEnd); + EXPECT_EQ(it->second.MispredCount, BI.second.MispredCount); + EXPECT_EQ(it->second.TakenCount, BI.second.TakenCount); + } + } +}; + +} // namespace bolt +} // namespace llvm + +TEST_F(PerfSpeEventsTestHelper, SpeBranchesWithBrstack) { + // Check perf input with SPE branch events as brstack format. + // Example collection command: + // ``` + // perf record -e 'arm_spe_0/branch_filter=1/u' -- BINARY + // ``` + // How Bolt extracts the branch events: + // ``` + // perf script -F pid,brstack --itrace=bl + // ``` + + opts::ArmSPE = true; + opts::ReadPerfEvents = " 1234 0xa001/0xa002/PN/-/-/10/COND/-\n" + " 1234 0xb001/0xb002/P/-/-/4/RET/-\n" + " 1234 0xc456/0xc789/P/-/-/13/-/-\n" + " 1234 0xd123/0xd456/M/-/-/7/RET/-\n" + " 1234 0xe001/0xe002/P/-/-/14/RET/-\n" + " 1234 0xd123/0xd456/M/-/-/7/RET/-\n" + " 1234 0xf001/0xf002/MN/-/-/8/COND/-\n" + " 1234 0xc456/0xc789/M/-/-/13/-/-\n"; + + // ExpectedSamples contains the aggregated information about + // a branch {{Branch From, To}, {TakenCount, MispredCount}}. + // Consider this example trace: {{0xd123, 0xd456, Trace::BR_ONLY}, + // {2,2}}. This entry has a TakenCount = 2, as we have two samples for + // (0xd123, 0xd456) in our input. It also has MispredsCount = 2, + // as 'M' misprediction flag appears in both cases. BR_ONLY means + // the trace only contains branch data. + std::vector> ExpectedSamples = { + {{0xa001, 0xa002, Trace::BR_ONLY}, {1, 0}}, + {{0xb001, 0xb002, Trace::BR_ONLY}, {1, 0}}, + {{0xc456, 0xc789, Trace::BR_ONLY}, {2, 1}}, + {{0xd123, 0xd456, Trace::BR_ONLY}, {2, 2}}, + {{0xe001, 0xe002, Trace::BR_ONLY}, {1, 0}}, + {{0xf001, 0xf002, Trace::BR_ONLY}, {1, 1}}}; + + parseAndCheckBrstackEvents(1234, ExpectedSamples); +} + +#endif diff --git a/external/llvm-project/clang-tools-extra/clang-doc/BitcodeReader.cpp b/external/llvm-project/clang-tools-extra/clang-doc/BitcodeReader.cpp index 35058abab066..66852931226b 100644 --- a/external/llvm-project/clang-tools-extra/clang-doc/BitcodeReader.cpp +++ b/external/llvm-project/clang-tools-extra/clang-doc/BitcodeReader.cpp @@ -92,6 +92,7 @@ static llvm::Error decodeRecord(const Record &R, InfoType &Field, case InfoType::IT_default: case InfoType::IT_enum: case InfoType::IT_typedef: + case InfoType::IT_concept: Field = IT; return llvm::Error::success(); } @@ -108,6 +109,7 @@ static llvm::Error decodeRecord(const Record &R, FieldId &Field, case FieldId::F_type: case FieldId::F_child_namespace: case FieldId::F_child_record: + case FieldId::F_concept: case FieldId::F_default: Field = F; return llvm::Error::success(); @@ -391,6 +393,29 @@ static llvm::Error parseRecord(const Record &R, unsigned ID, "invalid field for TemplateParamInfo"); } +static llvm::Error parseRecord(const Record &R, unsigned ID, + llvm::StringRef Blob, ConceptInfo *I) { + switch (ID) { + case CONCEPT_USR: + return decodeRecord(R, I->USR, Blob); + case CONCEPT_NAME: + return decodeRecord(R, I->Name, Blob); + case CONCEPT_IS_TYPE: + return decodeRecord(R, I->IsType, Blob); + case CONCEPT_CONSTRAINT_EXPRESSION: + return decodeRecord(R, I->ConstraintExpression, Blob); + } + llvm_unreachable("invalid field for ConceptInfo"); +} + +static llvm::Error parseRecord(const Record &R, unsigned ID, + llvm::StringRef Blob, ConstraintInfo *I) { + if (ID == CONSTRAINT_EXPRESSION) + return decodeRecord(R, I->ConstraintExpr, Blob); + return llvm::createStringError(llvm::inconvertibleErrorCode(), + "invalid field for ConstraintInfo"); +} + template static llvm::Expected getCommentInfo(T I) { return llvm::createStringError(llvm::inconvertibleErrorCode(), "invalid type cannot contain CommentInfo"); @@ -429,6 +454,10 @@ template <> llvm::Expected getCommentInfo(CommentInfo *I) { return I->Children.back().get(); } +template <> llvm::Expected getCommentInfo(ConceptInfo *I) { + return &I->Description.emplace_back(); +} + // When readSubBlock encounters a TypeInfo sub-block, it calls addTypeInfo on // the parent block to set it. The template specializations define what to do // for each supported parent block. @@ -584,6 +613,17 @@ template <> llvm::Error addReference(RecordInfo *I, Reference &&R, FieldId F) { } } +template <> +llvm::Error addReference(ConstraintInfo *I, Reference &&R, FieldId F) { + if (F == FieldId::F_concept) { + I->ConceptRef = std::move(R); + return llvm::Error::success(); + } + return llvm::createStringError( + llvm::inconvertibleErrorCode(), + "ConstraintInfo cannot contain this Reference"); +} + template static void addChild(T I, ChildInfoType &&R) { llvm::errs() << "invalid child type for info"; @@ -600,6 +640,9 @@ template <> void addChild(NamespaceInfo *I, EnumInfo &&R) { template <> void addChild(NamespaceInfo *I, TypedefInfo &&R) { I->Children.Typedefs.emplace_back(std::move(R)); } +template <> void addChild(NamespaceInfo *I, ConceptInfo &&R) { + I->Children.Concepts.emplace_back(std::move(R)); +} // Record children: template <> void addChild(RecordInfo *I, FunctionInfo &&R) { @@ -649,6 +692,9 @@ template <> void addTemplate(RecordInfo *I, TemplateInfo &&P) { template <> void addTemplate(FunctionInfo *I, TemplateInfo &&P) { I->Template.emplace(std::move(P)); } +template <> void addTemplate(ConceptInfo *I, TemplateInfo &&P) { + I->Template = std::move(P); +} // Template specializations go only into template records. template @@ -662,6 +708,14 @@ void addTemplateSpecialization(TemplateInfo *I, I->Specialization.emplace(std::move(TSI)); } +template static void addConstraint(T I, ConstraintInfo &&C) { + llvm::errs() << "invalid container for constraint info"; + exit(1); +} +template <> void addConstraint(TemplateInfo *I, ConstraintInfo &&C) { + I->Constraints.emplace_back(std::move(C)); +} + // Read records from bitcode into a given info. template llvm::Error ClangDocBitcodeReader::readRecord(unsigned ID, T I) { @@ -716,6 +770,8 @@ llvm::Error ClangDocBitcodeReader::readBlock(unsigned ID, T I) { } } +// TODO: Create a helper that can receive a function to reduce repetition for +// most blocks. template llvm::Error ClangDocBitcodeReader::readSubBlock(unsigned ID, T I) { llvm::TimeTraceScope("Reducing infos", "readSubBlock"); @@ -817,6 +873,20 @@ llvm::Error ClangDocBitcodeReader::readSubBlock(unsigned ID, T I) { addChild(I, std::move(TI)); return llvm::Error::success(); } + case BI_CONSTRAINT_BLOCK_ID: { + ConstraintInfo CI; + if (auto Err = readBlock(ID, &CI)) + return Err; + addConstraint(I, std::move(CI)); + return llvm::Error::success(); + } + case BI_CONCEPT_BLOCK_ID: { + ConceptInfo CI; + if (auto Err = readBlock(ID, &CI)) + return Err; + addChild(I, std::move(CI)); + return llvm::Error::success(); + } default: return llvm::createStringError(llvm::inconvertibleErrorCode(), "invalid subblock type"); @@ -922,6 +992,8 @@ ClangDocBitcodeReader::readBlockToInfo(unsigned ID) { return createInfo(ID); case BI_TYPEDEF_BLOCK_ID: return createInfo(ID); + case BI_CONCEPT_BLOCK_ID: + return createInfo(ID); case BI_FUNCTION_BLOCK_ID: return createInfo(ID); default: @@ -962,6 +1034,7 @@ ClangDocBitcodeReader::readBitcode() { case BI_RECORD_BLOCK_ID: case BI_ENUM_BLOCK_ID: case BI_TYPEDEF_BLOCK_ID: + case BI_CONCEPT_BLOCK_ID: case BI_FUNCTION_BLOCK_ID: { auto InfoOrErr = readBlockToInfo(ID); if (!InfoOrErr) diff --git a/external/llvm-project/clang-tools-extra/clang-doc/BitcodeWriter.cpp b/external/llvm-project/clang-tools-extra/clang-doc/BitcodeWriter.cpp index f8a6859169b0..b7308c012786 100644 --- a/external/llvm-project/clang-tools-extra/clang-doc/BitcodeWriter.cpp +++ b/external/llvm-project/clang-tools-extra/clang-doc/BitcodeWriter.cpp @@ -128,7 +128,9 @@ static const llvm::IndexedMap {BI_REFERENCE_BLOCK_ID, "ReferenceBlock"}, {BI_TEMPLATE_BLOCK_ID, "TemplateBlock"}, {BI_TEMPLATE_SPECIALIZATION_BLOCK_ID, "TemplateSpecializationBlock"}, - {BI_TEMPLATE_PARAM_BLOCK_ID, "TemplateParamBlock"}}; + {BI_TEMPLATE_PARAM_BLOCK_ID, "TemplateParamBlock"}, + {BI_CONSTRAINT_BLOCK_ID, "ConstraintBlock"}, + {BI_CONCEPT_BLOCK_ID, "ConceptBlock"}}; assert(Inits.size() == BlockIdCount); for (const auto &Init : Inits) BlockIdNameMap[Init.first] = Init.second; @@ -205,7 +207,13 @@ static const llvm::IndexedMap {TYPEDEF_USR, {"USR", &genSymbolIdAbbrev}}, {TYPEDEF_NAME, {"Name", &genStringAbbrev}}, {TYPEDEF_DEFLOCATION, {"DefLocation", &genLocationAbbrev}}, - {TYPEDEF_IS_USING, {"IsUsing", &genBoolAbbrev}}}; + {TYPEDEF_IS_USING, {"IsUsing", &genBoolAbbrev}}, + {CONCEPT_USR, {"USR", &genSymbolIdAbbrev}}, + {CONCEPT_NAME, {"Name", &genStringAbbrev}}, + {CONCEPT_IS_TYPE, {"IsType", &genBoolAbbrev}}, + {CONCEPT_CONSTRAINT_EXPRESSION, + {"ConstraintExpression", &genStringAbbrev}}, + {CONSTRAINT_EXPRESSION, {"Expression", &genStringAbbrev}}}; assert(Inits.size() == RecordIdCount); for (const auto &Init : Inits) { RecordIdNameMap[Init.first] = Init.second; @@ -263,7 +271,13 @@ static const std::vector>> // Template Blocks. {BI_TEMPLATE_BLOCK_ID, {}}, {BI_TEMPLATE_PARAM_BLOCK_ID, {TEMPLATE_PARAM_CONTENTS}}, - {BI_TEMPLATE_SPECIALIZATION_BLOCK_ID, {TEMPLATE_SPECIALIZATION_OF}}}; + {BI_TEMPLATE_SPECIALIZATION_BLOCK_ID, {TEMPLATE_SPECIALIZATION_OF}}, + // Concept Block + {BI_CONCEPT_BLOCK_ID, + {CONCEPT_USR, CONCEPT_NAME, CONCEPT_IS_TYPE, + CONCEPT_CONSTRAINT_EXPRESSION}}, + // Constraint Block + {BI_CONSTRAINT_BLOCK_ID, {CONSTRAINT_EXPRESSION}}}; // AbbreviationMap @@ -524,6 +538,8 @@ void ClangDocBitcodeWriter::emitBlock(const NamespaceInfo &I) { emitBlock(C); for (const auto &C : I.Children.Typedefs) emitBlock(C); + for (const auto &C : I.Children.Concepts) + emitBlock(C); } void ClangDocBitcodeWriter::emitBlock(const EnumInfo &I) { @@ -627,12 +643,25 @@ void ClangDocBitcodeWriter::emitBlock(const FunctionInfo &I) { emitBlock(*I.Template); } +void ClangDocBitcodeWriter::emitBlock(const ConceptInfo &I) { + StreamSubBlockGuard Block(Stream, BI_CONCEPT_BLOCK_ID); + emitRecord(I.USR, CONCEPT_USR); + emitRecord(I.Name, CONCEPT_NAME); + for (const auto &CI : I.Description) + emitBlock(CI); + emitRecord(I.IsType, CONCEPT_IS_TYPE); + emitRecord(I.ConstraintExpression, CONCEPT_CONSTRAINT_EXPRESSION); + emitBlock(I.Template); +} + void ClangDocBitcodeWriter::emitBlock(const TemplateInfo &T) { StreamSubBlockGuard Block(Stream, BI_TEMPLATE_BLOCK_ID); for (const auto &P : T.Params) emitBlock(P); if (T.Specialization) emitBlock(*T.Specialization); + for (const auto &C : T.Constraints) + emitBlock(C); } void ClangDocBitcodeWriter::emitBlock(const TemplateSpecializationInfo &T) { @@ -647,6 +676,12 @@ void ClangDocBitcodeWriter::emitBlock(const TemplateParamInfo &T) { emitRecord(T.Contents, TEMPLATE_PARAM_CONTENTS); } +void ClangDocBitcodeWriter::emitBlock(const ConstraintInfo &C) { + StreamSubBlockGuard Block(Stream, BI_CONSTRAINT_BLOCK_ID); + emitRecord(C.ConstraintExpr, CONSTRAINT_EXPRESSION); + emitBlock(C.ConceptRef, FieldId::F_concept); +} + bool ClangDocBitcodeWriter::dispatchInfoForWrite(Info *I) { switch (I->IT) { case InfoType::IT_namespace: @@ -664,6 +699,9 @@ bool ClangDocBitcodeWriter::dispatchInfoForWrite(Info *I) { case InfoType::IT_typedef: emitBlock(*static_cast(I)); break; + case InfoType::IT_concept: + emitBlock(*static_cast(I)); + break; case InfoType::IT_default: llvm::errs() << "Unexpected info, unable to write.\n"; return true; diff --git a/external/llvm-project/clang-tools-extra/clang-doc/BitcodeWriter.h b/external/llvm-project/clang-tools-extra/clang-doc/BitcodeWriter.h index e33a1aece883..4d0c0c07805e 100644 --- a/external/llvm-project/clang-tools-extra/clang-doc/BitcodeWriter.h +++ b/external/llvm-project/clang-tools-extra/clang-doc/BitcodeWriter.h @@ -66,7 +66,9 @@ enum BlockId { BI_TEMPLATE_BLOCK_ID, BI_TEMPLATE_SPECIALIZATION_BLOCK_ID, BI_TEMPLATE_PARAM_BLOCK_ID, + BI_CONSTRAINT_BLOCK_ID, BI_TYPEDEF_BLOCK_ID, + BI_CONCEPT_BLOCK_ID, BI_LAST, BI_FIRST = BI_VERSION_BLOCK_ID }; @@ -135,6 +137,11 @@ enum RecordId { TYPEDEF_NAME, TYPEDEF_DEFLOCATION, TYPEDEF_IS_USING, + CONCEPT_USR, + CONCEPT_NAME, + CONCEPT_IS_TYPE, + CONCEPT_CONSTRAINT_EXPRESSION, + CONSTRAINT_EXPRESSION, RI_LAST, RI_FIRST = VERSION }; @@ -150,7 +157,8 @@ enum class FieldId { F_vparent, F_type, F_child_namespace, - F_child_record + F_child_record, + F_concept }; class ClangDocBitcodeWriter { @@ -179,6 +187,8 @@ class ClangDocBitcodeWriter { void emitBlock(const TemplateInfo &T); void emitBlock(const TemplateSpecializationInfo &T); void emitBlock(const TemplateParamInfo &T); + void emitBlock(const ConceptInfo &T); + void emitBlock(const ConstraintInfo &T); void emitBlock(const Reference &B, FieldId F); private: diff --git a/external/llvm-project/clang-tools-extra/clang-doc/HTMLGenerator.cpp b/external/llvm-project/clang-tools-extra/clang-doc/HTMLGenerator.cpp index 7293a129177c..935bbfee7a9b 100644 --- a/external/llvm-project/clang-tools-extra/clang-doc/HTMLGenerator.cpp +++ b/external/llvm-project/clang-tools-extra/clang-doc/HTMLGenerator.cpp @@ -985,6 +985,8 @@ llvm::Error HTMLGenerator::generateDocForInfo(Info *I, llvm::raw_ostream &OS, MainContentNodes = genHTML(*static_cast(I), CDCtx, InfoTitle); break; + case InfoType::IT_concept: + break; case InfoType::IT_default: return llvm::createStringError(llvm::inconvertibleErrorCode(), "unexpected info type"); @@ -1011,6 +1013,8 @@ static std::string getRefType(InfoType IT) { return "enum"; case InfoType::IT_typedef: return "typedef"; + case InfoType::IT_concept: + return "concept"; } llvm_unreachable("Unknown InfoType"); } diff --git a/external/llvm-project/clang-tools-extra/clang-doc/HTMLMustacheGenerator.cpp b/external/llvm-project/clang-tools-extra/clang-doc/HTMLMustacheGenerator.cpp index 69c670b20844..81ba99c21e37 100644 --- a/external/llvm-project/clang-tools-extra/clang-doc/HTMLMustacheGenerator.cpp +++ b/external/llvm-project/clang-tools-extra/clang-doc/HTMLMustacheGenerator.cpp @@ -585,6 +585,8 @@ Error MustacheHTMLGenerator::generateDocForInfo(Info *I, raw_ostream &OS, case InfoType::IT_typedef: OS << "IT_typedef\n"; break; + case InfoType::IT_concept: + break; case InfoType::IT_default: return createStringError(inconvertibleErrorCode(), "unexpected InfoType"); } diff --git a/external/llvm-project/clang-tools-extra/clang-doc/JSONGenerator.cpp b/external/llvm-project/clang-tools-extra/clang-doc/JSONGenerator.cpp index 0f7cbafcf513..8a37621597c6 100644 --- a/external/llvm-project/clang-tools-extra/clang-doc/JSONGenerator.cpp +++ b/external/llvm-project/clang-tools-extra/clang-doc/JSONGenerator.cpp @@ -26,6 +26,15 @@ static void serializeInfo(const TypedefInfo &I, json::Object &Obj, std::optional RepositoryUrl); static void serializeInfo(const EnumInfo &I, json::Object &Obj, std::optional RepositoryUrl); +static void serializeInfo(const ConstraintInfo &I, Object &Obj); + +// Convenience lambda to pass to serializeArray. +// If a serializeInfo needs a RepositoryUrl, create a local lambda that captures +// the optional. +static auto SerializeInfoLambda = [](const ConstraintInfo &Info, + Object &Object) { + serializeInfo(Info, Object); +}; static json::Object serializeLocation(const Location &Loc, std::optional RepositoryUrl) { @@ -248,6 +257,27 @@ static void serializeCommonChildren(const ScopeChildren &Children, } } +template +static void serializeArray(const std::vector &Records, Object &Obj, + const std::string &Key, + SerializationFunc SerializeInfo) { + json::Value RecordsArray = Array(); + auto &RecordsArrayRef = *RecordsArray.getAsArray(); + RecordsArrayRef.reserve(Records.size()); + for (const auto &Item : Records) { + json::Value ItemVal = Object(); + auto &ItemObj = *ItemVal.getAsObject(); + SerializeInfo(Item, ItemObj); + RecordsArrayRef.push_back(ItemVal); + } + Obj[Key] = RecordsArray; +} + +static void serializeInfo(const ConstraintInfo &I, Object &Obj) { + serializeReference(I.ConceptRef, Obj); + Obj["Expression"] = I.ConstraintExpr; +} + static void serializeInfo(const TemplateInfo &Template, Object &Obj) { json::Value TemplateVal = Object(); auto &TemplateObj = *TemplateVal.getAsObject(); @@ -277,9 +307,21 @@ static void serializeInfo(const TemplateInfo &Template, Object &Obj) { TemplateObj["Parameters"] = ParamsArray; } + if (!Template.Constraints.empty()) + serializeArray(Template.Constraints, TemplateObj, "Constraints", + SerializeInfoLambda); + Obj["Template"] = TemplateVal; } +static void serializeInfo(const ConceptInfo &I, Object &Obj, + std::optional RepositoryUrl) { + serializeCommonAttributes(I, Obj, RepositoryUrl); + Obj["IsType"] = I.IsType; + Obj["ConstraintExpression"] = I.ConstraintExpression; + serializeInfo(I.Template, Obj); +} + static void serializeInfo(const TypeInfo &I, Object &Obj) { Obj["Name"] = I.Type.Name; Obj["QualName"] = I.Type.QualName; @@ -457,6 +499,10 @@ static void serializeInfo(const NamespaceInfo &I, json::Object &Obj, Obj["Namespaces"] = NamespacesArray; } + auto SerializeInfo = [RepositoryUrl](const auto &Info, Object &Object) { + serializeInfo(Info, Object, RepositoryUrl); + }; + if (!I.Children.Functions.empty()) { json::Value FunctionsArray = Array(); auto &FunctionsArrayRef = *FunctionsArray.getAsArray(); @@ -470,6 +516,9 @@ static void serializeInfo(const NamespaceInfo &I, json::Object &Obj, Obj["Functions"] = FunctionsArray; } + if (!I.Children.Concepts.empty()) + serializeArray(I.Children.Concepts, Obj, "Concepts", SerializeInfo); + serializeCommonChildren(I.Children, Obj, RepositoryUrl); } @@ -520,6 +569,7 @@ Error JSONGenerator::generateDocForInfo(Info *I, raw_ostream &OS, case InfoType::IT_record: serializeInfo(*static_cast(I), Obj, CDCtx.RepositoryUrl); break; + case InfoType::IT_concept: case InfoType::IT_enum: case InfoType::IT_function: case InfoType::IT_typedef: diff --git a/external/llvm-project/clang-tools-extra/clang-doc/MDGenerator.cpp b/external/llvm-project/clang-tools-extra/clang-doc/MDGenerator.cpp index 2becccf8b07d..6e68e09cfa2a 100644 --- a/external/llvm-project/clang-tools-extra/clang-doc/MDGenerator.cpp +++ b/external/llvm-project/clang-tools-extra/clang-doc/MDGenerator.cpp @@ -372,6 +372,9 @@ static llvm::Error genIndex(ClangDocContext &CDCtx) { case InfoType::IT_typedef: Type = "Typedef"; break; + case InfoType::IT_concept: + Type = "Concept"; + break; case InfoType::IT_default: Type = "Other"; } @@ -464,6 +467,8 @@ llvm::Error MDGenerator::generateDocForInfo(Info *I, llvm::raw_ostream &OS, case InfoType::IT_typedef: genMarkdown(CDCtx, *static_cast(I), OS); break; + case InfoType::IT_concept: + break; case InfoType::IT_default: return createStringError(llvm::inconvertibleErrorCode(), "unexpected InfoType"); diff --git a/external/llvm-project/clang-tools-extra/clang-doc/Mapper.cpp b/external/llvm-project/clang-tools-extra/clang-doc/Mapper.cpp index 9f640b5325da..6021e17b4696 100644 --- a/external/llvm-project/clang-tools-extra/clang-doc/Mapper.cpp +++ b/external/llvm-project/clang-tools-extra/clang-doc/Mapper.cpp @@ -134,6 +134,10 @@ bool MapASTVisitor::VisitTypeAliasDecl(const TypeAliasDecl *D) { return mapDecl(D, /*isDefinition=*/true); } +bool MapASTVisitor::VisitConceptDecl(const ConceptDecl *D) { + return mapDecl(D, true); +} + comments::FullComment * MapASTVisitor::getComment(const NamedDecl *D, const ASTContext &Context) const { RawComment *Comment = Context.getRawCommentForDeclNoCache(D); diff --git a/external/llvm-project/clang-tools-extra/clang-doc/Mapper.h b/external/llvm-project/clang-tools-extra/clang-doc/Mapper.h index 36322ea2bfb7..04dc5450c8ba 100644 --- a/external/llvm-project/clang-tools-extra/clang-doc/Mapper.h +++ b/external/llvm-project/clang-tools-extra/clang-doc/Mapper.h @@ -41,6 +41,7 @@ class MapASTVisitor : public clang::RecursiveASTVisitor, bool VisitFunctionDecl(const FunctionDecl *D); bool VisitTypedefDecl(const TypedefDecl *D); bool VisitTypeAliasDecl(const TypeAliasDecl *D); + bool VisitConceptDecl(const ConceptDecl *D); private: template bool mapDecl(const T *D, bool IsDefinition); diff --git a/external/llvm-project/clang-tools-extra/clang-doc/Representation.cpp b/external/llvm-project/clang-tools-extra/clang-doc/Representation.cpp index 71a926f1c73e..286aeeea1001 100644 --- a/external/llvm-project/clang-tools-extra/clang-doc/Representation.cpp +++ b/external/llvm-project/clang-tools-extra/clang-doc/Representation.cpp @@ -143,6 +143,8 @@ mergeInfos(std::vector> &Values) { return reduce(Values); case InfoType::IT_typedef: return reduce(Values); + case InfoType::IT_concept: + return reduce(Values); case InfoType::IT_default: return llvm::createStringError(llvm::inconvertibleErrorCode(), "unexpected info type"); @@ -288,6 +290,7 @@ void NamespaceInfo::merge(NamespaceInfo &&Other) { reduceChildren(Children.Functions, std::move(Other.Children.Functions)); reduceChildren(Children.Enums, std::move(Other.Children.Enums)); reduceChildren(Children.Typedefs, std::move(Other.Children.Typedefs)); + reduceChildren(Children.Concepts, std::move(Other.Children.Concepts)); mergeBase(std::move(Other)); } @@ -352,6 +355,19 @@ void TypedefInfo::merge(TypedefInfo &&Other) { SymbolInfo::merge(std::move(Other)); } +void ConceptInfo::merge(ConceptInfo &&Other) { + assert(mergeable(Other)); + if (!IsType) + IsType = Other.IsType; + if (ConstraintExpression.empty()) + ConstraintExpression = std::move(Other.ConstraintExpression); + if (Template.Constraints.empty()) + Template.Constraints = std::move(Other.Template.Constraints); + if (Template.Params.empty()) + Template.Params = std::move(Other.Template.Params); + SymbolInfo::merge(std::move(Other)); +} + BaseRecordInfo::BaseRecordInfo() : RecordInfo() {} BaseRecordInfo::BaseRecordInfo(SymbolID USR, StringRef Name, StringRef Path, @@ -388,6 +404,9 @@ llvm::SmallString<16> Info::extractName() const { case InfoType::IT_function: return llvm::SmallString<16>("@nonymous_function_" + toHex(llvm::toStringRef(USR))); + case InfoType::IT_concept: + return llvm::SmallString<16>("@nonymous_concept_" + + toHex(llvm::toStringRef(USR))); case InfoType::IT_default: return llvm::SmallString<16>("@nonymous_" + toHex(llvm::toStringRef(USR))); } @@ -453,6 +472,7 @@ void ScopeChildren::sort() { llvm::sort(Functions.begin(), Functions.end()); llvm::sort(Enums.begin(), Enums.end()); llvm::sort(Typedefs.begin(), Typedefs.end()); + llvm::sort(Concepts.begin(), Concepts.end()); } } // namespace doc } // namespace clang diff --git a/external/llvm-project/clang-tools-extra/clang-doc/Representation.h b/external/llvm-project/clang-tools-extra/clang-doc/Representation.h index 75da50064581..b23069f2bd32 100644 --- a/external/llvm-project/clang-tools-extra/clang-doc/Representation.h +++ b/external/llvm-project/clang-tools-extra/clang-doc/Representation.h @@ -35,6 +35,7 @@ struct EnumInfo; struct FunctionInfo; struct Info; struct TypedefInfo; +struct ConceptInfo; enum class InfoType { IT_default, @@ -42,7 +43,8 @@ enum class InfoType { IT_record, IT_function, IT_enum, - IT_typedef + IT_typedef, + IT_concept }; enum class CommentKind { @@ -166,6 +168,7 @@ struct ScopeChildren { std::vector Functions; std::vector Enums; std::vector Typedefs; + std::vector Concepts; void sort(); }; @@ -211,6 +214,15 @@ struct TemplateSpecializationInfo { std::vector Params; }; +struct ConstraintInfo { + ConstraintInfo() = default; + ConstraintInfo(SymbolID USR, StringRef Name) + : ConceptRef(USR, Name, InfoType::IT_concept) {} + Reference ConceptRef; + + SmallString<16> ConstraintExpr; +}; + // Records the template information for a struct or function that is a template // or an explicit template specialization. struct TemplateInfo { @@ -219,6 +231,7 @@ struct TemplateInfo { // Set when this is a specialization of another record/function. std::optional Specialization; + std::vector Constraints; }; // Info for field types. @@ -513,6 +526,17 @@ struct EnumInfo : public SymbolInfo { llvm::SmallVector Members; // List of enum members. }; +struct ConceptInfo : public SymbolInfo { + ConceptInfo() : SymbolInfo(InfoType::IT_concept) {} + ConceptInfo(SymbolID USR) : SymbolInfo(InfoType::IT_concept, USR) {} + + void merge(ConceptInfo &&I); + + bool IsType; + TemplateInfo Template; + SmallString<16> ConstraintExpression; +}; + struct Index : public Reference { Index() = default; Index(StringRef Name) : Reference(SymbolID(), Name) {} diff --git a/external/llvm-project/clang-tools-extra/clang-doc/Serialize.cpp b/external/llvm-project/clang-tools-extra/clang-doc/Serialize.cpp index 820e8bfd8e64..5f3e5c37fa34 100644 --- a/external/llvm-project/clang-tools-extra/clang-doc/Serialize.cpp +++ b/external/llvm-project/clang-tools-extra/clang-doc/Serialize.cpp @@ -21,6 +21,17 @@ namespace clang { namespace doc { namespace serialize { +namespace { +static SmallString<16> exprToString(const clang::Expr *E) { + clang::LangOptions Opts; + clang::PrintingPolicy Policy(Opts); + SmallString<16> Result; + llvm::raw_svector_ostream OS(Result); + E->printPretty(OS, nullptr, Policy); + return Result; +} +} // namespace + SymbolID hashUSR(llvm::StringRef USR) { return llvm::SHA1::hash(arrayRefFromStringRef(USR)); } @@ -388,6 +399,8 @@ std::string serialize(std::unique_ptr &I) { return serialize(*static_cast(I.get())); case InfoType::IT_function: return serialize(*static_cast(I.get())); + case InfoType::IT_concept: + return serialize(*static_cast(I.get())); case InfoType::IT_typedef: case InfoType::IT_default: return ""; @@ -491,6 +504,10 @@ static void InsertChild(ScopeChildren &Scope, TypedefInfo Info) { Scope.Typedefs.push_back(std::move(Info)); } +static void InsertChild(ScopeChildren &Scope, ConceptInfo Info) { + Scope.Concepts.push_back(std::move(Info)); +} + // Creates a parent of the correct type for the given child and inserts it into // that parent. // @@ -531,6 +548,7 @@ static std::unique_ptr makeAndInsertIntoParent(ChildType Child) { case InfoType::IT_enum: case InfoType::IT_function: case InfoType::IT_typedef: + case InfoType::IT_concept: break; } llvm_unreachable("Invalid reference type for parent namespace"); @@ -740,6 +758,50 @@ static void populateSymbolInfo(SymbolInfo &I, const T *D, const FullComment *C, I.Loc.emplace_back(Loc); } +static void +handleCompoundConstraints(const Expr *Constraint, + std::vector &ConstraintInfos) { + if (Constraint->getStmtClass() == Stmt::ParenExprClass) { + handleCompoundConstraints(dyn_cast(Constraint)->getSubExpr(), + ConstraintInfos); + } else if (Constraint->getStmtClass() == Stmt::BinaryOperatorClass) { + auto *BinaryOpExpr = dyn_cast(Constraint); + handleCompoundConstraints(BinaryOpExpr->getLHS(), ConstraintInfos); + handleCompoundConstraints(BinaryOpExpr->getRHS(), ConstraintInfos); + } else if (Constraint->getStmtClass() == + Stmt::ConceptSpecializationExprClass) { + auto *Concept = dyn_cast(Constraint); + ConstraintInfo CI(getUSRForDecl(Concept->getNamedConcept()), + Concept->getNamedConcept()->getNameAsString()); + CI.ConstraintExpr = exprToString(Concept); + ConstraintInfos.push_back(CI); + } +} + +static void populateConstraints(TemplateInfo &I, const TemplateDecl *D) { + if (!D || !D->hasAssociatedConstraints()) + return; + + SmallVector AssociatedConstraints; + D->getAssociatedConstraints(AssociatedConstraints); + for (const auto &Constraint : AssociatedConstraints) { + if (!Constraint) + continue; + + // TODO: Investigate if atomic constraints need to be handled specifically. + if (const auto *ConstraintExpr = + dyn_cast_or_null( + Constraint.ConstraintExpr)) { + ConstraintInfo CI(getUSRForDecl(ConstraintExpr->getNamedConcept()), + ConstraintExpr->getNamedConcept()->getNameAsString()); + CI.ConstraintExpr = exprToString(ConstraintExpr); + I.Constraints.push_back(std::move(CI)); + } else { + handleCompoundConstraints(Constraint.ConstraintExpr, I.Constraints); + } + } +} + static void populateFunctionInfo(FunctionInfo &I, const FunctionDecl *D, const FullComment *FC, Location Loc, bool &IsInAnonymousNamespace) { @@ -751,6 +813,8 @@ static void populateFunctionInfo(FunctionInfo &I, const FunctionDecl *D, I.IsStatic = D->isStatic(); populateTemplateParameters(I.Template, D); + if (I.Template) + populateConstraints(I.Template.value(), D->getDescribedFunctionTemplate()); // Handle function template specializations. if (const FunctionTemplateSpecializationInfo *FTSI = @@ -903,6 +967,8 @@ emitInfo(const RecordDecl *D, const FullComment *FC, Location Loc, RI->Path = getInfoRelativePath(RI->Namespace); populateTemplateParameters(RI->Template, D); + if (RI->Template) + populateConstraints(RI->Template.value(), D->getDescribedTemplate()); // Full and partial specializations. if (auto *CTSD = dyn_cast(D)) { @@ -1074,6 +1140,30 @@ emitInfo(const EnumDecl *D, const FullComment *FC, Location Loc, return {nullptr, makeAndInsertIntoParent(std::move(Enum))}; } +std::pair, std::unique_ptr> +emitInfo(const ConceptDecl *D, const FullComment *FC, const Location &Loc, + bool PublicOnly) { + ConceptInfo Concept; + + bool IsInAnonymousNamespace = false; + populateInfo(Concept, D, FC, IsInAnonymousNamespace); + Concept.IsType = D->isTypeConcept(); + Concept.DefLoc = Loc; + Concept.ConstraintExpression = exprToString(D->getConstraintExpr()); + + if (auto *ConceptParams = D->getTemplateParameters()) { + for (const auto *Param : ConceptParams->asArray()) { + Concept.Template.Params.emplace_back( + getSourceCode(Param, Param->getSourceRange())); + } + } + + if (!shouldSerializeInfo(PublicOnly, IsInAnonymousNamespace, D)) + return {}; + + return {nullptr, makeAndInsertIntoParent(std::move(Concept))}; +} + } // namespace serialize } // namespace doc } // namespace clang diff --git a/external/llvm-project/clang-tools-extra/clang-doc/Serialize.h b/external/llvm-project/clang-tools-extra/clang-doc/Serialize.h index 7e6cbb70721e..497b09bb339f 100644 --- a/external/llvm-project/clang-tools-extra/clang-doc/Serialize.h +++ b/external/llvm-project/clang-tools-extra/clang-doc/Serialize.h @@ -68,6 +68,10 @@ std::pair, std::unique_ptr> emitInfo(const TypeAliasDecl *D, const FullComment *FC, Location Loc, bool PublicOnly); +std::pair, std::unique_ptr> +emitInfo(const ConceptDecl *D, const FullComment *FC, const Location &Loc, + bool PublicOnly); + // Function to hash a given USR value for storage. // As USRs (Unified Symbol Resolution) could be large, especially for functions // with long type arguments, we use 160-bits SHA1(USR) values to diff --git a/external/llvm-project/clang-tools-extra/clang-doc/YAMLGenerator.cpp b/external/llvm-project/clang-tools-extra/clang-doc/YAMLGenerator.cpp index 897b5d5ae4c9..f95887104698 100644 --- a/external/llvm-project/clang-tools-extra/clang-doc/YAMLGenerator.cpp +++ b/external/llvm-project/clang-tools-extra/clang-doc/YAMLGenerator.cpp @@ -408,6 +408,8 @@ llvm::Error YAMLGenerator::generateDocForInfo(Info *I, llvm::raw_ostream &OS, case InfoType::IT_typedef: InfoYAML << *static_cast(I); break; + case InfoType::IT_concept: + break; case InfoType::IT_default: return llvm::createStringError(llvm::inconvertibleErrorCode(), "unexpected InfoType"); diff --git a/external/llvm-project/clang-tools-extra/clang-reorder-fields/ReorderFieldsAction.cpp b/external/llvm-project/clang-tools-extra/clang-reorder-fields/ReorderFieldsAction.cpp index 3b1cd18d8034..ada9122b587a 100644 --- a/external/llvm-project/clang-tools-extra/clang-reorder-fields/ReorderFieldsAction.cpp +++ b/external/llvm-project/clang-tools-extra/clang-reorder-fields/ReorderFieldsAction.cpp @@ -19,6 +19,8 @@ #include "clang/AST/Decl.h" #include "clang/AST/RecursiveASTVisitor.h" #include "clang/ASTMatchers/ASTMatchFinder.h" +#include "clang/Basic/LangOptions.h" +#include "clang/Basic/SourceLocation.h" #include "clang/Lex/Lexer.h" #include "clang/Tooling/Refactoring.h" #include "llvm/ADT/STLExtras.h" @@ -50,6 +52,85 @@ static const RecordDecl *findDefinition(StringRef RecordName, return selectFirst("recordDecl", Results); } +static bool declaresMultipleFieldsInStatement(const RecordDecl *Decl) { + SourceLocation LastTypeLoc; + for (const auto &Field : Decl->fields()) { + SourceLocation TypeLoc = + Field->getTypeSourceInfo()->getTypeLoc().getBeginLoc(); + if (LastTypeLoc.isValid() && TypeLoc == LastTypeLoc) + return true; + LastTypeLoc = TypeLoc; + } + return false; +} + +static bool declaresMultipleFieldsInMacro(const RecordDecl *Decl, + const SourceManager &SrcMgr) { + SourceLocation LastMacroLoc; + for (const auto &Field : Decl->fields()) { + if (!Field->getLocation().isMacroID()) + continue; + SourceLocation MacroLoc = SrcMgr.getExpansionLoc(Field->getLocation()); + if (LastMacroLoc.isValid() && MacroLoc == LastMacroLoc) + return true; + LastMacroLoc = MacroLoc; + } + return false; +} + +static bool containsPreprocessorDirectives(const RecordDecl *Decl, + const SourceManager &SrcMgr, + const LangOptions &LangOpts) { + std::pair FileAndOffset = + SrcMgr.getDecomposedLoc(Decl->field_begin()->getBeginLoc()); + assert(!Decl->field_empty()); + auto LastField = Decl->field_begin(); + while (std::next(LastField) != Decl->field_end()) + ++LastField; + unsigned EndOffset = SrcMgr.getFileOffset(LastField->getEndLoc()); + StringRef SrcBuffer = SrcMgr.getBufferData(FileAndOffset.first); + Lexer L(SrcMgr.getLocForStartOfFile(FileAndOffset.first), LangOpts, + SrcBuffer.data(), SrcBuffer.data() + FileAndOffset.second, + SrcBuffer.data() + SrcBuffer.size()); + IdentifierTable Identifiers(LangOpts); + clang::Token T; + while (!L.LexFromRawLexer(T) && L.getCurrentBufferOffset() < EndOffset) { + if (T.getKind() == tok::hash) { + L.LexFromRawLexer(T); + if (T.getKind() == tok::raw_identifier) { + clang::IdentifierInfo &II = Identifiers.get(T.getRawIdentifier()); + if (II.getPPKeywordID() != clang::tok::pp_not_keyword) + return true; + } + } + } + return false; +} + +static bool isSafeToRewrite(const RecordDecl *Decl, const ASTContext &Context) { + // All following checks expect at least one field declaration. + if (Decl->field_empty()) + return true; + + // Don't attempt to rewrite if there is a declaration like 'int a, b;'. + if (declaresMultipleFieldsInStatement(Decl)) + return false; + + const SourceManager &SrcMgr = Context.getSourceManager(); + + // Don't attempt to rewrite if a single macro expansion creates multiple + // fields. + if (declaresMultipleFieldsInMacro(Decl, SrcMgr)) + return false; + + // Prevent rewriting if there are preprocessor directives present between the + // start of the first field and the end of last field. + if (containsPreprocessorDirectives(Decl, SrcMgr, Context.getLangOpts())) + return false; + + return true; +} + /// Calculates the new order of fields. /// /// \returns empty vector if the list of fields doesn't match the definition. @@ -345,6 +426,8 @@ class ReorderingConsumer : public ASTConsumer { const RecordDecl *RD = findDefinition(RecordName, Context); if (!RD) return; + if (!isSafeToRewrite(RD, Context)) + return; SmallVector NewFieldsOrder = getNewFieldsOrder(RD, DesiredFieldsOrder); if (NewFieldsOrder.empty()) diff --git a/external/llvm-project/clang-tools-extra/clang-tidy/cppcoreguidelines/AvoidGotoCheck.cpp b/external/llvm-project/clang-tools-extra/clang-tidy/cppcoreguidelines/AvoidGotoCheck.cpp index 8ffa44d41fa9..b14587ad7db8 100644 --- a/external/llvm-project/clang-tools-extra/clang-tidy/cppcoreguidelines/AvoidGotoCheck.cpp +++ b/external/llvm-project/clang-tools-extra/clang-tidy/cppcoreguidelines/AvoidGotoCheck.cpp @@ -17,8 +17,20 @@ namespace { AST_MATCHER(GotoStmt, isForwardJumping) { return Node.getBeginLoc() < Node.getLabel()->getBeginLoc(); } + +AST_MATCHER(GotoStmt, isInMacro) { + return Node.getBeginLoc().isMacroID() && Node.getEndLoc().isMacroID(); +} } // namespace +AvoidGotoCheck::AvoidGotoCheck(StringRef Name, ClangTidyContext *Context) + : ClangTidyCheck(Name, Context), + IgnoreMacros(Options.get("IgnoreMacros", false)) {} + +void AvoidGotoCheck::storeOptions(ClangTidyOptions::OptionMap &Opts) { + Options.store(Opts, "IgnoreMacros", IgnoreMacros); +} + void AvoidGotoCheck::registerMatchers(MatchFinder *Finder) { // TODO: This check does not recognize `IndirectGotoStmt` which is a // GNU extension. These must be matched separately and an AST matcher @@ -29,7 +41,10 @@ void AvoidGotoCheck::registerMatchers(MatchFinder *Finder) { auto Loop = mapAnyOf(forStmt, cxxForRangeStmt, whileStmt, doStmt); auto NestedLoop = Loop.with(hasAncestor(Loop)); - Finder->addMatcher(gotoStmt(anyOf(unless(hasAncestor(NestedLoop)), + const ast_matchers::internal::Matcher Anything = anything(); + + Finder->addMatcher(gotoStmt(IgnoreMacros ? unless(isInMacro()) : Anything, + anyOf(unless(hasAncestor(NestedLoop)), unless(isForwardJumping()))) .bind("goto"), this); diff --git a/external/llvm-project/clang-tools-extra/clang-tidy/cppcoreguidelines/AvoidGotoCheck.h b/external/llvm-project/clang-tools-extra/clang-tidy/cppcoreguidelines/AvoidGotoCheck.h index 883ba78855e7..8eae409462c9 100644 --- a/external/llvm-project/clang-tools-extra/clang-tidy/cppcoreguidelines/AvoidGotoCheck.h +++ b/external/llvm-project/clang-tools-extra/clang-tidy/cppcoreguidelines/AvoidGotoCheck.h @@ -20,13 +20,16 @@ namespace clang::tidy::cppcoreguidelines { /// http://clang.llvm.org/extra/clang-tidy/checks/cppcoreguidelines/avoid-goto.html class AvoidGotoCheck : public ClangTidyCheck { public: - AvoidGotoCheck(StringRef Name, ClangTidyContext *Context) - : ClangTidyCheck(Name, Context) {} + AvoidGotoCheck(StringRef Name, ClangTidyContext *Context); bool isLanguageVersionSupported(const LangOptions &LangOpts) const override { return LangOpts.CPlusPlus; } + void storeOptions(ClangTidyOptions::OptionMap &Opts) override; void registerMatchers(ast_matchers::MatchFinder *Finder) override; void check(const ast_matchers::MatchFinder::MatchResult &Result) override; + +private: + const bool IgnoreMacros; }; } // namespace clang::tidy::cppcoreguidelines diff --git a/external/llvm-project/clang-tools-extra/clang-tidy/cppcoreguidelines/CMakeLists.txt b/external/llvm-project/clang-tools-extra/clang-tidy/cppcoreguidelines/CMakeLists.txt index b023f76a2543..2fb4d7f1d734 100644 --- a/external/llvm-project/clang-tools-extra/clang-tidy/cppcoreguidelines/CMakeLists.txt +++ b/external/llvm-project/clang-tools-extra/clang-tidy/cppcoreguidelines/CMakeLists.txt @@ -33,6 +33,7 @@ add_clang_library(clangTidyCppCoreGuidelinesModule STATIC RvalueReferenceParamNotMovedCheck.cpp SlicingCheck.cpp SpecialMemberFunctionsCheck.cpp + UseEnumClassCheck.cpp VirtualClassDestructorCheck.cpp LINK_LIBS diff --git a/external/llvm-project/clang-tools-extra/clang-tidy/cppcoreguidelines/CppCoreGuidelinesTidyModule.cpp b/external/llvm-project/clang-tools-extra/clang-tidy/cppcoreguidelines/CppCoreGuidelinesTidyModule.cpp index 4dd9b0904f07..4b3b7bf963fd 100644 --- a/external/llvm-project/clang-tools-extra/clang-tidy/cppcoreguidelines/CppCoreGuidelinesTidyModule.cpp +++ b/external/llvm-project/clang-tools-extra/clang-tidy/cppcoreguidelines/CppCoreGuidelinesTidyModule.cpp @@ -48,6 +48,7 @@ #include "RvalueReferenceParamNotMovedCheck.h" #include "SlicingCheck.h" #include "SpecialMemberFunctionsCheck.h" +#include "UseEnumClassCheck.h" #include "VirtualClassDestructorCheck.h" namespace clang::tidy { @@ -131,6 +132,8 @@ class CppCoreGuidelinesModule : public ClangTidyModule { CheckFactories.registerCheck("cppcoreguidelines-slicing"); CheckFactories.registerCheck( "cppcoreguidelines-use-default-member-init"); + CheckFactories.registerCheck( + "cppcoreguidelines-use-enum-class"); CheckFactories.registerCheck( "cppcoreguidelines-c-copy-assignment-signature"); CheckFactories.registerCheck( diff --git a/external/llvm-project/clang-tools-extra/clang-tidy/cppcoreguidelines/SpecialMemberFunctionsCheck.cpp b/external/llvm-project/clang-tools-extra/clang-tidy/cppcoreguidelines/SpecialMemberFunctionsCheck.cpp index 0de143dbb1b8..0b6b8d9c9713 100644 --- a/external/llvm-project/clang-tools-extra/clang-tidy/cppcoreguidelines/SpecialMemberFunctionsCheck.cpp +++ b/external/llvm-project/clang-tools-extra/clang-tidy/cppcoreguidelines/SpecialMemberFunctionsCheck.cpp @@ -18,6 +18,12 @@ using namespace clang::ast_matchers; namespace clang::tidy::cppcoreguidelines { +namespace { +AST_MATCHER(CXXRecordDecl, isInMacro) { + return Node.getBeginLoc().isMacroID() && Node.getEndLoc().isMacroID(); +} +} // namespace + SpecialMemberFunctionsCheck::SpecialMemberFunctionsCheck( StringRef Name, ClangTidyContext *Context) : ClangTidyCheck(Name, Context), AllowMissingMoveFunctions(Options.get( @@ -26,7 +32,8 @@ SpecialMemberFunctionsCheck::SpecialMemberFunctionsCheck( AllowMissingMoveFunctionsWhenCopyIsDeleted( Options.get("AllowMissingMoveFunctionsWhenCopyIsDeleted", false)), AllowImplicitlyDeletedCopyOrMove( - Options.get("AllowImplicitlyDeletedCopyOrMove", false)) {} + Options.get("AllowImplicitlyDeletedCopyOrMove", false)), + IgnoreMacros(Options.get("IgnoreMacros", true)) {} void SpecialMemberFunctionsCheck::storeOptions( ClangTidyOptions::OptionMap &Opts) { @@ -36,6 +43,7 @@ void SpecialMemberFunctionsCheck::storeOptions( AllowMissingMoveFunctionsWhenCopyIsDeleted); Options.store(Opts, "AllowImplicitlyDeletedCopyOrMove", AllowImplicitlyDeletedCopyOrMove); + Options.store(Opts, "IgnoreMacros", IgnoreMacros); } std::optional @@ -45,11 +53,12 @@ SpecialMemberFunctionsCheck::getCheckTraversalKind() const { } void SpecialMemberFunctionsCheck::registerMatchers(MatchFinder *Finder) { - auto IsNotImplicitOrDeleted = anyOf(unless(isImplicit()), isDeleted()); + const auto IsNotImplicitOrDeleted = anyOf(unless(isImplicit()), isDeleted()); + const ast_matchers::internal::Matcher Anything = anything(); Finder->addMatcher( cxxRecordDecl( - unless(isImplicit()), + unless(isImplicit()), IgnoreMacros ? unless(isInMacro()) : Anything, eachOf(has(cxxDestructorDecl(unless(isImplicit())).bind("dtor")), has(cxxConstructorDecl(isCopyConstructor(), IsNotImplicitOrDeleted) diff --git a/external/llvm-project/clang-tools-extra/clang-tidy/cppcoreguidelines/SpecialMemberFunctionsCheck.h b/external/llvm-project/clang-tools-extra/clang-tidy/cppcoreguidelines/SpecialMemberFunctionsCheck.h index dee01cb5a9fd..c18ed7db055b 100644 --- a/external/llvm-project/clang-tools-extra/clang-tidy/cppcoreguidelines/SpecialMemberFunctionsCheck.h +++ b/external/llvm-project/clang-tools-extra/clang-tidy/cppcoreguidelines/SpecialMemberFunctionsCheck.h @@ -69,6 +69,7 @@ class SpecialMemberFunctionsCheck : public ClangTidyCheck { const bool AllowMissingMoveFunctionsWhenCopyIsDeleted; const bool AllowImplicitlyDeletedCopyOrMove; ClassDefiningSpecialMembersMap ClassWithSpecialMembers; + const bool IgnoreMacros; }; } // namespace clang::tidy::cppcoreguidelines diff --git a/external/llvm-project/clang-tools-extra/clang-tidy/cppcoreguidelines/UseEnumClassCheck.cpp b/external/llvm-project/clang-tools-extra/clang-tidy/cppcoreguidelines/UseEnumClassCheck.cpp new file mode 100644 index 000000000000..ec7d9237afa3 --- /dev/null +++ b/external/llvm-project/clang-tools-extra/clang-tidy/cppcoreguidelines/UseEnumClassCheck.cpp @@ -0,0 +1,42 @@ +//===--- UseEnumClassCheck.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 "UseEnumClassCheck.h" +#include "clang/ASTMatchers/ASTMatchFinder.h" + +using namespace clang::ast_matchers; + +namespace clang::tidy::cppcoreguidelines { + +UseEnumClassCheck::UseEnumClassCheck(StringRef Name, ClangTidyContext *Context) + : ClangTidyCheck(Name, Context), + IgnoreUnscopedEnumsInClasses( + Options.get("IgnoreUnscopedEnumsInClasses", false)) {} + +void UseEnumClassCheck::storeOptions(ClangTidyOptions::OptionMap &Opts) { + Options.store(Opts, "IgnoreUnscopedEnumsInClasses", + IgnoreUnscopedEnumsInClasses); +} + +void UseEnumClassCheck::registerMatchers(MatchFinder *Finder) { + auto EnumDecl = + IgnoreUnscopedEnumsInClasses + ? enumDecl(unless(isScoped()), unless(hasParent(recordDecl()))) + : enumDecl(unless(isScoped())); + Finder->addMatcher(EnumDecl.bind("unscoped_enum"), this); +} + +void UseEnumClassCheck::check(const MatchFinder::MatchResult &Result) { + const auto *UnscopedEnum = Result.Nodes.getNodeAs("unscoped_enum"); + + diag(UnscopedEnum->getLocation(), + "enum %0 is unscoped, use 'enum class' instead") + << UnscopedEnum; +} + +} // namespace clang::tidy::cppcoreguidelines diff --git a/external/llvm-project/clang-tools-extra/clang-tidy/cppcoreguidelines/UseEnumClassCheck.h b/external/llvm-project/clang-tools-extra/clang-tidy/cppcoreguidelines/UseEnumClassCheck.h new file mode 100644 index 000000000000..dfa4b7e3fda6 --- /dev/null +++ b/external/llvm-project/clang-tools-extra/clang-tidy/cppcoreguidelines/UseEnumClassCheck.h @@ -0,0 +1,40 @@ +//===--- UseEnumClassCheck.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_CPPCOREGUIDELINES_USEENUMCLASSCHECK_H +#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_CPPCOREGUIDELINES_USEENUMCLASSCHECK_H + +#include "../ClangTidyCheck.h" + +namespace clang::tidy::cppcoreguidelines { + +/// Finds unscoped (non-class) enum declarations and suggests using enum class +/// instead. +/// +/// For the user-facing documentation see: +/// http://clang.llvm.org/extra/clang-tidy/checks/cppcoreguidelines/use-enum-class.html +class UseEnumClassCheck : public ClangTidyCheck { +public: + UseEnumClassCheck(StringRef Name, ClangTidyContext *Context); + void storeOptions(ClangTidyOptions::OptionMap &Opts) override; + void registerMatchers(ast_matchers::MatchFinder *Finder) override; + void check(const ast_matchers::MatchFinder::MatchResult &Result) override; + bool isLanguageVersionSupported(const LangOptions &LangOpts) const override { + return LangOpts.CPlusPlus11; + } + std::optional getCheckTraversalKind() const override { + return TraversalKind::TK_IgnoreUnlessSpelledInSource; + } + +private: + const bool IgnoreUnscopedEnumsInClasses; +}; + +} // namespace clang::tidy::cppcoreguidelines + +#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_CPPCOREGUIDELINES_USEENUMCLASSCHECK_H diff --git a/external/llvm-project/clang-tools-extra/clang-tidy/performance/UnnecessaryValueParamCheck.cpp b/external/llvm-project/clang-tools-extra/clang-tidy/performance/UnnecessaryValueParamCheck.cpp index a877f9a7ee91..d89c3a69fc84 100644 --- a/external/llvm-project/clang-tools-extra/clang-tidy/performance/UnnecessaryValueParamCheck.cpp +++ b/external/llvm-project/clang-tools-extra/clang-tidy/performance/UnnecessaryValueParamCheck.cpp @@ -50,7 +50,8 @@ UnnecessaryValueParamCheck::UnnecessaryValueParamCheck( utils::IncludeSorter::IS_LLVM), areDiagsSelfContained()), AllowedTypes( - utils::options::parseStringList(Options.get("AllowedTypes", ""))) {} + utils::options::parseStringList(Options.get("AllowedTypes", ""))), + IgnoreCoroutines(Options.get("IgnoreCoroutines", true)) {} void UnnecessaryValueParamCheck::registerMatchers(MatchFinder *Finder) { const auto ExpensiveValueParamDecl = parmVarDecl( @@ -61,12 +62,14 @@ void UnnecessaryValueParamCheck::registerMatchers(MatchFinder *Finder) { matchers::matchesAnyListedName(AllowedTypes))))))), decl().bind("param")); Finder->addMatcher( - traverse( - TK_AsIs, - functionDecl(hasBody(stmt()), isDefinition(), unless(isImplicit()), - unless(cxxMethodDecl(anyOf(isOverride(), isFinal()))), - has(typeLoc(forEach(ExpensiveValueParamDecl))), - decl().bind("functionDecl"))), + traverse(TK_AsIs, + functionDecl( + hasBody(IgnoreCoroutines ? stmt(unless(coroutineBodyStmt())) + : stmt()), + isDefinition(), unless(isImplicit()), + unless(cxxMethodDecl(anyOf(isOverride(), isFinal()))), + has(typeLoc(forEach(ExpensiveValueParamDecl))), + decl().bind("functionDecl"))), this); } @@ -123,6 +126,7 @@ void UnnecessaryValueParamCheck::storeOptions( Options.store(Opts, "IncludeStyle", Inserter.getStyle()); Options.store(Opts, "AllowedTypes", utils::options::serializeStringList(AllowedTypes)); + Options.store(Opts, "IgnoreCoroutines", IgnoreCoroutines); } void UnnecessaryValueParamCheck::onEndOfTranslationUnit() { diff --git a/external/llvm-project/clang-tools-extra/clang-tidy/performance/UnnecessaryValueParamCheck.h b/external/llvm-project/clang-tools-extra/clang-tidy/performance/UnnecessaryValueParamCheck.h index 8bfd814d1635..b52043416e76 100644 --- a/external/llvm-project/clang-tools-extra/clang-tidy/performance/UnnecessaryValueParamCheck.h +++ b/external/llvm-project/clang-tools-extra/clang-tidy/performance/UnnecessaryValueParamCheck.h @@ -46,6 +46,7 @@ class UnnecessaryValueParamCheck : public ClangTidyCheck { ExprMutationAnalyzer::Memoized MutationAnalyzerCache; utils::IncludeInserter Inserter; const std::vector AllowedTypes; + bool IgnoreCoroutines; }; } // namespace clang::tidy::performance diff --git a/external/llvm-project/clang-tools-extra/clang-tidy/readability/FunctionSizeCheck.cpp b/external/llvm-project/clang-tools-extra/clang-tidy/readability/FunctionSizeCheck.cpp index 3313bcb39b7f..8e3a2e306dbf 100644 --- a/external/llvm-project/clang-tools-extra/clang-tidy/readability/FunctionSizeCheck.cpp +++ b/external/llvm-project/clang-tools-extra/clang-tidy/readability/FunctionSizeCheck.cpp @@ -108,6 +108,14 @@ class FunctionASTVisitor : public RecursiveASTVisitor { return true; } + bool TraverseConstructorInitializer(CXXCtorInitializer *Init) { + if (CountMemberInitAsStmt) + ++Info.Statements; + + Base::TraverseConstructorInitializer(Init); + return true; + } + struct FunctionInfo { unsigned Lines = 0; unsigned Statements = 0; @@ -120,6 +128,7 @@ class FunctionASTVisitor : public RecursiveASTVisitor { llvm::BitVector TrackedParent; unsigned StructNesting = 0; unsigned CurrentNestingLevel = 0; + bool CountMemberInitAsStmt; }; } // namespace @@ -135,7 +144,9 @@ FunctionSizeCheck::FunctionSizeCheck(StringRef Name, ClangTidyContext *Context) NestingThreshold( Options.get("NestingThreshold", DefaultNestingThreshold)), VariableThreshold( - Options.get("VariableThreshold", DefaultVariableThreshold)) {} + Options.get("VariableThreshold", DefaultVariableThreshold)), + CountMemberInitAsStmt( + Options.get("CountMemberInitAsStmt", DefaultCountMemberInitAsStmt)) {} void FunctionSizeCheck::storeOptions(ClangTidyOptions::OptionMap &Opts) { Options.store(Opts, "LineThreshold", LineThreshold); @@ -144,6 +155,7 @@ void FunctionSizeCheck::storeOptions(ClangTidyOptions::OptionMap &Opts) { Options.store(Opts, "ParameterThreshold", ParameterThreshold); Options.store(Opts, "NestingThreshold", NestingThreshold); Options.store(Opts, "VariableThreshold", VariableThreshold); + Options.store(Opts, "CountMemberInitAsStmt", CountMemberInitAsStmt); } void FunctionSizeCheck::registerMatchers(MatchFinder *Finder) { @@ -160,6 +172,7 @@ void FunctionSizeCheck::check(const MatchFinder::MatchResult &Result) { FunctionASTVisitor Visitor; Visitor.Info.NestingThreshold = NestingThreshold.value_or(-1); + Visitor.CountMemberInitAsStmt = CountMemberInitAsStmt; Visitor.TraverseDecl(const_cast(Func)); auto &FI = Visitor.Info; diff --git a/external/llvm-project/clang-tools-extra/clang-tidy/readability/FunctionSizeCheck.h b/external/llvm-project/clang-tools-extra/clang-tidy/readability/FunctionSizeCheck.h index 106c69ff0739..f668ab18fea5 100644 --- a/external/llvm-project/clang-tools-extra/clang-tidy/readability/FunctionSizeCheck.h +++ b/external/llvm-project/clang-tools-extra/clang-tidy/readability/FunctionSizeCheck.h @@ -47,6 +47,7 @@ class FunctionSizeCheck : public ClangTidyCheck { const std::optional ParameterThreshold; const std::optional NestingThreshold; const std::optional VariableThreshold; + const bool CountMemberInitAsStmt; static constexpr std::optional DefaultLineThreshold = std::nullopt; static constexpr std::optional DefaultStatementThreshold = 800U; @@ -58,6 +59,7 @@ class FunctionSizeCheck : public ClangTidyCheck { std::nullopt; static constexpr std::optional DefaultVariableThreshold = std::nullopt; + static constexpr bool DefaultCountMemberInitAsStmt = true; }; } // namespace clang::tidy::readability diff --git a/external/llvm-project/clang-tools-extra/clangd/ClangdLSPServer.cpp b/external/llvm-project/clang-tools-extra/clangd/ClangdLSPServer.cpp index 29321f7cd3fa..a703009e2b46 100644 --- a/external/llvm-project/clang-tools-extra/clangd/ClangdLSPServer.cpp +++ b/external/llvm-project/clang-tools-extra/clangd/ClangdLSPServer.cpp @@ -494,9 +494,9 @@ static std::vector semanticTokenModifiers() { void ClangdLSPServer::onInitialize(const InitializeParams &Params, Callback Reply) { // Determine character encoding first as it affects constructed ClangdServer. - if (Params.capabilities.offsetEncoding && !Opts.Encoding) { + if (Params.capabilities.PositionEncodings && !Opts.Encoding) { Opts.Encoding = OffsetEncoding::UTF16; // fallback - for (OffsetEncoding Supported : *Params.capabilities.offsetEncoding) + for (OffsetEncoding Supported : *Params.capabilities.PositionEncodings) if (Supported != OffsetEncoding::UnsupportedEncoding) { Opts.Encoding = Supported; break; @@ -686,6 +686,9 @@ void ClangdLSPServer::onInitialize(const InitializeParams &Params, ServerCaps["executeCommandProvider"] = llvm::json::Object{{"commands", Commands}}; + if (Opts.Encoding) + ServerCaps["positionEncoding"] = *Opts.Encoding; + llvm::json::Object Result{ {{"serverInfo", llvm::json::Object{ @@ -693,6 +696,9 @@ void ClangdLSPServer::onInitialize(const InitializeParams &Params, {"version", llvm::formatv("{0} {1} {2}", versionString(), featureString(), platformString())}}}, {"capabilities", std::move(ServerCaps)}}}; + + // TODO: offsetEncoding capability is a deprecated clangd extension and should + // be deleted. if (Opts.Encoding) Result["offsetEncoding"] = *Opts.Encoding; Reply(std::move(Result)); diff --git a/external/llvm-project/clang-tools-extra/clangd/Protocol.cpp b/external/llvm-project/clang-tools-extra/clangd/Protocol.cpp index c9e8a175b5d7..2c858e28fa24 100644 --- a/external/llvm-project/clang-tools-extra/clangd/Protocol.cpp +++ b/external/llvm-project/clang-tools-extra/clangd/Protocol.cpp @@ -497,10 +497,19 @@ bool fromJSON(const llvm::json::Value &Params, ClientCapabilities &R, if (auto Cancel = StaleRequestSupport->getBoolean("cancel")) R.CancelsStaleRequests = *Cancel; } + if (auto *PositionEncodings = General->get("positionEncodings")) { + R.PositionEncodings.emplace(); + if (!fromJSON(*PositionEncodings, *R.PositionEncodings, + P.field("general").field("positionEncodings"))) + return false; + } } if (auto *OffsetEncoding = O->get("offsetEncoding")) { - R.offsetEncoding.emplace(); - if (!fromJSON(*OffsetEncoding, *R.offsetEncoding, + R.PositionEncodings.emplace(); + elog("offsetEncoding capability is a deprecated clangd extension that'll " + "go away with clangd 23. Migrate to standard positionEncodings " + "capability introduced by LSP 3.17"); + if (!fromJSON(*OffsetEncoding, *R.PositionEncodings, P.field("offsetEncoding"))) return false; } @@ -536,8 +545,11 @@ bool fromJSON(const llvm::json::Value &Params, ClientCapabilities &R, } } if (auto *OffsetEncoding = Experimental->get("offsetEncoding")) { - R.offsetEncoding.emplace(); - if (!fromJSON(*OffsetEncoding, *R.offsetEncoding, + R.PositionEncodings.emplace(); + elog("offsetEncoding capability is a deprecated clangd extension that'll " + "go away with clangd 23. Migrate to standard positionEncodings " + "capability introduced by LSP 3.17"); + if (!fromJSON(*OffsetEncoding, *R.PositionEncodings, P.field("offsetEncoding"))) return false; } diff --git a/external/llvm-project/clang-tools-extra/clangd/Protocol.h b/external/llvm-project/clang-tools-extra/clangd/Protocol.h index 8a7809d6677e..3a6bf155ee15 100644 --- a/external/llvm-project/clang-tools-extra/clangd/Protocol.h +++ b/external/llvm-project/clang-tools-extra/clangd/Protocol.h @@ -528,8 +528,9 @@ struct ClientCapabilities { /// textDocument.semanticHighlightingCapabilities.semanticHighlighting bool TheiaSemanticHighlighting = false; - /// Supported encodings for LSP character offsets. (clangd extension). - std::optional> offsetEncoding; + /// Supported encodings for LSP character offsets. + /// general.positionEncodings + std::optional> PositionEncodings; /// The content format that should be used for Hover requests. /// textDocument.hover.contentEncoding diff --git a/external/llvm-project/clang-tools-extra/clangd/test/positionencoding.test b/external/llvm-project/clang-tools-extra/clangd/test/positionencoding.test new file mode 100644 index 000000000000..eea7a1a596e9 --- /dev/null +++ b/external/llvm-project/clang-tools-extra/clangd/test/positionencoding.test @@ -0,0 +1,32 @@ +# RUN: clangd -lit-test < %s | FileCheck -strict-whitespace %s +# This test verifies that we can negotiate UTF-8 offsets via the positionEncodings capability introduced in LSP 3.17. +{"jsonrpc":"2.0","id":0,"method":"initialize","params":{"processId":123,"rootPath":"clangd","capabilities":{"general":{"positionEncodings":["utf-8","utf-16"]}},"trace":"off"}} +# CHECK: "positionEncoding": "utf-8" +--- +{"jsonrpc":"2.0","method":"textDocument/didOpen","params":{"textDocument":{"uri":"test:///main.cpp","languageId":"cpp","version":1,"text":"/*ö*/int x;\nint y=x;"}}} +--- +{"jsonrpc":"2.0","id":1,"method":"textDocument/definition","params":{"textDocument":{"uri":"test:///main.cpp"},"position":{"line":1,"character":6}}} +# /*ö*/int x; +# 01234567890 +# x is character (and utf-16) range [9,10) but byte range [10,11). +# CHECK: "id": 1, +# CHECK-NEXT: "jsonrpc": "2.0", +# CHECK-NEXT: "result": [ +# CHECK-NEXT: { +# CHECK-NEXT: "range": { +# CHECK-NEXT: "end": { +# CHECK-NEXT: "character": 11, +# CHECK-NEXT: "line": 0 +# CHECK-NEXT: }, +# CHECK-NEXT: "start": { +# CHECK-NEXT: "character": 10, +# CHECK-NEXT: "line": 0 +# CHECK-NEXT: } +# CHECK-NEXT: }, +# CHECK-NEXT: "uri": "file://{{.*}}/main.cpp" +# CHECK-NEXT: } +# CHECK-NEXT: ] +--- +{"jsonrpc":"2.0","id":10000,"method":"shutdown"} +--- +{"jsonrpc":"2.0","method":"exit"} diff --git a/external/llvm-project/clang-tools-extra/docs/ReleaseNotes.rst b/external/llvm-project/clang-tools-extra/docs/ReleaseNotes.rst index 19ccd1790e75..fc51f3c9329a 100644 --- a/external/llvm-project/clang-tools-extra/docs/ReleaseNotes.rst +++ b/external/llvm-project/clang-tools-extra/docs/ReleaseNotes.rst @@ -136,6 +136,12 @@ New checks Finds unintended character output from ``unsigned char`` and ``signed char`` to an ``ostream``. +- New :doc:`cppcoreguidelines-use-enum-class + ` check. + + Finds unscoped (non-class) ``enum`` declarations and suggests using + ``enum class`` instead. + - New :doc:`portability-avoid-pragma-once ` check. @@ -191,11 +197,27 @@ Changes in existing checks ` check by fixing a false positive where ``strerror`` was flagged as MT-unsafe. +- Improved :doc:`cppcoreguidelines-avoid-goto + ` check by adding the option + `IgnoreMacros` to ignore ``goto`` labels defined in macros. + +- Improved :doc:`cppcoreguidelines-special-member-functions + ` check by + adding the option `IgnoreMacros` to ignore classes defined in macros. + - Improved :doc:`google-readability-namespace-comments ` check by adding the option `AllowOmittingNamespaceComments` to accept if a namespace comment is omitted entirely. +- Improved :doc:`hicpp-avoid-goto + ` check by adding the option + `IgnoreMacros` to ignore ``goto`` labels defined in macros. + +- Improved :doc:`hicpp-special-member-functions + ` check by adding the + option `IgnoreMacros` to ignore classes defined in macros. + - Improved :doc:`llvm-namespace-comment ` check by adding the option `AllowOmittingNamespaceComments` to accept if a namespace comment is omitted @@ -265,11 +287,18 @@ Changes in existing checks ` check performance by tolerating fix-it breaking compilation when functions is used as pointers to avoid matching usage of functions within the current compilation unit. + Added an option `IgnoreCoroutines` with the default value `true` to + suppress this check for coroutines where passing by reference may be unsafe. - Improved :doc:`readability-convert-member-functions-to-static ` check by fixing false positives on member functions with an explicit object parameter. +- Improved :doc:`readability-function-size + ` check by adding new option + `CountMemberInitAsStmt` that allows counting class member initializers in + constructors as statements. + - Improved :doc:`readability-math-missing-parentheses ` check by fixing false negatives where math expressions are the operand of assignment operators diff --git a/external/llvm-project/clang-tools-extra/docs/clang-tidy/checks/cppcoreguidelines/avoid-goto.rst b/external/llvm-project/clang-tools-extra/docs/clang-tidy/checks/cppcoreguidelines/avoid-goto.rst index 71b579a4ae99..1f9dc0a1edb3 100644 --- a/external/llvm-project/clang-tools-extra/docs/clang-tidy/checks/cppcoreguidelines/avoid-goto.rst +++ b/external/llvm-project/clang-tools-extra/docs/clang-tidy/checks/cppcoreguidelines/avoid-goto.rst @@ -50,3 +50,12 @@ Modern C++ needs ``goto`` only to jump out of nested loops. some_operation(); All other uses of ``goto`` are diagnosed in `C++`. + + +Options +------- + +.. option:: IgnoreMacros + + If set to `true`, the check will not warn if a ``goto`` statement is + expanded from a macro. Default is `false`. diff --git a/external/llvm-project/clang-tools-extra/docs/clang-tidy/checks/cppcoreguidelines/special-member-functions.rst b/external/llvm-project/clang-tools-extra/docs/clang-tidy/checks/cppcoreguidelines/special-member-functions.rst index 20f898fdab93..982d16fc8d23 100644 --- a/external/llvm-project/clang-tools-extra/docs/clang-tidy/checks/cppcoreguidelines/special-member-functions.rst +++ b/external/llvm-project/clang-tools-extra/docs/clang-tidy/checks/cppcoreguidelines/special-member-functions.rst @@ -85,3 +85,8 @@ Options struct A : boost::noncopyable { ~A() { std::cout << "dtor\n"; } }; + +.. option:: IgnoreMacros + + If set to `true`, the check will not give warnings for classes defined + inside macros. Default is `true`. diff --git a/external/llvm-project/clang-tools-extra/docs/clang-tidy/checks/cppcoreguidelines/use-enum-class.rst b/external/llvm-project/clang-tools-extra/docs/clang-tidy/checks/cppcoreguidelines/use-enum-class.rst new file mode 100644 index 000000000000..9e9f4c99dc24 --- /dev/null +++ b/external/llvm-project/clang-tools-extra/docs/clang-tidy/checks/cppcoreguidelines/use-enum-class.rst @@ -0,0 +1,35 @@ +.. title:: clang-tidy - cppcoreguidelines-use-enum-class + +cppcoreguidelines-use-enum-class +================================ + +Finds unscoped (non-class) ``enum`` declarations and suggests using +``enum class`` instead. + +This check implements `Enum.3 +`_ +from the C++ Core Guidelines." + +Example: + +.. code-block:: c++ + + enum E {}; // use "enum class E {};" instead + enum class E {}; // OK + + struct S { + enum E {}; // use "enum class E {};" instead + // OK with option IgnoreUnscopedEnumsInClasses + }; + + namespace N { + enum E {}; // use "enum class E {};" instead + } + +Options +------- + +.. option:: IgnoreUnscopedEnumsInClasses + + When `true`, ignores unscoped ``enum`` declarations in classes. + Default is `false`. diff --git a/external/llvm-project/clang-tools-extra/docs/clang-tidy/checks/list.rst b/external/llvm-project/clang-tools-extra/docs/clang-tidy/checks/list.rst index 5a79d61b1fd7..ccb78ee45e9c 100644 --- a/external/llvm-project/clang-tools-extra/docs/clang-tidy/checks/list.rst +++ b/external/llvm-project/clang-tools-extra/docs/clang-tidy/checks/list.rst @@ -212,6 +212,7 @@ Clang-Tidy Checks :doc:`cppcoreguidelines-rvalue-reference-param-not-moved `, :doc:`cppcoreguidelines-slicing `, :doc:`cppcoreguidelines-special-member-functions `, + :doc:`cppcoreguidelines-use-enum-class `, :doc:`cppcoreguidelines-virtual-class-destructor `, "Yes" :doc:`darwin-avoid-spinlock `, :doc:`darwin-dispatch-once-nonstatic `, "Yes" diff --git a/external/llvm-project/clang-tools-extra/docs/clang-tidy/checks/performance/enum-size.rst b/external/llvm-project/clang-tools-extra/docs/clang-tidy/checks/performance/enum-size.rst index f72b8c7eabc2..b7631139a013 100644 --- a/external/llvm-project/clang-tools-extra/docs/clang-tidy/checks/performance/enum-size.rst +++ b/external/llvm-project/clang-tools-extra/docs/clang-tidy/checks/performance/enum-size.rst @@ -34,7 +34,7 @@ dependent). .. code-block:: c++ // AFTER - enum Color : std:int8_t { + enum Color : std::int8_t { RED = -1, GREEN = 0, BLUE = 1 diff --git a/external/llvm-project/clang-tools-extra/docs/clang-tidy/checks/performance/unnecessary-value-param.rst b/external/llvm-project/clang-tools-extra/docs/clang-tidy/checks/performance/unnecessary-value-param.rst index dc86530b95f1..cd25d7d94d99 100644 --- a/external/llvm-project/clang-tools-extra/docs/clang-tidy/checks/performance/unnecessary-value-param.rst +++ b/external/llvm-project/clang-tools-extra/docs/clang-tidy/checks/performance/unnecessary-value-param.rst @@ -56,7 +56,7 @@ Will become: Because the fix-it needs to change the signature of the function, it may break builds if the function is used in multiple translation units or some codes -depends on funcion signatures. +depends on function signatures. Options ------- @@ -74,3 +74,10 @@ Options default is empty. If a name in the list contains the sequence `::`, it is matched against the qualified type name (i.e. ``namespace::Type``), otherwise it is matched against only the type name (i.e. ``Type``). + +.. option:: IgnoreCoroutines + + A boolean specifying whether the check should suggest passing parameters by + reference in coroutines. Passing parameters by reference in coroutines may + not be safe, please see :doc:`cppcoreguidelines-avoid-reference-coroutine-parameters <../cppcoreguidelines/avoid-reference-coroutine-parameters>` + for more information. Default is `true`. diff --git a/external/llvm-project/clang-tools-extra/docs/clang-tidy/checks/readability/function-size.rst b/external/llvm-project/clang-tools-extra/docs/clang-tidy/checks/readability/function-size.rst index 133bd3e9c8cb..253e7c483cb8 100644 --- a/external/llvm-project/clang-tools-extra/docs/clang-tidy/checks/readability/function-size.rst +++ b/external/llvm-project/clang-tools-extra/docs/clang-tidy/checks/readability/function-size.rst @@ -43,3 +43,8 @@ Options The default is `none` (ignore the number of variables). Please note that function parameters and variables declared in lambdas, GNU Statement Expressions, and nested class inline functions are not counted. + +.. option:: CountMemberInitAsStmt + + When `true`, count class member initializers in constructors as statements. + Default is `true`. diff --git a/external/llvm-project/clang-tools-extra/test/clang-doc/json/class-requires.cpp b/external/llvm-project/clang-tools-extra/test/clang-doc/json/class-requires.cpp new file mode 100644 index 000000000000..2dd25771d6d8 --- /dev/null +++ b/external/llvm-project/clang-tools-extra/test/clang-doc/json/class-requires.cpp @@ -0,0 +1,34 @@ +// RUN: rm -rf %t && mkdir -p %t +// RUN: clang-doc --extra-arg -std=c++20 --output=%t --format=json --executor=standalone %s +// RUN: FileCheck %s < %t/GlobalNamespace/MyClass.json + +template +concept Addable = requires(T a, T b) { + { a + b }; +}; + +template +requires Addable +struct MyClass; + +// CHECK: "Name": "MyClass", +// CHECK-NEXT: "Namespace": [ +// CHECK-NEXT: "GlobalNamespace" +// CHECK-NEXT: ], +// CHECK-NEXT: "Path": "GlobalNamespace", +// CHECK-NEXT: "TagType": "struct", +// CHECK-NEXT: "Template": { +// CHECK-NEXT: "Constraints": [ +// CHECK-NEXT: { +// CHECK-NEXT: "Expression": "Addable", +// CHECK-NEXT: "Name": "Addable", +// CHECK-NEXT: "Path": "", +// CHECK-NEXT: "QualName": "Addable", +// CHECK-NEXT: "USR": "{{[0-9A-F]*}}" +// CHECK-NEXT: } +// CHECK-NEXT: ], +// CHECK-NEXT: "Parameters": [ +// CHECK-NEXT: "typename T" +// CHECK-NEXT: ] +// CHECK-NEXT: }, +// CHECK-NEXT: "USR": "{{[0-9A-F]*}}" diff --git a/external/llvm-project/clang-tools-extra/test/clang-doc/json/compound-constraints.cpp b/external/llvm-project/clang-tools-extra/test/clang-doc/json/compound-constraints.cpp new file mode 100644 index 000000000000..b49dec5cc78c --- /dev/null +++ b/external/llvm-project/clang-tools-extra/test/clang-doc/json/compound-constraints.cpp @@ -0,0 +1,121 @@ +// RUN: rm -rf %t && mkdir -p %t +// RUN: clang-doc --extra-arg -std=c++20 --output=%t --format=json --executor=standalone %s +// RUN: FileCheck %s < %t/GlobalNamespace/index.json + +template concept Incrementable = requires (T a) { + a++; +}; + +template concept Decrementable = requires (T a) { + a--; +}; + +template concept PreIncrementable = requires (T a) { + ++a; +}; + +template concept PreDecrementable = requires (T a) { + --a; +}; + +template requires Incrementable && Decrementable void One(); + +template requires (Incrementable && Decrementable) void Two(); + +template requires (Incrementable && Decrementable) || (PreIncrementable && PreDecrementable) void Three(); + +template requires (Incrementable && Decrementable) || PreIncrementable void Four(); + +// CHECK: "Name": "One", +// CHECK: "Template": { +// CHECK-NEXT: "Constraints": [ +// CHECK-NEXT: { +// CHECK-NEXT: "Expression": "Incrementable", +// CHECK-NEXT: "Name": "Incrementable", +// CHECK-NEXT: "Path": "", +// CHECK-NEXT: "QualName": "Incrementable", +// CHECK-NEXT: "USR": "{{[0-9A-F]*}}" +// CHECK-NEXT: }, +// CHECK-NEXT: { +// CHECK-NEXT: "Expression": "Decrementable", +// CHECK-NEXT: "Name": "Decrementable", +// CHECK-NEXT: "Path": "", +// CHECK-NEXT: "QualName": "Decrementable", +// CHECK-NEXT: "USR": "{{[0-9A-F]*}}" +// CHECK-NEXT: } +// CHECK-NEXT: ], +// CHECK: "Name": "Two", +// CHECK: "Template": { +// CHECK-NEXT: "Constraints": [ +// CHECK-NEXT: { +// CHECK-NEXT: "Expression": "Incrementable", +// CHECK-NEXT: "Name": "Incrementable", +// CHECK-NEXT: "Path": "", +// CHECK-NEXT: "QualName": "Incrementable", +// CHECK-NEXT: "USR": "{{[0-9A-F]*}}" +// CHECK-NEXT: }, +// CHECK-NEXT: { +// CHECK-NEXT: "Expression": "Decrementable", +// CHECK-NEXT: "Name": "Decrementable", +// CHECK-NEXT: "Path": "", +// CHECK-NEXT: "QualName": "Decrementable", +// CHECK-NEXT: "USR": "{{[0-9A-F]*}}" +// CHECK-NEXT: } +// CHECK-NEXT: ], +// CHECK: "Name": "Three", +// CHECK: "Template": { +// CHECK-NEXT: "Constraints": [ +// CHECK-NEXT: { +// CHECK-NEXT: "Expression": "Incrementable", +// CHECK-NEXT: "Name": "Incrementable", +// CHECK-NEXT: "Path": "", +// CHECK-NEXT: "QualName": "Incrementable", +// CHECK-NEXT: "USR": "{{[0-9A-F]*}}" +// CHECK-NEXT: }, +// CHECK-NEXT: { +// CHECK-NEXT: "Expression": "Decrementable", +// CHECK-NEXT: "Name": "Decrementable", +// CHECK-NEXT: "Path": "", +// CHECK-NEXT: "QualName": "Decrementable", +// CHECK-NEXT: "USR": "{{[0-9A-F]*}}" +// CHECK-NEXT: }, +// CHECK-NEXT: { +// CHECK-NEXT: "Expression": "PreIncrementable", +// CHECK-NEXT: "Name": "PreIncrementable", +// CHECK-NEXT: "Path": "", +// CHECK-NEXT: "QualName": "PreIncrementable", +// CHECK-NEXT: "USR": "{{[0-9A-F]*}}" +// CHECK-NEXT: }, +// CHECK-NEXT: { +// CHECK-NEXT: "Expression": "PreDecrementable", +// CHECK-NEXT: "Name": "PreDecrementable", +// CHECK-NEXT: "Path": "", +// CHECK-NEXT: "QualName": "PreDecrementable", +// CHECK-NEXT: "USR": "{{[0-9A-F]*}}" +// CHECK-NEXT: } +// CHECK-NEXT: ], +// CHECK: "Name": "Four", +// CHECK: "Template": { +// CHECK-NEXT: "Constraints": [ +// CHECK-NEXT: { +// CHECK-NEXT: "Expression": "Incrementable", +// CHECK-NEXT: "Name": "Incrementable", +// CHECK-NEXT: "Path": "", +// CHECK-NEXT: "QualName": "Incrementable", +// CHECK-NEXT: "USR": "{{[0-9A-F]*}}" +// CHECK-NEXT: }, +// CHECK-NEXT: { +// CHECK-NEXT: "Expression": "Decrementable", +// CHECK-NEXT: "Name": "Decrementable", +// CHECK-NEXT: "Path": "", +// CHECK-NEXT: "QualName": "Decrementable", +// CHECK-NEXT: "USR": "{{[0-9A-F]*}}" +// CHECK-NEXT: }, +// CHECK-NEXT: { +// CHECK-NEXT: "Expression": "PreIncrementable", +// CHECK-NEXT: "Name": "PreIncrementable", +// CHECK-NEXT: "Path": "", +// CHECK-NEXT: "QualName": "PreIncrementable", +// CHECK-NEXT: "USR": "{{[0-9A-F]*}}" +// CHECK-NEXT: } +// CHECK-NEXT: ], diff --git a/external/llvm-project/clang-tools-extra/test/clang-doc/json/concept.cpp b/external/llvm-project/clang-tools-extra/test/clang-doc/json/concept.cpp new file mode 100644 index 000000000000..887c9d79146a --- /dev/null +++ b/external/llvm-project/clang-tools-extra/test/clang-doc/json/concept.cpp @@ -0,0 +1,38 @@ +// RUN: rm -rf %t && mkdir -p %t +// RUN: clang-doc --extra-arg -std=c++20 --output=%t --format=json --executor=standalone %s +// RUN: FileCheck %s < %t/GlobalNamespace/index.json + +// Requires that T suports post and pre-incrementing. +template +concept Incrementable = requires(T x) { + ++x; + x++; +}; + +// CHECK: { +// CHECK-NEXT: "Concepts": [ +// CHECK-NEXT: { +// CHECK-NEXT: "ConstraintExpression": "requires (T x) { ++x; x++; }", +// CHECK-NEXT: "Description": [ +// CHECK-NEXT: { +// CHECK-NEXT: "FullComment": { +// CHECK-NEXT: "Children": [ +// CHECK-NEXT: { +// CHECK-NEXT: "ParagraphComment": { +// CHECK-NEXT: "Children": [ +// CHECK-NEXT: { +// CHECK-NEXT: "TextComment": " Requires that T suports post and pre-incrementing." +// CHECK: ], +// CHECK-NEXT: "IsType": true, +// CHECK-NEXT: "Name": "Incrementable", +// CHECK-NEXT: "Template": { +// CHECK-NEXT: "Parameters": [ +// CHECK-NEXT: "typename T" +// CHECK-NEXT: ] +// CHECK-NEXT: }, +// CHECK-NEXT: "USR": "{{[0-9A-F]*}}" +// CHECK-NEXT: } +// CHECK-NEXT: ], +// CHECK: "Name": "", +// CHECK: "USR": "0000000000000000000000000000000000000000" +// CHECK: } diff --git a/external/llvm-project/clang-tools-extra/test/clang-doc/json/function-requires.cpp b/external/llvm-project/clang-tools-extra/test/clang-doc/json/function-requires.cpp new file mode 100644 index 000000000000..99eb2bdb898f --- /dev/null +++ b/external/llvm-project/clang-tools-extra/test/clang-doc/json/function-requires.cpp @@ -0,0 +1,79 @@ +// RUN: rm -rf %t && mkdir -p %t +// RUN: clang-doc --extra-arg -std=c++20 --output=%t --format=json --executor=standalone %s +// RUN: FileCheck %s < %t/GlobalNamespace/index.json + +template +concept Incrementable = requires(T x) { + ++x; + x++; +}; + +template void increment(T t) requires Incrementable; + +template Incrementable auto incrementTwo(T t); + +// CHECK: "Functions": [ +// CHECK-NEXT: { +// CHECK-NEXT: "IsStatic": false, +// CHECK-NEXT: "Name": "increment", +// CHECK-NEXT: "Params": [ +// CHECK-NEXT: { +// CHECK-NEXT: "Name": "t", +// CHECK-NEXT: "Type": "T" +// CHECK-NEXT: } +// CHECK-NEXT: ], +// CHECK-NEXT: "ReturnType": { +// CHECK-NEXT: "IsBuiltIn": false, +// CHECK-NEXT: "IsTemplate": false, +// CHECK-NEXT: "Name": "void", +// CHECK-NEXT: "QualName": "void", +// CHECK-NEXT: "USR": "0000000000000000000000000000000000000000" +// CHECK-NEXT: }, +// CHECK-NEXT: "Template": { +// CHECK-NEXT: "Constraints": [ +// CHECK-NEXT: { +// CHECK-NEXT: "Expression": "Incrementable", +// CHECK-NEXT: "Name": "Incrementable", +// CHECK-NEXT: "Path": "", +// CHECK-NEXT: "QualName": "Incrementable", +// CHECK-NEXT: "USR": "{{[0-9A-F]*}}" +// CHECK-NEXT: } +// CHECK-NEXT: ], +// CHECK-NEXT: "Parameters": [ +// CHECK-NEXT: "typename T" +// CHECK-NEXT: ] +// CHECK-NEXT: }, +// CHECK-NEXT: "USR": "{{[0-9A-F]*}}" +// CHECK-NEXT: }, +// CHECK-NEXT: { +// CHECK-NEXT: "IsStatic": false, +// CHECK-NEXT: "Name": "incrementTwo", +// CHECK-NEXT: "Params": [ +// CHECK-NEXT: { +// CHECK-NEXT: "Name": "t", +// CHECK-NEXT: "Type": "T" +// CHECK-NEXT: } +// CHECK-NEXT: ], +// CHECK-NEXT: "ReturnType": { +// CHECK-NEXT: "IsBuiltIn": false, +// CHECK-NEXT: "IsTemplate": false, +// CHECK-NEXT: "Name": "Incrementable auto", +// CHECK-NEXT: "QualName": "Incrementable auto", +// CHECK-NEXT: "USR": "0000000000000000000000000000000000000000" +// CHECK-NEXT: }, +// CHECK-NEXT: "Template": { +// CHECK-NEXT: "Constraints": [ +// CHECK-NEXT: { +// CHECK-NEXT: "Expression": "Incrementable", +// CHECK-NEXT: "Name": "Incrementable", +// CHECK-NEXT: "Path": "", +// CHECK-NEXT: "QualName": "Incrementable", +// CHECK-NEXT: "USR": "{{[0-9A-F]*}}" +// CHECK-NEXT: } +// CHECK-NEXT: ], +// CHECK-NEXT: "Parameters": [ +// CHECK-NEXT: "Incrementable T" +// CHECK-NEXT: ] +// CHECK-NEXT: }, +// CHECK-NEXT: "USR": "{{[0-9A-F]*}}" +// CHECK-NEXT: } diff --git a/external/llvm-project/clang-tools-extra/test/clang-doc/json/namespace.cpp b/external/llvm-project/clang-tools-extra/test/clang-doc/json/namespace.cpp index 928864be1feb..248d47351bd3 100644 --- a/external/llvm-project/clang-tools-extra/test/clang-doc/json/namespace.cpp +++ b/external/llvm-project/clang-tools-extra/test/clang-doc/json/namespace.cpp @@ -103,5 +103,23 @@ typedef int MyTypedef; // CHECK-NEXT: } // CHECK-NEXT: ], // CHECK-NEXT: "USR": "0000000000000000000000000000000000000000" -// CHECK-NOT: "Variables": [ +// CHECK-NOT: "Variables": [ +// CHECK-NOT: { +// CHECK-NOT: "IsStatic": true, +// CHECK-NOT: "Location": { +// CHECK-NOT: "Filename": "{{.*}}namespace.cpp", +// CHECK-NOT: "LineNumber": 13 +// CHECK-NOT: }, +// CHECK-NOT: "Name": "Global", +// CHECK-NOT: "Type": { +// COM: FIXME: IsBuiltIn emits as its default value +// CHECK-NOT: "IsBuiltIn": false, +// CHECK-NOT: "IsTemplate": false, +// CHECK-NOT: "Name": "int", +// CHECK-NOT: "QualName": "int", +// CHECK-NOT: "USR": "0000000000000000000000000000000000000000" +// CHECK-NOT: }, +// CHECK-NOT: "USR": "{{[0-9A-F]*}}" +// CHECK-NOT: } +// CHECK-NOT: ] // CHECK-NEXT: } diff --git a/external/llvm-project/clang-tools-extra/test/clang-reorder-fields/MacroExpandsToMultipleFields.cpp b/external/llvm-project/clang-tools-extra/test/clang-reorder-fields/MacroExpandsToMultipleFields.cpp new file mode 100644 index 000000000000..5bafcd19ea82 --- /dev/null +++ b/external/llvm-project/clang-tools-extra/test/clang-reorder-fields/MacroExpandsToMultipleFields.cpp @@ -0,0 +1,13 @@ +// RUN: clang-reorder-fields -record-name ::bar::Foo -fields-order z,y,x %s -- | FileCheck %s + +namespace bar { + +#define FIELDS_DECL int x; int y; // CHECK: {{^#define FIELDS_DECL int x; int y;}} + +// The order of fields should not change. +struct Foo { + FIELDS_DECL // CHECK: {{^ FIELDS_DECL}} + int z; // CHECK-NEXT: {{^ int z;}} +}; + +} // end namespace bar diff --git a/external/llvm-project/clang-tools-extra/test/clang-reorder-fields/MultipleFieldDeclsInStatement.cpp b/external/llvm-project/clang-tools-extra/test/clang-reorder-fields/MultipleFieldDeclsInStatement.cpp new file mode 100644 index 000000000000..437e7b91e27a --- /dev/null +++ b/external/llvm-project/clang-tools-extra/test/clang-reorder-fields/MultipleFieldDeclsInStatement.cpp @@ -0,0 +1,11 @@ +// RUN: clang-reorder-fields -record-name ::bar::Foo -fields-order z,y,x %s -- | FileCheck %s + +namespace bar { + +// The order of fields should not change. +struct Foo { + int x, y; // CHECK: {{^ int x, y;}} + double z; // CHECK-NEXT: {{^ double z;}} +}; + +} // end namespace bar diff --git a/external/llvm-project/clang-tools-extra/test/clang-reorder-fields/PreprocessorDirectiveAroundDefinition.cpp b/external/llvm-project/clang-tools-extra/test/clang-reorder-fields/PreprocessorDirectiveAroundDefinition.cpp new file mode 100644 index 000000000000..f00b4b0b57bf --- /dev/null +++ b/external/llvm-project/clang-tools-extra/test/clang-reorder-fields/PreprocessorDirectiveAroundDefinition.cpp @@ -0,0 +1,15 @@ +// RUN: clang-reorder-fields -record-name ::bar::Foo -fields-order y,x %s -- | FileCheck %s + +namespace bar { + +#define DEFINE_FOO + +// This is okay to reorder. +#ifdef DEFINE_FOO +struct Foo { + int x; // CHECK: {{^ int y;}} + int y; // CHECK-NEXT: {{^ int x;}} +}; +#endif + +} // end namespace bar diff --git a/external/llvm-project/clang-tools-extra/test/clang-reorder-fields/PreprocessorDirectiveAroundFields.cpp b/external/llvm-project/clang-tools-extra/test/clang-reorder-fields/PreprocessorDirectiveAroundFields.cpp new file mode 100644 index 000000000000..c37546a05afd --- /dev/null +++ b/external/llvm-project/clang-tools-extra/test/clang-reorder-fields/PreprocessorDirectiveAroundFields.cpp @@ -0,0 +1,15 @@ +// RUN: clang-reorder-fields -record-name ::bar::Foo -fields-order y,x %s -- | FileCheck %s + +namespace bar { + +#define DEFINE_FIELDS + +// This is okay to reorder. +struct Foo { +#ifdef DEFINE_FIELDS // CHECK: {{^#ifdef DEFINE_FIELDS}} + int x; // CHECK-NEXT: {{^ int y;}} + int y; // CHECK-NEXT: {{^ int x;}} +#endif // CHECK-NEXT: {{^#endif}} +}; + +} // end namespace bar diff --git a/external/llvm-project/clang-tools-extra/test/clang-reorder-fields/PreprocessorDirectiveInDefinition.cpp b/external/llvm-project/clang-tools-extra/test/clang-reorder-fields/PreprocessorDirectiveInDefinition.cpp new file mode 100644 index 000000000000..fee6b0e637b9 --- /dev/null +++ b/external/llvm-project/clang-tools-extra/test/clang-reorder-fields/PreprocessorDirectiveInDefinition.cpp @@ -0,0 +1,16 @@ +// RUN: clang-reorder-fields -record-name ::bar::Foo -fields-order z,y,x %s -- | FileCheck %s + +namespace bar { + +#define ADD_Z + +// The order of fields should not change. +struct Foo { + int x; // CHECK: {{^ int x;}} + int y; // CHECK-NEXT: {{^ int y;}} +#ifdef ADD_Z // CHECK-NEXT: {{^#ifdef ADD_Z}} + int z; // CHECK-NEXT: {{^ int z;}} +#endif // CHECK-NEXT: {{^#endif}} +}; + +} // end namespace bar diff --git a/external/llvm-project/clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/avoid-goto.cpp b/external/llvm-project/clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/avoid-goto.cpp index ee236bc44695..908132b7c9a6 100644 --- a/external/llvm-project/clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/avoid-goto.cpp +++ b/external/llvm-project/clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/avoid-goto.cpp @@ -1,12 +1,13 @@ -// RUN: %check_clang_tidy %s cppcoreguidelines-avoid-goto %t +// RUN: %check_clang_tidy -check-suffix=,MACRO %s cppcoreguidelines-avoid-goto %t +// RUN: %check_clang_tidy %s cppcoreguidelines-avoid-goto %t -- -config="{CheckOptions: { cppcoreguidelines-avoid-goto.IgnoreMacros: true }}" void noop() {} int main() { noop(); goto jump_to_me; - // CHECK-NOTES: [[@LINE-1]]:3: warning: avoid using 'goto' for flow control - // CHECK-NOTES: [[@LINE+3]]:1: note: label defined here + // CHECK-MESSAGES: [[@LINE-1]]:3: warning: avoid using 'goto' for flow control + // CHECK-MESSAGES: [[@LINE+3]]:1: note: label defined here noop(); jump_to_me:; @@ -14,14 +15,14 @@ jump_to_me:; jump_backwards:; noop(); goto jump_backwards; - // CHECK-NOTES: [[@LINE-1]]:3: warning: avoid using 'goto' for flow control - // CHECK-NOTES: [[@LINE-4]]:1: note: label defined here + // CHECK-MESSAGES: [[@LINE-1]]:3: warning: avoid using 'goto' for flow control + // CHECK-MESSAGES: [[@LINE-4]]:1: note: label defined here goto jump_in_line; ; jump_in_line:; - // CHECK-NOTES: [[@LINE-3]]:3: warning: avoid using 'goto' for flow control - // CHECK-NOTES: [[@LINE-2]]:1: note: label defined here + // CHECK-MESSAGES: [[@LINE-3]]:3: warning: avoid using 'goto' for flow control + // CHECK-MESSAGES: [[@LINE-2]]:1: note: label defined here // Test the GNU extension https://gcc.gnu.org/onlinedocs/gcc/Labels-as-Values.html some_label:; @@ -132,8 +133,41 @@ void jump_out_backwards() { for (int j = 0; j < 10; ++j) { if (i * j > 80) goto before_the_loop; - // CHECK-NOTES: [[@LINE-1]]:9: warning: avoid using 'goto' for flow control - // CHECK-NOTES: [[@LINE-8]]:1: note: label defined here + // CHECK-MESSAGES: [[@LINE-1]]:9: warning: avoid using 'goto' for flow control + // CHECK-MESSAGES: [[@LINE-8]]:1: note: label defined here } } } + +#define macro_goto_code \ + noop(); \ + goto jump_to_me; \ + noop(); \ +jump_to_me:; \ + +#define macro_goto_label jump_to_me:; +#define macro_goto_jump goto jump_to_me; + +void inside_macro_all() { + macro_goto_code + // CHECK-MESSAGES-MACRO: [[@LINE-1]]:3: warning: avoid using 'goto' for flow control + // CHECK-MESSAGES-MACRO: [[@LINE-2]]:3: note: label defined here +} + +void inside_macro_label() { + noop(); + goto jump_to_me; + // CHECK-MESSAGES: [[@LINE-1]]:3: warning: avoid using 'goto' for flow control + // CHECK-MESSAGES: [[@LINE+2]]:3: note: label defined here + noop(); + macro_goto_label +} + +void inside_macro_goto() { + noop(); + macro_goto_jump + // CHECK-MESSAGES-MACRO: [[@LINE-1]]:3: warning: avoid using 'goto' for flow control + // CHECK-MESSAGES-MACRO: [[@LINE+2]]:3: note: label defined here + noop(); + jump_to_me:; +} diff --git a/external/llvm-project/clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/special-member-functions-macros.cpp b/external/llvm-project/clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/special-member-functions-macros.cpp new file mode 100644 index 000000000000..58198979203e --- /dev/null +++ b/external/llvm-project/clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/special-member-functions-macros.cpp @@ -0,0 +1,57 @@ +// RUN: %check_clang_tidy %s cppcoreguidelines-special-member-functions %t -- -config="{CheckOptions: {cppcoreguidelines-special-member-functions.IgnoreMacros: false}}" -- + +class DefinesDestructor { + ~DefinesDestructor(); +}; +// CHECK-MESSAGES: [[@LINE-3]]:7: warning: class 'DefinesDestructor' defines a destructor but does not define a copy constructor, a copy assignment operator, a move constructor or a move assignment operator [cppcoreguidelines-special-member-functions] + +class DefinesDefaultedDestructor { + ~DefinesDefaultedDestructor() = default; +}; +// CHECK-MESSAGES: [[@LINE-3]]:7: warning: class 'DefinesDefaultedDestructor' defines a default destructor but does not define a copy constructor, a copy assignment operator, a move constructor or a move assignment operator [cppcoreguidelines-special-member-functions] + +class DefinesCopyConstructor { + DefinesCopyConstructor(const DefinesCopyConstructor &); +}; +// CHECK-MESSAGES: [[@LINE-3]]:7: warning: class 'DefinesCopyConstructor' defines a copy constructor but does not define a destructor, a copy assignment operator, a move constructor or a move assignment operator [cppcoreguidelines-special-member-functions] + +class DefinesNothing { +}; + +class DefinesEverything { + DefinesEverything(const DefinesEverything &); + DefinesEverything &operator=(const DefinesEverything &); + DefinesEverything(DefinesEverything &&); + DefinesEverything &operator=(DefinesEverything &&); + ~DefinesEverything(); +}; + +#define DEFINE_DESTRUCTOR_ONLY(ClassName) \ + class ClassName { \ + ~ClassName(); \ + }; + +#define DEFINE_COPY_CTOR_ONLY(ClassName) \ + class ClassName { \ + ClassName(const ClassName &); \ + }; + +#define DEFINE_CLASS_WITH_DTOR(ClassName) \ + class ClassName { \ + ~ClassName(); \ + }; + +DEFINE_DESTRUCTOR_ONLY(MacroDefinedClass1) +// CHECK-MESSAGES: [[@LINE-1]]:24: warning: class 'MacroDefinedClass1' defines a destructor but does not define a copy constructor, a copy assignment operator, a move constructor or a move assignment operator +DEFINE_COPY_CTOR_ONLY(MacroDefinedClass2) +// CHECK-MESSAGES: [[@LINE-1]]:23: warning: class 'MacroDefinedClass2' defines a copy constructor but does not define a destructor, a copy assignment operator, a move constructor or a move assignment operator +DEFINE_CLASS_WITH_DTOR(MacroDefinedClass3) +// CHECK-MESSAGES: [[@LINE-1]]:24: warning: class 'MacroDefinedClass3' defines a destructor but does not define a copy constructor, a copy assignment operator, a move constructor or a move assignment operator + +// Test partial macro expansion +#define CLASS_NAME MacroNamedClass +class CLASS_NAME { + ~MacroNamedClass(); +}; +// CHECK-MESSAGES: [[@LINE-3]]:7: warning: class 'MacroNamedClass' defines a destructor but does not define a copy constructor, a copy assignment operator, a move constructor or a move assignment operator + diff --git a/external/llvm-project/clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/special-member-functions.cpp b/external/llvm-project/clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/special-member-functions.cpp index 60c945c8e20c..28b515fb6afa 100644 --- a/external/llvm-project/clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/special-member-functions.cpp +++ b/external/llvm-project/clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/special-member-functions.cpp @@ -70,3 +70,29 @@ struct TemplateClass { // This should not cause problems. TemplateClass InstantiationWithInt; TemplateClass InstantiationWithDouble; + +#define DEFINE_DESTRUCTOR_ONLY(ClassName) \ + class ClassName { \ + ~ClassName(); \ + }; + +#define DEFINE_COPY_CTOR_ONLY(ClassName) \ + class ClassName { \ + ClassName(const ClassName &); \ + }; + +#define DEFINE_CLASS_WITH_DTOR(ClassName) \ + class ClassName { \ + ~ClassName(); \ + }; + +DEFINE_DESTRUCTOR_ONLY(MacroDefinedClass1) +DEFINE_COPY_CTOR_ONLY(MacroDefinedClass2) +DEFINE_CLASS_WITH_DTOR(MacroDefinedClass3) + +// Test partial macro expansion +#define CLASS_NAME MacroNamedClass +class CLASS_NAME { + ~MacroNamedClass(); +}; +// CHECK-MESSAGES: [[@LINE-3]]:7: warning: class 'MacroNamedClass' defines a destructor but does not define a copy constructor, a copy assignment operator, a move constructor or a move assignment operator diff --git a/external/llvm-project/clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/use-enum-class.cpp b/external/llvm-project/clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/use-enum-class.cpp new file mode 100644 index 000000000000..f53d787f80ef --- /dev/null +++ b/external/llvm-project/clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/use-enum-class.cpp @@ -0,0 +1,62 @@ +// RUN: %check_clang_tidy -std=c++11-or-later -check-suffix=ALL,DEFAULT %s \ +// RUN: cppcoreguidelines-use-enum-class %t -- + +// RUN: %check_clang_tidy -std=c++11-or-later -check-suffix=ALL %s \ +// RUN: cppcoreguidelines-use-enum-class %t -- \ +// RUN: -config="{CheckOptions: { \ +// RUN: cppcoreguidelines-use-enum-class.IgnoreUnscopedEnumsInClasses: true \ +// RUN: }}" -- + +enum E {}; +// CHECK-MESSAGES-ALL: :[[@LINE-1]]:6: warning: enum 'E' is unscoped, use 'enum class' instead + +enum class EC {}; + +enum struct ES {}; + +struct S { + enum E {}; + // CHECK-MESSAGES-DEFAULT: :[[@LINE-1]]:8: warning: enum 'E' is unscoped, use 'enum class' instead + enum class EC {}; +}; + +class C { + enum E {}; + // CHECK-MESSAGES-DEFAULT: :[[@LINE-1]]:8: warning: enum 'E' is unscoped, use 'enum class' instead + enum class EC {}; +}; + +template +class TC { + enum E {}; + // CHECK-MESSAGES-DEFAULT: :[[@LINE-1]]:8: warning: enum 'E' is unscoped, use 'enum class' instead + enum class EC {}; +}; + +union U { + enum E {}; + // CHECK-MESSAGES-DEFAULT: :[[@LINE-1]]:8: warning: enum 'E' is unscoped, use 'enum class' instead + enum class EC {}; +}; + +namespace { +enum E {}; +// CHECK-MESSAGES-ALL: :[[@LINE-1]]:6: warning: enum 'E' is unscoped, use 'enum class' instead +enum class EC {}; +} // namespace + +namespace N { +enum E {}; +// CHECK-MESSAGES-ALL: :[[@LINE-1]]:6: warning: enum 'E' is unscoped, use 'enum class' instead +enum class EC {}; +} // namespace N + +template +static void foo(); + +enum ForwardE : int; +// CHECK-MESSAGES-ALL: :[[@LINE-1]]:6: warning: enum 'ForwardE' is unscoped, use 'enum class' instead + +enum class ForwardEC : int; + +enum struct ForwardES : int; diff --git a/external/llvm-project/clang-tools-extra/test/clang-tidy/checkers/performance/unnecessary-value-param-coroutine.cpp b/external/llvm-project/clang-tools-extra/test/clang-tidy/checkers/performance/unnecessary-value-param-coroutine.cpp new file mode 100644 index 000000000000..0a84dc467647 --- /dev/null +++ b/external/llvm-project/clang-tools-extra/test/clang-tidy/checkers/performance/unnecessary-value-param-coroutine.cpp @@ -0,0 +1,65 @@ +// RUN: %check_clang_tidy -std=c++20-or-later %s performance-unnecessary-value-param %t -- -fix-errors +// RUN: %check_clang_tidy -std=c++20-or-later %s performance-unnecessary-value-param %t -- \ +// RUN: -config='{CheckOptions: {performance-unnecessary-value-param.IgnoreCoroutines: true}}' -fix-errors +// RUN: %check_clang_tidy -check-suffix=ALLOWED -std=c++20-or-later %s performance-unnecessary-value-param %t -- \ +// RUN: -config='{CheckOptions: {performance-unnecessary-value-param.IgnoreCoroutines: false}}' -fix-errors + +namespace std { + +template struct coroutine_traits { + using promise_type = typename Ret::promise_type; +}; + +template struct coroutine_handle { + static coroutine_handle from_address(void *) noexcept; + static coroutine_handle from_promise(Promise &promise); + constexpr void *address() const noexcept; +}; + +template <> struct coroutine_handle { + template + coroutine_handle(coroutine_handle) noexcept; + static coroutine_handle from_address(void *); + constexpr void *address() const noexcept; +}; + +struct suspend_always { + bool await_ready() noexcept { return false; } + void await_suspend(coroutine_handle<>) noexcept {} + void await_resume() noexcept {} +}; + +struct suspend_never { + bool await_ready() noexcept { return true; } + void await_suspend(coroutine_handle<>) noexcept {} + void await_resume() noexcept {} +}; + +} // namespace std + +struct ReturnObject { + struct promise_type { + ReturnObject get_return_object() { return {}; } + ReturnObject return_void() { return {}; } + std::suspend_always initial_suspend() { return {}; } + std::suspend_always final_suspend() noexcept { return {}; } + void unhandled_exception() {} + std::suspend_always yield_value(int value) { return {}; } + }; +}; + +struct A { + A(const A&); +}; + +ReturnObject foo_coroutine(const A a) { +// CHECK-MESSAGES-ALLOWED: [[@LINE-1]]:36: warning: the const qualified parameter 'a' +// CHECK-FIXES: ReturnObject foo_coroutine(const A a) { + co_return; +} + +ReturnObject foo_not_coroutine(const A a) { +// CHECK-MESSAGES: [[@LINE-1]]:40: warning: the const qualified parameter 'a' +// CHECK-MESSAGES-ALLOWED: [[@LINE-2]]:40: warning: the const qualified parameter 'a' + return ReturnObject{}; +} diff --git a/external/llvm-project/clang-tools-extra/test/clang-tidy/checkers/readability/function-size-no-member-init-as-stmts.cpp b/external/llvm-project/clang-tools-extra/test/clang-tidy/checkers/readability/function-size-no-member-init-as-stmts.cpp new file mode 100644 index 000000000000..d335988e5e03 --- /dev/null +++ b/external/llvm-project/clang-tools-extra/test/clang-tidy/checkers/readability/function-size-no-member-init-as-stmts.cpp @@ -0,0 +1,73 @@ +// RUN: %check_clang_tidy %s readability-function-size %t -- \ +// RUN: -config='{CheckOptions: { \ +// RUN: readability-function-size.LineThreshold: 0, \ +// RUN: readability-function-size.StatementThreshold: 0, \ +// RUN: readability-function-size.BranchThreshold: 0, \ +// RUN: readability-function-size.ParameterThreshold: 5, \ +// RUN: readability-function-size.NestingThreshold: 2, \ +// RUN: readability-function-size.VariableThreshold: 1, \ +// RUN: readability-function-size.CountMemberInitAsStmt: false \ +// RUN: }}' + +// Bad formatting is intentional, don't run clang-format over the whole file! + +void foo1() { +} + +void foo2() {;} +// CHECK-MESSAGES: :[[@LINE-1]]:6: warning: function 'foo2' exceeds recommended size/complexity thresholds [readability-function-size] +// CHECK-MESSAGES: :[[@LINE-2]]:6: note: 1 statements (threshold 0) + +struct A { + A(int c, int d) : a(0), b(c) { ; } + int a; + int b; +}; +// CHECK-MESSAGES: :[[@LINE-4]]:3: warning: function 'A' exceeds recommended size/complexity thresholds [readability-function-size] +// CHECK-MESSAGES: :[[@LINE-5]]:3: note: 1 statements (threshold 0) + +struct B { + B(int x, int y, int z) : a(x + y * z), b(), c_a(y, z) { + ; + } + int a; + int b; + A c_a; +}; +// CHECK-MESSAGES: :[[@LINE-7]]:3: warning: function 'B' exceeds recommended size/complexity thresholds [readability-function-size] +// CHECK-MESSAGES: :[[@LINE-8]]:3: note: 2 lines including whitespace and comments (threshold 0) +// CHECK-MESSAGES: :[[@LINE-9]]:3: note: 1 statements (threshold 0) + +struct C : A, B { + // 0 statements + C() : A(0, 4), B(1, 2, 3) {} +}; + +template +struct TemplateC { + // 0 statements + TemplateC() : a(3) {} + T a; +}; + +template +struct TemplateD { + template + TemplateD(U&& val) : member(val) { + ; + } + + T member; +}; +// CHECK-MESSAGES: :[[@LINE-6]]:3: warning: function 'TemplateD' exceeds recommended size/complexity thresholds [readability-function-size] +// CHECK-MESSAGES: :[[@LINE-7]]:3: note: 2 lines including whitespace and comments (threshold 0) +// CHECK-MESSAGES: :[[@LINE-8]]:3: note: 1 statements (threshold 0) + +void instantiate() { + TemplateC c; + TemplateD d(5); +} +// CHECK-MESSAGES: :[[@LINE-4]]:6: warning: function 'instantiate' exceeds recommended size/complexity thresholds [readability-function-size] +// CHECK-MESSAGES: :[[@LINE-5]]:6: note: 3 lines including whitespace and comments (threshold 0) +// CHECK-MESSAGES: :[[@LINE-6]]:6: note: 2 statements (threshold 0) +// CHECK-MESSAGES: :[[@LINE-7]]:6: note: 2 variables (threshold 1) diff --git a/external/llvm-project/clang-tools-extra/test/clang-tidy/checkers/readability/function-size.cpp b/external/llvm-project/clang-tools-extra/test/clang-tidy/checkers/readability/function-size.cpp index 45b2604b43d0..9364fa3077da 100644 --- a/external/llvm-project/clang-tools-extra/test/clang-tidy/checkers/readability/function-size.cpp +++ b/external/llvm-project/clang-tools-extra/test/clang-tidy/checkers/readability/function-size.cpp @@ -319,3 +319,60 @@ void variables_16() { // CHECK-MESSAGES: :[[@LINE-5]]:6: note: 3 lines including whitespace and comments (threshold 0) // CHECK-MESSAGES: :[[@LINE-6]]:6: note: 4 statements (threshold 0) // CHECK-MESSAGES: :[[@LINE-7]]:6: note: 2 variables (threshold 1) + +struct A { + A(int c, int d) : a(0), b(c) { ; } + int a; + int b; +}; +// CHECK-MESSAGES: :[[@LINE-4]]:3: warning: function 'A' exceeds recommended size/complexity thresholds [readability-function-size] +// CHECK-MESSAGES: :[[@LINE-5]]:3: note: 3 statements (threshold 0) + +struct B { + B(int x, int y, int z) : a(x + y * z), b(), c_a(y, z) { + ; + } + int a; + int b; + A c_a; +}; +// CHECK-MESSAGES: :[[@LINE-7]]:3: warning: function 'B' exceeds recommended size/complexity thresholds [readability-function-size] +// CHECK-MESSAGES: :[[@LINE-8]]:3: note: 2 lines including whitespace and comments (threshold 0) +// CHECK-MESSAGES: :[[@LINE-9]]:3: note: 4 statements (threshold 0) + +struct C : A, B { + C() : A(0, 4), B(1, 2, 3) {} +}; +// CHECK-MESSAGES: :[[@LINE-2]]:3: warning: function 'C' exceeds recommended size/complexity thresholds [readability-function-size] +// CHECK-MESSAGES: :[[@LINE-3]]:3: note: 2 statements (threshold 0) + +template +struct TemplateC { + // 0 statements + TemplateC() : a(3) {} + T a; +}; +// CHECK-MESSAGES: :[[@LINE-3]]:3: warning: function 'TemplateC' exceeds recommended size/complexity thresholds [readability-function-size] +// CHECK-MESSAGES: :[[@LINE-4]]:3: note: 1 statements (threshold 0) + +template +struct TemplateD { + template + TemplateD(U&& val) : member(val) { + ; + } + + T member; +}; +// CHECK-MESSAGES: :[[@LINE-6]]:3: warning: function 'TemplateD' exceeds recommended size/complexity thresholds [readability-function-size] +// CHECK-MESSAGES: :[[@LINE-7]]:3: note: 2 lines including whitespace and comments (threshold 0) +// CHECK-MESSAGES: :[[@LINE-8]]:3: note: 2 statements (threshold 0) + +void instantiate() { + TemplateC c; + TemplateD d(5); +} +// CHECK-MESSAGES: :[[@LINE-4]]:6: warning: function 'instantiate' exceeds recommended size/complexity thresholds [readability-function-size] +// CHECK-MESSAGES: :[[@LINE-5]]:6: note: 3 lines including whitespace and comments (threshold 0) +// CHECK-MESSAGES: :[[@LINE-6]]:6: note: 2 statements (threshold 0) +// CHECK-MESSAGES: :[[@LINE-7]]:6: note: 2 variables (threshold 1) diff --git a/external/llvm-project/clang-tools-extra/unittests/clang-doc/BitcodeTest.cpp b/external/llvm-project/clang-tools-extra/unittests/clang-doc/BitcodeTest.cpp index 659870d2a5c0..a38dfd303660 100644 --- a/external/llvm-project/clang-tools-extra/unittests/clang-doc/BitcodeTest.cpp +++ b/external/llvm-project/clang-tools-extra/unittests/clang-doc/BitcodeTest.cpp @@ -37,6 +37,8 @@ static std::string writeInfo(Info *I) { return writeInfo(*static_cast(I)); case InfoType::IT_typedef: return writeInfo(*static_cast(I)); + case InfoType::IT_concept: + return writeInfo(*static_cast(I)); case InfoType::IT_default: return ""; } diff --git a/external/llvm-project/clang/docs/ClangFormatStyleOptions.rst b/external/llvm-project/clang/docs/ClangFormatStyleOptions.rst index 83716cc049ee..548c73af6587 100644 --- a/external/llvm-project/clang/docs/ClangFormatStyleOptions.rst +++ b/external/llvm-project/clang/docs/ClangFormatStyleOptions.rst @@ -6992,7 +6992,7 @@ the configuration (without a prefix: ``Auto``). .. code-block:: c++ namespace N1 { - namespace N2 + namespace N2 { function(); } } diff --git a/external/llvm-project/clang/docs/CommandGuide/clang.rst b/external/llvm-project/clang/docs/CommandGuide/clang.rst index 1b8776c5e9ad..7d49f2cc28a1 100644 --- a/external/llvm-project/clang/docs/CommandGuide/clang.rst +++ b/external/llvm-project/clang/docs/CommandGuide/clang.rst @@ -460,8 +460,11 @@ Code Generation Options :option:`-Oz` Like :option:`-Os` (and thus :option:`-O2`), but reduces code size further. - :option:`-Og` Like :option:`-O1`. In future versions, this option might - disable different optimizations in order to improve debuggability. + :option:`-Og` Similar to :option:`-O1`, but with slightly reduced + optimization and better variable visibility. The same optimizations are run + as at :option:`-O1`, but the ``-fextend-variable-liveness`` flag is + also set, which tries to prevent optimizations from reducing the liveness of + user variables, improving their availability when debugging. :option:`-O` Equivalent to :option:`-O1`. diff --git a/external/llvm-project/clang/docs/ReleaseNotes.rst b/external/llvm-project/clang/docs/ReleaseNotes.rst index 12c68b96f253..0d7173d6b4a4 100644 --- a/external/llvm-project/clang/docs/ReleaseNotes.rst +++ b/external/llvm-project/clang/docs/ReleaseNotes.rst @@ -65,8 +65,10 @@ C++ Specific Potentially Breaking Changes standard library already have their own bespoke builtins. - A workaround for libstdc++4.7 has been removed. Note that 4.8.3 remains the oldest supported libstdc++ version. - - Added ``!nonnull/!align`` metadata to load of references for better codegen. +- Checking for int->enum conversions in constant expressions is more strict; + in particular, ``const E x = (E)-1;`` is not treated as a constant if it's + out of range. This impacts old versions of Boost. (#GH143034) ABI Changes in This Version --------------------------- @@ -293,6 +295,8 @@ C23 Feature Support type. Fixes #GH140887 - Documented `WG14 N3006 `_ which clarified how Clang is handling underspecified object declarations. +- Clang now accepts single variadic parameter in type-name. It's a part of + `WG14 N2975 `_ C11 Feature Support ^^^^^^^^^^^^^^^^^^^ @@ -325,6 +329,9 @@ Non-comprehensive list of changes in this release ``__reference_constructs_from_temporary`` should be used instead. (#GH44056) - Added `__builtin_get_vtable_pointer` to directly load the primary vtable pointer from a polymorphic object. +- Clang no longer rejects reinterpret_cast conversions between indirect + ARC-managed pointers and other pointer types. The prior behavior was overly + strict and inconsistent with the ARC specification. New Compiler Flags ------------------ @@ -339,6 +346,8 @@ New Compiler Flags - New option ``-Wnrvo`` added and disabled by default to warn about missed NRVO opportunities. +- New option ``-ignore-pch`` added to disable precompiled headers. It overrides ``-emit-pch`` and ``-include-pch``. (#GH142409, `PCHDocs `_). + Deprecated Compiler Flags ------------------------- @@ -357,6 +366,12 @@ Modified Compiler Flags - The ``-fchar8_t`` flag is no longer considered in non-C++ languages modes. (#GH55373) +- The ``-fveclib=libmvec`` option now supports AArch64 targets (requires GLIBC 2.40 or newer). + +- The ``-Og`` optimization flag now sets ``-fextend-variable-liveness``, + reducing performance slightly while reducing the number of optimized-out + variables. (#GH118026) + Removed Compiler Flags ------------------------- @@ -704,6 +719,8 @@ Bug Fixes in This Version ``#include`` directive. (#GH138094) - Fixed a crash during constant evaluation involving invalid lambda captures (#GH138832) +- Fixed compound literal is not constant expression inside initializer list + (#GH87867) - Fixed a crash when instantiating an invalid dependent friend template specialization. (#GH139052) - Fixed a crash with an invalid member function parameter list with a default @@ -857,6 +874,7 @@ Bug Fixes to C++ Support - Fixed the handling of pack indexing types in the constraints of a member function redeclaration. (#GH138255) - Clang now correctly parses arbitrary order of ``[[]]``, ``__attribute__`` and ``alignas`` attributes for declarations (#GH133107) - Fixed a crash when forming an invalid function type in a dependent context. (#GH138657) (#GH115725) (#GH68852) +- Fixed a function declaration mismatch that caused inconsistencies between concepts and variable template declarations. (#GH139476) - Clang no longer segfaults when there is a configuration mismatch between modules and their users (http://crbug.com/400353616). - Fix an incorrect deduction when calling an explicit object member function template through an overload set address. - Fixed bug in constant evaluation that would allow using the value of a diff --git a/external/llvm-project/clang/docs/UsersManual.rst b/external/llvm-project/clang/docs/UsersManual.rst index 62844f7e6a2f..284a404026df 100644 --- a/external/llvm-project/clang/docs/UsersManual.rst +++ b/external/llvm-project/clang/docs/UsersManual.rst @@ -1458,6 +1458,19 @@ will be processed from the PCH file. Otherwise, Clang will report an error. ``test.h`` since ``test.h`` was included directly in the source file and not specified on the command line using ``-include-pch``. +Ignoring a PCH File +^^^^^^^^^^^^^^^^^^^ + +To ignore PCH options, a `-ignore-pch` option is passed to ``clang``: + +.. code-block:: console + + $ clang -x c-header test.h -Xclang -ignore-pch -o test.h.pch + $ clang -include-pch test.h.pch -Xclang -ignore-pch test.c -o test + +This option disables precompiled headers, overrides -emit-pch and -include-pch. +test.h.pch is not generated and not used as a prefix header. + Relocatable PCH Files ^^^^^^^^^^^^^^^^^^^^^ diff --git a/external/llvm-project/clang/include/clang/AST/ASTContext.h b/external/llvm-project/clang/include/clang/AST/ASTContext.h index e01361e2466b..10537c94babd 100644 --- a/external/llvm-project/clang/include/clang/AST/ASTContext.h +++ b/external/llvm-project/clang/include/clang/AST/ASTContext.h @@ -814,7 +814,7 @@ class ASTContext : public RefCountedBase { llvm::StringRef backupStr(llvm::StringRef S) const { char *Buf = new (*this) char[S.size()]; - std::copy(S.begin(), S.end(), Buf); + llvm::copy(S, Buf); return llvm::StringRef(Buf, S.size()); } diff --git a/external/llvm-project/clang/include/clang/AST/AbstractBasicReader.h b/external/llvm-project/clang/include/clang/AST/AbstractBasicReader.h index 586ad3be62a7..514f4cef3a69 100644 --- a/external/llvm-project/clang/include/clang/AST/AbstractBasicReader.h +++ b/external/llvm-project/clang/include/clang/AST/AbstractBasicReader.h @@ -143,8 +143,7 @@ class DataStreamBasicReader : public BasicReaderBase { // structure into a single data stream. Impl &readObject() { return asImpl(); } - template - llvm::ArrayRef readArray(llvm::SmallVectorImpl &buffer) { + template ArrayRef readArray(llvm::SmallVectorImpl &buffer) { assert(buffer.empty()); uint32_t size = asImpl().readUInt32(); diff --git a/external/llvm-project/clang/include/clang/AST/AbstractBasicWriter.h b/external/llvm-project/clang/include/clang/AST/AbstractBasicWriter.h index f65d94abc2ff..fedde8a2e46c 100644 --- a/external/llvm-project/clang/include/clang/AST/AbstractBasicWriter.h +++ b/external/llvm-project/clang/include/clang/AST/AbstractBasicWriter.h @@ -138,8 +138,7 @@ class DataStreamBasicWriter : public BasicWriterBase { asImpl().writeUInt32(uint32_t(value)); } - template - void writeArray(llvm::ArrayRef array) { + template void writeArray(ArrayRef array) { asImpl().writeUInt32(array.size()); for (const T &elt : array) { WriteDispatcher::write(asImpl(), elt); diff --git a/external/llvm-project/clang/include/clang/AST/ComputeDependence.h b/external/llvm-project/clang/include/clang/AST/ComputeDependence.h index e96275e5f2e0..c298f2620f21 100644 --- a/external/llvm-project/clang/include/clang/AST/ComputeDependence.h +++ b/external/llvm-project/clang/include/clang/AST/ComputeDependence.h @@ -15,7 +15,7 @@ #include "clang/AST/DependenceFlags.h" #include "clang/Basic/ExceptionSpecificationType.h" -#include "llvm/ADT/ArrayRef.h" +#include "clang/Basic/LLVM.h" namespace clang { @@ -180,7 +180,7 @@ ExprDependence computeDependence(ConceptSpecializationExpr *E, ExprDependence computeDependence(SYCLUniqueStableNameExpr *E); ExprDependence computeDependence(PredefinedExpr *E); -ExprDependence computeDependence(CallExpr *E, llvm::ArrayRef PreArgs); +ExprDependence computeDependence(CallExpr *E, ArrayRef PreArgs); ExprDependence computeDependence(OffsetOfExpr *E); ExprDependence computeDependence(MemberExpr *E); ExprDependence computeDependence(ShuffleVectorExpr *E); diff --git a/external/llvm-project/clang/include/clang/AST/Decl.h b/external/llvm-project/clang/include/clang/AST/Decl.h index 05aac15b30cd..0da940883b6f 100644 --- a/external/llvm-project/clang/include/clang/AST/Decl.h +++ b/external/llvm-project/clang/include/clang/AST/Decl.h @@ -1352,6 +1352,11 @@ class VarDecl : public DeclaratorDecl, public Redeclarable { return const_cast(this)->getInitializingDeclaration(); } + /// Checks whether this declaration has an initializer with side effects, + /// without triggering deserialization if the initializer is not yet + /// deserialized. + bool hasInitWithSideEffects() const; + /// Determine whether this variable's value might be usable in a /// constant expression, according to the relevant language standard. /// This only checks properties of the declaration, and does not check @@ -3417,16 +3422,13 @@ class IndirectFieldDecl : public ValueDecl, static IndirectFieldDecl *Create(ASTContext &C, DeclContext *DC, SourceLocation L, const IdentifierInfo *Id, - QualType T, - llvm::MutableArrayRef CH); + QualType T, MutableArrayRef CH); static IndirectFieldDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID); using chain_iterator = ArrayRef::const_iterator; - ArrayRef chain() const { - return llvm::ArrayRef(Chaining, ChainingSize); - } + ArrayRef chain() const { return {Chaining, ChainingSize}; } chain_iterator chain_begin() const { return chain().begin(); } chain_iterator chain_end() const { return chain().end(); } diff --git a/external/llvm-project/clang/include/clang/AST/DeclCXX.h b/external/llvm-project/clang/include/clang/AST/DeclCXX.h index df76e6f5015b..05cddd024d7c 100644 --- a/external/llvm-project/clang/include/clang/AST/DeclCXX.h +++ b/external/llvm-project/clang/include/clang/AST/DeclCXX.h @@ -365,12 +365,10 @@ class CXXRecordDecl : public RecordDecl { return getVBasesSlowCase(); } - ArrayRef bases() const { - return llvm::ArrayRef(getBases(), NumBases); - } + ArrayRef bases() const { return {getBases(), NumBases}; } ArrayRef vbases() const { - return llvm::ArrayRef(getVBases(), NumVBases); + return {getVBases(), NumVBases}; } private: @@ -4190,7 +4188,7 @@ class BindingDecl : public ValueDecl { Expr *getBinding() const { return Binding; } // Get the array of nested BindingDecls when the binding represents a pack. - llvm::ArrayRef getBindingPackDecls() const; + ArrayRef getBindingPackDecls() const; /// Get the decomposition declaration that this binding represents a /// decomposition of. @@ -4269,11 +4267,11 @@ class DecompositionDecl final // Provide a flattened range to visit each binding. auto flat_bindings() const { - llvm::ArrayRef Bindings = bindings(); - llvm::ArrayRef PackBindings; + ArrayRef Bindings = bindings(); + ArrayRef PackBindings; // Split the bindings into subranges split by the pack. - llvm::ArrayRef BeforePackBindings = Bindings.take_until( + ArrayRef BeforePackBindings = Bindings.take_until( [](BindingDecl *BD) { return BD->isParameterPack(); }); Bindings = Bindings.drop_front(BeforePackBindings.size()); diff --git a/external/llvm-project/clang/include/clang/AST/DeclObjC.h b/external/llvm-project/clang/include/clang/AST/DeclObjC.h index 6e582627c45e..9014d76f8433 100644 --- a/external/llvm-project/clang/include/clang/AST/DeclObjC.h +++ b/external/llvm-project/clang/include/clang/AST/DeclObjC.h @@ -371,7 +371,7 @@ class ObjCMethodDecl : public NamedDecl, public DeclContext { // ArrayRef access to formal parameters. This should eventually // replace the iterator interface above. ArrayRef parameters() const { - return llvm::ArrayRef(const_cast(getParams()), NumParams); + return {const_cast(getParams()), NumParams}; } ParmVarDecl *getParamDecl(unsigned Idx) { diff --git a/external/llvm-project/clang/include/clang/AST/DeclOpenMP.h b/external/llvm-project/clang/include/clang/AST/DeclOpenMP.h index 2d07f9d9f5d8..f3e18ad0339a 100644 --- a/external/llvm-project/clang/include/clang/AST/DeclOpenMP.h +++ b/external/llvm-project/clang/include/clang/AST/DeclOpenMP.h @@ -118,12 +118,12 @@ class OMPThreadPrivateDecl final : public OMPDeclarativeDirective { ArrayRef getVars() const { auto **Storage = reinterpret_cast(Data->getChildren().data()); - return llvm::ArrayRef(Storage, Data->getNumChildren()); + return {Storage, Data->getNumChildren()}; } MutableArrayRef getVars() { auto **Storage = reinterpret_cast(Data->getChildren().data()); - return llvm::MutableArrayRef(Storage, Data->getNumChildren()); + return {Storage, Data->getNumChildren()}; } void setVars(ArrayRef VL); @@ -482,12 +482,12 @@ class OMPAllocateDecl final : public OMPDeclarativeDirective { ArrayRef getVars() const { auto **Storage = reinterpret_cast(Data->getChildren().data()); - return llvm::ArrayRef(Storage, Data->getNumChildren()); + return {Storage, Data->getNumChildren()}; } MutableArrayRef getVars() { auto **Storage = reinterpret_cast(Data->getChildren().data()); - return llvm::MutableArrayRef(Storage, Data->getNumChildren()); + return {Storage, Data->getNumChildren()}; } void setVars(ArrayRef VL); diff --git a/external/llvm-project/clang/include/clang/AST/DeclTemplate.h b/external/llvm-project/clang/include/clang/AST/DeclTemplate.h index 8d8b1ca93882..1ff6cc6fcb7d 100644 --- a/external/llvm-project/clang/include/clang/AST/DeclTemplate.h +++ b/external/llvm-project/clang/include/clang/AST/DeclTemplate.h @@ -139,10 +139,8 @@ class TemplateParameterList final unsigned size() const { return NumParams; } bool empty() const { return NumParams == 0; } - ArrayRef asArray() { return llvm::ArrayRef(begin(), end()); } - ArrayRef asArray() const { - return llvm::ArrayRef(begin(), size()); - } + ArrayRef asArray() { return {begin(), end()}; } + ArrayRef asArray() const { return {begin(), size()}; } NamedDecl* getParam(unsigned Idx) { assert(Idx < size() && "Template parameter index out-of-range"); @@ -279,7 +277,7 @@ class TemplateArgumentList final /// Produce this as an array ref. ArrayRef asArray() const { - return llvm::ArrayRef(data(), size()); + return getTrailingObjects(size()); } /// Retrieve the number of template arguments in this @@ -287,9 +285,7 @@ class TemplateArgumentList final unsigned size() const { return NumArguments; } /// Retrieve a pointer to the template argument list. - const TemplateArgument *data() const { - return getTrailingObjects(); - } + const TemplateArgument *data() const { return getTrailingObjects(); } }; void *allocateDefaultArgStorageChain(const ASTContext &C); @@ -505,12 +501,10 @@ class FunctionTemplateSpecializationInfo final TemplateArgumentsAsWritten(TemplateArgsAsWritten), PointOfInstantiation(POI) { if (MSInfo) - getTrailingObjects()[0] = MSInfo; + getTrailingObjects()[0] = MSInfo; } - size_t numTrailingObjects(OverloadToken) const { - return Function.getInt(); - } + size_t numTrailingObjects() const { return Function.getInt(); } public: friend TrailingObjects; @@ -597,9 +591,7 @@ class FunctionTemplateSpecializationInfo final /// function and the function template, and should always be /// TSK_ExplicitSpecialization whenever we have MemberSpecializationInfo. MemberSpecializationInfo *getMemberSpecializationInfo() const { - return numTrailingObjects(OverloadToken()) - ? getTrailingObjects()[0] - : nullptr; + return numTrailingObjects() ? getTrailingObjects()[0] : nullptr; } void Profile(llvm::FoldingSetNodeID &ID) { @@ -778,7 +770,7 @@ class RedeclarableTemplateDecl : public TemplateDecl, void loadLazySpecializationsImpl(bool OnlyPartial = false) const; - bool loadLazySpecializationsImpl(llvm::ArrayRef Args, + bool loadLazySpecializationsImpl(ArrayRef Args, TemplateParameterList *TPL = nullptr) const; template diff --git a/external/llvm-project/clang/include/clang/AST/Expr.h b/external/llvm-project/clang/include/clang/AST/Expr.h index 9fc23d30b733..d95396fd59b9 100644 --- a/external/llvm-project/clang/include/clang/AST/Expr.h +++ b/external/llvm-project/clang/include/clang/AST/Expr.h @@ -1834,8 +1834,7 @@ class StringLiteral final /// Build a string literal. StringLiteral(const ASTContext &Ctx, StringRef Str, StringLiteralKind Kind, - bool Pascal, QualType Ty, const SourceLocation *Loc, - unsigned NumConcatenated); + bool Pascal, QualType Ty, ArrayRef Locs); /// Build an empty string literal. StringLiteral(EmptyShell Empty, unsigned NumConcatenated, unsigned Length, @@ -1853,18 +1852,10 @@ class StringLiteral final public: /// This is the "fully general" constructor that allows representation of - /// strings formed from multiple concatenated tokens. + /// strings formed from one or more concatenated tokens. static StringLiteral *Create(const ASTContext &Ctx, StringRef Str, StringLiteralKind Kind, bool Pascal, QualType Ty, - const SourceLocation *Loc, - unsigned NumConcatenated); - - /// Simple constructor for string literals made from one token. - static StringLiteral *Create(const ASTContext &Ctx, StringRef Str, - StringLiteralKind Kind, bool Pascal, QualType Ty, - SourceLocation Loc) { - return Create(Ctx, Str, Kind, Pascal, Ty, &Loc, 1); - } + ArrayRef Locs); /// Construct an empty string literal. static StringLiteral *CreateEmpty(const ASTContext &Ctx, @@ -3106,9 +3097,9 @@ class CallExpr : public Expr { /// Compute and set dependence bits. void computeDependence() { setDependence(clang::computeDependence( - this, llvm::ArrayRef( - reinterpret_cast(getTrailingStmts() + PREARGS_START), - getNumPreArgs()))); + this, + ArrayRef(reinterpret_cast(getTrailingStmts() + PREARGS_START), + getNumPreArgs()))); } /// Reduce the number of arguments in this call expression. This is used for @@ -3153,8 +3144,7 @@ class CallExpr : public Expr { /// interface. This provides efficient reverse iteration of the /// subexpressions. This is currently used for CFG construction. ArrayRef getRawSubExprs() { - return llvm::ArrayRef(getTrailingStmts(), - PREARGS_START + getNumPreArgs() + getNumArgs()); + return {getTrailingStmts(), PREARGS_START + getNumPreArgs() + getNumArgs()}; } /// Get FPOptionsOverride from trailing storage. @@ -5276,11 +5266,9 @@ class InitListExpr : public Expr { return reinterpret_cast(InitExprs.data()); } - ArrayRef inits() { return llvm::ArrayRef(getInits(), getNumInits()); } + ArrayRef inits() { return {getInits(), getNumInits()}; } - ArrayRef inits() const { - return llvm::ArrayRef(getInits(), getNumInits()); - } + ArrayRef inits() const { return {getInits(), getNumInits()}; } const Expr *getInit(unsigned Init) const { assert(Init < getNumInits() && "Initializer access out of range!"); @@ -5508,7 +5496,7 @@ class DesignatedInitExpr final Designator *Designators; DesignatedInitExpr(const ASTContext &C, QualType Ty, - llvm::ArrayRef Designators, + ArrayRef Designators, SourceLocation EqualOrColonLoc, bool GNUSyntax, ArrayRef IndexExprs, Expr *Init); @@ -5701,8 +5689,8 @@ class DesignatedInitExpr final }; static DesignatedInitExpr *Create(const ASTContext &C, - llvm::ArrayRef Designators, - ArrayRef IndexExprs, + ArrayRef Designators, + ArrayRef IndexExprs, SourceLocation EqualOrColonLoc, bool GNUSyntax, Expr *Init); @@ -5713,11 +5701,11 @@ class DesignatedInitExpr final unsigned size() const { return NumDesignators; } // Iterator access to the designators. - llvm::MutableArrayRef designators() { + MutableArrayRef designators() { return {Designators, NumDesignators}; } - llvm::ArrayRef designators() const { + ArrayRef designators() const { return {Designators, NumDesignators}; } @@ -6052,7 +6040,7 @@ class ParenListExpr final Expr **getExprs() { return reinterpret_cast(getTrailingObjects()); } - ArrayRef exprs() { return llvm::ArrayRef(getExprs(), getNumExprs()); } + ArrayRef exprs() { return {getExprs(), getNumExprs()}; } SourceLocation getLParenLoc() const { return LParenLoc; } SourceLocation getRParenLoc() const { return RParenLoc; } @@ -7364,17 +7352,14 @@ class RecoveryExpr final : public Expr, ArrayRef SubExprs); static RecoveryExpr *CreateEmpty(ASTContext &Ctx, unsigned NumSubExprs); - ArrayRef subExpressions() { - auto *B = getTrailingObjects(); - return llvm::ArrayRef(B, B + NumExprs); - } + ArrayRef subExpressions() { return getTrailingObjects(NumExprs); } ArrayRef subExpressions() const { return const_cast(this)->subExpressions(); } child_range children() { - Stmt **B = reinterpret_cast(getTrailingObjects()); + Stmt **B = reinterpret_cast(getTrailingObjects()); return child_range(B, B + NumExprs); } diff --git a/external/llvm-project/clang/include/clang/AST/ExprObjC.h b/external/llvm-project/clang/include/clang/AST/ExprObjC.h index 3d9b3c4585e8..8210be38608a 100644 --- a/external/llvm-project/clang/include/clang/AST/ExprObjC.h +++ b/external/llvm-project/clang/include/clang/AST/ExprObjC.h @@ -1421,8 +1421,7 @@ class ObjCMessageExpr final if (hasStandardSelLocs()) return getStandardSelectorLoc( Index, getSelector(), getSelLocsKind() == SelLoc_StandardWithSpace, - llvm::ArrayRef(const_cast(getArgs()), getNumArgs()), - RBracLoc); + ArrayRef(const_cast(getArgs()), getNumArgs()), RBracLoc); return getStoredSelLocs()[Index]; } diff --git a/external/llvm-project/clang/include/clang/AST/ExternalASTMerger.h b/external/llvm-project/clang/include/clang/AST/ExternalASTMerger.h index 2c6f2a941311..bc3cd3163525 100644 --- a/external/llvm-project/clang/include/clang/AST/ExternalASTMerger.h +++ b/external/llvm-project/clang/include/clang/AST/ExternalASTMerger.h @@ -113,7 +113,7 @@ class ExternalASTMerger : public ExternalASTSource { public: ExternalASTMerger(const ImporterTarget &Target, - llvm::ArrayRef Sources); + ArrayRef Sources); /// Asks all connected ASTImporters if any of them imported the given /// declaration. If any ASTImporter did import the given declaration, @@ -128,7 +128,7 @@ class ExternalASTMerger : public ExternalASTSource { /// newly-parsed source files). /// /// Ensures that Importers does not gain duplicate entries as a result. - void AddSources(llvm::ArrayRef Sources); + void AddSources(ArrayRef Sources); /// Remove a set of ASTContexts as possible origins. /// @@ -137,7 +137,7 @@ class ExternalASTMerger : public ExternalASTSource { /// /// The caller is responsible for ensuring that this doesn't leave /// DeclContexts that can't be completed. - void RemoveSources(llvm::ArrayRef Sources); + void RemoveSources(ArrayRef Sources); /// Implementation of the ExternalASTSource API. bool FindExternalVisibleDeclsByName(const DeclContext *DC, diff --git a/external/llvm-project/clang/include/clang/AST/ExternalASTSource.h b/external/llvm-project/clang/include/clang/AST/ExternalASTSource.h index f45e3af7602c..e91d5132da10 100644 --- a/external/llvm-project/clang/include/clang/AST/ExternalASTSource.h +++ b/external/llvm-project/clang/include/clang/AST/ExternalASTSource.h @@ -51,6 +51,7 @@ class RecordDecl; class Selector; class Stmt; class TagDecl; +class VarDecl; /// Abstract interface for external sources of AST nodes. /// @@ -195,6 +196,10 @@ class ExternalASTSource : public RefCountedBase { /// module. virtual bool wasThisDeclarationADefinition(const FunctionDecl *FD); + virtual bool hasInitializerWithSideEffects(const VarDecl *VD) const { + return false; + } + /// Finds all declarations lexically contained within the given /// DeclContext, after applying an optional filter predicate. /// @@ -429,6 +434,17 @@ struct LazyOffsetPtr { return GetPtr(); } + /// Retrieve the pointer to the AST node that this lazy pointer points to, + /// if it can be done without triggering deserialization. + /// + /// \returns a pointer to the AST node, or null if not yet deserialized. + T *getWithoutDeserializing() const { + if (isOffset()) { + return nullptr; + } + return GetPtr(); + } + /// Retrieve the address of the AST node pointer. Deserializes the pointee if /// necessary. T **getAddressOfPointer(ExternalASTSource *Source) const { diff --git a/external/llvm-project/clang/include/clang/AST/OpenACCClause.h b/external/llvm-project/clang/include/clang/AST/OpenACCClause.h index 67fbdfeb0702..71ad24a42710 100644 --- a/external/llvm-project/clang/include/clang/AST/OpenACCClause.h +++ b/external/llvm-project/clang/include/clang/AST/OpenACCClause.h @@ -307,7 +307,7 @@ class OpenACCDeviceTypeClause final } ArrayRef getArchitectures() const { - return getTrailingObjects(NumArchs); + return getTrailingObjects(NumArchs); } static OpenACCDeviceTypeClause * @@ -513,7 +513,7 @@ class OpenACCClauseWithExprs : public OpenACCClauseWithParams { /// Gets the entire list of expressions, but leave it to the /// individual clauses to expose this how they'd like. - llvm::ArrayRef getExprs() const { return Exprs; } + ArrayRef getExprs() const { return Exprs; } public: static bool classof(const OpenACCClause *C); @@ -563,10 +563,10 @@ class OpenACCWaitClause final SourceLocation getQueuesLoc() const { return QueuesLoc; } bool hasDevNumExpr() const { return getExprs()[0]; } Expr *getDevNumExpr() const { return getExprs()[0]; } - llvm::ArrayRef getQueueIdExprs() { + ArrayRef getQueueIdExprs() { return OpenACCClauseWithExprs::getExprs().drop_front(); } - llvm::ArrayRef getQueueIdExprs() const { + ArrayRef getQueueIdExprs() const { return OpenACCClauseWithExprs::getExprs().drop_front(); } // If this is a plain `wait` (no parens) this returns 'false'. Else Sema/Parse @@ -594,11 +594,9 @@ class OpenACCNumGangsClause final Create(const ASTContext &C, SourceLocation BeginLoc, SourceLocation LParenLoc, ArrayRef IntExprs, SourceLocation EndLoc); - llvm::ArrayRef getIntExprs() { - return OpenACCClauseWithExprs::getExprs(); - } + ArrayRef getIntExprs() { return OpenACCClauseWithExprs::getExprs(); } - llvm::ArrayRef getIntExprs() const { + ArrayRef getIntExprs() const { return OpenACCClauseWithExprs::getExprs(); } }; @@ -622,11 +620,9 @@ class OpenACCTileClause final SourceLocation LParenLoc, ArrayRef SizeExprs, SourceLocation EndLoc); - llvm::ArrayRef getSizeExprs() { - return OpenACCClauseWithExprs::getExprs(); - } + ArrayRef getSizeExprs() { return OpenACCClauseWithExprs::getExprs(); } - llvm::ArrayRef getSizeExprs() const { + ArrayRef getSizeExprs() const { return OpenACCClauseWithExprs::getExprs(); } }; diff --git a/external/llvm-project/clang/include/clang/AST/OpenMPClause.h b/external/llvm-project/clang/include/clang/AST/OpenMPClause.h index 6fd16bc0f03b..05239668b34b 100644 --- a/external/llvm-project/clang/include/clang/AST/OpenMPClause.h +++ b/external/llvm-project/clang/include/clang/AST/OpenMPClause.h @@ -302,8 +302,7 @@ template class OMPVarListClause : public OMPClause { void setVarRefs(ArrayRef VL) { assert(VL.size() == NumVars && "Number of variables is not the same as the preallocated buffer"); - std::copy(VL.begin(), VL.end(), - static_cast(this)->template getTrailingObjects()); + llvm::copy(VL, getVarRefs().begin()); } public: @@ -388,9 +387,7 @@ template class OMPDirectiveListClause : public OMPClause { assert( DK.size() == NumKinds && "Number of directive kinds is not the same as the preallocated buffer"); - std::copy(DK.begin(), DK.end(), - static_cast(this) - ->template getTrailingObjects()); + llvm::copy(DK, getDirectiveKinds().begin()); } SourceLocation getLParenLoc() { return LParenLoc; } @@ -980,20 +977,14 @@ class OMPSizesClause final /// Returns the tile size expressions. MutableArrayRef getSizesRefs() { - return static_cast(this) - ->template getTrailingObjects(NumSizes); - } - ArrayRef getSizesRefs() const { - return static_cast(this) - ->template getTrailingObjects(NumSizes); + return getTrailingObjects(NumSizes); } + ArrayRef getSizesRefs() const { return getTrailingObjects(NumSizes); } /// Sets the tile size expressions. void setSizesRefs(ArrayRef VL) { assert(VL.size() == NumSizes); - std::copy(VL.begin(), VL.end(), - static_cast(this) - ->template getTrailingObjects()); + llvm::copy(VL, getSizesRefs().begin()); } child_range children() { @@ -1043,8 +1034,7 @@ class OMPPermutationClause final /// Sets the permutation index expressions. void setArgRefs(ArrayRef VL) { assert(VL.size() == NumLoops && "Expecting one expression per loop"); - llvm::copy(VL, static_cast(this) - ->template getTrailingObjects()); + llvm::copy(VL, getTrailingObjects()); } /// Build an empty clause. @@ -1083,14 +1073,8 @@ class OMPPermutationClause final /// Returns the permutation index expressions. ///@{ - MutableArrayRef getArgsRefs() { - return static_cast(this) - ->template getTrailingObjects(NumLoops); - } - ArrayRef getArgsRefs() const { - return static_cast(this) - ->template getTrailingObjects(NumLoops); - } + MutableArrayRef getArgsRefs() { return getTrailingObjects(NumLoops); } + ArrayRef getArgsRefs() const { return getTrailingObjects(NumLoops); } ///@} child_range children() { @@ -3166,10 +3150,10 @@ class OMPPrivateClause final /// Gets the list of references to private copies with initializers for /// new private variables. MutableArrayRef getPrivateCopies() { - return MutableArrayRef(varlist_end(), varlist_size()); + return {varlist_end(), varlist_size()}; } ArrayRef getPrivateCopies() const { - return llvm::ArrayRef(varlist_end(), varlist_size()); + return {varlist_end(), varlist_size()}; } public: @@ -3275,10 +3259,10 @@ class OMPFirstprivateClause final /// Gets the list of references to private copies with initializers for /// new private variables. MutableArrayRef getPrivateCopies() { - return MutableArrayRef(varlist_end(), varlist_size()); + return {varlist_end(), varlist_size()}; } ArrayRef getPrivateCopies() const { - return llvm::ArrayRef(varlist_end(), varlist_size()); + return {varlist_end(), varlist_size()}; } /// Sets the list of references to initializer variables for new @@ -3289,10 +3273,10 @@ class OMPFirstprivateClause final /// Gets the list of references to initializer variables for new /// private variables. MutableArrayRef getInits() { - return MutableArrayRef(getPrivateCopies().end(), varlist_size()); + return {getPrivateCopies().end(), varlist_size()}; } ArrayRef getInits() const { - return llvm::ArrayRef(getPrivateCopies().end(), varlist_size()); + return {getPrivateCopies().end(), varlist_size()}; } public: @@ -3440,7 +3424,7 @@ class OMPLastprivateClause final return MutableArrayRef(varlist_end(), varlist_size()); } ArrayRef getPrivateCopies() const { - return llvm::ArrayRef(varlist_end(), varlist_size()); + return {varlist_end(), varlist_size()}; } /// Set list of helper expressions, required for proper codegen of the @@ -3451,10 +3435,10 @@ class OMPLastprivateClause final /// Get the list of helper source expressions. MutableArrayRef getSourceExprs() { - return MutableArrayRef(getPrivateCopies().end(), varlist_size()); + return {getPrivateCopies().end(), varlist_size()}; } ArrayRef getSourceExprs() const { - return llvm::ArrayRef(getPrivateCopies().end(), varlist_size()); + return {getPrivateCopies().end(), varlist_size()}; } /// Set list of helper expressions, required for proper codegen of the @@ -3465,10 +3449,10 @@ class OMPLastprivateClause final /// Get the list of helper destination expressions. MutableArrayRef getDestinationExprs() { - return MutableArrayRef(getSourceExprs().end(), varlist_size()); + return {getSourceExprs().end(), varlist_size()}; } ArrayRef getDestinationExprs() const { - return llvm::ArrayRef(getSourceExprs().end(), varlist_size()); + return {getSourceExprs().end(), varlist_size()}; } /// Set list of helper assignment expressions, required for proper @@ -3478,10 +3462,10 @@ class OMPLastprivateClause final /// Get the list of helper assignment expressions. MutableArrayRef getAssignmentOps() { - return MutableArrayRef(getDestinationExprs().end(), varlist_size()); + return {getDestinationExprs().end(), varlist_size()}; } ArrayRef getAssignmentOps() const { - return llvm::ArrayRef(getDestinationExprs().end(), varlist_size()); + return {getDestinationExprs().end(), varlist_size()}; } /// Sets lastprivate kind. @@ -3777,10 +3761,10 @@ class OMPReductionClause final /// Get the list of helper privates. MutableArrayRef getPrivates() { - return MutableArrayRef(varlist_end(), varlist_size()); + return {varlist_end(), varlist_size()}; } ArrayRef getPrivates() const { - return llvm::ArrayRef(varlist_end(), varlist_size()); + return {varlist_end(), varlist_size()}; } /// Set list of helper expressions, required for proper codegen of the @@ -3790,10 +3774,10 @@ class OMPReductionClause final /// Get the list of helper LHS expressions. MutableArrayRef getLHSExprs() { - return MutableArrayRef(getPrivates().end(), varlist_size()); + return {getPrivates().end(), varlist_size()}; } ArrayRef getLHSExprs() const { - return llvm::ArrayRef(getPrivates().end(), varlist_size()); + return {getPrivates().end(), varlist_size()}; } /// Set list of helper expressions, required for proper codegen of the @@ -3833,7 +3817,7 @@ class OMPReductionClause final return MutableArrayRef(getLHSExprs().end(), varlist_size()); } ArrayRef getRHSExprs() const { - return ArrayRef(getLHSExprs().end(), varlist_size()); + return {getLHSExprs().end(), varlist_size()}; } /// Set list of helper reduction expressions, required for proper @@ -3844,10 +3828,10 @@ class OMPReductionClause final /// Get the list of helper reduction expressions. MutableArrayRef getReductionOps() { - return MutableArrayRef(getRHSExprs().end(), varlist_size()); + return {getRHSExprs().end(), varlist_size()}; } ArrayRef getReductionOps() const { - return llvm::ArrayRef(getRHSExprs().end(), varlist_size()); + return {getRHSExprs().end(), varlist_size()}; } /// Set list of helper copy operations for inscan reductions. @@ -3856,10 +3840,10 @@ class OMPReductionClause final /// Get the list of helper inscan copy operations. MutableArrayRef getInscanCopyOps() { - return MutableArrayRef(getReductionOps().end(), varlist_size()); + return {getReductionOps().end(), varlist_size()}; } ArrayRef getInscanCopyOps() const { - return llvm::ArrayRef(getReductionOps().end(), varlist_size()); + return {getReductionOps().end(), varlist_size()}; } /// Set list of helper temp vars for inscan copy array operations. @@ -3867,10 +3851,10 @@ class OMPReductionClause final /// Get the list of helper inscan copy temps. MutableArrayRef getInscanCopyArrayTemps() { - return MutableArrayRef(getInscanCopyOps().end(), varlist_size()); + return {getInscanCopyOps().end(), varlist_size()}; } ArrayRef getInscanCopyArrayTemps() const { - return llvm::ArrayRef(getInscanCopyOps().end(), varlist_size()); + return {getInscanCopyOps().end(), varlist_size()}; } /// Set list of helper temp elements vars for inscan copy array operations. @@ -3878,11 +3862,10 @@ class OMPReductionClause final /// Get the list of helper inscan copy temps. MutableArrayRef getInscanCopyArrayElems() { - return MutableArrayRef(getInscanCopyArrayTemps().end(), - varlist_size()); + return {getInscanCopyArrayTemps().end(), varlist_size()}; } ArrayRef getInscanCopyArrayElems() const { - return llvm::ArrayRef(getInscanCopyArrayTemps().end(), varlist_size()); + return {getInscanCopyArrayTemps().end(), varlist_size()}; } public: @@ -4143,10 +4126,10 @@ class OMPTaskReductionClause final /// Get the list of helper privates. MutableArrayRef getPrivates() { - return MutableArrayRef(varlist_end(), varlist_size()); + return {varlist_end(), varlist_size()}; } ArrayRef getPrivates() const { - return llvm::ArrayRef(varlist_end(), varlist_size()); + return {varlist_end(), varlist_size()}; } /// Set list of helper expressions, required for proper codegen of the clause. @@ -4156,10 +4139,10 @@ class OMPTaskReductionClause final /// Get the list of helper LHS expressions. MutableArrayRef getLHSExprs() { - return MutableArrayRef(getPrivates().end(), varlist_size()); + return {getPrivates().end(), varlist_size()}; } ArrayRef getLHSExprs() const { - return llvm::ArrayRef(getPrivates().end(), varlist_size()); + return {getPrivates().end(), varlist_size()}; } /// Set list of helper expressions, required for proper codegen of the clause. @@ -4170,10 +4153,10 @@ class OMPTaskReductionClause final /// Get the list of helper destination expressions. MutableArrayRef getRHSExprs() { - return MutableArrayRef(getLHSExprs().end(), varlist_size()); + return {getLHSExprs().end(), varlist_size()}; } ArrayRef getRHSExprs() const { - return llvm::ArrayRef(getLHSExprs().end(), varlist_size()); + return {getLHSExprs().end(), varlist_size()}; } /// Set list of helper reduction expressions, required for proper @@ -4184,10 +4167,10 @@ class OMPTaskReductionClause final /// Get the list of helper reduction expressions. MutableArrayRef getReductionOps() { - return MutableArrayRef(getRHSExprs().end(), varlist_size()); + return {getRHSExprs().end(), varlist_size()}; } ArrayRef getReductionOps() const { - return llvm::ArrayRef(getRHSExprs().end(), varlist_size()); + return {getRHSExprs().end(), varlist_size()}; } public: @@ -4374,10 +4357,10 @@ class OMPInReductionClause final /// Get the list of helper privates. MutableArrayRef getPrivates() { - return MutableArrayRef(varlist_end(), varlist_size()); + return {varlist_end(), varlist_size()}; } ArrayRef getPrivates() const { - return llvm::ArrayRef(varlist_end(), varlist_size()); + return {varlist_end(), varlist_size()}; } /// Set list of helper expressions, required for proper codegen of the clause. @@ -4387,10 +4370,10 @@ class OMPInReductionClause final /// Get the list of helper LHS expressions. MutableArrayRef getLHSExprs() { - return MutableArrayRef(getPrivates().end(), varlist_size()); + return {getPrivates().end(), varlist_size()}; } ArrayRef getLHSExprs() const { - return llvm::ArrayRef(getPrivates().end(), varlist_size()); + return {getPrivates().end(), varlist_size()}; } /// Set list of helper expressions, required for proper codegen of the clause. @@ -4401,10 +4384,10 @@ class OMPInReductionClause final /// Get the list of helper destination expressions. MutableArrayRef getRHSExprs() { - return MutableArrayRef(getLHSExprs().end(), varlist_size()); + return {getLHSExprs().end(), varlist_size()}; } ArrayRef getRHSExprs() const { - return llvm::ArrayRef(getLHSExprs().end(), varlist_size()); + return {getLHSExprs().end(), varlist_size()}; } /// Set list of helper reduction expressions, required for proper @@ -4415,10 +4398,10 @@ class OMPInReductionClause final /// Get the list of helper reduction expressions. MutableArrayRef getReductionOps() { - return MutableArrayRef(getRHSExprs().end(), varlist_size()); + return {getRHSExprs().end(), varlist_size()}; } ArrayRef getReductionOps() const { - return llvm::ArrayRef(getRHSExprs().end(), varlist_size()); + return {getRHSExprs().end(), varlist_size()}; } /// Set list of helper reduction taskgroup descriptors. @@ -4426,10 +4409,10 @@ class OMPInReductionClause final /// Get the list of helper reduction taskgroup descriptors. MutableArrayRef getTaskgroupDescriptors() { - return MutableArrayRef(getReductionOps().end(), varlist_size()); + return {getReductionOps().end(), varlist_size()}; } ArrayRef getTaskgroupDescriptors() const { - return llvm::ArrayRef(getReductionOps().end(), varlist_size()); + return {getReductionOps().end(), varlist_size()}; } public: @@ -4637,41 +4620,41 @@ class OMPLinearClause final /// { Vars[] /* in OMPVarListClause */; Privates[]; Inits[]; Updates[]; /// Finals[]; Step; CalcStep; } MutableArrayRef getPrivates() { - return MutableArrayRef(varlist_end(), varlist_size()); + return {varlist_end(), varlist_size()}; } ArrayRef getPrivates() const { - return llvm::ArrayRef(varlist_end(), varlist_size()); + return {varlist_end(), varlist_size()}; } MutableArrayRef getInits() { - return MutableArrayRef(getPrivates().end(), varlist_size()); + return {getPrivates().end(), varlist_size()}; } ArrayRef getInits() const { - return llvm::ArrayRef(getPrivates().end(), varlist_size()); + return {getPrivates().end(), varlist_size()}; } /// Sets the list of update expressions for linear variables. MutableArrayRef getUpdates() { - return MutableArrayRef(getInits().end(), varlist_size()); + return {getInits().end(), varlist_size()}; } ArrayRef getUpdates() const { - return llvm::ArrayRef(getInits().end(), varlist_size()); + return {getInits().end(), varlist_size()}; } /// Sets the list of final update expressions for linear variables. MutableArrayRef getFinals() { - return MutableArrayRef(getUpdates().end(), varlist_size()); + return {getUpdates().end(), varlist_size()}; } ArrayRef getFinals() const { - return llvm::ArrayRef(getUpdates().end(), varlist_size()); + return {getUpdates().end(), varlist_size()}; } /// Gets the list of used expressions for linear variables. MutableArrayRef getUsedExprs() { - return MutableArrayRef(getFinals().end() + 2, varlist_size() + 1); + return {getFinals().end() + 2, varlist_size() + 1}; } ArrayRef getUsedExprs() const { - return llvm::ArrayRef(getFinals().end() + 2, varlist_size() + 1); + return {getFinals().end() + 2, varlist_size() + 1}; } /// Sets the list of the copies of original linear variables. @@ -5005,10 +4988,10 @@ class OMPCopyinClause final /// Get the list of helper source expressions. MutableArrayRef getSourceExprs() { - return MutableArrayRef(varlist_end(), varlist_size()); + return {varlist_end(), varlist_size()}; } ArrayRef getSourceExprs() const { - return llvm::ArrayRef(varlist_end(), varlist_size()); + return {varlist_end(), varlist_size()}; } /// Set list of helper expressions, required for proper codegen of the @@ -5018,10 +5001,10 @@ class OMPCopyinClause final /// Get the list of helper destination expressions. MutableArrayRef getDestinationExprs() { - return MutableArrayRef(getSourceExprs().end(), varlist_size()); + return {getSourceExprs().end(), varlist_size()}; } ArrayRef getDestinationExprs() const { - return llvm::ArrayRef(getSourceExprs().end(), varlist_size()); + return {getSourceExprs().end(), varlist_size()}; } /// Set list of helper assignment expressions, required for proper @@ -5032,10 +5015,10 @@ class OMPCopyinClause final /// Get the list of helper assignment expressions. MutableArrayRef getAssignmentOps() { - return MutableArrayRef(getDestinationExprs().end(), varlist_size()); + return {getDestinationExprs().end(), varlist_size()}; } ArrayRef getAssignmentOps() const { - return llvm::ArrayRef(getDestinationExprs().end(), varlist_size()); + return {getDestinationExprs().end(), varlist_size()}; } public: @@ -5170,10 +5153,10 @@ class OMPCopyprivateClause final /// Get the list of helper source expressions. MutableArrayRef getSourceExprs() { - return MutableArrayRef(varlist_end(), varlist_size()); + return {varlist_end(), varlist_size()}; } ArrayRef getSourceExprs() const { - return llvm::ArrayRef(varlist_end(), varlist_size()); + return {varlist_end(), varlist_size()}; } /// Set list of helper expressions, required for proper codegen of the @@ -5183,10 +5166,10 @@ class OMPCopyprivateClause final /// Get the list of helper destination expressions. MutableArrayRef getDestinationExprs() { - return MutableArrayRef(getSourceExprs().end(), varlist_size()); + return {getSourceExprs().end(), varlist_size()}; } ArrayRef getDestinationExprs() const { - return llvm::ArrayRef(getSourceExprs().end(), varlist_size()); + return {getSourceExprs().end(), varlist_size()}; } /// Set list of helper assignment expressions, required for proper @@ -5197,10 +5180,10 @@ class OMPCopyprivateClause final /// Get the list of helper assignment expressions. MutableArrayRef getAssignmentOps() { - return MutableArrayRef(getDestinationExprs().end(), varlist_size()); + return {getDestinationExprs().end(), varlist_size()}; } ArrayRef getAssignmentOps() const { - return llvm::ArrayRef(getDestinationExprs().end(), varlist_size()); + return {getDestinationExprs().end(), varlist_size()}; } public: @@ -5933,7 +5916,7 @@ class OMPMappableExprListClause : public OMPVarListClause, void setUniqueDecls(ArrayRef UDs) { assert(UDs.size() == NumUniqueDeclarations && "Unexpected amount of unique declarations."); - std::copy(UDs.begin(), UDs.end(), getUniqueDeclsRef().begin()); + llvm::copy(UDs, getUniqueDeclsRef().begin()); } /// Get the number of lists per declaration that are in the trailing @@ -5955,7 +5938,7 @@ class OMPMappableExprListClause : public OMPVarListClause, void setDeclNumLists(ArrayRef DNLs) { assert(DNLs.size() == NumUniqueDeclarations && "Unexpected amount of list numbers."); - std::copy(DNLs.begin(), DNLs.end(), getDeclNumListsRef().begin()); + llvm::copy(DNLs, getDeclNumListsRef().begin()); } /// Get the cumulative component lists sizes that are in the trailing @@ -5981,7 +5964,7 @@ class OMPMappableExprListClause : public OMPVarListClause, void setComponentListSizes(ArrayRef CLSs) { assert(CLSs.size() == NumComponentLists && "Unexpected amount of component lists."); - std::copy(CLSs.begin(), CLSs.end(), getComponentListSizesRef().begin()); + llvm::copy(CLSs, getComponentListSizesRef().begin()); } /// Get the components that are in the trailing objects of the class. @@ -6005,7 +5988,7 @@ class OMPMappableExprListClause : public OMPVarListClause, "Unexpected amount of component lists."); assert(CLSs.size() == NumComponentLists && "Unexpected amount of list sizes."); - std::copy(Components.begin(), Components.end(), getComponentsRef().begin()); + llvm::copy(Components, getComponentsRef().begin()); } /// Fill the clause information from the list of declarations and @@ -6079,7 +6062,7 @@ class OMPMappableExprListClause : public OMPVarListClause, ++CLSI; // Append components after the current components iterator. - CI = std::copy(C.begin(), C.end(), CI); + CI = llvm::copy(C, CI); } } } @@ -6099,7 +6082,7 @@ class OMPMappableExprListClause : public OMPVarListClause, MutableArrayRef getUDMapperRefs() { assert(SupportsMapper && "Must be a clause that is possible to have user-defined mappers"); - return llvm::MutableArrayRef( + return MutableArrayRef( static_cast(this)->template getTrailingObjects() + OMPVarListClause::varlist_size(), OMPVarListClause::varlist_size()); @@ -6110,7 +6093,7 @@ class OMPMappableExprListClause : public OMPVarListClause, ArrayRef getUDMapperRefs() const { assert(SupportsMapper && "Must be a clause that is possible to have user-defined mappers"); - return llvm::ArrayRef( + return ArrayRef( static_cast(this)->template getTrailingObjects() + OMPVarListClause::varlist_size(), OMPVarListClause::varlist_size()); @@ -6123,7 +6106,7 @@ class OMPMappableExprListClause : public OMPVarListClause, "Unexpected number of user-defined mappers."); assert(SupportsMapper && "Must be a clause that is possible to have user-defined mappers"); - std::copy(DMDs.begin(), DMDs.end(), getUDMapperRefs().begin()); + llvm::copy(DMDs, getUDMapperRefs().begin()); } public: @@ -6620,12 +6603,12 @@ class OMPMapClause final : public OMPMappableExprListClause, /// Fetches ArrayRef of map-type-modifiers. ArrayRef getMapTypeModifiers() const LLVM_READONLY { - return llvm::ArrayRef(MapTypeModifiers); + return MapTypeModifiers; } /// Fetches ArrayRef of location of map-type-modifiers. ArrayRef getMapTypeModifiersLoc() const LLVM_READONLY { - return llvm::ArrayRef(MapTypeModifiersLoc); + return MapTypeModifiersLoc; } /// Fetches location of clause mapping kind. @@ -7610,12 +7593,12 @@ class OMPToClause final : public OMPMappableExprListClause, /// Fetches ArrayRef of motion-modifiers. ArrayRef getMotionModifiers() const LLVM_READONLY { - return llvm::ArrayRef(MotionModifiers); + return MotionModifiers; } /// Fetches ArrayRef of location of motion-modifiers. ArrayRef getMotionModifiersLoc() const LLVM_READONLY { - return llvm::ArrayRef(MotionModifiersLoc); + return MotionModifiersLoc; } /// Get colon location. @@ -7810,12 +7793,12 @@ class OMPFromClause final /// Fetches ArrayRef of motion-modifiers. ArrayRef getMotionModifiers() const LLVM_READONLY { - return llvm::ArrayRef(MotionModifiers); + return MotionModifiers; } /// Fetches ArrayRef of location of motion-modifiers. ArrayRef getMotionModifiersLoc() const LLVM_READONLY { - return llvm::ArrayRef(MotionModifiersLoc); + return MotionModifiersLoc; } /// Get colon location. @@ -7910,7 +7893,7 @@ class OMPUseDevicePtrClause final return MutableArrayRef(varlist_end(), varlist_size()); } ArrayRef getPrivateCopies() const { - return llvm::ArrayRef(varlist_end(), varlist_size()); + return {varlist_end(), varlist_size()}; } /// Sets the list of references to initializer variables for new private @@ -7921,10 +7904,10 @@ class OMPUseDevicePtrClause final /// Gets the list of references to initializer variables for new private /// variables. MutableArrayRef getInits() { - return MutableArrayRef(getPrivateCopies().end(), varlist_size()); + return {getPrivateCopies().end(), varlist_size()}; } ArrayRef getInits() const { - return llvm::ArrayRef(getPrivateCopies().end(), varlist_size()); + return {getPrivateCopies().end(), varlist_size()}; } public: @@ -8355,10 +8338,10 @@ class OMPNontemporalClause final /// Get the list of privatied copies if the member expression was captured by /// one of the privatization clauses. MutableArrayRef getPrivateRefs() { - return MutableArrayRef(varlist_end(), varlist_size()); + return {varlist_end(), varlist_size()}; } ArrayRef getPrivateRefs() const { - return llvm::ArrayRef(varlist_end(), varlist_size()); + return {varlist_end(), varlist_size()}; } public: @@ -9239,9 +9222,7 @@ class OMPAffinityClause final SourceLocation(), N) {} /// Sets the affinity modifier for the clause, if any. - void setModifier(Expr *E) { - getTrailingObjects()[varlist_size()] = E; - } + void setModifier(Expr *E) { getTrailingObjects()[varlist_size()] = E; } /// Sets the location of ':' symbol. void setColonLoc(SourceLocation Loc) { ColonLoc = Loc; } @@ -9268,10 +9249,8 @@ class OMPAffinityClause final static OMPAffinityClause *CreateEmpty(const ASTContext &C, unsigned N); /// Gets affinity modifier. - Expr *getModifier() { return getTrailingObjects()[varlist_size()]; } - Expr *getModifier() const { - return getTrailingObjects()[varlist_size()]; - } + Expr *getModifier() { return getTrailingObjects()[varlist_size()]; } + Expr *getModifier() const { return getTrailingObjects()[varlist_size()]; } /// Gets the location of ':' symbol. SourceLocation getColonLoc() const { return ColonLoc; } @@ -9482,14 +9461,16 @@ struct OMPTraitProperty { /// (which accepts anything) and (later) extensions. StringRef RawString; }; + struct OMPTraitSelector { Expr *ScoreOrCondition = nullptr; llvm::omp::TraitSelector Kind = llvm::omp::TraitSelector::invalid; - llvm::SmallVector Properties; + SmallVector Properties; }; + struct OMPTraitSet { llvm::omp::TraitSet Kind = llvm::omp::TraitSet::invalid; - llvm::SmallVector Selectors; + SmallVector Selectors; }; /// Helper data structure representing the traits in a match clause of an diff --git a/external/llvm-project/clang/include/clang/AST/PropertiesBase.td b/external/llvm-project/clang/include/clang/AST/PropertiesBase.td index 8317b6a874fa..1215056ffde1 100644 --- a/external/llvm-project/clang/include/clang/AST/PropertiesBase.td +++ b/external/llvm-project/clang/include/clang/AST/PropertiesBase.td @@ -898,6 +898,6 @@ let Class = PropertyTypeCase in { TemplateArgument *ctxElements = new (ctx) TemplateArgument[elements.size()]; for (size_t i = 0, e = elements.size(); i != e; ++i) ctxElements[i] = elements[i]; - return TemplateArgument(llvm::ArrayRef(ctxElements, elements.size())); + return TemplateArgument(ArrayRef(ctxElements, elements.size())); }]>; } diff --git a/external/llvm-project/clang/include/clang/AST/Stmt.h b/external/llvm-project/clang/include/clang/AST/Stmt.h index 6c4bd6f6946b..a5b0d5053003 100644 --- a/external/llvm-project/clang/include/clang/AST/Stmt.h +++ b/external/llvm-project/clang/include/clang/AST/Stmt.h @@ -2214,7 +2214,7 @@ class AttributedStmt final : ValueStmt(AttributedStmtClass), SubStmt(SubStmt) { AttributedStmtBits.NumAttrs = Attrs.size(); AttributedStmtBits.AttrLoc = Loc; - std::copy(Attrs.begin(), Attrs.end(), getAttrArrayPtr()); + llvm::copy(Attrs, getAttrArrayPtr()); } explicit AttributedStmt(EmptyShell Empty, unsigned NumAttrs) @@ -2236,7 +2236,7 @@ class AttributedStmt final SourceLocation getAttrLoc() const { return AttributedStmtBits.AttrLoc; } ArrayRef getAttrs() const { - return llvm::ArrayRef(getAttrArrayPtr(), AttributedStmtBits.NumAttrs); + return {getAttrArrayPtr(), AttributedStmtBits.NumAttrs}; } Stmt *getSubStmt() { return SubStmt; } @@ -3649,16 +3649,13 @@ class MSAsmStmt : public AsmStmt { //===--- Other ---===// ArrayRef getAllConstraints() const { - return llvm::ArrayRef(Constraints, NumInputs + NumOutputs); + return {Constraints, NumInputs + NumOutputs}; } - ArrayRef getClobbers() const { - return llvm::ArrayRef(Clobbers, NumClobbers); - } + ArrayRef getClobbers() const { return {Clobbers, NumClobbers}; } ArrayRef getAllExprs() const { - return llvm::ArrayRef(reinterpret_cast(Exprs), - NumInputs + NumOutputs); + return {reinterpret_cast(Exprs), NumInputs + NumOutputs}; } StringRef getClobber(unsigned i) const { return getClobbers()[i]; } diff --git a/external/llvm-project/clang/include/clang/AST/StmtOpenACC.h b/external/llvm-project/clang/include/clang/AST/StmtOpenACC.h index c8f8b968b1c8..8b4554e99632 100644 --- a/external/llvm-project/clang/include/clang/AST/StmtOpenACC.h +++ b/external/llvm-project/clang/include/clang/AST/StmtOpenACC.h @@ -538,10 +538,8 @@ class OpenACCWaitConstruct final bool hasDevNumExpr() const { return getExprs()[0]; } Expr *getDevNumExpr() const { return getExprs()[0]; } - llvm::ArrayRef getQueueIdExprs() { return getExprs().drop_front(); } - llvm::ArrayRef getQueueIdExprs() const { - return getExprs().drop_front(); - } + ArrayRef getQueueIdExprs() { return getExprs().drop_front(); } + ArrayRef getQueueIdExprs() const { return getExprs().drop_front(); } child_range children() { Stmt **Begin = reinterpret_cast(getExprPtr()); @@ -736,7 +734,7 @@ class OpenACCUpdateConstruct final OpenACCDirectiveKind::Update, SourceLocation{}, SourceLocation{}, SourceLocation{}) { std::uninitialized_value_construct_n(getTrailingObjects(), NumClauses); - setClauseList(getTrailingObjects(NumClauses)); + setClauseList(getTrailingObjects(NumClauses)); } OpenACCUpdateConstruct(SourceLocation Start, SourceLocation DirectiveLoc, diff --git a/external/llvm-project/clang/include/clang/AST/StmtOpenMP.h b/external/llvm-project/clang/include/clang/AST/StmtOpenMP.h index 736bcabbad1f..2fb33d3036bc 100644 --- a/external/llvm-project/clang/include/clang/AST/StmtOpenMP.h +++ b/external/llvm-project/clang/include/clang/AST/StmtOpenMP.h @@ -399,9 +399,8 @@ class OMPExecutableDirective : public Stmt { static llvm::iterator_range used_clauses_children(ArrayRef Clauses) { - return { - used_clauses_child_iterator(Clauses), - used_clauses_child_iterator(llvm::ArrayRef(Clauses.end(), (size_t)0))}; + return {used_clauses_child_iterator(Clauses), + used_clauses_child_iterator(ArrayRef(Clauses.end(), (size_t)0))}; } /// Iterates over a filtered subrange of clauses applied to a @@ -446,7 +445,7 @@ class OMPExecutableDirective : public Stmt { getClausesOfKind(ArrayRef Clauses) { return {specific_clause_iterator(Clauses), specific_clause_iterator( - llvm::ArrayRef(Clauses.end(), (size_t)0))}; + ArrayRef(Clauses.end(), (size_t)0))}; } template @@ -1069,7 +1068,7 @@ class OMPLoopDirective : public OMPLoopBasedDirective { MutableArrayRef getCounters() { auto **Storage = reinterpret_cast( &Data->getChildren()[getArraysOffset(getDirectiveKind())]); - return llvm::MutableArrayRef(Storage, getLoopsNumber()); + return {Storage, getLoopsNumber()}; } /// Get the private counters storage. @@ -1077,7 +1076,7 @@ class OMPLoopDirective : public OMPLoopBasedDirective { auto **Storage = reinterpret_cast( &Data->getChildren()[getArraysOffset(getDirectiveKind()) + getLoopsNumber()]); - return llvm::MutableArrayRef(Storage, getLoopsNumber()); + return {Storage, getLoopsNumber()}; } /// Get the updates storage. @@ -1085,7 +1084,7 @@ class OMPLoopDirective : public OMPLoopBasedDirective { auto **Storage = reinterpret_cast( &Data->getChildren()[getArraysOffset(getDirectiveKind()) + 2 * getLoopsNumber()]); - return llvm::MutableArrayRef(Storage, getLoopsNumber()); + return {Storage, getLoopsNumber()}; } /// Get the updates storage. @@ -1093,7 +1092,7 @@ class OMPLoopDirective : public OMPLoopBasedDirective { auto **Storage = reinterpret_cast( &Data->getChildren()[getArraysOffset(getDirectiveKind()) + 3 * getLoopsNumber()]); - return llvm::MutableArrayRef(Storage, getLoopsNumber()); + return {Storage, getLoopsNumber()}; } /// Get the final counter updates storage. @@ -1101,7 +1100,7 @@ class OMPLoopDirective : public OMPLoopBasedDirective { auto **Storage = reinterpret_cast( &Data->getChildren()[getArraysOffset(getDirectiveKind()) + 4 * getLoopsNumber()]); - return llvm::MutableArrayRef(Storage, getLoopsNumber()); + return {Storage, getLoopsNumber()}; } /// Get the dependent counters storage. @@ -1109,7 +1108,7 @@ class OMPLoopDirective : public OMPLoopBasedDirective { auto **Storage = reinterpret_cast( &Data->getChildren()[getArraysOffset(getDirectiveKind()) + 5 * getLoopsNumber()]); - return llvm::MutableArrayRef(Storage, getLoopsNumber()); + return {Storage, getLoopsNumber()}; } /// Get the dependent inits storage. @@ -1117,7 +1116,7 @@ class OMPLoopDirective : public OMPLoopBasedDirective { auto **Storage = reinterpret_cast( &Data->getChildren()[getArraysOffset(getDirectiveKind()) + 6 * getLoopsNumber()]); - return llvm::MutableArrayRef(Storage, getLoopsNumber()); + return {Storage, getLoopsNumber()}; } /// Get the finals conditions storage. @@ -1125,7 +1124,7 @@ class OMPLoopDirective : public OMPLoopBasedDirective { auto **Storage = reinterpret_cast( &Data->getChildren()[getArraysOffset(getDirectiveKind()) + 7 * getLoopsNumber()]); - return llvm::MutableArrayRef(Storage, getLoopsNumber()); + return {Storage, getLoopsNumber()}; } protected: @@ -5787,10 +5786,13 @@ class OMPReverseDirective final : public OMPLoopTransformationDirective { TransformedStmtOffset, }; - explicit OMPReverseDirective(SourceLocation StartLoc, SourceLocation EndLoc) + explicit OMPReverseDirective(SourceLocation StartLoc, SourceLocation EndLoc, + unsigned NumLoops) : OMPLoopTransformationDirective(OMPReverseDirectiveClass, llvm::omp::OMPD_reverse, StartLoc, - EndLoc, 1) {} + EndLoc, NumLoops) { + setNumGeneratedLoops(NumLoops); + } void setPreInits(Stmt *PreInits) { Data->getChildren()[PreInitsOffset] = PreInits; @@ -5806,19 +5808,23 @@ class OMPReverseDirective final : public OMPLoopTransformationDirective { /// \param C Context of the AST. /// \param StartLoc Location of the introducer (e.g. the 'omp' token). /// \param EndLoc Location of the directive's end (e.g. the tok::eod). + /// \param NumLoops Number of affected loops /// \param AssociatedStmt The outermost associated loop. /// \param TransformedStmt The loop nest after tiling, or nullptr in /// dependent contexts. /// \param PreInits Helper preinits statements for the loop nest. - static OMPReverseDirective * - Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, - Stmt *AssociatedStmt, Stmt *TransformedStmt, Stmt *PreInits); + static OMPReverseDirective *Create(const ASTContext &C, + SourceLocation StartLoc, + SourceLocation EndLoc, + Stmt *AssociatedStmt, unsigned NumLoops, + Stmt *TransformedStmt, Stmt *PreInits); /// Build an empty '#pragma omp reverse' AST node for deserialization. /// /// \param C Context of the AST. - /// \param NumClauses Number of clauses to allocate. - static OMPReverseDirective *CreateEmpty(const ASTContext &C); + /// \param NumLoops Number of associated loops to allocate + static OMPReverseDirective *CreateEmpty(const ASTContext &C, + unsigned NumLoops); /// Gets/sets the associated loops after the transformation, i.e. after /// de-sugaring. @@ -5857,7 +5863,7 @@ class OMPInterchangeDirective final : public OMPLoopTransformationDirective { : OMPLoopTransformationDirective(OMPInterchangeDirectiveClass, llvm::omp::OMPD_interchange, StartLoc, EndLoc, NumLoops) { - setNumGeneratedLoops(3 * NumLoops); + setNumGeneratedLoops(NumLoops); } void setPreInits(Stmt *PreInits) { diff --git a/external/llvm-project/clang/include/clang/AST/TemplateBase.h b/external/llvm-project/clang/include/clang/AST/TemplateBase.h index 84a342ec053a..b67036cae426 100644 --- a/external/llvm-project/clang/include/clang/AST/TemplateBase.h +++ b/external/llvm-project/clang/include/clang/AST/TemplateBase.h @@ -436,7 +436,7 @@ class TemplateArgument { /// Iterator range referencing all of the elements of a template /// argument pack. ArrayRef pack_elements() const { - return llvm::ArrayRef(pack_begin(), pack_end()); + return {pack_begin(), pack_end()}; } /// The number of template arguments in the given template argument @@ -449,7 +449,7 @@ class TemplateArgument { /// Return the array of arguments in this template argument pack. ArrayRef getPackAsArray() const { assert(getKind() == Pack); - return llvm::ArrayRef(Args.Args, Args.NumArgs); + return {Args.Args, Args.NumArgs}; } /// Determines whether two template arguments are superficially the @@ -662,7 +662,7 @@ class TemplateArgumentListInfo { return Arguments.data(); } - llvm::ArrayRef arguments() const { return Arguments; } + ArrayRef arguments() const { return Arguments; } const TemplateArgumentLoc &operator[](unsigned I) const { return Arguments[I]; @@ -708,8 +708,8 @@ struct ASTTemplateArgumentListInfo final } unsigned getNumTemplateArgs() const { return NumTemplateArgs; } - llvm::ArrayRef arguments() const { - return llvm::ArrayRef(getTemplateArgs(), getNumTemplateArgs()); + ArrayRef arguments() const { + return {getTemplateArgs(), getNumTemplateArgs()}; } const TemplateArgumentLoc &operator[](unsigned I) const { diff --git a/external/llvm-project/clang/include/clang/AST/Type.h b/external/llvm-project/clang/include/clang/AST/Type.h index 3896cd914bf0..24f3ae78e857 100644 --- a/external/llvm-project/clang/include/clang/AST/Type.h +++ b/external/llvm-project/clang/include/clang/AST/Type.h @@ -5439,7 +5439,7 @@ class FunctionProtoType final } ArrayRef getParamTypes() const { - return llvm::ArrayRef(param_type_begin(), param_type_end()); + return {param_type_begin(), param_type_end()}; } ExtProtoInfo getExtProtoInfo() const { @@ -5593,7 +5593,7 @@ class FunctionProtoType final using param_type_iterator = const QualType *; ArrayRef param_types() const { - return llvm::ArrayRef(param_type_begin(), param_type_end()); + return {param_type_begin(), param_type_end()}; } param_type_iterator param_type_begin() const { @@ -5607,7 +5607,7 @@ class FunctionProtoType final using exception_iterator = const QualType *; ArrayRef exceptions() const { - return llvm::ArrayRef(exception_begin(), exception_end()); + return {exception_begin(), exception_end()}; } exception_iterator exception_begin() const { @@ -6052,9 +6052,7 @@ class PackIndexingType final ArrayRef Expansions); private: - const QualType *getExpansionsPtr() const { - return getTrailingObjects(); - } + const QualType *getExpansionsPtr() const { return getTrailingObjects(); } static TypeDependence computeDependence(QualType Pattern, Expr *IndexExpr, ArrayRef Expansions = {}); @@ -6494,7 +6492,7 @@ class HLSLInlineSpirvType final uint32_t getSize() const { return Size; } uint32_t getAlignment() const { return Alignment; } ArrayRef getOperands() const { - return getTrailingObjects(NumOperands); + return getTrailingObjects(NumOperands); } bool isSugared() const { return false; } @@ -7612,7 +7610,7 @@ class ObjCObjectType : public Type, /// Retrieve the type arguments of this object type as they were /// written. ArrayRef getTypeArgsAsWritten() const { - return llvm::ArrayRef(getTypeArgStorage(), ObjCObjectTypeBits.NumTypeArgs); + return {getTypeArgStorage(), ObjCObjectTypeBits.NumTypeArgs}; } /// Whether this is a "__kindof" type as written. diff --git a/external/llvm-project/clang/include/clang/AST/TypeLoc.h b/external/llvm-project/clang/include/clang/AST/TypeLoc.h index 53c7ea8c65df..cf06e2775899 100644 --- a/external/llvm-project/clang/include/clang/AST/TypeLoc.h +++ b/external/llvm-project/clang/include/clang/AST/TypeLoc.h @@ -828,7 +828,7 @@ class ObjCTypeParamTypeLoc : public ConcreteTypeLoc getProtocolLocs() const { - return llvm::ArrayRef(getProtocolLocArray(), getNumProtocols()); + return {getProtocolLocArray(), getNumProtocols()}; } void initializeLocal(ASTContext &Context, SourceLocation Loc); @@ -1088,7 +1088,7 @@ class ObjCObjectTypeLoc : public ConcreteTypeLoc getProtocolLocs() const { - return llvm::ArrayRef(getProtocolLocArray(), getNumProtocols()); + return {getProtocolLocArray(), getNumProtocols()}; } bool hasBaseTypeAsWritten() const { @@ -1545,7 +1545,7 @@ class FunctionTypeLoc : public ConcreteTypeLoc getParams() const { - return llvm::ArrayRef(getParmArray(), getNumParams()); + return {getParmArray(), getNumParams()}; } // ParmVarDecls* are stored after Info, one for each parameter. diff --git a/external/llvm-project/clang/include/clang/AST/TypeProperties.td b/external/llvm-project/clang/include/clang/AST/TypeProperties.td index 6e44bce893e7..a6157649060b 100644 --- a/external/llvm-project/clang/include/clang/AST/TypeProperties.td +++ b/external/llvm-project/clang/include/clang/AST/TypeProperties.td @@ -335,7 +335,7 @@ let Class = FunctionProtoType in { def : Property<"extParameterInfo", Array> { let Read = [{ node->hasExtParameterInfos() ? node->getExtParameterInfos() - : llvm::ArrayRef() }]; + : ArrayRef() }]; } def : Property<"AArch64SMEAttributes", UInt32> { let Read = [{ node->getAArch64SMEAttributes() }]; @@ -753,7 +753,7 @@ let Class = TemplateSpecializationType in { } def : Creator<[{ - return ctx.getTemplateSpecializationType(templateName, args, std::nullopt, UnderlyingType); + return ctx.getTemplateSpecializationType(templateName, args, {}, UnderlyingType); }]>; } diff --git a/external/llvm-project/clang/include/clang/Basic/Attr.td b/external/llvm-project/clang/include/clang/Basic/Attr.td index f113cd2ba2fb..27fea7dea0a5 100644 --- a/external/llvm-project/clang/include/clang/Basic/Attr.td +++ b/external/llvm-project/clang/include/clang/Basic/Attr.td @@ -5023,6 +5023,14 @@ def HLSLVkExtBuiltinInput : InheritableAttr { let Documentation = [HLSLVkExtBuiltinInputDocs]; } +def HLSLVkConstantId : InheritableAttr { + let Spellings = [CXX11<"vk", "constant_id">]; + let Args = [IntArgument<"Id">]; + let Subjects = SubjectList<[ExternalGlobalVar]>; + let LangOpts = [HLSL]; + let Documentation = [VkConstantIdDocs]; +} + def RandomizeLayout : InheritableAttr { let Spellings = [GCC<"randomize_layout">]; let Subjects = SubjectList<[Record]>; diff --git a/external/llvm-project/clang/include/clang/Basic/AttrDocs.td b/external/llvm-project/clang/include/clang/Basic/AttrDocs.td index 047f51ffa59e..43442f177ab7 100644 --- a/external/llvm-project/clang/include/clang/Basic/AttrDocs.td +++ b/external/llvm-project/clang/include/clang/Basic/AttrDocs.td @@ -2934,7 +2934,7 @@ https://gcc.gnu.org/onlinedocs/gcc/RISC-V-Function-Attributes.html https://riscv.org/specifications/privileged-isa/ The RISC-V Instruction Set Manual Volume II: Privileged Architecture Version 1.10. -https://github.com/quic/riscv-unified-db/releases/tag/Xqci-0.7 +https://github.com/quic/riscv-unified-db/releases/tag/Xqci-0.13.0 https://sifive.cdn.prismic.io/sifive/d1984d2b-c9b9-4c91-8de0-d68a5e64fa0f_sifive-interrupt-cookbook-v1p2.pdf }]; } @@ -8252,6 +8252,21 @@ and https://microsoft.github.io/hlsl-specs/proposals/0013-wave-size-range.html }]; } +def VkConstantIdDocs : Documentation { + let Category = DocCatFunction; + let Content = [{ +The ``vk::constant_id`` attribute specifies the id for a SPIR-V specialization +constant. The attribute applies to const global scalar variables. The variable must be initialized with a C++11 constexpr. +In SPIR-V, the +variable will be replaced with an `OpSpecConstant` with the given id. +The syntax is: + +.. code-block:: text + + ``[[vk::constant_id()]] const T Name = `` +}]; +} + def RootSignatureDocs : Documentation { let Category = DocCatFunction; let Content = [{ diff --git a/external/llvm-project/clang/include/clang/Basic/Builtins.td b/external/llvm-project/clang/include/clang/Basic/Builtins.td index 68cd3d790e78..d65b3a5d2f44 100644 --- a/external/llvm-project/clang/include/clang/Basic/Builtins.td +++ b/external/llvm-project/clang/include/clang/Basic/Builtins.td @@ -5065,6 +5065,19 @@ def HLSLGroupMemoryBarrierWithGroupSync: LangBuiltin<"HLSL_LANG"> { let Prototype = "void()"; } +class HLSLScalarTemplate + : Template<["bool", "char", "short", "int", "long long int", + "unsigned short", "unsigned int", "unsigned long long int", + "__fp16", "float", "double"], + ["_bool", "_char", "_short", "_int", "_longlong", "_ushort", + "_uint", "_ulonglong", "_half", "_float", "_double"]>; + +def HLSLGetSpirvSpecConstant : LangBuiltin<"HLSL_LANG">, HLSLScalarTemplate { + let Spellings = ["__builtin_get_spirv_spec_constant"]; + let Attributes = [NoThrow, Const, Pure]; + let Prototype = "T(unsigned int, T)"; +} + // Builtins for XRay. def XRayCustomEvent : Builtin { let Spellings = ["__xray_customevent"]; diff --git a/external/llvm-project/clang/include/clang/Basic/BuiltinsAMDGPU.def b/external/llvm-project/clang/include/clang/Basic/BuiltinsAMDGPU.def index 264cdb52671b..3b969be5316d 100644 --- a/external/llvm-project/clang/include/clang/Basic/BuiltinsAMDGPU.def +++ b/external/llvm-project/clang/include/clang/Basic/BuiltinsAMDGPU.def @@ -641,5 +641,11 @@ TARGET_BUILTIN(__builtin_amdgcn_bitop3_b16, "ssssIUi", "nc", "bitop3-insts") TARGET_BUILTIN(__builtin_amdgcn_cvt_sr_bf16_f32, "V2yV2yfUiIb", "nc", "f32-to-f16bf16-cvt-sr-insts") TARGET_BUILTIN(__builtin_amdgcn_cvt_sr_f16_f32, "V2hV2hfUiIb", "nc", "f32-to-f16bf16-cvt-sr-insts") +//===----------------------------------------------------------------------===// +// GFX1250+ only builtins. +//===----------------------------------------------------------------------===// + +TARGET_BUILTIN(__builtin_amdgcn_s_setprio_inc_wg, "vIs", "n", "setprio-inc-wg-inst") + #undef BUILTIN #undef TARGET_BUILTIN diff --git a/external/llvm-project/clang/include/clang/Basic/BuiltinsPPC.def b/external/llvm-project/clang/include/clang/Basic/BuiltinsPPC.def index bb7d54bbb793..099500754a0e 100644 --- a/external/llvm-project/clang/include/clang/Basic/BuiltinsPPC.def +++ b/external/llvm-project/clang/include/clang/Basic/BuiltinsPPC.def @@ -1134,6 +1134,18 @@ UNALIASED_CUSTOM_BUILTIN(mma_pmxvbf16ger2np, "vW512*VVi15i15i3", true, "mma,paired-vector-memops") UNALIASED_CUSTOM_BUILTIN(mma_pmxvbf16ger2nn, "vW512*VVi15i15i3", true, "mma,paired-vector-memops") +UNALIASED_CUSTOM_BUILTIN(mma_dmxvi8gerx4, "vW1024*W256V", false, + "mma,paired-vector-memops") +UNALIASED_CUSTOM_BUILTIN(mma_pmdmxvi8gerx4, "vW1024*W256Vi255i15i15", false, + "mma,paired-vector-memops") +UNALIASED_CUSTOM_BUILTIN(mma_dmxvi8gerx4pp, "vW1024*W256V", true, + "mma,paired-vector-memops") +UNALIASED_CUSTOM_BUILTIN(mma_pmdmxvi8gerx4pp, "vW1024*W256Vi255i15i15", true, + "mma,paired-vector-memops") +UNALIASED_CUSTOM_BUILTIN(mma_dmxvi8gerx4spp, "vW1024*W256V", true, + "mma,paired-vector-memops") +UNALIASED_CUSTOM_BUILTIN(mma_pmdmxvi8gerx4spp, "vW1024*W256Vi255i15i15", true, + "mma,paired-vector-memops") // FIXME: Obviously incomplete. diff --git a/external/llvm-project/clang/include/clang/Basic/CodeGenOptions.def b/external/llvm-project/clang/include/clang/Basic/CodeGenOptions.def index 2a30ff11464d..e5566a540dc6 100644 --- a/external/llvm-project/clang/include/clang/Basic/CodeGenOptions.def +++ b/external/llvm-project/clang/include/clang/Basic/CodeGenOptions.def @@ -483,8 +483,10 @@ CODEGENOPT(StaticClosure, 1, 0) /// Assume that UAVs/SRVs may alias CODEGENOPT(ResMayAlias, 1, 0) -/// Enables unwind v2 (epilog) information for x64 Windows. -CODEGENOPT(WinX64EHUnwindV2, 1, 0) +/// Controls how unwind v2 (epilog) information should be generated for x64 +/// Windows. +ENUM_CODEGENOPT(WinX64EHUnwindV2, llvm::WinX64EHUnwindV2Mode, + 2, llvm::WinX64EHUnwindV2Mode::Disabled) /// FIXME: Make DebugOptions its own top-level .def file. #include "DebugOptions.def" diff --git a/external/llvm-project/clang/include/clang/Basic/DiagnosticSemaKinds.td b/external/llvm-project/clang/include/clang/Basic/DiagnosticSemaKinds.td index e5681a22c1e9..98d4523a5660 100644 --- a/external/llvm-project/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/external/llvm-project/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -12931,6 +12931,10 @@ def err_spirv_enum_not_int : Error< def err_spirv_enum_not_valid : Error< "invalid value for %select{storage class}0 argument">; +def err_specialization_const + : Error<"variable with 'vk::constant_id' attribute must be a const " + "int/float/enum/bool and be initialized with a literal">; + // errors of expect.with.probability def err_probability_not_constant_float : Error< "probability argument to __builtin_expect_with_probability must be constant " @@ -13054,6 +13058,11 @@ def err_invalid_hlsl_resource_type: Error< def err_hlsl_spirv_only: Error<"%0 is only available for the SPIR-V target">; def err_hlsl_vk_literal_must_contain_constant: Error<"the argument to vk::Literal must be a vk::integral_constant">; +def err_hlsl_resource_range_overlap: Error< + "resource ranges %select{t|u|b|s}0[%1;%2] and %select{t|u|b|s}3[%4;%5] " + "overlap within space = %6 and visibility = " + "%select{All|Vertex|Hull|Domain|Geometry|Pixel|Amplification|Mesh}7">; + // Layout randomization diagnostics. def err_non_designated_init_used : Error< "a randomized struct can only be initialized with a designated initializer">; diff --git a/external/llvm-project/clang/include/clang/Basic/OffloadArch.h b/external/llvm-project/clang/include/clang/Basic/OffloadArch.h index 99b1024b9d0d..4dda3ec2216f 100644 --- a/external/llvm-project/clang/include/clang/Basic/OffloadArch.h +++ b/external/llvm-project/clang/include/clang/Basic/OffloadArch.h @@ -98,6 +98,7 @@ enum class OffloadArch { GFX12_GENERIC, GFX1200, GFX1201, + GFX1250, AMDGCNSPIRV, Generic, // A processor model named 'generic' if the target backend defines a // public one. diff --git a/external/llvm-project/clang/include/clang/Basic/PPCTypes.def b/external/llvm-project/clang/include/clang/Basic/PPCTypes.def index 9e2cb2aedc9f..fc4155ca98b2 100644 --- a/external/llvm-project/clang/include/clang/Basic/PPCTypes.def +++ b/external/llvm-project/clang/include/clang/Basic/PPCTypes.def @@ -30,6 +30,7 @@ #endif +PPC_VECTOR_MMA_TYPE(__dmr1024, DMR1024, 1024) PPC_VECTOR_MMA_TYPE(__vector_quad, VectorQuad, 512) PPC_VECTOR_VSX_TYPE(__vector_pair, VectorPair, 256) diff --git a/external/llvm-project/clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h b/external/llvm-project/clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h index 502d58d7db8b..3e052c564112 100644 --- a/external/llvm-project/clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h +++ b/external/llvm-project/clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h @@ -227,22 +227,26 @@ class CIRBaseBuilderTy : public mlir::OpBuilder { //===--------------------------------------------------------------------===// cir::CallOp createCallOp(mlir::Location loc, mlir::SymbolRefAttr callee, - mlir::Type returnType, mlir::ValueRange operands) { - return create(loc, callee, returnType, operands); + mlir::Type returnType, mlir::ValueRange operands, + cir::SideEffect sideEffect = cir::SideEffect::All) { + return create(loc, callee, returnType, operands, sideEffect); } cir::CallOp createCallOp(mlir::Location loc, cir::FuncOp callee, - mlir::ValueRange operands) { + mlir::ValueRange operands, + cir::SideEffect sideEffect = cir::SideEffect::All) { return createCallOp(loc, mlir::SymbolRefAttr::get(callee), - callee.getFunctionType().getReturnType(), operands); + callee.getFunctionType().getReturnType(), operands, + sideEffect); } cir::CallOp createIndirectCallOp(mlir::Location loc, mlir::Value indirectTarget, cir::FuncType funcType, - mlir::ValueRange operands) { + mlir::ValueRange operands, + cir::SideEffect sideEffect) { return create(loc, indirectTarget, funcType.getReturnType(), - operands); + operands, sideEffect); } //===--------------------------------------------------------------------===// diff --git a/external/llvm-project/clang/include/clang/CIR/Dialect/IR/CIRAttrs.td b/external/llvm-project/clang/include/clang/CIR/Dialect/IR/CIRAttrs.td index b48f4ed461cc..03e970db2847 100644 --- a/external/llvm-project/clang/include/clang/CIR/Dialect/IR/CIRAttrs.td +++ b/external/llvm-project/clang/include/clang/CIR/Dialect/IR/CIRAttrs.td @@ -42,6 +42,21 @@ class CIR_TypedAttr traits = []> let assemblyFormat = [{}]; } +class CIR_I32EnumAttr cases> + : I32EnumAttr { + let cppNamespace = "::cir"; +} + +class CIR_I64EnumAttr cases> + : I64EnumAttr { + let cppNamespace = "::cir"; +} + +class CIR_EnumAttr traits = []> + : EnumAttr { + let assemblyFormat = "`<` $value `>`"; +} + class CIRUnitAttr traits = []> : CIR_Attr { let returnType = "bool"; @@ -325,36 +340,33 @@ def ConstComplexAttr : CIR_Attr<"ConstComplex", "const_complex", // VisibilityAttr //===----------------------------------------------------------------------===// -def CIR_VisibilityKind : I32EnumAttr<"VisibilityKind", "C/C++ visibility", [ - I32EnumAttrCase<"Default", 1, "default">, - I32EnumAttrCase<"Hidden", 2, "hidden">, - I32EnumAttrCase<"Protected", 3, "protected"> +def CIR_VisibilityKind : CIR_I32EnumAttr<"VisibilityKind", "C/C++ visibility", [ + I32EnumAttrCase<"Default", 0, "default">, + I32EnumAttrCase<"Hidden", 1, "hidden">, + I32EnumAttrCase<"Protected", 2, "protected"> ]> { let genSpecializedAttr = 0; - let cppNamespace = "::cir"; } -def CIR_VisibilityAttr : CIR_Attr<"Visibility", "visibility"> { +def CIR_VisibilityAttr : CIR_EnumAttr { let summary = "Visibility attribute"; let description = [{ Visibility attributes. }]; - let parameters = (ins "VisibilityKind":$value); - let assemblyFormat = [{ - $value - }]; + let cppClassName = "VisibilityAttr"; + let skipDefaultBuilders = 1; let builders = [ - AttrBuilder<(ins CArg<"VisibilityKind", "cir::VisibilityKind::Default">:$value), [{ + AttrBuilder<(ins CArg<"VisibilityKind", + "cir::VisibilityKind::Default">:$value), [{ return $_get($_ctxt, value); }]> ]; - let skipDefaultBuilders = 1; - - // Make DefaultValuedAttr accept VisibilityKind as default value ($0). - let constBuilderCall = "cir::VisibilityAttr::get($_builder.getContext(), $0)"; + let assemblyFormat = [{ + $value + }]; let extraClassDeclaration = [{ bool isDefault() const { return getValue() == VisibilityKind::Default; }; diff --git a/external/llvm-project/clang/include/clang/CIR/Dialect/IR/CIRDialect.h b/external/llvm-project/clang/include/clang/CIR/Dialect/IR/CIRDialect.h index aa1494ab4df1..5de1722cf5bc 100644 --- a/external/llvm-project/clang/include/clang/CIR/Dialect/IR/CIRDialect.h +++ b/external/llvm-project/clang/include/clang/CIR/Dialect/IR/CIRDialect.h @@ -33,31 +33,6 @@ #include "clang/CIR/Interfaces/CIROpInterfaces.h" #include "clang/CIR/MissingFeatures.h" -namespace mlir { -namespace OpTrait { - -namespace impl { -// These functions are out-of-line implementations of the methods in the -// corresponding trait classes. This avoids them being template -// instantiated/duplicated. -LogicalResult verifySameFirstOperandAndResultType(Operation *op); -} // namespace impl - -/// This class provides verification for ops that are known to have the same -/// first operand and result type. -/// -template -class SameFirstOperandAndResultType - : public TraitBase { -public: - static llvm::LogicalResult verifyTrait(Operation *op) { - return impl::verifySameFirstOperandAndResultType(op); - } -}; - -} // namespace OpTrait -} // namespace mlir - using BuilderCallbackRef = llvm::function_ref; using BuilderOpStateCallbackRef = llvm::function_ref traits = []> : Op, LLVMLoweringInfo; -//===----------------------------------------------------------------------===// -// CIR Op Traits -//===----------------------------------------------------------------------===// - -def SameFirstOperandAndResultType : - NativeOpTrait<"SameFirstOperandAndResultType">; - //===----------------------------------------------------------------------===// // CastOp //===----------------------------------------------------------------------===// -// CK_Dependent -def CK_BitCast : I32EnumAttrCase<"bitcast", 1>; -// CK_LValueBitCast -// CK_LValueToRValueBitCast -// CK_LValueToRValue -// CK_NoOp -// CK_BaseToDerived -// CK_DerivedToBase -// CK_UncheckedDerivedToBase -// CK_Dynamic -// CK_ToUnion -def CK_ArrayToPointerDecay : I32EnumAttrCase<"array_to_ptrdecay", 11>; -// CK_FunctionToPointerDecay -// CK_NullToPointer -// CK_NullToMemberPointer -// CK_BaseToDerivedMemberPointer -// CK_DerivedToBaseMemberPointer -def CK_MemberPointerToBoolean : I32EnumAttrCase<"member_ptr_to_bool", 17>; -// CK_ReinterpretMemberPointer -// CK_UserDefinedConversion -// CK_ConstructorConversion -def CK_IntegralToPointer : I32EnumAttrCase<"int_to_ptr", 21>; -def CK_PointerToIntegral : I32EnumAttrCase<"ptr_to_int", 22>; -def CK_PointerToBoolean : I32EnumAttrCase<"ptr_to_bool", 23>; -// CK_ToVoid -// CK_MatrixCast -// CK_VectorSplat -def CK_IntegralCast : I32EnumAttrCase<"integral", 27>; -def CK_IntegralToBoolean : I32EnumAttrCase<"int_to_bool", 28>; -def CK_IntegralToFloating : I32EnumAttrCase<"int_to_float", 29>; -// CK_FloatingToFixedPoint -// CK_FixedPointToFloating -// CK_FixedPointCast -// CK_FixedPointToIntegral -// CK_IntegralToFixedPoint -// CK_FixedPointToBoolean -def CK_FloatingToIntegral : I32EnumAttrCase<"float_to_int", 36>; -def CK_FloatingToBoolean : I32EnumAttrCase<"float_to_bool", 37>; -def CK_BooleanToSignedIntegral : I32EnumAttrCase<"bool_to_int", 38>; -def CK_FloatingCast : I32EnumAttrCase<"floating", 39>; -// CK_CPointerToObjCPointerCast -// CK_BlockPointerToObjCPointerCast -// CK_AnyPointerToBlockPointerCast -// CK_ObjCObjectLValueCast -// CK_FloatingRealToComplex -// CK_FloatingComplexToReal -// CK_FloatingComplexToBoolean -def CK_FloatingComplexCast : I32EnumAttrCase<"float_complex", 47>; -// CK_FloatingComplexToIntegralComplex -// CK_IntegralRealToComplex -def CK_IntegralComplexToReal : I32EnumAttrCase<"int_complex_to_real", 50>; -def CK_IntegralComplexToBoolean : I32EnumAttrCase<"int_complex_to_bool", 51>; -def CK_IntegralComplexCast : I32EnumAttrCase<"int_complex", 52>; -def CK_IntegralComplexToFloatingComplex - : I32EnumAttrCase<"int_complex_to_float_complex", 53>; -// CK_ARCProduceObject -// CK_ARCConsumeObject -// CK_ARCReclaimReturnedObject -// CK_ARCExtendBlockObject -// CK_AtomicToNonAtomic -// CK_NonAtomicToAtomic -// CK_CopyAndAutoreleaseBlockObject -// CK_BuiltinFnToFnPtr -// CK_ZeroToOCLOpaqueType -def CK_AddressSpaceConversion : I32EnumAttrCase<"address_space", 63>; -// CK_IntToOCLSampler -// CK_HLSLVectorTruncation -// CK_HLSLArrayRValue -// CK_HLSLElementwiseCast -// CK_HLSLAggregateSplatCast - -// Enums below are specific to CIR and don't have a correspondence to classic -// codegen: -def CK_BooleanToFloat : I32EnumAttrCase<"bool_to_float", 1000>; - -def CastKind : I32EnumAttr< - "CastKind", - "cast kind", - [CK_BitCast, CK_ArrayToPointerDecay, CK_MemberPointerToBoolean, - CK_IntegralToPointer, CK_PointerToIntegral, CK_PointerToBoolean, - CK_IntegralCast, CK_IntegralToBoolean, CK_IntegralToFloating, - CK_FloatingToIntegral, CK_FloatingToBoolean, CK_BooleanToSignedIntegral, - CK_FloatingCast, CK_FloatingComplexCast, CK_IntegralComplexToReal, - CK_IntegralComplexToBoolean, CK_IntegralComplexCast, - CK_IntegralComplexToFloatingComplex, CK_AddressSpaceConversion, - CK_BooleanToFloat]> { - let cppNamespace = "::cir"; -} +def CIR_CastKind : CIR_I32EnumAttr<"CastKind", "cast kind", [ + I32EnumAttrCase<"bitcast", 1>, + // CK_LValueBitCast + // CK_LValueToRValueBitCast + // CK_LValueToRValue + // CK_NoOp + // CK_BaseToDerived + // CK_DerivedToBase + // CK_UncheckedDerivedToBase + // CK_Dynamic + // CK_ToUnion + I32EnumAttrCase<"array_to_ptrdecay", 11>, + // CK_FunctionToPointerDecay + // CK_NullToPointer + // CK_NullToMemberPointer + // CK_BaseToDerivedMemberPointer + // CK_DerivedToBaseMemberPointer + I32EnumAttrCase<"member_ptr_to_bool", 17>, + // CK_ReinterpretMemberPointer + // CK_UserDefinedConversion + // CK_ConstructorConversion + I32EnumAttrCase<"int_to_ptr", 21>, + I32EnumAttrCase<"ptr_to_int", 22>, + I32EnumAttrCase<"ptr_to_bool", 23>, + // CK_ToVoid + // CK_MatrixCast + // CK_VectorSplat + I32EnumAttrCase<"integral", 27>, + I32EnumAttrCase<"int_to_bool", 28>, + I32EnumAttrCase<"int_to_float", 29>, + // CK_FloatingToFixedPoint + // CK_FixedPointToFloating + // CK_FixedPointCast + // CK_FixedPointToIntegral + // CK_IntegralToFixedPoint + // CK_FixedPointToBoolean + I32EnumAttrCase<"float_to_int", 36>, + I32EnumAttrCase<"float_to_bool", 37>, + I32EnumAttrCase<"bool_to_int", 38>, + I32EnumAttrCase<"floating", 39>, + // CK_CPointerToObjCPointerCast + // CK_BlockPointerToObjCPointerCast + // CK_AnyPointerToBlockPointerCast + // CK_ObjCObjectLValueCast + // I32EnumAttrCase<"float_to_complex", 44>, + // I32EnumAttrCase<"float_complex_to_real", 45>, + // I32EnumAttrCase<"float_complex_to_bool", 46>, + I32EnumAttrCase<"float_complex", 47>, + // I32EnumAttrCase<"float_complex_to_int_complex", 48>, + // I32EnumAttrCase<"int_to_complex", 49>, + I32EnumAttrCase<"int_complex_to_real", 50>, + I32EnumAttrCase<"int_complex_to_bool", 51>, + I32EnumAttrCase<"int_complex", 52>, + I32EnumAttrCase<"int_complex_to_float_complex", 53>, + // CK_ARCProduceObject + // CK_ARCConsumeObject + // CK_ARCReclaimReturnedObject + // CK_ARCExtendBlockObject + // CK_AtomicToNonAtomic + // CK_NonAtomicToAtomic + // CK_CopyAndAutoreleaseBlockObject + // CK_BuiltinFnToFnPtr + // CK_ZeroToOCLOpaqueType + I32EnumAttrCase<"address_space", 63>, + // CK_IntToOCLSampler + // CK_HLSLVectorTruncation + // CK_HLSLArrayRValue + // CK_HLSLElementwiseCast + // CK_HLSLAggregateSplatCast + + // Enums below are specific to CIR and don't have a correspondence to classic + // codegen: + I32EnumAttrCase<"bool_to_float", 1000>, +]>; def CastOp : CIR_Op<"cast", [Pure, @@ -186,45 +165,49 @@ def CastOp : CIR_Op<"cast", // FIXME: not all conversions are free of side effects. let summary = "Conversion between values of different types"; let description = [{ - Apply C/C++ usual conversions rules between values. Currently supported kinds: + Apply the usual C/C++ conversion rules between values. This operation models + a subset of conversions as defined in Clang's `OperationKinds.def` + (`llvm-project/clang/include/clang/AST/OperationKinds.def`). + + Note: not all conversions are implemented using `cir.cast`. For instance, + lvalue-to-rvalue conversion is modeled as a `cir.load` instead. Currently + supported kinds: - - `array_to_ptrdecay` - `bitcast` + - `array_to_ptrdecay` + - `member_ptr_to_bool + - `int_to_ptr` + - `ptr_to_int` + - `ptr_to_bool` - `integral` - `int_to_bool` - `int_to_float` - - `floating` - `float_to_int` - `float_to_bool` - - `ptr_to_int` - - `ptr_to_bool` - `bool_to_int` - - `bool_to_float` - - `address_space` - - `float_to_complex` - - `int_to_complex` - - `float_complex_to_real` + - `floating` + - `float_complex` - `int_complex_to_real` - - `float_complex_to_bool` - `int_complex_to_bool` - - `float_complex` - - `float_complex_to_int_complex` - `int_complex` - `int_complex_to_float_complex` + - `address_space` + + CIR also supports some additional conversions that are not part of the classic + Clang codegen: - This is effectively a subset of the rules from - `llvm-project/clang/include/clang/AST/OperationKinds.def`; but note that some - of the conversions aren't implemented in terms of `cir.cast`, `lvalue-to-rvalue` - for instance is modeled as a regular `cir.load`. + - `bool_to_float` + + Example: ```mlir - %4 = cir.cast (int_to_bool, %3 : i32), !cir.bool + %4 = cir.cast(int_to_bool, %3 : i32), !cir.bool ... %x = cir.cast(array_to_ptrdecay, %0 : !cir.ptr>), !cir.ptr ``` }]; - let arguments = (ins CastKind:$kind, CIR_AnyType:$src); + let arguments = (ins CIR_CastKind:$kind, CIR_AnyType:$src); let results = (outs CIR_AnyType:$result); let assemblyFormat = [{ @@ -243,7 +226,7 @@ def CastOp : CIR_Op<"cast", //===----------------------------------------------------------------------===// def PtrStrideOp : CIR_Op<"ptr_stride", - [Pure, SameFirstOperandAndResultType]> { + [Pure, AllTypesMatch<["base", "result"]>]> { let summary = "Pointer access with stride"; let description = [{ Given a base pointer as first operand, provides a new pointer after applying @@ -767,17 +750,12 @@ def ScopeOp : CIR_Op<"scope", [ // SwitchOp //===----------------------------------------------------------------------===// -def CaseOpKind_DT : I32EnumAttrCase<"Default", 1, "default">; -def CaseOpKind_EQ : I32EnumAttrCase<"Equal", 2, "equal">; -def CaseOpKind_AO : I32EnumAttrCase<"Anyof", 3, "anyof">; -def CaseOpKind_RG : I32EnumAttrCase<"Range", 4, "range">; - -def CaseOpKind : I32EnumAttr< - "CaseOpKind", - "case kind", - [CaseOpKind_DT, CaseOpKind_EQ, CaseOpKind_AO, CaseOpKind_RG]> { - let cppNamespace = "::cir"; -} +def CIR_CaseOpKind : CIR_I32EnumAttr<"CaseOpKind", "case kind", [ + I32EnumAttrCase<"Default", 0, "default">, + I32EnumAttrCase<"Equal", 1, "equal">, + I32EnumAttrCase<"Anyof", 2, "anyof">, + I32EnumAttrCase<"Range", 3, "range"> +]>; def CaseOp : CIR_Op<"case", [ DeclareOpInterfaceMethods, @@ -800,7 +778,7 @@ def CaseOp : CIR_Op<"case", [ Each case region must be explicitly terminated. }]; - let arguments = (ins ArrayAttr:$value, CaseOpKind:$kind); + let arguments = (ins ArrayAttr:$value, CIR_CaseOpKind:$kind); let regions = (region AnyRegion:$caseRegion); let assemblyFormat = "`(` $kind `,` $value `)` $caseRegion attr-dict"; @@ -1067,23 +1045,13 @@ def BrOp : CIR_Op<"br", // UnaryOp //===----------------------------------------------------------------------===// -def UnaryOpKind_Inc : I32EnumAttrCase<"Inc", 1, "inc">; -def UnaryOpKind_Dec : I32EnumAttrCase<"Dec", 2, "dec">; -def UnaryOpKind_Plus : I32EnumAttrCase<"Plus", 3, "plus">; -def UnaryOpKind_Minus : I32EnumAttrCase<"Minus", 4, "minus">; -def UnaryOpKind_Not : I32EnumAttrCase<"Not", 5, "not">; - -def UnaryOpKind : I32EnumAttr< - "UnaryOpKind", - "unary operation kind", - [UnaryOpKind_Inc, - UnaryOpKind_Dec, - UnaryOpKind_Plus, - UnaryOpKind_Minus, - UnaryOpKind_Not, - ]> { - let cppNamespace = "::cir"; -} +def CIR_UnaryOpKind : CIR_I32EnumAttr<"UnaryOpKind", "unary operation kind", [ + I32EnumAttrCase<"Inc", 0, "inc">, + I32EnumAttrCase<"Dec", 1, "dec">, + I32EnumAttrCase<"Plus", 2, "plus">, + I32EnumAttrCase<"Minus", 3, "minus">, + I32EnumAttrCase<"Not", 4, "not"> +]>; def UnaryOp : CIR_Op<"unary", [Pure, SameOperandsAndResultType]> { let summary = "Unary operations"; @@ -1103,10 +1071,13 @@ def UnaryOp : CIR_Op<"unary", [Pure, SameOperandsAndResultType]> { ``` }]; + let arguments = (ins + Arg:$kind, + Arg:$input, + UnitAttr:$no_signed_wrap + ); + let results = (outs CIR_AnyType:$result); - let arguments = (ins Arg:$kind, - Arg:$input, - UnitAttr:$no_signed_wrap); let assemblyFormat = [{ `(` $kind `,` $input `)` @@ -1331,20 +1302,14 @@ def ForOp : LoopOpBase<"for"> { // CmpOp //===----------------------------------------------------------------------===// -def CmpOpKind_LT : I32EnumAttrCase<"lt", 1>; -def CmpOpKind_LE : I32EnumAttrCase<"le", 2>; -def CmpOpKind_GT : I32EnumAttrCase<"gt", 3>; -def CmpOpKind_GE : I32EnumAttrCase<"ge", 4>; -def CmpOpKind_EQ : I32EnumAttrCase<"eq", 5>; -def CmpOpKind_NE : I32EnumAttrCase<"ne", 6>; - -def CmpOpKind : I32EnumAttr< - "CmpOpKind", - "compare operation kind", - [CmpOpKind_LT, CmpOpKind_LE, CmpOpKind_GT, - CmpOpKind_GE, CmpOpKind_EQ, CmpOpKind_NE]> { - let cppNamespace = "::cir"; -} +def CIR_CmpOpKind : CIR_I32EnumAttr<"CmpOpKind", "compare operation kind", [ + I32EnumAttrCase<"lt", 0>, + I32EnumAttrCase<"le", 1>, + I32EnumAttrCase<"gt", 2>, + I32EnumAttrCase<"ge", 3>, + I32EnumAttrCase<"eq", 4>, + I32EnumAttrCase<"ne", 5> +]>; def CmpOp : CIR_Op<"cmp", [Pure, SameTypeOperands]> { @@ -1359,9 +1324,13 @@ def CmpOp : CIR_Op<"cmp", [Pure, SameTypeOperands]> { ``` }]; + let arguments = (ins + CIR_CmpOpKind:$kind, + CIR_AnyType:$lhs, + CIR_AnyType:$rhs + ); + let results = (outs CIR_BoolType:$result); - let arguments = (ins Arg:$kind, - CIR_AnyType:$lhs, CIR_AnyType:$rhs); let assemblyFormat = [{ `(` $kind `,` $lhs `,` $rhs `)` `:` type($lhs) `,` type($result) attr-dict @@ -1373,26 +1342,18 @@ def CmpOp : CIR_Op<"cmp", [Pure, SameTypeOperands]> { //===----------------------------------------------------------------------===// // FIXME: represent Commutative, Idempotent traits for appropriate binops -def BinOpKind_Mul : I32EnumAttrCase<"Mul", 1, "mul">; -def BinOpKind_Div : I32EnumAttrCase<"Div", 2, "div">; -def BinOpKind_Rem : I32EnumAttrCase<"Rem", 3, "rem">; -def BinOpKind_Add : I32EnumAttrCase<"Add", 4, "add">; -def BinOpKind_Sub : I32EnumAttrCase<"Sub", 5, "sub">; -def BinOpKind_And : I32EnumAttrCase<"And", 8, "and">; -def BinOpKind_Xor : I32EnumAttrCase<"Xor", 9, "xor">; -def BinOpKind_Or : I32EnumAttrCase<"Or", 10, "or">; -// TODO(cir): Do we need a min binop? -def BinOpKind_Max : I32EnumAttrCase<"Max", 11, "max">; - -def BinOpKind : I32EnumAttr< - "BinOpKind", - "binary operation (arith and logic) kind", - [BinOpKind_Mul, BinOpKind_Div, BinOpKind_Rem, - BinOpKind_Add, BinOpKind_Sub, - BinOpKind_And, BinOpKind_Xor, - BinOpKind_Or, BinOpKind_Max]> { - let cppNamespace = "::cir"; -} +def CIR_BinOpKind : CIR_I32EnumAttr< + "BinOpKind", "binary operation (arith and logic) kind", [ + I32EnumAttrCase<"Mul", 0, "mul">, + I32EnumAttrCase<"Div", 1, "div">, + I32EnumAttrCase<"Rem", 2, "rem">, + I32EnumAttrCase<"Add", 3, "add">, + I32EnumAttrCase<"Sub", 4, "sub">, + I32EnumAttrCase<"And", 5, "and">, + I32EnumAttrCase<"Xor", 6, "xor">, + I32EnumAttrCase<"Or", 7, "or">, + I32EnumAttrCase<"Max", 8, "max"> +]>; def BinOp : CIR_Op<"binop", [Pure, SameTypeOperands, SameOperandsAndResultType]> { @@ -1424,13 +1385,16 @@ def BinOp : CIR_Op<"binop", [Pure, ``` }]; + let arguments = (ins + CIR_BinOpKind:$kind, + CIR_AnyType:$lhs, CIR_AnyType:$rhs, + UnitAttr:$no_unsigned_wrap, + UnitAttr:$no_signed_wrap, + UnitAttr:$saturated + ); + // TODO: get more accurate than CIR_AnyType let results = (outs CIR_AnyType:$result); - let arguments = (ins Arg:$kind, - CIR_AnyType:$lhs, CIR_AnyType:$rhs, - UnitAttr:$no_unsigned_wrap, - UnitAttr:$no_signed_wrap, - UnitAttr:$saturated); let assemblyFormat = [{ `(` $kind `,` $lhs `,` $rhs `)` @@ -1586,54 +1550,34 @@ def TernaryOp : CIR_Op<"ternary", // currently handy as part of forwarding appropriate linkage types for LLVM // lowering, specially useful for C++ support. -// Externally visible function -def Global_ExternalLinkage : - I32EnumAttrCase<"ExternalLinkage", 0, "external">; -// Available for inspection, not emission. -def Global_AvailableExternallyLinkage : - I32EnumAttrCase<"AvailableExternallyLinkage", 1, "available_externally">; -// Keep one copy of function when linking (inline) -def Global_LinkOnceAnyLinkage : - I32EnumAttrCase<"LinkOnceAnyLinkage", 2, "linkonce">; -// Same, but only replaced by something equivalent. -def Global_LinkOnceODRLinkage : - I32EnumAttrCase<"LinkOnceODRLinkage", 3, "linkonce_odr">; -// Keep one copy of named function when linking (weak) -def Global_WeakAnyLinkage : - I32EnumAttrCase<"WeakAnyLinkage", 4, "weak">; -// Same, but only replaced by something equivalent. -def Global_WeakODRLinkage : - I32EnumAttrCase<"WeakODRLinkage", 5, "weak_odr">; -// TODO: should we add something like appending linkage too? -// Special purpose, only applies to global arrays -// def Global_AppendingLinkage : -// I32EnumAttrCase<"AppendingLinkage", 6, "appending">; -// Rename collisions when linking (static functions). -def Global_InternalLinkage : - I32EnumAttrCase<"InternalLinkage", 7, "internal">; -// Like Internal, but omit from symbol table, prefix it with -// "cir_" to prevent clash with MLIR's symbol "private". -def Global_PrivateLinkage : - I32EnumAttrCase<"PrivateLinkage", 8, "cir_private">; -// ExternalWeak linkage description. -def Global_ExternalWeakLinkage : - I32EnumAttrCase<"ExternalWeakLinkage", 9, "extern_weak">; -// Tentative definitions. -def Global_CommonLinkage : - I32EnumAttrCase<"CommonLinkage", 10, "common">; - /// An enumeration for the kinds of linkage for global values. -def GlobalLinkageKind : I32EnumAttr< - "GlobalLinkageKind", - "Linkage type/kind", - [Global_ExternalLinkage, Global_AvailableExternallyLinkage, - Global_LinkOnceAnyLinkage, Global_LinkOnceODRLinkage, - Global_WeakAnyLinkage, Global_WeakODRLinkage, - Global_InternalLinkage, Global_PrivateLinkage, - Global_ExternalWeakLinkage, Global_CommonLinkage - ]> { - let cppNamespace = "::cir"; -} +def CIR_GlobalLinkageKind : CIR_I32EnumAttr< + "GlobalLinkageKind", "linkage kind", [ + // Externally visible function + I32EnumAttrCase<"ExternalLinkage", 0, "external">, + // Available for inspection, not emission. + I32EnumAttrCase<"AvailableExternallyLinkage", 1, "available_externally">, + // Keep one copy of function when linking (inline) + I32EnumAttrCase<"LinkOnceAnyLinkage", 2, "linkonce">, + // Same, but only replaced by something equivalent. + I32EnumAttrCase<"LinkOnceODRLinkage", 3, "linkonce_odr">, + // Keep one copy of named function when linking (weak) + I32EnumAttrCase<"WeakAnyLinkage", 4, "weak">, + // Same, but only replaced by something equivalent. + I32EnumAttrCase<"WeakODRLinkage", 5, "weak_odr">, + // TODO: should we add something like appending linkage too? + // Special purpose, only applies to global arrays + // I32EnumAttrCase<"AppendingLinkage", 6, "appending">, + // Rename collisions when linking (static functions). + I32EnumAttrCase<"InternalLinkage", 7, "internal">, + // Like Internal, but omit from symbol table, prefix it with + // "cir_" to prevent clash with MLIR's symbol "private". + I32EnumAttrCase<"PrivateLinkage", 8, "cir_private">, + // ExternalWeak linkage description. + I32EnumAttrCase<"ExternalWeakLinkage", 9, "extern_weak">, + // Tentative definitions. + I32EnumAttrCase<"CommonLinkage", 10, "common"> +]>; // TODO(CIR): For starters, cir.global has only name and type. The other // properties of a global variable will be added over time as more of ClangIR @@ -1663,7 +1607,7 @@ def GlobalOp : CIR_Op<"global", >:$global_visibility, OptionalAttr:$sym_visibility, TypeAttr:$sym_type, - Arg:$linkage, + CIR_GlobalLinkageKind:$linkage, OptionalAttr:$initial_value, UnitAttr:$comdat, UnitAttr:$dsolocal, @@ -1858,6 +1802,35 @@ def FuncOp : CIR_Op<"func", [ // CallOp //===----------------------------------------------------------------------===// +def CIR_SideEffect : CIR_I32EnumAttr< + "SideEffect", "allowed side effects of a function", [ + I32EnumAttrCase<"All", 0, "all">, + I32EnumAttrCase<"Pure", 1, "pure">, + I32EnumAttrCase<"Const", 2, "const"> +]> { + let description = [{ + The side effect attribute specifies the possible side effects of the callee + of a call operation. This is an enumeration attribute and all possible + enumerators are: + + - all: The callee can have any side effects. This is the default if no side + effects are explicitly listed. + - pure: The callee may read data from memory, but it cannot write data to + memory. This has the same effect as the GNU C/C++ attribute + `__attribute__((pure))`. + - const: The callee may not read or write data from memory. This has the + same effect as the GNU C/C++ attribute `__attribute__((const))`. + + Examples: + + ```mlir + %2 = cir.call @add(%0, %1) : (!s32i, !s32i) -> !s32i + %2 = cir.call @add(%0, %1) : (!s32i, !s32i) -> !s32i side_effect(pure) + %2 = cir.call @add(%0, %1) : (!s32i, !s32i) -> !s32i side_effect(const) + ``` + }]; +} + class CIR_CallOpBase extra_traits = []> : Op extra_traits = []> // will add in the future. dag commonArgs = (ins OptionalAttr:$callee, - Variadic:$args); + Variadic:$args, + DefaultValuedAttr:$side_effect); } def CallOp : CIR_CallOpBase<"call", [NoRegionArguments]> { @@ -1942,20 +1916,26 @@ def CallOp : CIR_CallOpBase<"call", [NoRegionArguments]> { let builders = [ // Build a call op for a direct call OpBuilder<(ins "mlir::SymbolRefAttr":$callee, "mlir::Type":$resType, - "mlir::ValueRange":$operands), [{ + "mlir::ValueRange":$operands, + CArg<"SideEffect", "SideEffect::All">:$sideEffect), [{ assert(callee && "callee attribute is required for direct call"); $_state.addOperands(operands); $_state.addAttribute("callee", callee); + $_state.addAttribute("side_effect", + SideEffectAttr::get($_builder.getContext(), sideEffect)); if (resType && !isa(resType)) $_state.addTypes(resType); }]>, // Build a call op for an indirect call OpBuilder<(ins "mlir::Value":$calleePtr, "mlir::Type":$resType, - "mlir::ValueRange":$operands), [{ + "mlir::ValueRange":$operands, + CArg<"SideEffect", "SideEffect::All">:$sideEffect), [{ $_state.addOperands(calleePtr); $_state.addOperands(operands); if (resType && !isa(resType)) $_state.addTypes(resType); + $_state.addAttribute("side_effect", + SideEffectAttr::get($_builder.getContext(), sideEffect)); }]>, ]; } @@ -2147,14 +2127,20 @@ def VecCmpOp : CIR_Op<"vec.cmp", [Pure, SameTypeOperands]> { ``` }]; - let arguments = (ins Arg:$kind, CIR_VectorType:$lhs, - CIR_VectorType:$rhs); + let arguments = (ins + CIR_CmpOpKind:$kind, + CIR_VectorType:$lhs, + CIR_VectorType:$rhs + ); + let results = (outs CIR_VectorType:$result); let assemblyFormat = [{ `(` $kind `,` $lhs `,` $rhs `)` `:` qualified(type($lhs)) `,` qualified(type($result)) attr-dict }]; + + let hasFolder = 1; } //===----------------------------------------------------------------------===// @@ -2385,4 +2371,26 @@ def ComplexCreateOp : CIR_Op<"complex.create", [Pure, SameTypeOperands]> { let hasFolder = 1; } +//===----------------------------------------------------------------------===// +// Assume Operations +//===----------------------------------------------------------------------===// + +def AssumeOp : CIR_Op<"assume"> { + let summary = "Tell the optimizer that a boolean value is true"; + let description = [{ + The `cir.assume` operation takes a single boolean prediate as its only + argument and does not have any results. The operation tells the optimizer + that the predicate is always true. + + This operation corresponds to the `__assume` and the `__builtin_assume` + builtin functions. + }]; + + let arguments = (ins CIR_BoolType:$predicate); + + let assemblyFormat = [{ + $predicate `:` type($predicate) attr-dict + }]; +} + #endif // CLANG_CIR_DIALECT_IR_CIROPS_TD diff --git a/external/llvm-project/clang/include/clang/CIR/Interfaces/CIROpInterfaces.td b/external/llvm-project/clang/include/clang/CIR/Interfaces/CIROpInterfaces.td index 80d78b11c2ba..203e42f7c575 100644 --- a/external/llvm-project/clang/include/clang/CIR/Interfaces/CIROpInterfaces.td +++ b/external/llvm-project/clang/include/clang/CIR/Interfaces/CIROpInterfaces.td @@ -34,6 +34,8 @@ let cppNamespace = "::cir" in { "Return the number of operands, accounts for indirect call or " "exception info", "unsigned", "getNumArgOperands", (ins)>, + InterfaceMethod<"Return the side effects of the call operation", + "cir::SideEffect", "getSideEffect", (ins)>, ]; } diff --git a/external/llvm-project/clang/include/clang/CIR/MissingFeatures.h b/external/llvm-project/clang/include/clang/CIR/MissingFeatures.h index 13ddc77835fb..d8e45d02cd2a 100644 --- a/external/llvm-project/clang/include/clang/CIR/MissingFeatures.h +++ b/external/llvm-project/clang/include/clang/CIR/MissingFeatures.h @@ -95,7 +95,6 @@ struct MissingFeatures { static bool opCallReturn() { return false; } static bool opCallArgEvaluationOrder() { return false; } static bool opCallCallConv() { return false; } - static bool opCallSideEffect() { return false; } static bool opCallNoPrototypeFunc() { return false; } static bool opCallMustTail() { return false; } static bool opCallVirtual() { return false; } @@ -150,6 +149,7 @@ struct MissingFeatures { static bool cxxabiUseARMGuardVarABI() { return false; } static bool cxxabiAppleARM64CXXABI() { return false; } static bool cxxabiStructorImplicitParam() { return false; } + static bool isDiscreteBitFieldABI() { return false; } // Address class static bool addressOffset() { return false; } @@ -236,6 +236,11 @@ struct MissingFeatures { static bool runCleanupsScope() { return false; } static bool lowerAggregateLoadStore() { return false; } static bool dataLayoutTypeAllocSize() { return false; } + static bool asmLabelAttr() { return false; } + static bool builtinCall() { return false; } + static bool builtinCallF128() { return false; } + static bool builtinCallMathErrno() { return false; } + static bool nonFineGrainedBitfields() { return false; } // Missing types static bool dataMemberType() { return false; } diff --git a/external/llvm-project/clang/include/clang/CodeGen/CGFunctionInfo.h b/external/llvm-project/clang/include/clang/CodeGen/CGFunctionInfo.h index 040ee025afaa..50be51769f1a 100644 --- a/external/llvm-project/clang/include/clang/CodeGen/CGFunctionInfo.h +++ b/external/llvm-project/clang/include/clang/CodeGen/CGFunctionInfo.h @@ -828,10 +828,8 @@ class CGFunctionInfo final ID.AddInteger(paramInfo.getOpaqueValue()); } resultType.Profile(ID); - for (ArrayRef::iterator - i = argTypes.begin(), e = argTypes.end(); i != e; ++i) { - i->Profile(ID); - } + for (const CanQualType &argType : argTypes) + argType.Profile(ID); } }; diff --git a/external/llvm-project/clang/include/clang/Driver/Options.td b/external/llvm-project/clang/include/clang/Driver/Options.td index f10ac909d9da..fcc66446d5d8 100644 --- a/external/llvm-project/clang/include/clang/Driver/Options.td +++ b/external/llvm-project/clang/include/clang/Driver/Options.td @@ -577,7 +577,8 @@ multiclass BoolWOption> { + BothFlags suffix = BothFlags<[]>, + list flag_prefix = ["-"]> { defvar flag1 = FlagDefExpanded.Result, prefix, NAME, spelling_base>; @@ -598,12 +599,12 @@ multiclass BoolOptionWithoutMarshalling, Flags, + def flag1.RecordName : Flag, Flags, Visibility, HelpText, ImpliedByAnyOf {} - def flag2.RecordName : Flag<["-"], flag2.Spelling>, Flags, + def flag2.RecordName : Flag, Flags, Visibility, HelpText, ImpliedByAnyOf @@ -2176,11 +2177,14 @@ defm assume_nothrow_exception_dtor: BoolFOption<"assume-nothrow-exception-dtor", LangOpts<"AssumeNothrowExceptionDtor">, DefaultFalse, PosFlag, NegFlag>; -defm winx64_eh_unwindv2 : BoolFOption<"winx64-eh-unwindv2", - CodeGenOpts<"WinX64EHUnwindV2">, DefaultFalse, - PosFlag, - NegFlag, - BothFlags<[], [ClangOption], " unwind v2 (epilog) information for x64 Windows">>; +def winx64_eh_unwindv2 + : Joined<["-"], "fwinx64-eh-unwindv2=">, Group, + Visibility<[ClangOption, CC1Option]>, + HelpText<"Generate unwind v2 (epilog) information for x64 Windows">, + Values<"disabled,best-effort,required">, + NormalizedValues<["Disabled", "BestEffort", "Required"]>, + NormalizedValuesScope<"llvm::WinX64EHUnwindV2Mode">, + MarshallingInfoEnum, "Disabled">; def fexcess_precision_EQ : Joined<["-"], "fexcess-precision=">, Group, Visibility<[ClangOption, CLOption]>, HelpText<"Allows control over excess precision on targets where native " @@ -3357,6 +3361,9 @@ defm pch_codegen: OptInCC1FFlag<"pch-codegen", "Generate ", "Do not generate ", "code for uses of this PCH that assumes an explicit object file will be built for the PCH">; defm pch_debuginfo: OptInCC1FFlag<"pch-debuginfo", "Generate ", "Do not generate ", "debug info for types in an object file built from this PCH and do not generate them elsewhere">; +def ignore_pch : Flag<["-"], "ignore-pch">, Group, + Visibility<[ClangOption]>, + HelpText<"Disable precompiled headers, overrides -emit-pch and -include-pch">; def fimplicit_module_maps : Flag <["-"], "fimplicit-module-maps">, Group, Visibility<[ClangOption, CC1Option, CLOption]>, @@ -3482,8 +3489,9 @@ def fveclib : Joined<["-"], "fveclib=">, Group, Visibility<[ClangOption, CC1Option, FlangOption, FC1Option]>, HelpText<"Use the given vector functions library">, HelpTextForVariants<[ClangOption, CC1Option], - "Use the given vector functions library. " - "Note: -fveclib={ArmPL,SLEEF} implies -fno-math-errno">, + "Use the given vector functions library.\n" + " Note: -fveclib={ArmPL,SLEEF,libmvec} implies -fno-math-errno.\n" + " Note: -fveclib=libmvec on AArch64 requires GLIBC 2.40 or newer.">, Values<"Accelerate,libmvec,MASSV,SVML,SLEEF,Darwin_libsystem_m,ArmPL,AMDLIBM,none">, NormalizedValuesScope<"llvm::driver::VectorLibrary">, NormalizedValues<["Accelerate", "LIBMVEC", "MASSV", "SVML", "SLEEF", @@ -5285,10 +5293,16 @@ def mno_fix_cortex_a72_aes_1655431 : Flag<["-"], "mno-fix-cortex-a72-aes-1655431 Alias; def mfix_cortex_a53_835769 : Flag<["-"], "mfix-cortex-a53-835769">, Group, - HelpText<"Workaround Cortex-A53 erratum 835769 (AArch64 only)">; + HelpText<"Work around Cortex-A53 erratum 835769 (AArch64 only)">; def mno_fix_cortex_a53_835769 : Flag<["-"], "mno-fix-cortex-a53-835769">, Group, - HelpText<"Don't workaround Cortex-A53 erratum 835769 (AArch64 only)">; + HelpText<"Don't work around Cortex-A53 erratum 835769 (AArch64 only)">; +def mfix_cortex_a53_843419 : Flag<["-"], "mfix-cortex-a53-843419">, + Group, + HelpText<"Work around Cortex-A53 erratum 843419 (AArch64 only)">; +def mno_fix_cortex_a53_843419 : Flag<["-"], "mno-fix-cortex-a53-843419">, + Group, + HelpText<"Don't work around Cortex-A53 erratum 843419 (AArch64 only)">; def mmark_bti_property : Flag<["-"], "mmark-bti-property">, Group, HelpText<"Add .note.gnu.property with BTI to assembly files (AArch64 only)">; @@ -5888,12 +5902,17 @@ def nobuiltininc : Flag<["-"], "nobuiltininc">, Group, HelpText<"Disable builtin #include directories only">, MarshallingInfoNegativeFlag>; -def nogpuinc : Flag<["-"], "nogpuinc">, Group, - HelpText<"Do not add include paths for CUDA/HIP and" - " do not include the default CUDA/HIP wrapper headers">; +defm offload_inc: BoolOptionWithoutMarshalling<"", "offload-inc", + PosFlag, + NegFlag, + BothFlags<[]>, ["--"]>, Group; +def : Flag<["-"], "nogpuinc">, Alias; + def nohipwrapperinc : Flag<["-"], "nohipwrapperinc">, Group, HelpText<"Do not include the default HIP wrapper headers and include paths">; -def : Flag<["-"], "nocudainc">, Alias; +def : Flag<["-"], "nocudainc">, Alias; def no_offloadlib : Flag<["--"], "no-offloadlib">, MarshallingInfoFlag>, @@ -9154,7 +9173,9 @@ def _SLASH_volatile_Group : OptionGroup<"">, Group; def _SLASH_d2epilogunwind : CLFlag<"d2epilogunwind">, - HelpText<"Enable unwind v2 (epilog) information for x64 Windows">; + HelpText<"Best effort generate unwind v2 (epilog) information for x64 Windows">; +def _SLASH_d2epilogunwindrequirev2 : CLFlag<"d2epilogunwindrequirev2">, + HelpText<"Require generation of unwind v2 (epilog) information for x64 Windows">; def _SLASH_EH : CLJoined<"EH">, HelpText<"Set exception handling model">; def _SLASH_EP : CLFlag<"EP">, HelpText<"Disable linemarker output and preprocess to stdout">; diff --git a/external/llvm-project/clang/include/clang/Format/Format.h b/external/llvm-project/clang/include/clang/Format/Format.h index 127b1d08919d..2a5cf5fb50db 100644 --- a/external/llvm-project/clang/include/clang/Format/Format.h +++ b/external/llvm-project/clang/include/clang/Format/Format.h @@ -5275,7 +5275,7 @@ struct FormatStyle { /// Remove all empty lines at the beginning and the end of namespace body. /// \code /// namespace N1 { - /// namespace N2 + /// namespace N2 { /// function(); /// } /// } diff --git a/external/llvm-project/clang/include/clang/Lex/Lexer.h b/external/llvm-project/clang/include/clang/Lex/Lexer.h index bb65ae010cff..7a178b5b5c85 100644 --- a/external/llvm-project/clang/include/clang/Lex/Lexer.h +++ b/external/llvm-project/clang/include/clang/Lex/Lexer.h @@ -124,7 +124,7 @@ class Lexer : public PreprocessorLexer { //===--------------------------------------------------------------------===// // Context that changes as the file is lexed. // NOTE: any state that mutates when in raw mode must have save/restore code - // in Lexer::isNextPPTokenLParen. + // in Lexer::peekNextPPToken. // BufferPtr - Current pointer into the buffer. This is the next character // to be lexed. @@ -143,6 +143,9 @@ class Lexer : public PreprocessorLexer { /// True if this is the first time we're lexing the input file. bool IsFirstTimeLexingFile; + /// True if current lexing token is the first pp-token. + bool IsFirstPPToken; + // NewLinePtr - A pointer to new line character '\n' being lexed. For '\r\n', // it also points to '\n.' const char *NewLinePtr; @@ -642,10 +645,10 @@ class Lexer : public PreprocessorLexer { BufferPtr = TokEnd; } - /// isNextPPTokenLParen - Return 1 if the next unexpanded token will return a - /// tok::l_paren token, 0 if it is something else and 2 if there are no more - /// tokens in the buffer controlled by this lexer. - unsigned isNextPPTokenLParen(); + /// peekNextPPToken - Return std::nullopt if there are no more tokens in the + /// buffer controlled by this lexer, otherwise return the next unexpanded + /// token. + std::optional peekNextPPToken(); //===--------------------------------------------------------------------===// // Lexer character reading interfaces. diff --git a/external/llvm-project/clang/include/clang/Lex/Preprocessor.h b/external/llvm-project/clang/include/clang/Lex/Preprocessor.h index 78be2bd64d61..0ec1cb4d0c5d 100644 --- a/external/llvm-project/clang/include/clang/Lex/Preprocessor.h +++ b/external/llvm-project/clang/include/clang/Lex/Preprocessor.h @@ -350,6 +350,9 @@ class Preprocessor { /// Whether the last token we lexed was an '@'. bool LastTokenWasAt = false; + /// First pp-token in current translation unit. + std::optional FirstPPToken; + /// A position within a C++20 import-seq. class StdCXXImportSeq { public: @@ -1766,6 +1769,20 @@ class Preprocessor { std::optional LexEmbedParameters(Token &Current, bool ForHasEmbed); + /// Whether the preprocessor already seen the first pp-token in main file. + bool hasSeenMainFileFirstPPToken() const { return FirstPPToken.has_value(); } + + /// Record first pp-token and check if it has a Token::FirstPPToken flag. + void HandleMainFileFirstPPToken(const Token &Tok) { + if (!hasSeenMainFileFirstPPToken() && Tok.isFirstPPToken() && + SourceMgr.isWrittenInMainFile(Tok.getLocation())) + FirstPPToken = Tok; + } + + Token getMainFileFirstPPToken() const { + assert(FirstPPToken && "First main file pp-token doesn't exists"); + return *FirstPPToken; + } bool LexAfterModuleImport(Token &Result); void CollectPpImportSuffix(SmallVectorImpl &Toks); @@ -2285,10 +2302,41 @@ class Preprocessor { } } - /// Determine whether the next preprocessor token to be - /// lexed is a '('. If so, consume the token and return true, if not, this + /// Check whether the next pp-token is one of the specificed token kind. this /// method should have no observable side-effect on the lexed tokens. - bool isNextPPTokenLParen(); + template bool isNextPPTokenOneOf() { + // Do some quick tests for rejection cases. + std::optional Val; + if (CurLexer) + Val = CurLexer->peekNextPPToken(); + else + Val = CurTokenLexer->peekNextPPToken(); + + if (!Val) { + // We have run off the end. If it's a source file we don't + // examine enclosing ones (C99 5.1.1.2p4). Otherwise walk up the + // macro stack. + if (CurPPLexer) + return false; + for (const IncludeStackInfo &Entry : llvm::reverse(IncludeMacroStack)) { + if (Entry.TheLexer) + Val = Entry.TheLexer->peekNextPPToken(); + else + Val = Entry.TheTokenLexer->peekNextPPToken(); + + if (Val) + break; + + // Ran off the end of a source file? + if (Entry.ThePPLexer) + return false; + } + } + + // Okay, we found the token and return. Otherwise we found the end of the + // translation unit. + return Val->is(K) || (... || Val->is(Ks)); + } private: /// Identifiers used for SEH handling in Borland. These are only diff --git a/external/llvm-project/clang/include/clang/Lex/Token.h b/external/llvm-project/clang/include/clang/Lex/Token.h index 4f29fb7d1141..d4dfd7b44d9a 100644 --- a/external/llvm-project/clang/include/clang/Lex/Token.h +++ b/external/llvm-project/clang/include/clang/Lex/Token.h @@ -86,9 +86,12 @@ class Token { // macro stringizing or charizing operator. CommaAfterElided = 0x200, // The comma following this token was elided (MS). IsEditorPlaceholder = 0x400, // This identifier is a placeholder. - IsReinjected = 0x800, // A phase 4 token that was produced before and - // re-added, e.g. via EnterTokenStream. Annotation - // tokens are *not* reinjected. + + IsReinjected = 0x800, // A phase 4 token that was produced before and + // re-added, e.g. via EnterTokenStream. Annotation + // tokens are *not* reinjected. + FirstPPToken = 0x1000, // This token is the first pp token in the + // translation unit. }; tok::TokenKind getKind() const { return Kind; } @@ -318,6 +321,9 @@ class Token { /// represented as characters between '<#' and '#>' in the source code. The /// lexer uses identifier tokens to represent placeholders. bool isEditorPlaceholder() const { return getFlag(IsEditorPlaceholder); } + + /// Returns true if this token is the first pp-token. + bool isFirstPPToken() const { return getFlag(FirstPPToken); } }; /// Information about the conditional stack (\#if directives) diff --git a/external/llvm-project/clang/include/clang/Lex/TokenLexer.h b/external/llvm-project/clang/include/clang/Lex/TokenLexer.h index 4d229ae61067..777b4e6266c7 100644 --- a/external/llvm-project/clang/include/clang/Lex/TokenLexer.h +++ b/external/llvm-project/clang/include/clang/Lex/TokenLexer.h @@ -139,10 +139,9 @@ class TokenLexer { void Init(const Token *TokArray, unsigned NumToks, bool DisableMacroExpansion, bool OwnsTokens, bool IsReinject); - /// If the next token lexed will pop this macro off the - /// expansion stack, return 2. If the next unexpanded token is a '(', return - /// 1, otherwise return 0. - unsigned isNextTokenLParen() const; + /// If the next token lexed will pop this macro off the expansion stack, + /// return std::nullopt, otherwise return the next unexpanded token. + std::optional peekNextPPToken() const; /// Lex and return a token from this macro stream. bool Lex(Token &Tok); diff --git a/external/llvm-project/clang/include/clang/Parse/Parser.h b/external/llvm-project/clang/include/clang/Parse/Parser.h index 3243b94c5e5e..a47e23ffbd35 100644 --- a/external/llvm-project/clang/include/clang/Parse/Parser.h +++ b/external/llvm-project/clang/include/clang/Parse/Parser.h @@ -3598,7 +3598,7 @@ class Parser : public CodeCompletionHandler { /// keyword. bool isClassCompatibleKeyword(Token Tok) const; - void ParseMicrosoftRootSignatureAttributeArgs(ParsedAttributes &Attrs); + void ParseHLSLRootSignatureAttributeArgs(ParsedAttributes &Attrs); ///@} diff --git a/external/llvm-project/clang/include/clang/Sema/MultiplexExternalSemaSource.h b/external/llvm-project/clang/include/clang/Sema/MultiplexExternalSemaSource.h index 391c2177d75e..7c66c26a17a1 100644 --- a/external/llvm-project/clang/include/clang/Sema/MultiplexExternalSemaSource.h +++ b/external/llvm-project/clang/include/clang/Sema/MultiplexExternalSemaSource.h @@ -94,6 +94,8 @@ class MultiplexExternalSemaSource : public ExternalSemaSource { bool wasThisDeclarationADefinition(const FunctionDecl *FD) override; + bool hasInitializerWithSideEffects(const VarDecl *VD) const override; + /// Find all declarations with the given name in the /// given context. bool FindExternalVisibleDeclsByName(const DeclContext *DC, diff --git a/external/llvm-project/clang/include/clang/Sema/Scope.h b/external/llvm-project/clang/include/clang/Sema/Scope.h index ad12a3d73413..07b9e1bc10f5 100644 --- a/external/llvm-project/clang/include/clang/Sema/Scope.h +++ b/external/llvm-project/clang/include/clang/Sema/Scope.h @@ -427,6 +427,17 @@ class Scope { return false; } + /// isInObjcMethodScope - Return true if this scope is, or is contained, in an + /// C function body. + bool isInCFunctionScope() const { + for (const Scope *S = this; S; S = S->getParent()) { + if (S->isFunctionScope()) + return true; + } + + return false; + } + /// isInObjcMethodScope - Return true if this scope is, or is contained in, an /// Objective-C method body. Note that this method is not constant time. bool isInObjcMethodScope() const { diff --git a/external/llvm-project/clang/include/clang/Sema/Sema.h b/external/llvm-project/clang/include/clang/Sema/Sema.h index 29452bb37260..9397546c8fc5 100644 --- a/external/llvm-project/clang/include/clang/Sema/Sema.h +++ b/external/llvm-project/clang/include/clang/Sema/Sema.h @@ -9822,7 +9822,8 @@ class Sema final : public SemaBase { DeclGroupPtrTy ActOnModuleDecl(SourceLocation StartLoc, SourceLocation ModuleLoc, ModuleDeclKind MDK, ModuleIdPath Path, ModuleIdPath Partition, - ModuleImportState &ImportState); + ModuleImportState &ImportState, + bool IntroducerIsFirstPPToken); /// The parser has processed a global-module-fragment declaration that begins /// the definition of the global module fragment of the current module unit. diff --git a/external/llvm-project/clang/include/clang/Sema/SemaHLSL.h b/external/llvm-project/clang/include/clang/Sema/SemaHLSL.h index ba5f06f93dc3..7d7eae4db532 100644 --- a/external/llvm-project/clang/include/clang/Sema/SemaHLSL.h +++ b/external/llvm-project/clang/include/clang/Sema/SemaHLSL.h @@ -98,6 +98,8 @@ class SemaHLSL : public SemaBase { HLSLWaveSizeAttr *mergeWaveSizeAttr(Decl *D, const AttributeCommonInfo &AL, int Min, int Max, int Preferred, int SpelledArgsCount); + HLSLVkConstantIdAttr * + mergeVkConstantIdAttr(Decl *D, const AttributeCommonInfo &AL, int Id); HLSLShaderAttr *mergeShaderAttr(Decl *D, const AttributeCommonInfo &AL, llvm::Triple::EnvironmentType ShaderType); HLSLParamModifierAttr * @@ -119,9 +121,25 @@ class SemaHLSL : public SemaBase { bool IsCompAssign); void emitLogicalOperatorFixIt(Expr *LHS, Expr *RHS, BinaryOperatorKind Opc); + /// Computes the unique Root Signature identifier from the given signature, + /// then lookup if there is a previousy created Root Signature decl. + /// + /// Returns the identifier and if it was found + std::pair + ActOnStartRootSignatureDecl(StringRef Signature); + + /// Creates the Root Signature decl of the parsed Root Signature elements + /// onto the AST and push it onto current Scope + void ActOnFinishRootSignatureDecl( + SourceLocation Loc, IdentifierInfo *DeclIdent, + SmallVector &Elements); + + // Returns true when D is invalid and a diagnostic was produced + bool handleRootSignatureDecl(HLSLRootSignatureDecl *D, SourceLocation Loc); void handleRootSignatureAttr(Decl *D, const ParsedAttr &AL); void handleNumThreadsAttr(Decl *D, const ParsedAttr &AL); void handleWaveSizeAttr(Decl *D, const ParsedAttr &AL); + void handleVkConstantIdAttr(Decl *D, const ParsedAttr &AL); void handleSV_DispatchThreadIDAttr(Decl *D, const ParsedAttr &AL); void handleSV_GroupThreadIDAttr(Decl *D, const ParsedAttr &AL); void handleSV_GroupIDAttr(Decl *D, const ParsedAttr &AL); @@ -158,7 +176,7 @@ class SemaHLSL : public SemaBase { QualType getInoutParameterType(QualType Ty); bool transformInitList(const InitializedEntity &Entity, InitListExpr *Init); - + bool handleInitialization(VarDecl *VDecl, Expr *&Init); void deduceAddressSpace(VarDecl *Decl); private: diff --git a/external/llvm-project/clang/include/clang/Sema/SemaObjC.h b/external/llvm-project/clang/include/clang/Sema/SemaObjC.h index b629c6d29140..ed08ff0acf89 100644 --- a/external/llvm-project/clang/include/clang/Sema/SemaObjC.h +++ b/external/llvm-project/clang/include/clang/Sema/SemaObjC.h @@ -812,7 +812,8 @@ class SemaObjC : public SemaBase { CheckedConversionKind CCK, bool Diagnose = true, bool DiagnoseCFAudited = false, - BinaryOperatorKind Opc = BO_PtrMemD); + BinaryOperatorKind Opc = BO_PtrMemD, + bool IsReinterpretCast = false); Expr *stripARCUnbridgedCast(Expr *e); void diagnoseARCUnbridgedCast(Expr *e); diff --git a/external/llvm-project/clang/include/clang/Serialization/ASTReader.h b/external/llvm-project/clang/include/clang/Serialization/ASTReader.h index ba676fd8698e..7a4b7d21bb20 100644 --- a/external/llvm-project/clang/include/clang/Serialization/ASTReader.h +++ b/external/llvm-project/clang/include/clang/Serialization/ASTReader.h @@ -373,6 +373,24 @@ struct LazySpecializationInfoLookupTable; } // namespace serialization +struct VisibleLookupBlockOffsets { + uint64_t VisibleOffset = 0; + uint64_t ModuleLocalOffset = 0; + uint64_t TULocalOffset = 0; + + operator bool() const { + return VisibleOffset || ModuleLocalOffset || TULocalOffset; + } +}; + +struct LookupBlockOffsets : VisibleLookupBlockOffsets { + uint64_t LexicalOffset = 0; + + operator bool() const { + return VisibleLookupBlockOffsets::operator bool() || LexicalOffset; + } +}; + /// Reads an AST files chain containing the contents of a translation /// unit. /// @@ -535,13 +553,6 @@ class ASTReader /// in the chain. DeclUpdateOffsetsMap DeclUpdateOffsets; - struct LookupBlockOffsets { - uint64_t LexicalOffset; - uint64_t VisibleOffset; - uint64_t ModuleLocalOffset; - uint64_t TULocalOffset; - }; - using DelayedNamespaceOffsetMapTy = llvm::DenseMap; @@ -1444,6 +1455,12 @@ class ASTReader const StringRef &operator*() && = delete; }; + /// VarDecls with initializers containing side effects must be emitted, + /// but DeclMustBeEmitted is not allowed to deserialize the intializer. + /// FIXME: Lower memory usage by removing VarDecls once the initializer + /// is deserialized. + llvm::SmallPtrSet InitSideEffectVars; + public: /// Get the buffer for resolving paths. SmallString<0> &getPathBuf() { return PathBuf; } @@ -2395,6 +2412,8 @@ class ASTReader bool wasThisDeclarationADefinition(const FunctionDecl *FD) override; + bool hasInitializerWithSideEffects(const VarDecl *VD) const override; + /// Retrieve a selector from the given module with its local ID /// number. Selector getLocalSelector(ModuleFile &M, unsigned LocalID); diff --git a/external/llvm-project/clang/include/clang/Serialization/ASTRecordWriter.h b/external/llvm-project/clang/include/clang/Serialization/ASTRecordWriter.h index 07f7e8d919d8..964c9e6ea8a2 100644 --- a/external/llvm-project/clang/include/clang/Serialization/ASTRecordWriter.h +++ b/external/llvm-project/clang/include/clang/Serialization/ASTRecordWriter.h @@ -17,6 +17,7 @@ #include "clang/AST/AbstractBasicWriter.h" #include "clang/AST/OpenACCClause.h" #include "clang/AST/OpenMPClause.h" +#include "clang/Serialization/ASTReader.h" #include "clang/Serialization/ASTWriter.h" #include "clang/Serialization/SourceLocationEncoding.h" @@ -115,6 +116,13 @@ class ASTRecordWriter Record->push_back(BitOffset); } + void AddLookupOffsets(const LookupBlockOffsets &Offsets) { + AddOffset(Offsets.LexicalOffset); + AddOffset(Offsets.VisibleOffset); + AddOffset(Offsets.ModuleLocalOffset); + AddOffset(Offsets.TULocalOffset); + } + /// Add the given statement or expression to the queue of /// statements to emit. /// diff --git a/external/llvm-project/clang/include/clang/Serialization/ASTWriter.h b/external/llvm-project/clang/include/clang/Serialization/ASTWriter.h index cf4ae610ea51..97679ace8b61 100644 --- a/external/llvm-project/clang/include/clang/Serialization/ASTWriter.h +++ b/external/llvm-project/clang/include/clang/Serialization/ASTWriter.h @@ -75,6 +75,9 @@ class StoredDeclsList; class SwitchCase; class Token; +struct VisibleLookupBlockOffsets; +struct LookupBlockOffsets; + namespace serialization { enum class DeclUpdateKind; } // namespace serialization @@ -606,9 +609,7 @@ class ASTWriter : public ASTDeserializationListener, uint64_t WriteDeclContextLexicalBlock(ASTContext &Context, const DeclContext *DC); void WriteDeclContextVisibleBlock(ASTContext &Context, DeclContext *DC, - uint64_t &VisibleBlockOffset, - uint64_t &ModuleLocalBlockOffset, - uint64_t &TULocalBlockOffset); + VisibleLookupBlockOffsets &Offsets); void WriteTypeDeclOffsets(); void WriteFileDeclIDsMap(); void WriteComments(ASTContext &Context); @@ -777,6 +778,9 @@ class ASTWriter : public ASTDeserializationListener, return (I == DeclIDs.end() || I->second >= clang::NUM_PREDEF_DECL_IDS); }; + void AddLookupOffsets(const LookupBlockOffsets &Offsets, + RecordDataImpl &Record); + /// Emit a reference to a declaration. void AddDeclRef(const Decl *D, RecordDataImpl &Record); // Emit a reference to a declaration if the declaration was emitted. @@ -899,6 +903,10 @@ class ASTWriter : public ASTDeserializationListener, return WritingModule && WritingModule->isNamedModule(); } + bool isWritingStdCXXHeaderUnit() const { + return WritingModule && WritingModule->isHeaderUnit(); + } + bool isGeneratingReducedBMI() const { return GeneratingReducedBMI; } bool getDoneWritingDeclsAndTypes() const { return DoneWritingDeclsAndTypes; } diff --git a/external/llvm-project/clang/include/clang/StaticAnalyzer/Checkers/Checkers.td b/external/llvm-project/clang/include/clang/StaticAnalyzer/Checkers/Checkers.td index 2a96df80d100..2234143004b6 100644 --- a/external/llvm-project/clang/include/clang/StaticAnalyzer/Checkers/Checkers.td +++ b/external/llvm-project/clang/include/clang/StaticAnalyzer/Checkers/Checkers.td @@ -294,10 +294,12 @@ def TestAfterDivZeroChecker : Checker<"TestAfterDivZero">, "Either the comparison is useless or there is division by zero.">, Documentation; -def DynamicTypeChecker : Checker<"DynamicTypeChecker">, - HelpText<"Check for cases where the dynamic and the static type of an object " - "are unrelated.">, - Documentation; +def DynamicTypeChecker + : Checker<"DynamicTypeChecker">, + HelpText<"Check for cases where the dynamic and the static type of an " + "object are unrelated.">, + Dependencies<[DynamicTypePropagation]>, + Documentation; def StackAddrAsyncEscapeChecker : Checker<"StackAddressAsyncEscape">, HelpText<"Check that addresses to stack memory do not escape the function">, @@ -326,39 +328,34 @@ def StdVariantChecker : Checker<"StdVariant">, let ParentPackage = Nullability in { -def NullabilityBase : Checker<"NullabilityBase">, - HelpText<"Stores information during the analysis about nullability.">, - Documentation, - Hidden; - -def NullPassedToNonnullChecker : Checker<"NullPassedToNonnull">, - HelpText<"Warns when a null pointer is passed to a pointer which has a " - "_Nonnull type.">, - Dependencies<[NullabilityBase]>, - Documentation; + def NullPassedToNonnullChecker + : Checker<"NullPassedToNonnull">, + HelpText<"Warns when a null pointer is passed to a pointer which has a " + "_Nonnull type.">, + Documentation; -def NullReturnedFromNonnullChecker : Checker<"NullReturnedFromNonnull">, - HelpText<"Warns when a null pointer is returned from a function that has " - "_Nonnull return type.">, - Dependencies<[NullabilityBase]>, - Documentation; + def NullReturnedFromNonnullChecker + : Checker<"NullReturnedFromNonnull">, + HelpText<"Warns when a null pointer is returned from a function that " + "has _Nonnull return type.">, + Documentation; -def NullableDereferencedChecker : Checker<"NullableDereferenced">, - HelpText<"Warns when a nullable pointer is dereferenced.">, - Dependencies<[NullabilityBase]>, - Documentation; + def NullableDereferencedChecker + : Checker<"NullableDereferenced">, + HelpText<"Warns when a nullable pointer is dereferenced.">, + Documentation; -def NullablePassedToNonnullChecker : Checker<"NullablePassedToNonnull">, - HelpText<"Warns when a nullable pointer is passed to a pointer which has a " - "_Nonnull type.">, - Dependencies<[NullabilityBase]>, - Documentation; + def NullablePassedToNonnullChecker + : Checker<"NullablePassedToNonnull">, + HelpText<"Warns when a nullable pointer is passed to a pointer which " + "has a _Nonnull type.">, + Documentation; -def NullableReturnedFromNonnullChecker : Checker<"NullableReturnedFromNonnull">, - HelpText<"Warns when a nullable pointer is returned from a function that has " - "_Nonnull return type.">, - Dependencies<[NullabilityBase]>, - Documentation; + def NullableReturnedFromNonnullChecker + : Checker<"NullableReturnedFromNonnull">, + HelpText<"Warns when a nullable pointer is returned from a function " + "that has _Nonnull return type.">, + Documentation; } // end "nullability" diff --git a/external/llvm-project/clang/include/clang/Tooling/DependencyScanning/DependencyScanningFilesystem.h b/external/llvm-project/clang/include/clang/Tooling/DependencyScanning/DependencyScanningFilesystem.h index a20a89a4c2b7..da83220babea 100644 --- a/external/llvm-project/clang/include/clang/Tooling/DependencyScanning/DependencyScanningFilesystem.h +++ b/external/llvm-project/clang/include/clang/Tooling/DependencyScanning/DependencyScanningFilesystem.h @@ -23,6 +23,8 @@ namespace clang { namespace tooling { namespace dependencies { +class DependencyScanningService; + using DependencyDirectivesTy = SmallVector; @@ -349,7 +351,7 @@ class DependencyScanningWorkerFilesystem static const char ID; DependencyScanningWorkerFilesystem( - DependencyScanningFilesystemSharedCache &SharedCache, + DependencyScanningService &Service, IntrusiveRefCntPtr FS); llvm::ErrorOr status(const Twine &Path) override; @@ -435,10 +437,7 @@ class DependencyScanningWorkerFilesystem /// Returns entry associated with the unique ID in the shared cache or nullptr /// if none is found. const CachedFileSystemEntry * - findSharedEntryByUID(llvm::vfs::Status Stat) const { - return SharedCache.getShardForUID(Stat.getUniqueID()) - .findEntryByUID(Stat.getUniqueID()); - } + findSharedEntryByUID(llvm::vfs::Status Stat) const; /// Associates the given entry with the filename in the local cache and /// returns it. @@ -452,20 +451,14 @@ class DependencyScanningWorkerFilesystem /// some. Otherwise, constructs new one with the given error code, associates /// it with the filename and returns the result. const CachedFileSystemEntry & - getOrEmplaceSharedEntryForFilename(StringRef Filename, std::error_code EC) { - return SharedCache.getShardForFilename(Filename) - .getOrEmplaceEntryForFilename(Filename, EC); - } + getOrEmplaceSharedEntryForFilename(StringRef Filename, std::error_code EC); /// Returns entry associated with the filename in the shared cache if there is /// some. Otherwise, associates the given entry with the filename and returns /// it. const CachedFileSystemEntry & getOrInsertSharedEntryForFilename(StringRef Filename, - const CachedFileSystemEntry &Entry) { - return SharedCache.getShardForFilename(Filename) - .getOrInsertEntryForFilename(Filename, Entry); - } + const CachedFileSystemEntry &Entry); void printImpl(raw_ostream &OS, PrintType Type, unsigned IndentLevel) const override { @@ -478,8 +471,9 @@ class DependencyScanningWorkerFilesystem /// VFS. bool shouldBypass(StringRef Path) const; - /// The global cache shared between worker threads. - DependencyScanningFilesystemSharedCache &SharedCache; + /// The service associated with this VFS. + DependencyScanningService &Service; + /// The local cache is used by the worker thread to cache file system queries /// locally instead of querying the global cache every time. DependencyScanningFilesystemLocalCache LocalCache; diff --git a/external/llvm-project/clang/include/clang/Tooling/DependencyScanning/DependencyScanningService.h b/external/llvm-project/clang/include/clang/Tooling/DependencyScanning/DependencyScanningService.h index 4e97c7bc9f36..ceaf3c2279e7 100644 --- a/external/llvm-project/clang/include/clang/Tooling/DependencyScanning/DependencyScanningService.h +++ b/external/llvm-project/clang/include/clang/Tooling/DependencyScanning/DependencyScanningService.h @@ -87,7 +87,8 @@ class DependencyScanningService { ScanningOptimizations OptimizeArgs = ScanningOptimizations::Default, bool EagerLoadModules = false, bool TraceVFS = false, std::time_t BuildSessionTimestamp = - llvm::sys::toTimeT(std::chrono::system_clock::now())); + llvm::sys::toTimeT(std::chrono::system_clock::now()), + bool CacheNegativeStats = true); ScanningMode getMode() const { return Mode; } @@ -99,6 +100,8 @@ class DependencyScanningService { bool shouldTraceVFS() const { return TraceVFS; } + bool shouldCacheNegativeStats() const { return CacheNegativeStats; } + DependencyScanningFilesystemSharedCache &getSharedCache() { return SharedCache; } @@ -116,6 +119,7 @@ class DependencyScanningService { const bool EagerLoadModules; /// Whether to trace VFS accesses. const bool TraceVFS; + const bool CacheNegativeStats; /// The global file system cache. DependencyScanningFilesystemSharedCache SharedCache; /// The global module cache entries. diff --git a/external/llvm-project/clang/lib/AST/APValue.cpp b/external/llvm-project/clang/lib/AST/APValue.cpp index 7c33d3a165a0..c641ff6b99ba 100644 --- a/external/llvm-project/clang/lib/AST/APValue.cpp +++ b/external/llvm-project/clang/lib/AST/APValue.cpp @@ -1003,7 +1003,7 @@ bool APValue::hasLValuePath() const { ArrayRef APValue::getLValuePath() const { assert(isLValue() && hasLValuePath() && "Invalid accessor"); const LV &LVal = *((const LV *)(const char *)&Data); - return llvm::ArrayRef(LVal.getPath(), LVal.PathLength); + return {LVal.getPath(), LVal.PathLength}; } unsigned APValue::getLValueCallIndex() const { @@ -1081,7 +1081,7 @@ ArrayRef APValue::getMemberPointerPath() const { assert(isMemberPointer() && "Invalid accessor"); const MemberPointerData &MPD = *((const MemberPointerData *)(const char *)&Data); - return llvm::ArrayRef(MPD.getPath(), MPD.PathLength); + return {MPD.getPath(), MPD.PathLength}; } void APValue::MakeLValue() { diff --git a/external/llvm-project/clang/lib/AST/ASTContext.cpp b/external/llvm-project/clang/lib/AST/ASTContext.cpp index 189e67e4eed0..eba3c3de3d09 100644 --- a/external/llvm-project/clang/lib/AST/ASTContext.cpp +++ b/external/llvm-project/clang/lib/AST/ASTContext.cpp @@ -3522,6 +3522,7 @@ static void encodeTypeForFunctionPointerAuth(const ASTContext &Ctx, case BuiltinType::BFloat16: case BuiltinType::VectorQuad: case BuiltinType::VectorPair: + case BuiltinType::DMR1024: OS << "?"; return; @@ -6106,8 +6107,7 @@ SortAndUniqueProtocols(SmallVectorImpl &Protocols) { QualType ASTContext::getObjCObjectType(QualType BaseType, ObjCProtocolDecl * const *Protocols, unsigned NumProtocols) const { - return getObjCObjectType(BaseType, {}, - llvm::ArrayRef(Protocols, NumProtocols), + return getObjCObjectType(BaseType, {}, ArrayRef(Protocols, NumProtocols), /*isKindOf=*/false); } @@ -13110,9 +13110,7 @@ bool ASTContext::DeclMustBeEmitted(const Decl *D) { return true; // Variables that have initialization with side-effects are required. - if (VD->getInit() && VD->getInit()->HasSideEffects(*this) && - // We can get a value-dependent initializer during error recovery. - (VD->getInit()->isValueDependent() || !VD->evaluateValue())) + if (VD->hasInitWithSideEffects()) return true; // Likewise, variables with tuple-like bindings are required if their @@ -14283,7 +14281,7 @@ static QualType getCommonNonSugarTypeNode(ASTContext &Ctx, const Type *X, ::getCommonTemplateNameChecked(Ctx, TX->getTemplateName(), TY->getTemplateName(), /*IgnoreDeduced=*/true), - As, /*CanonicalArgs=*/std::nullopt, X->getCanonicalTypeInternal()); + As, /*CanonicalArgs=*/{}, X->getCanonicalTypeInternal()); } case Type::Decltype: { const auto *DX = cast(X); @@ -14529,7 +14527,7 @@ static QualType getCommonSugarTypeNode(ASTContext &Ctx, const Type *X, TY->template_arguments())) return QualType(); return Ctx.getTemplateSpecializationType(CTN, As, - /*CanonicalArgs=*/std::nullopt, + /*CanonicalArgs=*/{}, Ctx.getQualifiedType(Underlying)); } case Type::Typedef: { @@ -14592,7 +14590,7 @@ static QualType getCommonSugarTypeNode(ASTContext &Ctx, const Type *X, return QualType(); Expr *CEX = DX->getCountExpr(); Expr *CEY = DY->getCountExpr(); - llvm::ArrayRef CDX = DX->getCoupledDecls(); + ArrayRef CDX = DX->getCoupledDecls(); if (Ctx.hasSameExpr(CEX, CEY)) return Ctx.getCountAttributedType(Ctx.getQualifiedType(Underlying), CEX, DX->isCountInBytes(), DX->isOrNull(), diff --git a/external/llvm-project/clang/lib/AST/ASTDiagnostic.cpp b/external/llvm-project/clang/lib/AST/ASTDiagnostic.cpp index a00d5801f054..20a4c3a43d2c 100644 --- a/external/llvm-project/clang/lib/AST/ASTDiagnostic.cpp +++ b/external/llvm-project/clang/lib/AST/ASTDiagnostic.cpp @@ -130,7 +130,7 @@ QualType clang::desugarForDiagnostic(ASTContext &Context, QualType QT, if (DesugarArgument) { ShouldAKA = true; QT = Context.getTemplateSpecializationType( - TST->getTemplateName(), Args, /*CanonicalArgs=*/std::nullopt, QT); + TST->getTemplateName(), Args, /*CanonicalArgs=*/{}, QT); } break; } @@ -228,7 +228,7 @@ break; \ desugarForDiagnostic(Context, Ty->getBaseType(), ShouldAKA); QT = Context.getObjCObjectType( BaseType, Ty->getTypeArgsAsWritten(), - llvm::ArrayRef(Ty->qual_begin(), Ty->getNumProtocols()), + ArrayRef(Ty->qual_begin(), Ty->getNumProtocols()), Ty->isKindOfTypeAsWritten()); } } @@ -1143,7 +1143,7 @@ class TemplateDiff { Ty = Context.getTemplateSpecializationType( TemplateName(CTSD->getSpecializedTemplate()), - CTSD->getTemplateArgs().asArray(), /*CanonicalArgs=*/std::nullopt, + CTSD->getTemplateArgs().asArray(), /*CanonicalArgs=*/{}, Ty.getLocalUnqualifiedType().getCanonicalType()); return Ty->getAs(); diff --git a/external/llvm-project/clang/lib/AST/ASTImporter.cpp b/external/llvm-project/clang/lib/AST/ASTImporter.cpp index 5c44353d8b98..2b7d67f389a6 100644 --- a/external/llvm-project/clang/lib/AST/ASTImporter.cpp +++ b/external/llvm-project/clang/lib/AST/ASTImporter.cpp @@ -904,8 +904,7 @@ ASTNodeImporter::import(const TemplateArgument &From) { if (Error Err = ImportTemplateArguments(From.pack_elements(), ToPack)) return std::move(Err); - return TemplateArgument( - llvm::ArrayRef(ToPack).copy(Importer.getToContext())); + return TemplateArgument(ArrayRef(ToPack).copy(Importer.getToContext())); } } @@ -1664,7 +1663,7 @@ ExpectedType ASTNodeImporter::VisitTemplateSpecializationType( if (!ToUnderlyingOrErr) return ToUnderlyingOrErr.takeError(); return Importer.getToContext().getTemplateSpecializationType( - *ToTemplateOrErr, ToTemplateArgs, std::nullopt, *ToUnderlyingOrErr); + *ToTemplateOrErr, ToTemplateArgs, {}, *ToUnderlyingOrErr); } ExpectedType ASTNodeImporter::VisitElaboratedType(const ElaboratedType *T) { @@ -4123,7 +4122,7 @@ ExpectedDecl ASTNodeImporter::VisitFunctionDecl(FunctionDecl *D) { return std::move(Err); auto **Memory = new (Importer.getToContext()) CXXCtorInitializer *[NumInitializers]; - std::copy(CtorInitializers.begin(), CtorInitializers.end(), Memory); + llvm::copy(CtorInitializers, Memory); auto *ToCtor = cast(ToFunction); ToCtor->setCtorInitializers(Memory); ToCtor->setNumCtorInitializers(NumInitializers); @@ -4348,7 +4347,7 @@ ExpectedDecl ASTNodeImporter::VisitIndirectFieldDecl(IndirectFieldDecl *D) { else return ToD.takeError(); - llvm::MutableArrayRef CH = {NamedChain, D->getChainingSize()}; + MutableArrayRef CH = {NamedChain, D->getChainingSize()}; IndirectFieldDecl *ToIndirectField; if (GetImportedOrCreateDecl(ToIndirectField, D, Importer.getToContext(), DC, Loc, Name.getAsIdentifierInfo(), *TypeOrErr, CH)) @@ -4452,7 +4451,7 @@ ExpectedDecl ASTNodeImporter::VisitFriendDecl(FriendDecl *D) { } SmallVector ToTPLists(D->NumTPLists); - auto **FromTPLists = D->getTrailingObjects(); + auto **FromTPLists = D->getTrailingObjects(); for (unsigned I = 0; I < D->NumTPLists; I++) { if (auto ListOrErr = import(FromTPLists[I])) ToTPLists[I] = *ListOrErr; @@ -6339,8 +6338,7 @@ ExpectedDecl ASTNodeImporter::VisitClassTemplateSpecializationDecl( if (GetImportedOrCreateDecl( D2, D, Importer.getToContext(), D->getTagKind(), DC, *BeginLocOrErr, *IdLocOrErr, ToTPList, ClassTemplate, - llvm::ArrayRef(TemplateArgs.data(), TemplateArgs.size()), - CanonInjType, + ArrayRef(TemplateArgs.data(), TemplateArgs.size()), CanonInjType, cast_or_null(PrevDecl))) return D2; @@ -7439,7 +7437,7 @@ ExpectedStmt ASTNodeImporter::VisitShuffleVectorExpr(ShuffleVectorExpr *E) { const unsigned NumSubExprs = E->getNumSubExprs(); llvm::SmallVector ToSubExprs; - llvm::ArrayRef FromSubExprs(E->getSubExprs(), NumSubExprs); + ArrayRef FromSubExprs(E->getSubExprs(), NumSubExprs); ToSubExprs.resize(NumSubExprs); if ((Err = ImportContainerChecked(FromSubExprs, ToSubExprs))) @@ -7492,25 +7490,25 @@ ASTNodeImporter::VisitGenericSelectionExpr(GenericSelectionExpr *E) { if (E->isResultDependent()) { if (ToControllingExpr) { return GenericSelectionExpr::Create( - ToCtx, ToGenericLoc, ToControllingExpr, llvm::ArrayRef(ToAssocTypes), - llvm::ArrayRef(ToAssocExprs), ToDefaultLoc, ToRParenLoc, + ToCtx, ToGenericLoc, ToControllingExpr, ArrayRef(ToAssocTypes), + ArrayRef(ToAssocExprs), ToDefaultLoc, ToRParenLoc, E->containsUnexpandedParameterPack()); } return GenericSelectionExpr::Create( - ToCtx, ToGenericLoc, ToControllingType, llvm::ArrayRef(ToAssocTypes), - llvm::ArrayRef(ToAssocExprs), ToDefaultLoc, ToRParenLoc, + ToCtx, ToGenericLoc, ToControllingType, ArrayRef(ToAssocTypes), + ArrayRef(ToAssocExprs), ToDefaultLoc, ToRParenLoc, E->containsUnexpandedParameterPack()); } if (ToControllingExpr) { return GenericSelectionExpr::Create( - ToCtx, ToGenericLoc, ToControllingExpr, llvm::ArrayRef(ToAssocTypes), - llvm::ArrayRef(ToAssocExprs), ToDefaultLoc, ToRParenLoc, + ToCtx, ToGenericLoc, ToControllingExpr, ArrayRef(ToAssocTypes), + ArrayRef(ToAssocExprs), ToDefaultLoc, ToRParenLoc, E->containsUnexpandedParameterPack(), E->getResultIndex()); } return GenericSelectionExpr::Create( - ToCtx, ToGenericLoc, ToControllingType, llvm::ArrayRef(ToAssocTypes), - llvm::ArrayRef(ToAssocExprs), ToDefaultLoc, ToRParenLoc, + ToCtx, ToGenericLoc, ToControllingType, ArrayRef(ToAssocTypes), + ArrayRef(ToAssocExprs), ToDefaultLoc, ToRParenLoc, E->containsUnexpandedParameterPack(), E->getResultIndex()); } @@ -7695,9 +7693,9 @@ ExpectedStmt ASTNodeImporter::VisitStringLiteral(StringLiteral *E) { E->tokloc_begin(), E->tokloc_end(), ToLocations.begin())) return std::move(Err); - return StringLiteral::Create( - Importer.getToContext(), E->getBytes(), E->getKind(), E->isPascal(), - *ToTypeOrErr, ToLocations.data(), ToLocations.size()); + return StringLiteral::Create(Importer.getToContext(), E->getBytes(), + E->getKind(), E->isPascal(), *ToTypeOrErr, + ToLocations); } ExpectedStmt ASTNodeImporter::VisitCompoundLiteralExpr(CompoundLiteralExpr *E) { @@ -8636,7 +8634,7 @@ ExpectedStmt ASTNodeImporter::VisitCXXUnresolvedConstructExpr( return CXXUnresolvedConstructExpr::Create( Importer.getToContext(), ToType, ToTypeSourceInfo, ToLParenLoc, - llvm::ArrayRef(ToArgs), ToRParenLoc, E->isListInitialization()); + ArrayRef(ToArgs), ToRParenLoc, E->isListInitialization()); } ExpectedStmt @@ -10396,8 +10394,7 @@ ASTNodeImporter::ImportAPValue(const APValue &FromValue) { cast(ImpMemPtrDecl), FromValue.isMemberPointerToDerivedMember(), FromValue.getMemberPointerPath().size()); - llvm::ArrayRef FromPath = - Result.getMemberPointerPath(); + ArrayRef FromPath = Result.getMemberPointerPath(); for (unsigned Idx = 0; Idx < FromValue.getMemberPointerPath().size(); Idx++) { const Decl *ImpDecl = importChecked(Err, FromPath[Idx]); @@ -10454,8 +10451,7 @@ ASTNodeImporter::ImportAPValue(const APValue &FromValue) { MutableArrayRef ToPath = Result.setLValueUninit( Base, Offset, PathLength, FromValue.isLValueOnePastTheEnd(), FromValue.isNullPointer()); - llvm::ArrayRef FromPath = - FromValue.getLValuePath(); + ArrayRef FromPath = FromValue.getLValuePath(); for (unsigned LoopIdx = 0; LoopIdx < PathLength; LoopIdx++) { if (FromElemTy->isRecordType()) { const Decl *FromDecl = diff --git a/external/llvm-project/clang/lib/AST/ByteCode/ByteCodeEmitter.cpp b/external/llvm-project/clang/lib/AST/ByteCode/ByteCodeEmitter.cpp index d91d5f16fc7a..965e23503603 100644 --- a/external/llvm-project/clang/lib/AST/ByteCode/ByteCodeEmitter.cpp +++ b/external/llvm-project/clang/lib/AST/ByteCode/ByteCodeEmitter.cpp @@ -176,7 +176,8 @@ static void emitSerialized(std::vector &Code, const T &Val, } // Access must be aligned! - size_t ValPos = align(Code.size()); + assert(aligned(Code.size())); + size_t ValPos = Code.size(); Size = align(Size); assert(aligned(ValPos + Size)); Code.resize(ValPos + Size); diff --git a/external/llvm-project/clang/lib/AST/ByteCode/Compiler.cpp b/external/llvm-project/clang/lib/AST/ByteCode/Compiler.cpp index 9fe4803ce98e..81da16e797bc 100644 --- a/external/llvm-project/clang/lib/AST/ByteCode/Compiler.cpp +++ b/external/llvm-project/clang/lib/AST/ByteCode/Compiler.cpp @@ -748,7 +748,8 @@ bool Compiler::VisitFloatingLiteral(const FloatingLiteral *E) { if (DiscardResult) return true; - return this->emitConstFloat(E->getValue(), E); + APFloat F = E->getValue(); + return this->emitFloat(F, E); } template @@ -4185,13 +4186,14 @@ bool Compiler::visitZeroInitializer(PrimType T, QualType QT, nullptr, E); case PT_MemberPtr: return this->emitNullMemberPtr(0, nullptr, E); - case PT_Float: - return this->emitConstFloat(APFloat::getZero(Ctx.getFloatSemantics(QT)), E); + case PT_Float: { + APFloat F = APFloat::getZero(Ctx.getFloatSemantics(QT)); + return this->emitFloat(F, E); + } case PT_FixedPoint: { auto Sem = Ctx.getASTContext().getFixedPointSemantics(E->getType()); return this->emitConstFixedPoint(FixedPoint::zero(Sem), E); } - llvm_unreachable("Implement"); } llvm_unreachable("unknown primitive type"); } @@ -4674,10 +4676,7 @@ VarCreationState Compiler::visitVarDecl(const VarDecl *VD, if (!visitInitializer(Init)) return false; - if (!this->emitFinishInit(Init)) - return false; - - return this->emitPopPtr(Init); + return this->emitFinishInitGlobal(Init); }; DeclScope LocalScope(this, VD); @@ -4698,51 +4697,45 @@ VarCreationState Compiler::visitVarDecl(const VarDecl *VD, return false; return !Init || (checkDecl() && initGlobal(*GlobalIndex)); - } else { - InitLinkScope ILS(this, InitLink::Decl(VD)); - - if (VarT) { - unsigned Offset = this->allocateLocalPrimitive( - VD, *VarT, VD->getType().isConstQualified(), nullptr, - ScopeKind::Block, IsConstexprUnknown); - if (Init) { - // If this is a toplevel declaration, create a scope for the - // initializer. - if (Toplevel) { - LocalScope Scope(this); - if (!this->visit(Init)) - return false; - return this->emitSetLocal(*VarT, Offset, VD) && Scope.destroyLocals(); - } else { - if (!this->visit(Init)) - return false; - return this->emitSetLocal(*VarT, Offset, VD); - } - } - } else { - if (std::optional Offset = - this->allocateLocal(VD, VD->getType(), nullptr, ScopeKind::Block, - IsConstexprUnknown)) { - if (!Init) - return true; + } + // Local variables. + InitLinkScope ILS(this, InitLink::Decl(VD)); - if (!this->emitGetPtrLocal(*Offset, Init)) + if (VarT) { + unsigned Offset = this->allocateLocalPrimitive( + VD, *VarT, VD->getType().isConstQualified(), nullptr, ScopeKind::Block, + IsConstexprUnknown); + if (Init) { + // If this is a toplevel declaration, create a scope for the + // initializer. + if (Toplevel) { + LocalScope Scope(this); + if (!this->visit(Init)) return false; - - if (!visitInitializer(Init)) + return this->emitSetLocal(*VarT, Offset, VD) && Scope.destroyLocals(); + } else { + if (!this->visit(Init)) return false; + return this->emitSetLocal(*VarT, Offset, VD); + } + } + } else { + if (std::optional Offset = this->allocateLocal( + VD, VD->getType(), nullptr, ScopeKind::Block, IsConstexprUnknown)) { + if (!Init) + return true; - if (!this->emitFinishInit(Init)) - return false; + if (!this->emitGetPtrLocal(*Offset, Init)) + return false; - return this->emitPopPtr(Init); - } - return false; + if (!visitInitializer(Init)) + return false; + + return this->emitFinishInitPop(Init); } - return true; + return false; } - - return false; + return true; } template @@ -4751,8 +4744,10 @@ bool Compiler::visitAPValue(const APValue &Val, PrimType ValType, assert(!DiscardResult); if (Val.isInt()) return this->emitConst(Val.getInt(), ValType, E); - else if (Val.isFloat()) - return this->emitConstFloat(Val.getFloat(), E); + else if (Val.isFloat()) { + APFloat F = Val.getFloat(); + return this->emitFloat(F, E); + } if (Val.isLValue()) { if (Val.isNullPointer()) @@ -4961,8 +4956,7 @@ bool Compiler::VisitCallExpr(const CallExpr *E) { } } - SmallVector Args( - llvm::ArrayRef(E->getArgs(), E->getNumArgs())); + SmallVector Args(ArrayRef(E->getArgs(), E->getNumArgs())); bool IsAssignmentOperatorCall = false; if (const auto *OCE = dyn_cast(E); @@ -6133,8 +6127,10 @@ bool Compiler::VisitUnaryOperator(const UnaryOperator *E) { const auto &TargetSemantics = Ctx.getFloatSemantics(E->getType()); if (!this->emitLoadFloat(E)) return false; - if (!this->emitConstFloat(llvm::APFloat(TargetSemantics, 1), E)) + APFloat F(TargetSemantics, 1); + if (!this->emitFloat(F, E)) return false; + if (!this->emitAddf(getFPOptions(E), E)) return false; if (!this->emitStoreFloat(E)) @@ -6176,8 +6172,10 @@ bool Compiler::VisitUnaryOperator(const UnaryOperator *E) { const auto &TargetSemantics = Ctx.getFloatSemantics(E->getType()); if (!this->emitLoadFloat(E)) return false; - if (!this->emitConstFloat(llvm::APFloat(TargetSemantics, 1), E)) + APFloat F(TargetSemantics, 1); + if (!this->emitFloat(F, E)) return false; + if (!this->emitSubf(getFPOptions(E), E)) return false; if (!this->emitStoreFloat(E)) @@ -6953,6 +6951,20 @@ bool Compiler::emitDummyPtr(const DeclTy &D, const Expr *E) { return true; } +template +bool Compiler::emitFloat(const APFloat &F, const Expr *E) { + assert(!DiscardResult && "Should've been checked before"); + + if (Floating::singleWord(F.getSemantics())) + return this->emitConstFloat(Floating(F), E); + + APInt I = F.bitcastToAPInt(); + return this->emitConstFloat( + Floating(const_cast(I.getRawData()), + llvm::APFloatBase::SemanticsToEnum(F.getSemantics())), + E); +} + // This function is constexpr if and only if To, From, and the types of // all subobjects of To and From are types T such that... // (3.1) - is_union_v is false; diff --git a/external/llvm-project/clang/lib/AST/ByteCode/Compiler.h b/external/llvm-project/clang/lib/AST/ByteCode/Compiler.h index ac3ad84766dc..a1d068cc7e0a 100644 --- a/external/llvm-project/clang/lib/AST/ByteCode/Compiler.h +++ b/external/llvm-project/clang/lib/AST/ByteCode/Compiler.h @@ -391,6 +391,7 @@ class Compiler : public ConstStmtVisitor, bool>, bool emitRecordDestruction(const Record *R, SourceInfo Loc); bool emitDestruction(const Descriptor *Desc, SourceInfo Loc); bool emitDummyPtr(const DeclTy &D, const Expr *E); + bool emitFloat(const APFloat &F, const Expr *E); unsigned collectBaseOffset(const QualType BaseType, const QualType DerivedType); bool emitLambdaStaticInvokerBody(const CXXMethodDecl *MD); diff --git a/external/llvm-project/clang/lib/AST/ByteCode/Descriptor.cpp b/external/llvm-project/clang/lib/AST/ByteCode/Descriptor.cpp index 5531295dfa2f..46e4d0d940b3 100644 --- a/external/llvm-project/clang/lib/AST/ByteCode/Descriptor.cpp +++ b/external/llvm-project/clang/lib/AST/ByteCode/Descriptor.cpp @@ -368,7 +368,7 @@ Descriptor::Descriptor(const DeclTy &D, PrimType Type, MetadataSize MD, bool IsTemporary, bool IsConst, UnknownSize) : Source(D), ElemSize(primSize(Type)), Size(UnknownSizeMark), MDSize(MD.value_or(0)), - AllocSize(MDSize + sizeof(InitMapPtr) + alignof(void *)), + AllocSize(MDSize + sizeof(InitMapPtr) + alignof(void *)), PrimT(Type), IsConst(IsConst), IsMutable(false), IsTemporary(IsTemporary), IsArray(true), CtorFn(getCtorArrayPrim(Type)), DtorFn(getDtorArrayPrim(Type)), MoveFn(getMoveArrayPrim(Type)) { diff --git a/external/llvm-project/clang/lib/AST/ByteCode/Disasm.cpp b/external/llvm-project/clang/lib/AST/ByteCode/Disasm.cpp index 846dc2fe92a7..a3eecd06369b 100644 --- a/external/llvm-project/clang/lib/AST/ByteCode/Disasm.cpp +++ b/external/llvm-project/clang/lib/AST/ByteCode/Disasm.cpp @@ -50,34 +50,57 @@ inline static std::string printArg(Program &P, CodePtr &OpPC) { } template <> inline std::string printArg(Program &P, CodePtr &OpPC) { - auto F = Floating::deserialize(*OpPC); - OpPC += align(F.bytesToSerialize()); + auto Sem = Floating::deserializeSemantics(*OpPC); - std::string Result; - llvm::raw_string_ostream SS(Result); - SS << F; - return Result; + unsigned BitWidth = llvm::APFloatBase::semanticsSizeInBits( + llvm::APFloatBase::EnumToSemantics(Sem)); + auto Memory = + std::make_unique(llvm::APInt::getNumWords(BitWidth)); + Floating Result(Memory.get(), Sem); + Floating::deserialize(*OpPC, &Result); + + OpPC += align(Result.bytesToSerialize()); + + std::string S; + llvm::raw_string_ostream SS(S); + SS << Result; + return S; } template <> inline std::string printArg>(Program &P, CodePtr &OpPC) { - auto F = IntegralAP::deserialize(*OpPC); - OpPC += align(F.bytesToSerialize()); + using T = IntegralAP; + uint32_t BitWidth = T::deserializeSize(*OpPC); + auto Memory = + std::make_unique(llvm::APInt::getNumWords(BitWidth)); - std::string Result; - llvm::raw_string_ostream SS(Result); - SS << F; - return Result; + T Result(Memory.get(), BitWidth); + T::deserialize(*OpPC, &Result); + + OpPC += align(Result.bytesToSerialize()); + + std::string Str; + llvm::raw_string_ostream SS(Str); + SS << Result; + return Str; } + template <> inline std::string printArg>(Program &P, CodePtr &OpPC) { - auto F = IntegralAP::deserialize(*OpPC); - OpPC += align(F.bytesToSerialize()); + using T = IntegralAP; + uint32_t BitWidth = T::deserializeSize(*OpPC); + auto Memory = + std::make_unique(llvm::APInt::getNumWords(BitWidth)); - std::string Result; - llvm::raw_string_ostream SS(Result); - SS << F; - return Result; + T Result(Memory.get(), BitWidth); + T::deserialize(*OpPC, &Result); + + OpPC += align(Result.bytesToSerialize()); + + std::string Str; + llvm::raw_string_ostream SS(Str); + SS << Result; + return Str; } template <> inline std::string printArg(Program &P, CodePtr &OpPC) { diff --git a/external/llvm-project/clang/lib/AST/ByteCode/Floating.h b/external/llvm-project/clang/lib/AST/ByteCode/Floating.h index 3750568fc23c..659892e720ab 100644 --- a/external/llvm-project/clang/lib/AST/ByteCode/Floating.h +++ b/external/llvm-project/clang/lib/AST/ByteCode/Floating.h @@ -17,63 +17,79 @@ #include "clang/AST/APValue.h" #include "llvm/ADT/APFloat.h" +// XXX This is just a debugging help. Setting this to 1 will heap-allocate ALL +// floating values. +#define ALLOCATE_ALL 0 + namespace clang { namespace interp { using APFloat = llvm::APFloat; using APSInt = llvm::APSInt; +using APInt = llvm::APInt; +/// If a Floating is constructed from Memory, it DOES NOT OWN THAT MEMORY. +/// It will NOT copy the memory (unless, of course, copy() is called) and it +/// won't alllocate anything. The allocation should happen via InterpState or +/// Program. class Floating final { private: - // The underlying value storage. - APFloat F; + union { + uint64_t Val = 0; + uint64_t *Memory; + }; + llvm::APFloatBase::Semantics Semantics; + + APFloat getValue() const { + unsigned BitWidth = bitWidth(); + if (singleWord()) + return APFloat(getSemantics(), APInt(BitWidth, Val)); + unsigned NumWords = numWords(); + return APFloat(getSemantics(), APInt(BitWidth, NumWords, Memory)); + } public: - /// Zero-initializes a Floating. - Floating() : F(0.0f) {} - Floating(const APFloat &F) : F(F) {} + Floating() = default; + Floating(llvm::APFloatBase::Semantics Semantics) + : Val(0), Semantics(Semantics) {} + Floating(const APFloat &F) { - // Static constructors for special floating point values. - static Floating getInf(const llvm::fltSemantics &Sem) { - return Floating(APFloat::getInf(Sem)); + Semantics = llvm::APFloatBase::SemanticsToEnum(F.getSemantics()); + this->copy(F); } - const APFloat &getAPFloat() const { return F; } + Floating(uint64_t *Memory, llvm::APFloatBase::Semantics Semantics) + : Memory(Memory), Semantics(Semantics) {} + + APFloat getAPFloat() const { return getValue(); } - bool operator<(Floating RHS) const { return F < RHS.F; } - bool operator>(Floating RHS) const { return F > RHS.F; } - bool operator<=(Floating RHS) const { return F <= RHS.F; } - bool operator>=(Floating RHS) const { return F >= RHS.F; } - bool operator==(Floating RHS) const { return F == RHS.F; } - bool operator!=(Floating RHS) const { return F != RHS.F; } - Floating operator-() const { return Floating(-F); } + bool operator<(Floating RHS) const { return getValue() < RHS.getValue(); } + bool operator>(Floating RHS) const { return getValue() > RHS.getValue(); } + bool operator<=(Floating RHS) const { return getValue() <= RHS.getValue(); } + bool operator>=(Floating RHS) const { return getValue() >= RHS.getValue(); } APFloat::opStatus convertToInteger(APSInt &Result) const { bool IsExact; - return F.convertToInteger(Result, llvm::APFloat::rmTowardZero, &IsExact); + return getValue().convertToInteger(Result, llvm::APFloat::rmTowardZero, + &IsExact); } - Floating toSemantics(const llvm::fltSemantics *Sem, - llvm::RoundingMode RM) const { - APFloat Copy = F; + void toSemantics(const llvm::fltSemantics *Sem, llvm::RoundingMode RM, + Floating *Result) const { + APFloat Copy = getValue(); bool LosesInfo; Copy.convert(*Sem, RM, &LosesInfo); (void)LosesInfo; - return Floating(Copy); - } - - /// Convert this Floating to one with the same semantics as \Other. - Floating toSemantics(const Floating &Other, llvm::RoundingMode RM) const { - return toSemantics(&Other.F.getSemantics(), RM); + Result->copy(Copy); } APSInt toAPSInt(unsigned NumBits = 0) const { - return APSInt(F.bitcastToAPInt()); + return APSInt(getValue().bitcastToAPInt()); } - APValue toAPValue(const ASTContext &) const { return APValue(F); } + APValue toAPValue(const ASTContext &) const { return APValue(getValue()); } void print(llvm::raw_ostream &OS) const { // Can't use APFloat::print() since it appends a newline. SmallVector Buffer; - F.toString(Buffer); + getValue().toString(Buffer); OS << Buffer; } std::string toDiagnosticString(const ASTContext &Ctx) const { @@ -83,25 +99,62 @@ class Floating final { return NameStr; } - unsigned bitWidth() const { return F.semanticsSizeInBits(F.getSemantics()); } + unsigned bitWidth() const { + return llvm::APFloatBase::semanticsSizeInBits(getSemantics()); + } + unsigned numWords() const { return llvm::APInt::getNumWords(bitWidth()); } + bool singleWord() const { +#if ALLOCATE_ALL + return false; +#endif + return numWords() == 1; + } + static bool singleWord(const llvm::fltSemantics &Sem) { +#if ALLOCATE_ALL + return false; +#endif + return APInt::getNumWords(llvm::APFloatBase::getSizeInBits(Sem)) == 1; + } + const llvm::fltSemantics &getSemantics() const { + return llvm::APFloatBase::EnumToSemantics(Semantics); + } + + void copy(const APFloat &F) { + if (singleWord()) { + Val = F.bitcastToAPInt().getZExtValue(); + } else { + assert(Memory); + std::memcpy(Memory, F.bitcastToAPInt().getRawData(), + numWords() * sizeof(uint64_t)); + } + } + + void take(uint64_t *NewMemory) { + if (singleWord()) + return; + + if (Memory) + std::memcpy(NewMemory, Memory, numWords() * sizeof(uint64_t)); + Memory = NewMemory; + } bool isSigned() const { return true; } - bool isNegative() const { return F.isNegative(); } - bool isZero() const { return F.isZero(); } - bool isNonZero() const { return F.isNonZero(); } - bool isMin() const { return F.isSmallest(); } - bool isMinusOne() const { return F.isExactlyValue(-1.0); } - bool isNan() const { return F.isNaN(); } - bool isSignaling() const { return F.isSignaling(); } - bool isInf() const { return F.isInfinity(); } - bool isFinite() const { return F.isFinite(); } - bool isNormal() const { return F.isNormal(); } - bool isDenormal() const { return F.isDenormal(); } - llvm::FPClassTest classify() const { return F.classify(); } - APFloat::fltCategory getCategory() const { return F.getCategory(); } + bool isNegative() const { return getValue().isNegative(); } + bool isZero() const { return getValue().isZero(); } + bool isNonZero() const { return getValue().isNonZero(); } + bool isMin() const { return getValue().isSmallest(); } + bool isMinusOne() const { return getValue().isExactlyValue(-1.0); } + bool isNan() const { return getValue().isNaN(); } + bool isSignaling() const { return getValue().isSignaling(); } + bool isInf() const { return getValue().isInfinity(); } + bool isFinite() const { return getValue().isFinite(); } + bool isNormal() const { return getValue().isNormal(); } + bool isDenormal() const { return getValue().isDenormal(); } + llvm::FPClassTest classify() const { return getValue().classify(); } + APFloat::fltCategory getCategory() const { return getValue().getCategory(); } ComparisonCategoryResult compare(const Floating &RHS) const { - llvm::APFloatBase::cmpResult CmpRes = F.compare(RHS.F); + llvm::APFloatBase::cmpResult CmpRes = getValue().compare(RHS.getValue()); switch (CmpRes) { case llvm::APFloatBase::cmpLessThan: return ComparisonCategoryResult::Less; @@ -118,97 +171,130 @@ class Floating final { static APFloat::opStatus fromIntegral(APSInt Val, const llvm::fltSemantics &Sem, llvm::RoundingMode RM, - Floating &Result) { + Floating *Result) { APFloat F = APFloat(Sem); APFloat::opStatus Status = F.convertFromAPInt(Val, Val.isSigned(), RM); - Result = Floating(F); + Result->copy(F); return Status; } - static Floating bitcastFromMemory(const std::byte *Buff, - const llvm::fltSemantics &Sem) { + static void bitcastFromMemory(const std::byte *Buff, + const llvm::fltSemantics &Sem, + Floating *Result) { size_t Size = APFloat::semanticsSizeInBits(Sem); llvm::APInt API(Size, true); llvm::LoadIntFromMemory(API, (const uint8_t *)Buff, Size / 8); - - return Floating(APFloat(Sem, API)); + Result->copy(APFloat(Sem, API)); } void bitcastToMemory(std::byte *Buff) const { - llvm::APInt API = F.bitcastToAPInt(); + llvm::APInt API = getValue().bitcastToAPInt(); llvm::StoreIntToMemory(API, (uint8_t *)Buff, bitWidth() / 8); } // === Serialization support === size_t bytesToSerialize() const { - return sizeof(llvm::fltSemantics *) + - (APFloat::semanticsSizeInBits(F.getSemantics()) / 8); + return sizeof(Semantics) + (numWords() * sizeof(uint64_t)); } void serialize(std::byte *Buff) const { - // Semantics followed by an APInt. - *reinterpret_cast(Buff) = &F.getSemantics(); - - llvm::APInt API = F.bitcastToAPInt(); - llvm::StoreIntToMemory(API, (uint8_t *)(Buff + sizeof(void *)), - bitWidth() / 8); + std::memcpy(Buff, &Semantics, sizeof(Semantics)); + if (singleWord()) { + std::memcpy(Buff + sizeof(Semantics), &Val, sizeof(uint64_t)); + } else { + std::memcpy(Buff + sizeof(Semantics), Memory, + numWords() * sizeof(uint64_t)); + } } - static Floating deserialize(const std::byte *Buff) { - const llvm::fltSemantics *Sem; - std::memcpy((void *)&Sem, Buff, sizeof(void *)); - return bitcastFromMemory(Buff + sizeof(void *), *Sem); + static llvm::APFloatBase::Semantics + deserializeSemantics(const std::byte *Buff) { + return *reinterpret_cast(Buff); } - static Floating abs(const Floating &F) { - APFloat V = F.F; - if (V.isNegative()) - V.changeSign(); - return Floating(V); + static void deserialize(const std::byte *Buff, Floating *Result) { + llvm::APFloatBase::Semantics Semantics; + std::memcpy(&Semantics, Buff, sizeof(Semantics)); + + unsigned BitWidth = llvm::APFloat::semanticsSizeInBits( + llvm::APFloatBase::EnumToSemantics(Semantics)); + unsigned NumWords = llvm::APInt::getNumWords(BitWidth); + + Result->Semantics = Semantics; + if (NumWords == 1 && !ALLOCATE_ALL) { + std::memcpy(&Result->Val, Buff + sizeof(Semantics), sizeof(uint64_t)); + } else { + assert(Result->Memory); + std::memcpy(Result->Memory, Buff + sizeof(Semantics), + NumWords * sizeof(uint64_t)); + } } // ------- static APFloat::opStatus add(const Floating &A, const Floating &B, llvm::RoundingMode RM, Floating *R) { - *R = Floating(A.F); - return R->F.add(B.F, RM); + APFloat LHS = A.getValue(); + APFloat RHS = B.getValue(); + + auto Status = LHS.add(RHS, RM); + R->copy(LHS); + return Status; } static APFloat::opStatus increment(const Floating &A, llvm::RoundingMode RM, Floating *R) { - APFloat One(A.F.getSemantics(), 1); - *R = Floating(A.F); - return R->F.add(One, RM); + APFloat One(A.getSemantics(), 1); + APFloat LHS = A.getValue(); + + auto Status = LHS.add(One, RM); + R->copy(LHS); + return Status; } static APFloat::opStatus sub(const Floating &A, const Floating &B, llvm::RoundingMode RM, Floating *R) { - *R = Floating(A.F); - return R->F.subtract(B.F, RM); + APFloat LHS = A.getValue(); + APFloat RHS = B.getValue(); + + auto Status = LHS.subtract(RHS, RM); + R->copy(LHS); + return Status; } static APFloat::opStatus decrement(const Floating &A, llvm::RoundingMode RM, Floating *R) { - APFloat One(A.F.getSemantics(), 1); - *R = Floating(A.F); - return R->F.subtract(One, RM); + APFloat One(A.getSemantics(), 1); + APFloat LHS = A.getValue(); + + auto Status = LHS.subtract(One, RM); + R->copy(LHS); + return Status; } static APFloat::opStatus mul(const Floating &A, const Floating &B, llvm::RoundingMode RM, Floating *R) { - *R = Floating(A.F); - return R->F.multiply(B.F, RM); + + APFloat LHS = A.getValue(); + APFloat RHS = B.getValue(); + + auto Status = LHS.multiply(RHS, RM); + R->copy(LHS); + return Status; } static APFloat::opStatus div(const Floating &A, const Floating &B, llvm::RoundingMode RM, Floating *R) { - *R = Floating(A.F); - return R->F.divide(B.F, RM); + APFloat LHS = A.getValue(); + APFloat RHS = B.getValue(); + + auto Status = LHS.divide(RHS, RM); + R->copy(LHS); + return Status; } static bool neg(const Floating &A, Floating *R) { - *R = -A; + R->copy(-A.getValue()); return false; } }; diff --git a/external/llvm-project/clang/lib/AST/ByteCode/Integral.h b/external/llvm-project/clang/lib/AST/ByteCode/Integral.h index 13fdb5369f2b..af5cd2d13ecc 100644 --- a/external/llvm-project/clang/lib/AST/ByteCode/Integral.h +++ b/external/llvm-project/clang/lib/AST/ByteCode/Integral.h @@ -99,6 +99,9 @@ template class Integral final { bool operator>=(Integral RHS) const { return V >= RHS.V; } bool operator==(Integral RHS) const { return V == RHS.V; } bool operator!=(Integral RHS) const { return V != RHS.V; } + bool operator>=(unsigned RHS) const { + return static_cast(V) >= RHS; + } bool operator>(unsigned RHS) const { return V >= 0 && static_cast(V) > RHS; diff --git a/external/llvm-project/clang/lib/AST/ByteCode/IntegralAP.h b/external/llvm-project/clang/lib/AST/ByteCode/IntegralAP.h index 8ee08dfb5cfe..6683db941c73 100644 --- a/external/llvm-project/clang/lib/AST/ByteCode/IntegralAP.h +++ b/external/llvm-project/clang/lib/AST/ByteCode/IntegralAP.h @@ -28,12 +28,19 @@ namespace interp { using APInt = llvm::APInt; using APSInt = llvm::APSInt; -template class Integral; +/// If an IntegralAP is constructed from Memory, it DOES NOT OWN THAT MEMORY. +/// It will NOT copy the memory (unless, of course, copy() is called) and it +/// won't alllocate anything. The allocation should happen via InterpState or +/// Program. template class IntegralAP final { -private: +public: + union { + uint64_t *Memory = nullptr; + uint64_t Val; + }; + uint32_t BitWidth = 0; friend IntegralAP; - APInt V; template static T truncateCast(const APInt &V) { @@ -52,106 +59,126 @@ template class IntegralAP final { : V.trunc(BitSize).getZExtValue(); } + APInt getValue() const { + if (singleWord()) + return APInt(BitWidth, Val, Signed); + unsigned NumWords = llvm::APInt::getNumWords(BitWidth); + return llvm::APInt(BitWidth, NumWords, Memory); + } + public: using AsUnsigned = IntegralAP; - template - IntegralAP(T Value, unsigned BitWidth) - : V(APInt(BitWidth, static_cast(Value), Signed)) {} + void take(uint64_t *NewMemory) { + assert(!singleWord()); + std::memcpy(NewMemory, Memory, numWords() * sizeof(uint64_t)); + Memory = NewMemory; + } - IntegralAP(APInt V) : V(V) {} - /// Arbitrary value for uninitialized variables. - IntegralAP() : IntegralAP(Signed ? -1 : 7, 3) {} + void copy(const APInt &V) { + assert(BitWidth == V.getBitWidth()); + assert(numWords() == V.getNumWords()); - IntegralAP operator-() const { return IntegralAP(-V); } - IntegralAP operator-(const IntegralAP &Other) const { - return IntegralAP(V - Other.V); + if (V.isSingleWord()) { + if constexpr (Signed) + Val = V.getSExtValue(); + else + Val = V.getZExtValue(); + return; + } + assert(Memory); + std::memcpy(Memory, V.getRawData(), V.getNumWords() * sizeof(uint64_t)); + } + + IntegralAP() = default; + /// Zeroed, single-word IntegralAP of the given bitwidth. + IntegralAP(unsigned BitWidth) : Val(0), BitWidth(BitWidth) { + assert(singleWord()); + } + IntegralAP(uint64_t *Memory, unsigned BitWidth) + : Memory(Memory), BitWidth(BitWidth) {} + IntegralAP(const APInt &V) : BitWidth(V.getBitWidth()) { + if (V.isSingleWord()) { + Val = Signed ? V.getSExtValue() : V.getZExtValue(); + } else { + Memory = const_cast(V.getRawData()); + } } + + IntegralAP operator-() const { return IntegralAP(-getValue()); } bool operator>(const IntegralAP &RHS) const { if constexpr (Signed) - return V.ugt(RHS.V); - return V.sgt(RHS.V); + return getValue().sgt(RHS.getValue()); + return getValue().ugt(RHS.getValue()); } - bool operator>=(IntegralAP RHS) const { + bool operator>=(unsigned RHS) const { if constexpr (Signed) - return V.uge(RHS.V); - return V.sge(RHS.V); + return getValue().sge(RHS); + return getValue().uge(RHS); } bool operator<(IntegralAP RHS) const { if constexpr (Signed) - return V.slt(RHS.V); - return V.slt(RHS.V); - } - bool operator<=(IntegralAP RHS) const { - if constexpr (Signed) - return V.ult(RHS.V); - return V.ult(RHS.V); + return getValue().slt(RHS.getValue()); + return getValue().ult(RHS.getValue()); } template >> explicit operator Ty() const { - return truncateCast(V); + return truncateCast(getValue()); } template static IntegralAP from(T Value, unsigned NumBits = 0) { + if (NumBits == 0) + NumBits = sizeof(T) * 8; assert(NumBits > 0); + assert(APInt::getNumWords(NumBits) == 1); APInt Copy = APInt(NumBits, static_cast(Value), Signed); - return IntegralAP(Copy); } - template - static IntegralAP from(IntegralAP V, unsigned NumBits = 0) { - if (NumBits == 0) - NumBits = V.bitWidth(); - - if constexpr (InputSigned) - return IntegralAP(V.V.sextOrTrunc(NumBits)); - return IntegralAP(V.V.zextOrTrunc(NumBits)); - } - - template - static IntegralAP from(Integral I, unsigned BitWidth) { - return IntegralAP(I.toAPInt(BitWidth)); - } - - static IntegralAP zero(int32_t BitWidth) { - APInt V = APInt(BitWidth, 0LL, Signed); - return IntegralAP(V); - } - - constexpr unsigned bitWidth() const { return V.getBitWidth(); } + constexpr uint32_t bitWidth() const { return BitWidth; } + constexpr unsigned numWords() const { return APInt::getNumWords(BitWidth); } + constexpr bool singleWord() const { return numWords() == 1; } APSInt toAPSInt(unsigned Bits = 0) const { if (Bits == 0) Bits = bitWidth(); + APInt V = getValue(); if constexpr (Signed) - return APSInt(V.sext(Bits), !Signed); + return APSInt(getValue().sext(Bits), !Signed); else - return APSInt(V.zext(Bits), !Signed); + return APSInt(getValue().zext(Bits), !Signed); } APValue toAPValue(const ASTContext &) const { return APValue(toAPSInt()); } - bool isZero() const { return V.isZero(); } + bool isZero() const { return getValue().isZero(); } bool isPositive() const { if constexpr (Signed) - return V.isNonNegative(); + return getValue().isNonNegative(); return true; } bool isNegative() const { if constexpr (Signed) - return !V.isNonNegative(); + return !getValue().isNonNegative(); return false; } - bool isMin() const { return V.isMinValue(); } - bool isMax() const { return V.isMaxValue(); } + bool isMin() const { + if constexpr (Signed) + return getValue().isMinSignedValue(); + return getValue().isMinValue(); + } + bool isMax() const { + if constexpr (Signed) + return getValue().isMaxSignedValue(); + return getValue().isMaxValue(); + } static constexpr bool isSigned() { return Signed; } - bool isMinusOne() const { return Signed && V == -1; } + bool isMinusOne() const { return Signed && getValue().isAllOnes(); } - unsigned countLeadingZeros() const { return V.countl_zero(); } + unsigned countLeadingZeros() const { return getValue().countl_zero(); } - void print(llvm::raw_ostream &OS) const { V.print(OS, Signed);} + void print(llvm::raw_ostream &OS) const { getValue().print(OS, Signed); } std::string toDiagnosticString(const ASTContext &Ctx) const { std::string NameStr; llvm::raw_string_ostream OS(NameStr); @@ -161,53 +188,57 @@ template class IntegralAP final { IntegralAP truncate(unsigned BitWidth) const { if constexpr (Signed) - return IntegralAP(V.trunc(BitWidth).sextOrTrunc(this->bitWidth())); + return IntegralAP( + getValue().trunc(BitWidth).sextOrTrunc(this->bitWidth())); else - return IntegralAP(V.trunc(BitWidth).zextOrTrunc(this->bitWidth())); + return IntegralAP( + getValue().trunc(BitWidth).zextOrTrunc(this->bitWidth())); } IntegralAP toUnsigned() const { - APInt Copy = V; - return IntegralAP(Copy); + return IntegralAP(Memory, BitWidth); } void bitcastToMemory(std::byte *Dest) const { - llvm::StoreIntToMemory(V, (uint8_t *)Dest, bitWidth() / 8); + llvm::StoreIntToMemory(getValue(), (uint8_t *)Dest, bitWidth() / 8); } - static IntegralAP bitcastFromMemory(const std::byte *Src, unsigned BitWidth) { + static void bitcastFromMemory(const std::byte *Src, unsigned BitWidth, + IntegralAP *Result) { APInt V(BitWidth, static_cast(0), Signed); llvm::LoadIntFromMemory(V, (const uint8_t *)Src, BitWidth / 8); - return IntegralAP(V); + Result->copy(V); } ComparisonCategoryResult compare(const IntegralAP &RHS) const { assert(Signed == RHS.isSigned()); assert(bitWidth() == RHS.bitWidth()); + APInt V1 = getValue(); + APInt V2 = RHS.getValue(); if constexpr (Signed) { - if (V.slt(RHS.V)) + if (V1.slt(V2)) return ComparisonCategoryResult::Less; - if (V.sgt(RHS.V)) + if (V1.sgt(V2)) return ComparisonCategoryResult::Greater; return ComparisonCategoryResult::Equal; } assert(!Signed); - if (V.ult(RHS.V)) + if (V1.ult(V2)) return ComparisonCategoryResult::Less; - if (V.ugt(RHS.V)) + if (V1.ugt(V2)) return ComparisonCategoryResult::Greater; return ComparisonCategoryResult::Equal; } static bool increment(IntegralAP A, IntegralAP *R) { - IntegralAP One(1, A.bitWidth()); - return add(A, One, A.bitWidth() + 1, R); + APSInt One(APInt(A.bitWidth(), 1ull, Signed), !Signed); + return add(A, IntegralAP(One), A.bitWidth() + 1, R); } static bool decrement(IntegralAP A, IntegralAP *R) { - IntegralAP One(1, A.bitWidth()); - return sub(A, One, A.bitWidth() + 1, R); + APSInt One(APInt(A.bitWidth(), 1ull, Signed), !Signed); + return sub(A, IntegralAP(One), A.bitWidth() + 1, R); } static bool add(IntegralAP A, IntegralAP B, unsigned OpBits, IntegralAP *R) { @@ -224,87 +255,96 @@ template class IntegralAP final { static bool rem(IntegralAP A, IntegralAP B, unsigned OpBits, IntegralAP *R) { if constexpr (Signed) - *R = IntegralAP(A.V.srem(B.V)); + R->copy(A.getValue().srem(B.getValue())); else - *R = IntegralAP(A.V.urem(B.V)); + R->copy(A.getValue().urem(B.getValue())); return false; } static bool div(IntegralAP A, IntegralAP B, unsigned OpBits, IntegralAP *R) { if constexpr (Signed) - *R = IntegralAP(A.V.sdiv(B.V)); + R->copy(A.getValue().sdiv(B.getValue())); else - *R = IntegralAP(A.V.udiv(B.V)); + R->copy(A.getValue().udiv(B.getValue())); return false; } static bool bitAnd(IntegralAP A, IntegralAP B, unsigned OpBits, IntegralAP *R) { - *R = IntegralAP(A.V & B.V); + R->copy(A.getValue() & B.getValue()); return false; } static bool bitOr(IntegralAP A, IntegralAP B, unsigned OpBits, IntegralAP *R) { - *R = IntegralAP(A.V | B.V); + R->copy(A.getValue() | B.getValue()); return false; } static bool bitXor(IntegralAP A, IntegralAP B, unsigned OpBits, IntegralAP *R) { - *R = IntegralAP(A.V ^ B.V); + R->copy(A.getValue() ^ B.getValue()); return false; } static bool neg(const IntegralAP &A, IntegralAP *R) { - APInt AI = A.V; + APInt AI = A.getValue(); AI.negate(); - *R = IntegralAP(AI); + R->copy(AI); return false; } static bool comp(IntegralAP A, IntegralAP *R) { - *R = IntegralAP(~A.V); + R->copy(~A.getValue()); return false; } static void shiftLeft(const IntegralAP A, const IntegralAP B, unsigned OpBits, IntegralAP *R) { - *R = IntegralAP(A.V.shl(B.V.getZExtValue())); + *R = IntegralAP(A.getValue().shl(B.getValue().getZExtValue())); } static void shiftRight(const IntegralAP A, const IntegralAP B, unsigned OpBits, IntegralAP *R) { - unsigned ShiftAmount = B.V.getZExtValue(); + unsigned ShiftAmount = B.getValue().getZExtValue(); if constexpr (Signed) - *R = IntegralAP(A.V.ashr(ShiftAmount)); + R->copy(A.getValue().ashr(ShiftAmount)); else - *R = IntegralAP(A.V.lshr(ShiftAmount)); + R->copy(A.getValue().lshr(ShiftAmount)); } // === Serialization support === size_t bytesToSerialize() const { - // 4 bytes for the BitWidth followed by N bytes for the actual APInt. - return sizeof(uint32_t) + (V.getBitWidth() / CHAR_BIT); + assert(BitWidth != 0); + return sizeof(uint32_t) + (numWords() * sizeof(uint64_t)); } void serialize(std::byte *Buff) const { - assert(V.getBitWidth() < std::numeric_limits::max()); - uint32_t BitWidth = V.getBitWidth(); - std::memcpy(Buff, &BitWidth, sizeof(uint32_t)); - llvm::StoreIntToMemory(V, (uint8_t *)(Buff + sizeof(uint32_t)), - BitWidth / CHAR_BIT); + if (singleWord()) + std::memcpy(Buff + sizeof(uint32_t), &Val, sizeof(uint64_t)); + else { + std::memcpy(Buff + sizeof(uint32_t), Memory, + numWords() * sizeof(uint64_t)); + } } - static IntegralAP deserialize(const std::byte *Buff) { - uint32_t BitWidth; - std::memcpy(&BitWidth, Buff, sizeof(uint32_t)); - IntegralAP Val(APInt(BitWidth, 0ull, !Signed)); + static uint32_t deserializeSize(const std::byte *Buff) { + return *reinterpret_cast(Buff); + } + + static void deserialize(const std::byte *Buff, IntegralAP *Result) { + uint32_t BitWidth = Result->BitWidth; + assert(BitWidth != 0); + unsigned NumWords = llvm::APInt::getNumWords(BitWidth); - llvm::LoadIntFromMemory(Val.V, (const uint8_t *)Buff + sizeof(uint32_t), - BitWidth / CHAR_BIT); - return Val; + if (NumWords == 1) + std::memcpy(&Result->Val, Buff + sizeof(uint32_t), sizeof(uint64_t)); + else { + assert(Result->Memory); + std::memcpy(Result->Memory, Buff + sizeof(uint32_t), + NumWords * sizeof(uint64_t)); + } } private: @@ -312,7 +352,7 @@ template class IntegralAP final { static bool CheckAddSubMulUB(const IntegralAP &A, const IntegralAP &B, unsigned BitWidth, IntegralAP *R) { if constexpr (!Signed) { - R->V = Op{}(A.V, B.V); + R->copy(Op{}(A.getValue(), B.getValue())); return false; } @@ -320,7 +360,7 @@ template class IntegralAP final { const APSInt &RHS = B.toAPSInt(); APSInt Value = Op{}(LHS.extend(BitWidth), RHS.extend(BitWidth)); APSInt Result = Value.trunc(LHS.getBitWidth()); - R->V = Result; + R->copy(Result); return Result.extend(BitWidth) != Value; } diff --git a/external/llvm-project/clang/lib/AST/ByteCode/Interp.cpp b/external/llvm-project/clang/lib/AST/ByteCode/Interp.cpp index 5c8abffb3a99..51cf0c59f0b5 100644 --- a/external/llvm-project/clang/lib/AST/ByteCode/Interp.cpp +++ b/external/llvm-project/clang/lib/AST/ByteCode/Interp.cpp @@ -1108,7 +1108,7 @@ bool CheckDummy(InterpState &S, CodePtr OpPC, const Pointer &Ptr, bool CheckNonNullArgs(InterpState &S, CodePtr OpPC, const Function *F, const CallExpr *CE, unsigned ArgSize) { - auto Args = llvm::ArrayRef(CE->getArgs(), CE->getNumArgs()); + auto Args = ArrayRef(CE->getArgs(), CE->getNumArgs()); auto NonNullArgs = collectNonNullArgs(F->getDecl(), Args); unsigned Offset = 0; unsigned Index = 0; @@ -1935,8 +1935,10 @@ bool CastPointerIntegralAP(InterpState &S, CodePtr OpPC, uint32_t BitWidth) { if (!CheckPointerToIntegralCast(S, OpPC, Ptr, BitWidth)) return false; - S.Stk.push>( - IntegralAP::from(Ptr.getIntegerRepresentation(), BitWidth)); + auto Result = S.allocAP>(BitWidth); + Result.copy(APInt(BitWidth, Ptr.getIntegerRepresentation())); + + S.Stk.push>(Result); return true; } @@ -1946,8 +1948,10 @@ bool CastPointerIntegralAPS(InterpState &S, CodePtr OpPC, uint32_t BitWidth) { if (!CheckPointerToIntegralCast(S, OpPC, Ptr, BitWidth)) return false; - S.Stk.push>( - IntegralAP::from(Ptr.getIntegerRepresentation(), BitWidth)); + auto Result = S.allocAP>(BitWidth); + Result.copy(APInt(BitWidth, Ptr.getIntegerRepresentation())); + + S.Stk.push>(Result); return true; } @@ -2053,6 +2057,100 @@ bool arePotentiallyOverlappingStringLiterals(const Pointer &LHS, return Shorter == Longer.take_front(Shorter.size()); } +static void copyPrimitiveMemory(InterpState &S, const Pointer &Ptr, + PrimType T) { + + if (T == PT_IntAPS) { + auto &Val = Ptr.deref>(); + if (!Val.singleWord()) { + uint64_t *NewMemory = new (S.P) uint64_t[Val.numWords()]; + Val.take(NewMemory); + } + } else if (T == PT_IntAP) { + auto &Val = Ptr.deref>(); + if (!Val.singleWord()) { + uint64_t *NewMemory = new (S.P) uint64_t[Val.numWords()]; + Val.take(NewMemory); + } + } else if (T == PT_Float) { + auto &Val = Ptr.deref(); + if (!Val.singleWord()) { + uint64_t *NewMemory = new (S.P) uint64_t[Val.numWords()]; + Val.take(NewMemory); + } + } +} + +template +static void copyPrimitiveMemory(InterpState &S, const Pointer &Ptr) { + assert(needsAlloc()); + auto &Val = Ptr.deref(); + if (!Val.singleWord()) { + uint64_t *NewMemory = new (S.P) uint64_t[Val.numWords()]; + Val.take(NewMemory); + } +} + +static void finishGlobalRecurse(InterpState &S, const Pointer &Ptr) { + if (const Record *R = Ptr.getRecord()) { + for (const Record::Field &Fi : R->fields()) { + if (Fi.Desc->isPrimitive()) { + TYPE_SWITCH_ALLOC(Fi.Desc->getPrimType(), { + copyPrimitiveMemory(S, Ptr.atField(Fi.Offset)); + }); + copyPrimitiveMemory(S, Ptr.atField(Fi.Offset), Fi.Desc->getPrimType()); + } else + finishGlobalRecurse(S, Ptr.atField(Fi.Offset)); + } + return; + } + + if (const Descriptor *D = Ptr.getFieldDesc(); D && D->isArray()) { + unsigned NumElems = D->getNumElems(); + if (NumElems == 0) + return; + + if (D->isPrimitiveArray()) { + PrimType PT = D->getPrimType(); + if (!needsAlloc(PT)) + return; + assert(NumElems >= 1); + const Pointer EP = Ptr.atIndex(0); + bool AllSingleWord = true; + TYPE_SWITCH_ALLOC(PT, { + if (!EP.deref().singleWord()) { + copyPrimitiveMemory(S, EP); + AllSingleWord = false; + } + }); + if (AllSingleWord) + return; + for (unsigned I = 1; I != D->getNumElems(); ++I) { + const Pointer EP = Ptr.atIndex(I); + copyPrimitiveMemory(S, EP, PT); + } + } else { + assert(D->isCompositeArray()); + for (unsigned I = 0; I != D->getNumElems(); ++I) { + const Pointer EP = Ptr.atIndex(I).narrow(); + finishGlobalRecurse(S, EP); + } + } + } +} + +bool FinishInitGlobal(InterpState &S, CodePtr OpPC) { + const Pointer &Ptr = S.Stk.pop(); + + finishGlobalRecurse(S, Ptr); + if (Ptr.canBeInitialized()) { + Ptr.initialize(); + Ptr.activate(); + } + + return true; +} + // https://github.com/llvm/llvm-project/issues/102513 #if defined(_MSC_VER) && !defined(__clang__) && !defined(NDEBUG) #pragma optimize("", off) diff --git a/external/llvm-project/clang/lib/AST/ByteCode/Interp.h b/external/llvm-project/clang/lib/AST/ByteCode/Interp.h index ae3d4a441a79..dcc458775197 100644 --- a/external/llvm-project/clang/lib/AST/ByteCode/Interp.h +++ b/external/llvm-project/clang/lib/AST/ByteCode/Interp.h @@ -189,7 +189,7 @@ bool CheckShift(InterpState &S, CodePtr OpPC, const LT &LHS, const RT &RHS, // C++11 [expr.shift]p1: Shift width must be less than the bit width of // the shifted type. - if (Bits > 1 && RHS >= RT::from(Bits, RHS.bitWidth())) { + if (Bits > 1 && RHS >= Bits) { const Expr *E = S.Current->getExpr(OpPC); const APSInt Val = RHS.toAPSInt(); QualType Ty = E->getType(); @@ -307,7 +307,7 @@ bool InterpretBuiltin(InterpState &S, CodePtr OpPC, const CallExpr *Call, /// Interpret an offsetof operation. bool InterpretOffsetOf(InterpState &S, CodePtr OpPC, const OffsetOfExpr *E, - llvm::ArrayRef ArrayIndices, int64_t &Result); + ArrayRef ArrayIndices, int64_t &Result); inline bool Invalid(InterpState &S, CodePtr OpPC); @@ -370,6 +370,9 @@ bool AddSubMulHelper(InterpState &S, CodePtr OpPC, unsigned Bits, const T &LHS, const T &RHS) { // Fast path - add the numbers with fixed width. T Result; + if constexpr (needsAlloc()) + Result = S.allocAP(LHS.bitWidth()); + if (!OpFW(LHS, RHS, Bits, &Result)) { S.Stk.push(Result); return true; @@ -408,6 +411,7 @@ bool Add(InterpState &S, CodePtr OpPC) { const T &RHS = S.Stk.pop(); const T &LHS = S.Stk.pop(); const unsigned Bits = RHS.bitWidth() + 1; + return AddSubMulHelper(S, OpPC, Bits, LHS, RHS); } @@ -423,7 +427,7 @@ inline bool Addf(InterpState &S, CodePtr OpPC, uint32_t FPOI) { const Floating &LHS = S.Stk.pop(); FPOptions FPO = FPOptions::getFromOpaqueInt(FPOI); - Floating Result; + Floating Result = S.allocFloat(LHS.getSemantics()); auto Status = Floating::add(LHS, RHS, getRoundingMode(FPO), &Result); S.Stk.push(Result); return CheckFloatResult(S, OpPC, Result, Status, FPO); @@ -434,6 +438,7 @@ bool Sub(InterpState &S, CodePtr OpPC) { const T &RHS = S.Stk.pop(); const T &LHS = S.Stk.pop(); const unsigned Bits = RHS.bitWidth() + 1; + return AddSubMulHelper(S, OpPC, Bits, LHS, RHS); } @@ -442,7 +447,7 @@ inline bool Subf(InterpState &S, CodePtr OpPC, uint32_t FPOI) { const Floating &LHS = S.Stk.pop(); FPOptions FPO = FPOptions::getFromOpaqueInt(FPOI); - Floating Result; + Floating Result = S.allocFloat(LHS.getSemantics()); auto Status = Floating::sub(LHS, RHS, getRoundingMode(FPO), &Result); S.Stk.push(Result); return CheckFloatResult(S, OpPC, Result, Status, FPO); @@ -453,6 +458,7 @@ bool Mul(InterpState &S, CodePtr OpPC) { const T &RHS = S.Stk.pop(); const T &LHS = S.Stk.pop(); const unsigned Bits = RHS.bitWidth() * 2; + return AddSubMulHelper(S, OpPC, Bits, LHS, RHS); } @@ -461,8 +467,10 @@ inline bool Mulf(InterpState &S, CodePtr OpPC, uint32_t FPOI) { const Floating &LHS = S.Stk.pop(); FPOptions FPO = FPOptions::getFromOpaqueInt(FPOI); - Floating Result; + Floating Result = S.allocFloat(LHS.getSemantics()); + auto Status = Floating::mul(LHS, RHS, getRoundingMode(FPO), &Result); + S.Stk.push(Result); return CheckFloatResult(S, OpPC, Result, Status, FPO); } @@ -484,9 +492,14 @@ inline bool Mulc(InterpState &S, CodePtr OpPC) { HandleComplexComplexMul(A, B, C, D, ResR, ResI); // Copy into the result. - Result.atIndex(0).deref() = Floating(ResR); + Floating RA = S.allocFloat(A.getSemantics()); + RA.copy(ResR); + Result.atIndex(0).deref() = RA; // Floating(ResR); Result.atIndex(0).initialize(); - Result.atIndex(1).deref() = Floating(ResI); + + Floating RI = S.allocFloat(A.getSemantics()); + RI.copy(ResI); + Result.atIndex(1).deref() = RI; // Floating(ResI); Result.atIndex(1).initialize(); Result.initialize(); } else { @@ -539,10 +552,20 @@ inline bool Divc(InterpState &S, CodePtr OpPC) { HandleComplexComplexDiv(A, B, C, D, ResR, ResI); // Copy into the result. - Result.atIndex(0).deref() = Floating(ResR); + // Result.atIndex(0).deref() = Floating(ResR); + // Result.atIndex(0).initialize(); + // Result.atIndex(1).deref() = Floating(ResI); + // Result.atIndex(1).initialize(); + + Floating RA = S.allocFloat(A.getSemantics()); + RA.copy(ResR); + Result.atIndex(0).deref() = RA; // Floating(ResR); Result.atIndex(0).initialize(); - Result.atIndex(1).deref() = Floating(ResI); - Result.atIndex(1).initialize(); + + Floating RI = S.allocFloat(A.getSemantics()); + RI.copy(ResI); + Result.atIndex(1).deref() = RI; // Floating(ResI); + Result.initialize(); } else { // Integer element type. @@ -608,9 +631,12 @@ template ::T> bool BitAnd(InterpState &S, CodePtr OpPC) { const T &RHS = S.Stk.pop(); const T &LHS = S.Stk.pop(); - unsigned Bits = RHS.bitWidth(); + T Result; + if constexpr (needsAlloc()) + Result = S.allocAP(Bits); + if (!T::bitAnd(LHS, RHS, Bits, &Result)) { S.Stk.push(Result); return true; @@ -625,9 +651,12 @@ template ::T> bool BitOr(InterpState &S, CodePtr OpPC) { const T &RHS = S.Stk.pop(); const T &LHS = S.Stk.pop(); - unsigned Bits = RHS.bitWidth(); + T Result; + if constexpr (needsAlloc()) + Result = S.allocAP(Bits); + if (!T::bitOr(LHS, RHS, Bits, &Result)) { S.Stk.push(Result); return true; @@ -644,7 +673,11 @@ bool BitXor(InterpState &S, CodePtr OpPC) { const T &LHS = S.Stk.pop(); unsigned Bits = RHS.bitWidth(); + T Result; + if constexpr (needsAlloc()) + Result = S.allocAP(Bits); + if (!T::bitXor(LHS, RHS, Bits, &Result)) { S.Stk.push(Result); return true; @@ -659,12 +692,15 @@ template ::T> bool Rem(InterpState &S, CodePtr OpPC) { const T &RHS = S.Stk.pop(); const T &LHS = S.Stk.pop(); + const unsigned Bits = RHS.bitWidth() * 2; if (!CheckDivRem(S, OpPC, LHS, RHS)) return false; - const unsigned Bits = RHS.bitWidth() * 2; T Result; + if constexpr (needsAlloc()) + Result = S.allocAP(LHS.bitWidth()); + if (!T::rem(LHS, RHS, Bits, &Result)) { S.Stk.push(Result); return true; @@ -679,12 +715,15 @@ template ::T> bool Div(InterpState &S, CodePtr OpPC) { const T &RHS = S.Stk.pop(); const T &LHS = S.Stk.pop(); + const unsigned Bits = RHS.bitWidth() * 2; if (!CheckDivRem(S, OpPC, LHS, RHS)) return false; - const unsigned Bits = RHS.bitWidth() * 2; T Result; + if constexpr (needsAlloc()) + Result = S.allocAP(LHS.bitWidth()); + if (!T::div(LHS, RHS, Bits, &Result)) { S.Stk.push(Result); return true; @@ -707,8 +746,10 @@ inline bool Divf(InterpState &S, CodePtr OpPC, uint32_t FPOI) { return false; FPOptions FPO = FPOptions::getFromOpaqueInt(FPOI); - Floating Result; + + Floating Result = S.allocFloat(LHS.getSemantics()); auto Status = Floating::div(LHS, RHS, getRoundingMode(FPO), &Result); + S.Stk.push(Result); return CheckFloatResult(S, OpPC, Result, Status, FPO); } @@ -730,31 +771,44 @@ inline bool Inv(InterpState &S, CodePtr OpPC) { template ::T> bool Neg(InterpState &S, CodePtr OpPC) { const T &Value = S.Stk.pop(); - T Result; - if (!T::neg(Value, &Result)) { + if constexpr (std::is_same_v) { + T Result = S.allocFloat(Value.getSemantics()); + + if (!T::neg(Value, &Result)) { + S.Stk.push(Result); + return true; + } + return false; + } else { + T Result; + if constexpr (needsAlloc()) + Result = S.allocAP(Value.bitWidth()); + + if (!T::neg(Value, &Result)) { + S.Stk.push(Result); + return true; + } + + assert(isIntegralType(Name) && + "don't expect other types to fail at constexpr negation"); S.Stk.push(Result); - return true; - } - assert(isIntegralType(Name) && - "don't expect other types to fail at constexpr negation"); - S.Stk.push(Result); + APSInt NegatedValue = -Value.toAPSInt(Value.bitWidth() + 1); + if (S.checkingForUndefinedBehavior()) { + const Expr *E = S.Current->getExpr(OpPC); + QualType Type = E->getType(); + SmallString<32> Trunc; + NegatedValue.trunc(Result.bitWidth()) + .toString(Trunc, 10, Result.isSigned(), /*formatAsCLiteral=*/false, + /*UpperCase=*/true, /*InsertSeparators=*/true); + S.report(E->getExprLoc(), diag::warn_integer_constant_overflow) + << Trunc << Type << E->getSourceRange(); + return true; + } - APSInt NegatedValue = -Value.toAPSInt(Value.bitWidth() + 1); - if (S.checkingForUndefinedBehavior()) { - const Expr *E = S.Current->getExpr(OpPC); - QualType Type = E->getType(); - SmallString<32> Trunc; - NegatedValue.trunc(Result.bitWidth()) - .toString(Trunc, 10, Result.isSigned(), /*formatAsCLiteral=*/false, - /*UpperCase=*/true, /*InsertSeparators=*/true); - S.report(E->getExprLoc(), diag::warn_integer_constant_overflow) - << Trunc << Type << E->getSourceRange(); - return true; + return handleOverflow(S, OpPC, NegatedValue); } - - return handleOverflow(S, OpPC, NegatedValue); } enum class PushVal : bool { @@ -783,6 +837,8 @@ bool IncDecHelper(InterpState &S, CodePtr OpPC, const Pointer &Ptr, const T &Value = Ptr.deref(); T Result; + if constexpr (needsAlloc()) + Result = S.allocAP(Value.bitWidth()); if constexpr (DoPush == PushVal::Yes) S.Stk.push(Value); @@ -890,7 +946,6 @@ bool PreDec(InterpState &S, CodePtr OpPC, bool CanOverflow) { const Pointer &Ptr = S.Stk.peek(); if (!CheckLoad(S, OpPC, Ptr, AK_Decrement)) return false; - return IncDecHelper(S, OpPC, Ptr, CanOverflow); } @@ -898,7 +953,7 @@ template bool IncDecFloatHelper(InterpState &S, CodePtr OpPC, const Pointer &Ptr, uint32_t FPOI) { Floating Value = Ptr.deref(); - Floating Result; + Floating Result = S.allocFloat(Value.getSemantics()); if constexpr (DoPush == PushVal::Yes) S.Stk.push(Value); @@ -952,12 +1007,15 @@ inline bool DecfPop(InterpState &S, CodePtr OpPC, uint32_t FPOI) { template ::T> bool Comp(InterpState &S, CodePtr OpPC) { const T &Val = S.Stk.pop(); + T Result; + if constexpr (needsAlloc()) + Result = S.allocAP(Val.bitWidth()); + if (!T::comp(Val, &Result)) { S.Stk.push(Result); return true; } - return false; } @@ -1325,10 +1383,23 @@ bool Flip(InterpState &S, CodePtr OpPC) { template ::T> bool Const(InterpState &S, CodePtr OpPC, const T &Arg) { + if constexpr (needsAlloc()) { + T Result = S.allocAP(Arg.bitWidth()); + Result.copy(Arg.toAPSInt()); + S.Stk.push(Result); + return true; + } S.Stk.push(Arg); return true; } +inline bool ConstFloat(InterpState &S, CodePtr OpPC, const Floating &F) { + Floating Result = S.allocFloat(F.getSemantics()); + Result.copy(F.getAPFloat()); + S.Stk.push(Result); + return true; +} + //===----------------------------------------------------------------------===// // Get/Set Local/Param/Global/This //===----------------------------------------------------------------------===// @@ -1483,7 +1554,24 @@ bool SetGlobal(InterpState &S, CodePtr OpPC, uint32_t I) { template ::T> bool InitGlobal(InterpState &S, CodePtr OpPC, uint32_t I) { const Pointer &P = S.P.getGlobal(I); + P.deref() = S.Stk.pop(); + + if constexpr (std::is_same_v) { + auto &Val = P.deref(); + if (!Val.singleWord()) { + uint64_t *NewMemory = new (S.P) uint64_t[Val.numWords()]; + Val.take(NewMemory); + } + + } else if constexpr (needsAlloc()) { + auto &Val = P.deref(); + if (!Val.singleWord()) { + uint64_t *NewMemory = new (S.P) uint64_t[Val.numWords()]; + Val.take(NewMemory); + } + } + P.initialize(); return true; } @@ -1585,7 +1673,22 @@ bool InitBitField(InterpState &S, CodePtr OpPC, const Record::Field *F) { assert(F->isBitField()); const T &Value = S.Stk.pop(); const Pointer &Field = S.Stk.peek().atField(F->Offset); - Field.deref() = Value.truncate(F->Decl->getBitWidthValue()); + + if constexpr (needsAlloc()) { + T Result = S.allocAP(Value.bitWidth()); + if (T::isSigned()) + Result.copy(Value.toAPSInt() + .trunc(F->Decl->getBitWidthValue()) + .sextOrTrunc(Value.bitWidth())); + else + Result.copy(Value.toAPSInt() + .trunc(F->Decl->getBitWidthValue()) + .zextOrTrunc(Value.bitWidth())); + + Field.deref() = Result; + } else { + Field.deref() = Value.truncate(F->Decl->getBitWidthValue()); + } Field.activate(); Field.initialize(); return true; @@ -1765,6 +1868,8 @@ inline bool FinishInit(InterpState &S, CodePtr OpPC) { return true; } +bool FinishInitGlobal(InterpState &S, CodePtr OpPC); + inline bool Dump(InterpState &S, CodePtr OpPC) { S.Stk.dump(); return true; @@ -2271,7 +2376,8 @@ template bool Cast(InterpState &S, CodePtr OpPC) { inline bool CastFP(InterpState &S, CodePtr OpPC, const llvm::fltSemantics *Sem, llvm::RoundingMode RM) { Floating F = S.Stk.pop(); - Floating Result = F.toSemantics(Sem, RM); + Floating Result = S.allocFloat(*Sem); + F.toSemantics(Sem, RM, &Result); S.Stk.push(Result); return true; } @@ -2295,15 +2401,25 @@ inline bool CastFixedPoint(InterpState &S, CodePtr OpPC, uint32_t FPS) { /// to know what bitwidth the result should be. template ::T> bool CastAP(InterpState &S, CodePtr OpPC, uint32_t BitWidth) { - S.Stk.push>( - IntegralAP::from(S.Stk.pop(), BitWidth)); + auto Result = S.allocAP>(BitWidth); + // Copy data. + { + APInt Source = S.Stk.pop().toAPSInt().extOrTrunc(BitWidth); + Result.copy(Source); + } + S.Stk.push>(Result); return true; } template ::T> bool CastAPS(InterpState &S, CodePtr OpPC, uint32_t BitWidth) { - S.Stk.push>( - IntegralAP::from(S.Stk.pop(), BitWidth)); + auto Result = S.allocAP>(BitWidth); + // Copy data. + { + APInt Source = S.Stk.pop().toAPSInt().extOrTrunc(BitWidth); + Result.copy(Source); + } + S.Stk.push>(Result); return true; } @@ -2312,11 +2428,11 @@ bool CastIntegralFloating(InterpState &S, CodePtr OpPC, const llvm::fltSemantics *Sem, uint32_t FPOI) { const T &From = S.Stk.pop(); APSInt FromAP = From.toAPSInt(); - Floating Result; FPOptions FPO = FPOptions::getFromOpaqueInt(FPOI); + Floating Result = S.allocFloat(*Sem); auto Status = - Floating::fromIntegral(FromAP, *Sem, getRoundingMode(FPO), Result); + Floating::fromIntegral(FromAP, *Sem, getRoundingMode(FPO), &Result); S.Stk.push(Result); return CheckFloatResult(S, OpPC, Result, Status, FPO); @@ -2365,7 +2481,12 @@ static inline bool CastFloatingIntegralAP(InterpState &S, CodePtr OpPC, return handleOverflow(S, OpPC, F.getAPFloat()); FPOptions FPO = FPOptions::getFromOpaqueInt(FPOI); - S.Stk.push>(IntegralAP(Result)); + + auto ResultAP = S.allocAP>(BitWidth); + ResultAP.copy(Result); + + S.Stk.push>(ResultAP); + return CheckFloatResult(S, OpPC, F, Status, FPO); } @@ -2381,7 +2502,12 @@ static inline bool CastFloatingIntegralAPS(InterpState &S, CodePtr OpPC, return handleOverflow(S, OpPC, F.getAPFloat()); FPOptions FPO = FPOptions::getFromOpaqueInt(FPOI); - S.Stk.push>(IntegralAP(Result)); + + auto ResultAP = S.allocAP>(BitWidth); + ResultAP.copy(Result); + + S.Stk.push>(ResultAP); + return CheckFloatResult(S, OpPC, F, Status, FPO); } @@ -2441,8 +2567,9 @@ static inline bool CastFloatingFixedPoint(InterpState &S, CodePtr OpPC, static inline bool CastFixedPointFloating(InterpState &S, CodePtr OpPC, const llvm::fltSemantics *Sem) { const auto &Fixed = S.Stk.pop(); - - S.Stk.push(Fixed.toFloat(Sem)); + Floating Result = S.allocFloat(*Sem); + Result.copy(Fixed.toFloat(Sem)); + S.Stk.push(Result); return true; } @@ -2506,12 +2633,18 @@ bool Zero(InterpState &S, CodePtr OpPC) { } static inline bool ZeroIntAP(InterpState &S, CodePtr OpPC, uint32_t BitWidth) { - S.Stk.push>(IntegralAP::zero(BitWidth)); + auto Result = S.allocAP>(BitWidth); + if (!Result.singleWord()) + std::memset(Result.Memory, 0, Result.numWords() * sizeof(uint64_t)); + S.Stk.push>(Result); return true; } static inline bool ZeroIntAPS(InterpState &S, CodePtr OpPC, uint32_t BitWidth) { - S.Stk.push>(IntegralAP::zero(BitWidth)); + auto Result = S.allocAP>(BitWidth); + if (!Result.singleWord()) + std::memset(Result.Memory, 0, Result.numWords() * sizeof(uint64_t)); + S.Stk.push>(Result); return true; } @@ -2578,7 +2711,9 @@ inline bool RVOPtr(InterpState &S, CodePtr OpPC) { //===----------------------------------------------------------------------===// template -inline bool DoShift(InterpState &S, CodePtr OpPC, LT &LHS, RT &RHS) { +inline bool DoShift(InterpState &S, CodePtr OpPC, LT &LHS, RT &RHS, + LT *Result) { + static_assert(!needsAlloc()); const unsigned Bits = LHS.bitWidth(); // OpenCL 6.3j: shift values are effectively % word size of LHS. @@ -2596,7 +2731,7 @@ inline bool DoShift(InterpState &S, CodePtr OpPC, LT &LHS, RT &RHS) { RHS = -RHS; return DoShift( - S, OpPC, LHS, RHS); + S, OpPC, LHS, RHS, Result); } if (!CheckShift(S, OpPC, LHS, RHS, Bits)) @@ -2635,7 +2770,10 @@ inline bool DoShift(InterpState &S, CodePtr OpPC, LT &LHS, RT &RHS) { LT::AsUnsigned::shiftLeft(LT::AsUnsigned::from(LHS), LT::AsUnsigned::from(RHS, Bits), Bits, &R); } - } else { + S.Stk.push(LT::from(R)); + return true; + } + // Right shift. if (Compare(RHS, RT::from(MaxShiftAmount, RHS.bitWidth())) == ComparisonCategoryResult::Greater) { @@ -2646,12 +2784,56 @@ inline bool DoShift(InterpState &S, CodePtr OpPC, LT &LHS, RT &RHS) { LT::shiftRight(LHS, LT::from(RHS, Bits), Bits, &A); R = LT::AsUnsigned::from(A); } - } S.Stk.push(LT::from(R)); return true; } +/// A version of DoShift that works on IntegralAP. +template +inline bool DoShiftAP(InterpState &S, CodePtr OpPC, const APSInt &LHS, + APSInt RHS, LT *Result) { + const unsigned Bits = LHS.getBitWidth(); + + // OpenCL 6.3j: shift values are effectively % word size of LHS. + if (S.getLangOpts().OpenCL) + RHS &= + APSInt(llvm::APInt(RHS.getBitWidth(), static_cast(Bits - 1)), + RHS.isUnsigned()); + + if (RHS.isNegative()) { + // During constant-folding, a negative shift is an opposite shift. Such a + // shift is not a constant expression. + const SourceInfo &Loc = S.Current->getSource(OpPC); + S.CCEDiag(Loc, diag::note_constexpr_negative_shift) << RHS; //.toAPSInt(); + if (!S.noteUndefinedBehavior()) + return false; + return DoShiftAP( + S, OpPC, LHS, -RHS, Result); + } + + if (!CheckShift(S, OpPC, static_cast(LHS), static_cast(RHS), + Bits)) + return false; + + unsigned SA = (unsigned)RHS.getLimitedValue(Bits - 1); + if constexpr (Dir == ShiftDir::Left) { + if constexpr (needsAlloc()) + Result->copy(LHS << SA); + else + *Result = LT(LHS << SA); + } else { + if constexpr (needsAlloc()) + Result->copy(LHS >> SA); + else + *Result = LT(LHS >> SA); + } + + S.Stk.push(*Result); + return true; +} + template inline bool Shr(InterpState &S, CodePtr OpPC) { using LT = typename PrimConv::T; @@ -2659,7 +2841,16 @@ inline bool Shr(InterpState &S, CodePtr OpPC) { auto RHS = S.Stk.pop(); auto LHS = S.Stk.pop(); - return DoShift(S, OpPC, LHS, RHS); + if constexpr (needsAlloc() || needsAlloc()) { + LT Result; + if constexpr (needsAlloc()) + Result = S.allocAP(LHS.bitWidth()); + return DoShiftAP(S, OpPC, LHS.toAPSInt(), + RHS.toAPSInt(), &Result); + } else { + LT Result; + return DoShift(S, OpPC, LHS, RHS, &Result); + } } template @@ -2669,7 +2860,16 @@ inline bool Shl(InterpState &S, CodePtr OpPC) { auto RHS = S.Stk.pop(); auto LHS = S.Stk.pop(); - return DoShift(S, OpPC, LHS, RHS); + if constexpr (needsAlloc() || needsAlloc()) { + LT Result; + if constexpr (needsAlloc()) + Result = S.allocAP(LHS.bitWidth()); + return DoShiftAP(S, OpPC, LHS.toAPSInt(), + RHS.toAPSInt(), &Result); + } else { + LT Result; + return DoShift(S, OpPC, LHS, RHS, &Result); + } } static inline bool ShiftFixedPoint(InterpState &S, CodePtr OpPC, bool Left) { @@ -3252,7 +3452,15 @@ inline bool BitCastPrim(InterpState &S, CodePtr OpPC, bool TargetIsUCharOrByte, if constexpr (std::is_same_v) { assert(Sem); - S.Stk.push(T::bitcastFromMemory(Buff.data(), *Sem)); + Floating Result = S.allocFloat(*Sem); + Floating::bitcastFromMemory(Buff.data(), *Sem, &Result); + S.Stk.push(Result); + + // S.Stk.push(T::bitcastFromMemory(Buff.data(), *Sem)); + } else if constexpr (needsAlloc()) { + T Result = S.allocAP(ResultBitWidth); + T::bitcastFromMemory(Buff.data(), ResultBitWidth, &Result); + S.Stk.push(Result); } else { assert(!Sem); S.Stk.push(T::bitcastFromMemory(Buff.data(), ResultBitWidth)); @@ -3310,7 +3518,11 @@ template inline T ReadArg(InterpState &S, CodePtr &OpPC) { } template <> inline Floating ReadArg(InterpState &S, CodePtr &OpPC) { - Floating F = Floating::deserialize(*OpPC); + auto &Semantics = + llvm::APFloatBase::EnumToSemantics(Floating::deserializeSemantics(*OpPC)); + + auto F = S.allocFloat(Semantics); + Floating::deserialize(*OpPC, &F); OpPC += align(F.bytesToSerialize()); return F; } @@ -3318,17 +3530,25 @@ template <> inline Floating ReadArg(InterpState &S, CodePtr &OpPC) { template <> inline IntegralAP ReadArg>(InterpState &S, CodePtr &OpPC) { - IntegralAP I = IntegralAP::deserialize(*OpPC); - OpPC += align(I.bytesToSerialize()); - return I; + uint32_t BitWidth = IntegralAP::deserializeSize(*OpPC); + auto Result = S.allocAP>(BitWidth); + assert(Result.bitWidth() == BitWidth); + + IntegralAP::deserialize(*OpPC, &Result); + OpPC += align(Result.bytesToSerialize()); + return Result; } template <> inline IntegralAP ReadArg>(InterpState &S, CodePtr &OpPC) { - IntegralAP I = IntegralAP::deserialize(*OpPC); - OpPC += align(I.bytesToSerialize()); - return I; + uint32_t BitWidth = IntegralAP::deserializeSize(*OpPC); + auto Result = S.allocAP>(BitWidth); + assert(Result.bitWidth() == BitWidth); + + IntegralAP::deserialize(*OpPC, &Result); + OpPC += align(Result.bytesToSerialize()); + return Result; } template <> diff --git a/external/llvm-project/clang/lib/AST/ByteCode/InterpBlock.cpp b/external/llvm-project/clang/lib/AST/ByteCode/InterpBlock.cpp index 9ef44cd29ff8..f60307870ffc 100644 --- a/external/llvm-project/clang/lib/AST/ByteCode/InterpBlock.cpp +++ b/external/llvm-project/clang/lib/AST/ByteCode/InterpBlock.cpp @@ -69,20 +69,26 @@ void Block::cleanup() { void Block::replacePointer(Pointer *Old, Pointer *New) { assert(Old); assert(New); + assert(Old != New); if (IsStatic) { assert(!Pointers); return; } - #ifndef NDEBUG assert(hasPointer(Old)); #endif - removePointer(Old); - addPointer(New); + if (Old->Prev) + Old->Prev->Next = New; + if (Old->Next) + Old->Next->Prev = New; + New->Prev = Old->Prev; + New->Next = Old->Next; + if (Pointers == Old) + Pointers = New; Old->PointeeStorage.BS.Pointee = nullptr; - + New->PointeeStorage.BS.Pointee = this; #ifndef NDEBUG assert(!hasPointer(Old)); assert(hasPointer(New)); diff --git a/external/llvm-project/clang/lib/AST/ByteCode/InterpBuiltin.cpp b/external/llvm-project/clang/lib/AST/ByteCode/InterpBuiltin.cpp index d01e3d042a8b..93002172949a 100644 --- a/external/llvm-project/clang/lib/AST/ByteCode/InterpBuiltin.cpp +++ b/external/llvm-project/clang/lib/AST/ByteCode/InterpBuiltin.cpp @@ -57,6 +57,21 @@ static void pushInteger(InterpState &S, const APSInt &Val, QualType QT) { assert(T); unsigned BitWidth = S.getASTContext().getTypeSize(QT); + + if (T == PT_IntAPS) { + auto Result = S.allocAP>(BitWidth); + Result.copy(Val); + S.Stk.push>(Result); + return; + } + + if (T == PT_IntAP) { + auto Result = S.allocAP>(BitWidth); + Result.copy(Val); + S.Stk.push>(Result); + return; + } + if (QT->isSignedIntegerOrEnumerationType()) { int64_t V = Val.getSExtValue(); INT_TYPE_SWITCH(*T, { S.Stk.push(T::from(V, BitWidth)); }); @@ -81,10 +96,21 @@ static void pushInteger(InterpState &S, T Val, QualType QT) { QT); } -static void assignInteger(const Pointer &Dest, PrimType ValueT, +static void assignInteger(InterpState &S, const Pointer &Dest, PrimType ValueT, const APSInt &Value) { - INT_TYPE_SWITCH_NO_BOOL( - ValueT, { Dest.deref() = T::from(static_cast(Value)); }); + + if (ValueT == PT_IntAPS) { + Dest.deref>() = + S.allocAP>(Value.getBitWidth()); + Dest.deref>().copy(Value); + } else if (ValueT == PT_IntAP) { + Dest.deref>() = + S.allocAP>(Value.getBitWidth()); + Dest.deref>().copy(Value); + } else { + INT_TYPE_SWITCH_NO_BOOL( + ValueT, { Dest.deref() = T::from(static_cast(Value)); }); + } } static QualType getElemType(const Pointer &P) { @@ -327,13 +353,13 @@ static bool interp__builtin_nan(InterpState &S, CodePtr OpPC, S.getASTContext().getFloatTypeSemantics( Call->getDirectCallee()->getReturnType()); - Floating Result; + Floating Result = S.allocFloat(TargetSemantics); if (S.getASTContext().getTargetInfo().isNan2008()) { if (Signaling) - Result = Floating( + Result.copy( llvm::APFloat::getSNaN(TargetSemantics, /*Negative=*/false, &Fill)); else - Result = Floating( + Result.copy( llvm::APFloat::getQNaN(TargetSemantics, /*Negative=*/false, &Fill)); } else { // Prior to IEEE 754-2008, architectures were allowed to choose whether @@ -342,10 +368,10 @@ static bool interp__builtin_nan(InterpState &S, CodePtr OpPC, // 2008 revisions, MIPS interpreted sNaN-2008 as qNan and qNaN-2008 as // sNaN. This is now known as "legacy NaN" encoding. if (Signaling) - Result = Floating( + Result.copy( llvm::APFloat::getQNaN(TargetSemantics, /*Negative=*/false, &Fill)); else - Result = Floating( + Result.copy( llvm::APFloat::getSNaN(TargetSemantics, /*Negative=*/false, &Fill)); } @@ -360,7 +386,9 @@ static bool interp__builtin_inf(InterpState &S, CodePtr OpPC, S.getASTContext().getFloatTypeSemantics( Call->getDirectCallee()->getReturnType()); - S.Stk.push(Floating::getInf(TargetSemantics)); + Floating Result = S.allocFloat(TargetSemantics); + Result.copy(APFloat::getInf(TargetSemantics)); + S.Stk.push(Result); return true; } @@ -368,10 +396,12 @@ static bool interp__builtin_copysign(InterpState &S, CodePtr OpPC, const InterpFrame *Frame) { const Floating &Arg2 = S.Stk.pop(); const Floating &Arg1 = S.Stk.pop(); + Floating Result = S.allocFloat(Arg1.getSemantics()); APFloat Copy = Arg1.getAPFloat(); Copy.copySign(Arg2.getAPFloat()); - S.Stk.push(Floating(Copy)); + Result.copy(Copy); + S.Stk.push(Result); return true; } @@ -380,11 +410,13 @@ static bool interp__builtin_fmin(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, bool IsNumBuiltin) { const Floating &RHS = S.Stk.pop(); const Floating &LHS = S.Stk.pop(); + Floating Result = S.allocFloat(LHS.getSemantics()); if (IsNumBuiltin) - S.Stk.push(llvm::minimumnum(LHS.getAPFloat(), RHS.getAPFloat())); + Result.copy(llvm::minimumnum(LHS.getAPFloat(), RHS.getAPFloat())); else - S.Stk.push(minnum(LHS.getAPFloat(), RHS.getAPFloat())); + Result.copy(minnum(LHS.getAPFloat(), RHS.getAPFloat())); + S.Stk.push(Result); return true; } @@ -392,11 +424,13 @@ static bool interp__builtin_fmax(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, bool IsNumBuiltin) { const Floating &RHS = S.Stk.pop(); const Floating &LHS = S.Stk.pop(); + Floating Result = S.allocFloat(LHS.getSemantics()); if (IsNumBuiltin) - S.Stk.push(llvm::maximumnum(LHS.getAPFloat(), RHS.getAPFloat())); + Result.copy(llvm::maximumnum(LHS.getAPFloat(), RHS.getAPFloat())); else - S.Stk.push(maxnum(LHS.getAPFloat(), RHS.getAPFloat())); + Result.copy(maxnum(LHS.getAPFloat(), RHS.getAPFloat())); + S.Stk.push(Result); return true; } @@ -571,8 +605,16 @@ static bool interp__builtin_fpclassify(InterpState &S, CodePtr OpPC, static bool interp__builtin_fabs(InterpState &S, CodePtr OpPC, const InterpFrame *Frame) { const Floating &Val = S.Stk.pop(); + APFloat F = Val.getAPFloat(); + if (!F.isNegative()) { + S.Stk.push(Val); + return true; + } - S.Stk.push(Floating::abs(Val)); + Floating Result = S.allocFloat(Val.getSemantics()); + F.changeSign(); + Result.copy(F); + S.Stk.push(Result); return true; } @@ -818,7 +860,7 @@ static bool interp__builtin_overflowop(InterpState &S, CodePtr OpPC, } // Write Result to ResultPtr and put Overflow on the stack. - assignInteger(ResultPtr, ResultT, Result); + assignInteger(S, ResultPtr, ResultT, Result); ResultPtr.initialize(); assert(Call->getDirectCallee()->getReturnType()->isBooleanType()); S.Stk.push(Overflow); @@ -871,7 +913,7 @@ static bool interp__builtin_carryop(InterpState &S, CodePtr OpPC, QualType CarryOutType = Call->getArg(3)->getType()->getPointeeType(); PrimType CarryOutT = *S.getContext().classify(CarryOutType); - assignInteger(CarryOutPtr, CarryOutT, CarryOut); + assignInteger(S, CarryOutPtr, CarryOutT, CarryOut); CarryOutPtr.initialize(); assert(Call->getType() == Call->getArg(0)->getType()); @@ -1383,7 +1425,7 @@ static bool interp__builtin_ia32_addcarry_subborrow(InterpState &S, QualType CarryOutType = Call->getArg(3)->getType()->getPointeeType(); PrimType CarryOutT = *S.getContext().classify(CarryOutType); - assignInteger(CarryOutPtr, CarryOutT, APSInt(Result, true)); + assignInteger(S, CarryOutPtr, CarryOutT, APSInt(Result, true)); pushInteger(S, CarryOut, Call->getType()); @@ -1447,7 +1489,7 @@ static bool interp__builtin_operator_new(InterpState &S, CodePtr OpPC, // The std::nothrow_t arg never gets put on the stack. if (Call->getArg(NumArgs - 1)->getType()->isNothrowT()) --NumArgs; - auto Args = llvm::ArrayRef(Call->getArgs(), Call->getNumArgs()); + auto Args = ArrayRef(Call->getArgs(), Call->getNumArgs()); // First arg is needed. Args = Args.drop_front(); @@ -2595,8 +2637,7 @@ bool InterpretBuiltin(InterpState &S, CodePtr OpPC, const CallExpr *Call, } bool InterpretOffsetOf(InterpState &S, CodePtr OpPC, const OffsetOfExpr *E, - llvm::ArrayRef ArrayIndices, - int64_t &IntResult) { + ArrayRef ArrayIndices, int64_t &IntResult) { CharUnits Result; unsigned N = E->getNumComponents(); assert(N > 0); diff --git a/external/llvm-project/clang/lib/AST/ByteCode/InterpBuiltinBitCast.cpp b/external/llvm-project/clang/lib/AST/ByteCode/InterpBuiltinBitCast.cpp index 239b3104e89f..2569cac018b3 100644 --- a/external/llvm-project/clang/lib/AST/ByteCode/InterpBuiltinBitCast.cpp +++ b/external/llvm-project/clang/lib/AST/ByteCode/InterpBuiltinBitCast.cpp @@ -402,7 +402,9 @@ bool clang::interp::DoBitCastPtr(InterpState &S, CodePtr OpPC, if (llvm::sys::IsBigEndianHost) swapBytes(M.get(), NumBits.roundToBytes()); - P.deref() = Floating::bitcastFromMemory(M.get(), Semantics); + Floating R = S.allocFloat(Semantics); + Floating::bitcastFromMemory(M.get(), Semantics, &R); + P.deref() = R; P.initialize(); return true; } diff --git a/external/llvm-project/clang/lib/AST/ByteCode/InterpShared.cpp b/external/llvm-project/clang/lib/AST/ByteCode/InterpShared.cpp index 6af03691f1b2..1e94dc19d03c 100644 --- a/external/llvm-project/clang/lib/AST/ByteCode/InterpShared.cpp +++ b/external/llvm-project/clang/lib/AST/ByteCode/InterpShared.cpp @@ -14,7 +14,7 @@ namespace clang { namespace interp { llvm::BitVector collectNonNullArgs(const FunctionDecl *F, - const llvm::ArrayRef &Args) { + ArrayRef Args) { llvm::BitVector NonNullArgs; if (!F) return NonNullArgs; diff --git a/external/llvm-project/clang/lib/AST/ByteCode/InterpShared.h b/external/llvm-project/clang/lib/AST/ByteCode/InterpShared.h index 8c5e0bee22c9..9355fb77e143 100644 --- a/external/llvm-project/clang/lib/AST/ByteCode/InterpShared.h +++ b/external/llvm-project/clang/lib/AST/ByteCode/InterpShared.h @@ -9,6 +9,7 @@ #ifndef LLVM_CLANG_LIB_AST_INTERP_SHARED_H #define LLVM_CLANG_LIB_AST_INTERP_SHARED_H +#include "clang/Basic/LLVM.h" #include "llvm/ADT/BitVector.h" namespace clang { @@ -18,7 +19,7 @@ class Expr; namespace interp { llvm::BitVector collectNonNullArgs(const FunctionDecl *F, - const llvm::ArrayRef &Args); + ArrayRef Args); } // namespace interp } // namespace clang diff --git a/external/llvm-project/clang/lib/AST/ByteCode/InterpStack.cpp b/external/llvm-project/clang/lib/AST/ByteCode/InterpStack.cpp index b183335dd588..6b748d62b83b 100644 --- a/external/llvm-project/clang/lib/AST/ByteCode/InterpStack.cpp +++ b/external/llvm-project/clang/lib/AST/ByteCode/InterpStack.cpp @@ -19,9 +19,7 @@ using namespace clang; using namespace clang::interp; -InterpStack::~InterpStack() { clear(); } - -void InterpStack::clear() { +InterpStack::~InterpStack() { if (Chunk && Chunk->Next) std::free(Chunk->Next); if (Chunk) @@ -33,6 +31,21 @@ void InterpStack::clear() { #endif } +// We keep the last chunk around to reuse. +void InterpStack::clear() { + if (!Chunk) + return; + + if (Chunk->Next) + std::free(Chunk->Next); + + assert(Chunk); + StackSize = 0; +#ifndef NDEBUG + ItemTypes.clear(); +#endif +} + void InterpStack::clearTo(size_t NewSize) { assert(NewSize <= size()); size_t ToShrink = size() - NewSize; diff --git a/external/llvm-project/clang/lib/AST/ByteCode/InterpState.h b/external/llvm-project/clang/lib/AST/ByteCode/InterpState.h index e8dc6f0483d6..08765561985e 100644 --- a/external/llvm-project/clang/lib/AST/ByteCode/InterpState.h +++ b/external/llvm-project/clang/lib/AST/ByteCode/InterpState.h @@ -15,6 +15,7 @@ #include "Context.h" #include "DynamicAllocator.h" +#include "Floating.h" #include "Function.h" #include "InterpFrame.h" #include "InterpStack.h" @@ -126,6 +127,33 @@ class InterpState final : public State, public SourceMapper { StdAllocatorCaller getStdAllocatorCaller(StringRef Name) const; + void *allocate(size_t Size, unsigned Align = 8) const { + return Allocator.Allocate(Size, Align); + } + template T *allocate(size_t Num = 1) const { + return static_cast(allocate(Num * sizeof(T), alignof(T))); + } + + template T allocAP(unsigned BitWidth) { + unsigned NumWords = APInt::getNumWords(BitWidth); + if (NumWords == 1) + return T(BitWidth); + uint64_t *Mem = (uint64_t *)this->allocate(NumWords * sizeof(uint64_t)); + // std::memset(Mem, 0, NumWords * sizeof(uint64_t)); // Debug + return T(Mem, BitWidth); + } + + Floating allocFloat(const llvm::fltSemantics &Sem) { + if (Floating::singleWord(Sem)) + return Floating(llvm::APFloatBase::SemanticsToEnum(Sem)); + + unsigned NumWords = + APInt::getNumWords(llvm::APFloatBase::getSizeInBits(Sem)); + uint64_t *Mem = (uint64_t *)this->allocate(NumWords * sizeof(uint64_t)); + // std::memset(Mem, 0, NumWords * sizeof(uint64_t)); // Debug + return Floating(Mem, llvm::APFloatBase::SemanticsToEnum(Sem)); + } + private: friend class EvaluationResult; friend class InterpStateCCOverride; @@ -161,6 +189,8 @@ class InterpState final : public State, public SourceMapper { llvm::SmallVector< std::pair> SeenGlobalTemporaries; + + mutable llvm::BumpPtrAllocator Allocator; }; class InterpStateCCOverride final { diff --git a/external/llvm-project/clang/lib/AST/ByteCode/Opcodes.td b/external/llvm-project/clang/lib/AST/ByteCode/Opcodes.td index c76ac5f8ae86..57e01f7bd9da 100644 --- a/external/llvm-project/clang/lib/AST/ByteCode/Opcodes.td +++ b/external/llvm-project/clang/lib/AST/ByteCode/Opcodes.td @@ -48,6 +48,7 @@ def ArgUint64 : ArgType { let Name = "uint64_t"; } def ArgIntAP : ArgType { let Name = "IntegralAP"; let AsRef = true; } def ArgIntAPS : ArgType { let Name = "IntegralAP"; let AsRef = true; } def ArgFloat : ArgType { let Name = "Floating"; let AsRef = true; } + def ArgBool : ArgType { let Name = "bool"; } def ArgFixedPoint : ArgType { let Name = "FixedPoint"; let AsRef = true; } @@ -88,6 +89,9 @@ def IntegerAndFixedTypeClass : TypeClass { Uint32, Sint64, Uint64, IntAP, IntAPS, FixedPoint]; } +def IntegralTypeClass : TypeClass { + let Types = !listconcat(IntegerTypeClass.Types, [Bool]); +} def FixedSizeIntegralTypeClass : TypeClass { let Types = [Sint8, Uint8, Sint16, Uint16, Sint32, Uint32, Sint64, Uint64, Bool]; @@ -265,12 +269,13 @@ def ConstSint32 : ConstOpcode; def ConstUint32 : ConstOpcode; def ConstSint64 : ConstOpcode; def ConstUint64 : ConstOpcode; -def ConstFloat : ConstOpcode; -def constIntAP : ConstOpcode; -def constIntAPS : ConstOpcode; +def ConstIntAP : ConstOpcode; +def ConstIntAPS : ConstOpcode; def ConstBool : ConstOpcode; def ConstFixedPoint : ConstOpcode; +def ConstFloat : Opcode { let Args = [ArgFloat]; } + // [] -> [Integer] def Zero : Opcode { let Types = [FixedSizeIntegralTypeClass]; @@ -328,6 +333,7 @@ def GetMemberPtrBasePop : Opcode { def FinishInitPop : Opcode; def FinishInit : Opcode; +def FinishInitGlobal : Opcode; def GetPtrDerivedPop : Opcode { let Args = [ArgUint32, ArgBool, ArgTypePtr]; } @@ -389,7 +395,7 @@ class AccessOpcode : Opcode { } class BitFieldOpcode : Opcode { - let Types = [AluTypeClass]; + let Types = [IntegralTypeClass]; let Args = [ArgRecordField]; let HasGroup = 1; } diff --git a/external/llvm-project/clang/lib/AST/ByteCode/Pointer.cpp b/external/llvm-project/clang/lib/AST/ByteCode/Pointer.cpp index 50453c72c582..f0b0384f32ac 100644 --- a/external/llvm-project/clang/lib/AST/ByteCode/Pointer.cpp +++ b/external/llvm-project/clang/lib/AST/ByteCode/Pointer.cpp @@ -114,7 +114,6 @@ void Pointer::operator=(Pointer &&P) { } if (Block *Pointee = PointeeStorage.BS.Pointee) { - assert(P.block() != this->block()); Pointee->removePointer(this); PointeeStorage.BS.Pointee = nullptr; Pointee->cleanup(); diff --git a/external/llvm-project/clang/lib/AST/ByteCode/PrimType.h b/external/llvm-project/clang/lib/AST/ByteCode/PrimType.h index 6152fbfbe3a7..a156cccbb3c1 100644 --- a/external/llvm-project/clang/lib/AST/ByteCode/PrimType.h +++ b/external/llvm-project/clang/lib/AST/ByteCode/PrimType.h @@ -76,6 +76,13 @@ inline llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, } constexpr bool isIntegralType(PrimType T) { return T <= PT_FixedPoint; } +template constexpr bool needsAlloc() { + return std::is_same_v> || + std::is_same_v> || std::is_same_v; +} +constexpr bool needsAlloc(PrimType T) { + return T == PT_IntAP || T == PT_IntAPS || T == PT_Float; +} /// Mapping from primitive types to their representation. template struct PrimConv; @@ -209,6 +216,16 @@ static inline bool aligned(const void *P) { } \ } while (0) +#define TYPE_SWITCH_ALLOC(Expr, B) \ + do { \ + switch (Expr) { \ + TYPE_SWITCH_CASE(PT_Float, B) \ + TYPE_SWITCH_CASE(PT_IntAP, B) \ + TYPE_SWITCH_CASE(PT_IntAPS, B) \ + default:; \ + } \ + } while (0) + #define COMPOSITE_TYPE_SWITCH(Expr, B, D) \ do { \ switch (Expr) { \ diff --git a/external/llvm-project/clang/lib/AST/ByteCode/Program.h b/external/llvm-project/clang/lib/AST/ByteCode/Program.h index 23ba1bbd193b..5d9c42244749 100644 --- a/external/llvm-project/clang/lib/AST/ByteCode/Program.h +++ b/external/llvm-project/clang/lib/AST/ByteCode/Program.h @@ -132,6 +132,14 @@ class Program final { bool IsMutable = false, bool IsVolatile = false, const Expr *Init = nullptr); + void *Allocate(size_t Size, unsigned Align = 8) const { + return Allocator.Allocate(Size, Align); + } + template T *Allocate(size_t Num = 1) const { + return static_cast(Allocate(Num * sizeof(T), alignof(T))); + } + void Deallocate(void *Ptr) const {} + /// Context to manage declaration lifetimes. class DeclScope { public: @@ -204,7 +212,7 @@ class Program final { }; /// Allocator for globals. - PoolAllocTy Allocator; + mutable PoolAllocTy Allocator; /// Global objects. std::vector Globals; @@ -238,4 +246,18 @@ class Program final { } // namespace interp } // namespace clang +inline void *operator new(size_t Bytes, const clang::interp::Program &C, + size_t Alignment = 8) { + return C.Allocate(Bytes, Alignment); +} + +inline void operator delete(void *Ptr, const clang::interp::Program &C, + size_t) { + C.Deallocate(Ptr); +} +inline void *operator new[](size_t Bytes, const clang::interp::Program &C, + size_t Alignment = 8) { + return C.Allocate(Bytes, Alignment); +} + #endif diff --git a/external/llvm-project/clang/lib/AST/CommentParser.cpp b/external/llvm-project/clang/lib/AST/CommentParser.cpp index 12ed8e3f1b79..e61846d24191 100644 --- a/external/llvm-project/clang/lib/AST/CommentParser.cpp +++ b/external/llvm-project/clang/lib/AST/CommentParser.cpp @@ -375,7 +375,7 @@ class TextTokenRetokenizer { Pos.CurToken++; } - P.putBack(llvm::ArrayRef(Toks.begin() + Pos.CurToken, Toks.end())); + P.putBack(ArrayRef(Toks.begin() + Pos.CurToken, Toks.end())); Pos.CurToken = Toks.size(); if (HavePartialTok) @@ -431,7 +431,7 @@ Parser::parseCommandArgs(TextTokenRetokenizer &Retokenizer, unsigned NumArgs) { ParsedArgs++; } - return llvm::ArrayRef(Args, ParsedArgs); + return ArrayRef(Args, ParsedArgs); } ArrayRef @@ -448,7 +448,7 @@ Parser::parseThrowCommandArgs(TextTokenRetokenizer &Retokenizer, ParsedArgs++; } - return llvm::ArrayRef(Args, ParsedArgs); + return ArrayRef(Args, ParsedArgs); } ArrayRef @@ -466,7 +466,7 @@ Parser::parseParCommandArgs(TextTokenRetokenizer &Retokenizer, ParsedArgs++; } - return llvm::ArrayRef(Args, ParsedArgs); + return ArrayRef(Args, ParsedArgs); } BlockCommandComment *Parser::parseBlockCommand() { @@ -638,14 +638,14 @@ HTMLStartTagComment *Parser::parseHTMLStartTag() { } case tok::html_greater: - S.actOnHTMLStartTagFinish(HST, S.copyArray(llvm::ArrayRef(Attrs)), + S.actOnHTMLStartTagFinish(HST, S.copyArray(ArrayRef(Attrs)), Tok.getLocation(), /* IsSelfClosing = */ false); consumeToken(); return HST; case tok::html_slash_greater: - S.actOnHTMLStartTagFinish(HST, S.copyArray(llvm::ArrayRef(Attrs)), + S.actOnHTMLStartTagFinish(HST, S.copyArray(ArrayRef(Attrs)), Tok.getLocation(), /* IsSelfClosing = */ true); consumeToken(); @@ -663,14 +663,14 @@ HTMLStartTagComment *Parser::parseHTMLStartTag() { Tok.is(tok::html_slash_greater)) continue; - S.actOnHTMLStartTagFinish(HST, S.copyArray(llvm::ArrayRef(Attrs)), + S.actOnHTMLStartTagFinish(HST, S.copyArray(ArrayRef(Attrs)), SourceLocation(), /* IsSelfClosing = */ false); return HST; default: // Not a token from an HTML start tag. Thus HTML tag prematurely ended. - S.actOnHTMLStartTagFinish(HST, S.copyArray(llvm::ArrayRef(Attrs)), + S.actOnHTMLStartTagFinish(HST, S.copyArray(ArrayRef(Attrs)), SourceLocation(), /* IsSelfClosing = */ false); bool StartLineInvalid; @@ -809,7 +809,7 @@ BlockContentComment *Parser::parseParagraphOrBlockCommand() { break; } - return S.actOnParagraphComment(S.copyArray(llvm::ArrayRef(Content))); + return S.actOnParagraphComment(S.copyArray(ArrayRef(Content))); } VerbatimBlockComment *Parser::parseVerbatimBlock() { @@ -847,12 +847,12 @@ VerbatimBlockComment *Parser::parseVerbatimBlock() { if (Tok.is(tok::verbatim_block_end)) { const CommandInfo *Info = Traits.getCommandInfo(Tok.getVerbatimBlockID()); S.actOnVerbatimBlockFinish(VB, Tok.getLocation(), Info->Name, - S.copyArray(llvm::ArrayRef(Lines))); + S.copyArray(ArrayRef(Lines))); consumeToken(); } else { // Unterminated \\verbatim block S.actOnVerbatimBlockFinish(VB, SourceLocation(), "", - S.copyArray(llvm::ArrayRef(Lines))); + S.copyArray(ArrayRef(Lines))); } return VB; @@ -928,7 +928,7 @@ FullComment *Parser::parseFullComment() { while (Tok.is(tok::newline)) consumeToken(); } - return S.actOnFullComment(S.copyArray(llvm::ArrayRef(Blocks))); + return S.actOnFullComment(S.copyArray(ArrayRef(Blocks))); } } // end namespace comments diff --git a/external/llvm-project/clang/lib/AST/CommentSema.cpp b/external/llvm-project/clang/lib/AST/CommentSema.cpp index fb745fc560d2..36a9ebe14d7d 100644 --- a/external/llvm-project/clang/lib/AST/CommentSema.cpp +++ b/external/llvm-project/clang/lib/AST/CommentSema.cpp @@ -268,7 +268,7 @@ void Sema::actOnParamCommandParamNameArg(ParamCommandComment *Command, } auto *A = new (Allocator) Comment::Argument{SourceRange(ArgLocBegin, ArgLocEnd), Arg}; - Command->setArgs(llvm::ArrayRef(A, 1)); + Command->setArgs(ArrayRef(A, 1)); } void Sema::actOnParamCommandFinish(ParamCommandComment *Command, @@ -304,7 +304,7 @@ void Sema::actOnTParamCommandParamNameArg(TParamCommandComment *Command, auto *A = new (Allocator) Comment::Argument{SourceRange(ArgLocBegin, ArgLocEnd), Arg}; - Command->setArgs(llvm::ArrayRef(A, 1)); + Command->setArgs(ArrayRef(A, 1)); if (!isTemplateOrSpecialization()) { // We already warned that this \\tparam is not attached to a template decl. @@ -315,7 +315,7 @@ void Sema::actOnTParamCommandParamNameArg(TParamCommandComment *Command, ThisDeclInfo->TemplateParameters; SmallVector Position; if (resolveTParamReference(Arg, TemplateParameters, &Position)) { - Command->setPosition(copyArray(llvm::ArrayRef(Position))); + Command->setPosition(copyArray(ArrayRef(Position))); TParamCommandComment *&PrevCommand = TemplateParameterDocs[Arg]; if (PrevCommand) { SourceRange ArgRange(ArgLocBegin, ArgLocEnd); diff --git a/external/llvm-project/clang/lib/AST/ComputeDependence.cpp b/external/llvm-project/clang/lib/AST/ComputeDependence.cpp index fd2eefa1cf07..14ec93eb1d16 100644 --- a/external/llvm-project/clang/lib/AST/ComputeDependence.cpp +++ b/external/llvm-project/clang/lib/AST/ComputeDependence.cpp @@ -639,12 +639,11 @@ ExprDependence clang::computeDependence(PredefinedExpr *E) { return toExprDependenceForImpliedType(E->getType()->getDependence()); } -ExprDependence clang::computeDependence(CallExpr *E, - llvm::ArrayRef PreArgs) { +ExprDependence clang::computeDependence(CallExpr *E, ArrayRef PreArgs) { auto D = E->getCallee()->getDependence(); if (E->getType()->isDependentType()) D |= ExprDependence::Type; - for (auto *A : llvm::ArrayRef(E->getArgs(), E->getNumArgs())) { + for (auto *A : ArrayRef(E->getArgs(), E->getNumArgs())) { if (A) D |= A->getDependence(); } @@ -709,7 +708,7 @@ ExprDependence clang::computeDependence(InitListExpr *E) { ExprDependence clang::computeDependence(ShuffleVectorExpr *E) { auto D = toExprDependenceForImpliedType(E->getType()->getDependence()); - for (auto *C : llvm::ArrayRef(E->getSubExprs(), E->getNumSubExprs())) + for (auto *C : ArrayRef(E->getSubExprs(), E->getNumSubExprs())) D |= C->getDependence(); return D; } @@ -758,7 +757,7 @@ ExprDependence clang::computeDependence(PseudoObjectExpr *O) { ExprDependence clang::computeDependence(AtomicExpr *A) { auto D = ExprDependence::None; - for (auto *E : llvm::ArrayRef(A->getSubExprs(), A->getNumSubExprs())) + for (auto *E : ArrayRef(A->getSubExprs(), A->getNumSubExprs())) D |= E->getDependence(); return D; } diff --git a/external/llvm-project/clang/lib/AST/Decl.cpp b/external/llvm-project/clang/lib/AST/Decl.cpp index 860968939b4a..35c41859595d 100644 --- a/external/llvm-project/clang/lib/AST/Decl.cpp +++ b/external/llvm-project/clang/lib/AST/Decl.cpp @@ -2110,7 +2110,7 @@ void QualifierInfo::setTemplateParameterListsInfo( if (!TPLists.empty()) { TemplParamLists = new (Context) TemplateParameterList *[TPLists.size()]; NumTemplParamLists = TPLists.size(); - std::copy(TPLists.begin(), TPLists.end(), TemplParamLists); + llvm::copy(TPLists, TemplParamLists); } } @@ -2441,6 +2441,30 @@ VarDecl *VarDecl::getInitializingDeclaration() { return Def; } +bool VarDecl::hasInitWithSideEffects() const { + if (!hasInit()) + return false; + + // Check if we can get the initializer without deserializing + const Expr *E = nullptr; + if (auto *S = dyn_cast(Init)) { + E = cast(S); + } else { + E = cast_or_null(getEvaluatedStmt()->Value.getWithoutDeserializing()); + } + + if (E) + return E->HasSideEffects(getASTContext()) && + // We can get a value-dependent initializer during error recovery. + (E->isValueDependent() || !evaluateValue()); + + assert(getEvaluatedStmt()->Value.isOffset()); + // ASTReader tracks this without having to deserialize the initializer + if (auto Source = getASTContext().getExternalSource()) + return Source->hasInitializerWithSideEffects(this); + return false; +} + bool VarDecl::isOutOfLine() const { if (Decl::isOutOfLine()) return true; @@ -3753,7 +3777,7 @@ void FunctionDecl::setParams(ASTContext &C, // Zero params -> null pointer. if (!NewParamInfo.empty()) { ParamInfo = new (C) ParmVarDecl*[NewParamInfo.size()]; - std::copy(NewParamInfo.begin(), NewParamInfo.end(), ParamInfo); + llvm::copy(NewParamInfo, ParamInfo); } } @@ -5322,7 +5346,7 @@ void BlockDecl::setParams(ArrayRef NewParamInfo) { if (!NewParamInfo.empty()) { NumParams = NewParamInfo.size(); ParamInfo = new (getASTContext()) ParmVarDecl*[NewParamInfo.size()]; - std::copy(NewParamInfo.begin(), NewParamInfo.end(), ParamInfo); + llvm::copy(NewParamInfo, ParamInfo); } } @@ -5379,8 +5403,8 @@ PragmaCommentDecl *PragmaCommentDecl::Create(const ASTContext &C, PragmaCommentDecl *PCD = new (C, DC, additionalSizeToAlloc(Arg.size() + 1)) PragmaCommentDecl(DC, CommentLoc, CommentKind); - memcpy(PCD->getTrailingObjects(), Arg.data(), Arg.size()); - PCD->getTrailingObjects()[Arg.size()] = '\0'; + llvm::copy(Arg, PCD->getTrailingObjects()); + PCD->getTrailingObjects()[Arg.size()] = '\0'; return PCD; } @@ -5401,9 +5425,9 @@ PragmaDetectMismatchDecl::Create(const ASTContext &C, TranslationUnitDecl *DC, PragmaDetectMismatchDecl *PDMD = new (C, DC, additionalSizeToAlloc(ValueStart + Value.size() + 1)) PragmaDetectMismatchDecl(DC, Loc, ValueStart); - memcpy(PDMD->getTrailingObjects(), Name.data(), Name.size()); + llvm::copy(Name, PDMD->getTrailingObjects()); PDMD->getTrailingObjects()[Name.size()] = '\0'; - memcpy(PDMD->getTrailingObjects() + ValueStart, Value.data(), Value.size()); + llvm::copy(Value, PDMD->getTrailingObjects() + ValueStart); PDMD->getTrailingObjects()[ValueStart + Value.size()] = '\0'; return PDMD; } @@ -5443,9 +5467,9 @@ LabelDecl *LabelDecl::CreateDeserialized(ASTContext &C, GlobalDeclID ID) { void LabelDecl::setMSAsmLabel(StringRef Name) { char *Buffer = new (getASTContext(), 1) char[Name.size() + 1]; - memcpy(Buffer, Name.data(), Name.size()); - Buffer[Name.size()] = '\0'; - MSAsmName = Buffer; +llvm::copy(Name, Buffer); +Buffer[Name.size()] = '\0'; +MSAsmName = Buffer; } void ValueDecl::anchor() {} @@ -5607,10 +5631,11 @@ IndirectFieldDecl::IndirectFieldDecl(ASTContext &C, DeclContext *DC, IdentifierNamespace |= IDNS_Tag; } -IndirectFieldDecl * -IndirectFieldDecl::Create(ASTContext &C, DeclContext *DC, SourceLocation L, - const IdentifierInfo *Id, QualType T, - llvm::MutableArrayRef CH) { +IndirectFieldDecl *IndirectFieldDecl::Create(ASTContext &C, DeclContext *DC, + SourceLocation L, + const IdentifierInfo *Id, + QualType T, + MutableArrayRef CH) { return new (C, DC) IndirectFieldDecl(C, DC, L, Id, T, CH); } @@ -5828,7 +5853,7 @@ void HLSLBufferDecl::setDefaultBufferDecls(ArrayRef Decls) { // allocate array for default decls with ASTContext allocator Decl **DeclsArray = new (getASTContext()) Decl *[Decls.size()]; - std::copy(Decls.begin(), Decls.end(), DeclsArray); + llvm::copy(Decls, DeclsArray); DefaultBufferDecls = ArrayRef(DeclsArray, Decls.size()); } @@ -5869,8 +5894,7 @@ HLSLRootSignatureDecl *HLSLRootSignatureDecl::Create( RootElements.size())) HLSLRootSignatureDecl(DC, Loc, ID, RootElements.size()); auto *StoredElems = RSDecl->getElems(); - std::uninitialized_copy(RootElements.begin(), RootElements.end(), - StoredElems); + llvm::uninitialized_copy(RootElements, StoredElems); return RSDecl; } diff --git a/external/llvm-project/clang/lib/AST/DeclCXX.cpp b/external/llvm-project/clang/lib/AST/DeclCXX.cpp index f1f31d8be78c..ccb308e10325 100644 --- a/external/llvm-project/clang/lib/AST/DeclCXX.cpp +++ b/external/llvm-project/clang/lib/AST/DeclCXX.cpp @@ -1828,7 +1828,7 @@ CXXRecordDecl::getLambdaExplicitTemplateParameters() const { const auto ExplicitEnd = llvm::partition_point( *List, [](const NamedDecl *D) { return !D->isImplicit(); }); - return llvm::ArrayRef(List->begin(), ExplicitEnd); + return ArrayRef(List->begin(), ExplicitEnd); } Decl *CXXRecordDecl::getLambdaContextDecl() const { @@ -3578,13 +3578,13 @@ VarDecl *BindingDecl::getHoldingVar() const { return VD; } -llvm::ArrayRef BindingDecl::getBindingPackDecls() const { +ArrayRef BindingDecl::getBindingPackDecls() const { assert(Binding && "expecting a pack expr"); auto *FP = cast(Binding); ValueDecl *const *First = FP->getNumExpansions() > 0 ? FP->begin() : nullptr; assert((!First || isa(*First)) && "expecting a BindingDecl"); - return llvm::ArrayRef( - reinterpret_cast(First), FP->getNumExpansions()); + return ArrayRef(reinterpret_cast(First), + FP->getNumExpansions()); } void DecompositionDecl::anchor() {} diff --git a/external/llvm-project/clang/lib/AST/DeclObjC.cpp b/external/llvm-project/clang/lib/AST/DeclObjC.cpp index 596262e21798..5cf0e9a7b259 100644 --- a/external/llvm-project/clang/lib/AST/DeclObjC.cpp +++ b/external/llvm-project/clang/lib/AST/DeclObjC.cpp @@ -1512,7 +1512,7 @@ ObjCTypeParamList::ObjCTypeParamList(SourceLocation lAngleLoc, ArrayRef typeParams, SourceLocation rAngleLoc) : Brackets(lAngleLoc, rAngleLoc), NumParams(typeParams.size()) { - std::copy(typeParams.begin(), typeParams.end(), begin()); + llvm::copy(typeParams, begin()); } ObjCTypeParamList *ObjCTypeParamList::create( diff --git a/external/llvm-project/clang/lib/AST/DeclPrinter.cpp b/external/llvm-project/clang/lib/AST/DeclPrinter.cpp index 944385744334..9273f5816d5a 100644 --- a/external/llvm-project/clang/lib/AST/DeclPrinter.cpp +++ b/external/llvm-project/clang/lib/AST/DeclPrinter.cpp @@ -118,9 +118,9 @@ namespace { void printTemplateParameters(const TemplateParameterList *Params, bool OmitTemplateKW = false); - void printTemplateArguments(llvm::ArrayRef Args, + void printTemplateArguments(ArrayRef Args, const TemplateParameterList *Params); - void printTemplateArguments(llvm::ArrayRef Args, + void printTemplateArguments(ArrayRef Args, const TemplateParameterList *Params); enum class AttrPosAsWritten { Default = 0, Left, Right }; bool diff --git a/external/llvm-project/clang/lib/AST/DeclTemplate.cpp b/external/llvm-project/clang/lib/AST/DeclTemplate.cpp index e1ef2188dbdb..5035f2d33b0a 100644 --- a/external/llvm-project/clang/lib/AST/DeclTemplate.cpp +++ b/external/llvm-project/clang/lib/AST/DeclTemplate.cpp @@ -669,7 +669,7 @@ ClassTemplateDecl::getInjectedClassNameSpecialization() { CommonPtr->InjectedClassNameType = Context.getTemplateSpecializationType(Name, /*SpecifiedArgs=*/TemplateArgs, - /*CanonicalArgs=*/std::nullopt); + /*CanonicalArgs=*/{}); return CommonPtr->InjectedClassNameType; } diff --git a/external/llvm-project/clang/lib/AST/Expr.cpp b/external/llvm-project/clang/lib/AST/Expr.cpp index 7a11b9e55d1a..4edbcda9a456 100644 --- a/external/llvm-project/clang/lib/AST/Expr.cpp +++ b/external/llvm-project/clang/lib/AST/Expr.cpp @@ -1123,14 +1123,13 @@ unsigned StringLiteral::mapCharByteWidth(TargetInfo const &Target, StringLiteral::StringLiteral(const ASTContext &Ctx, StringRef Str, StringLiteralKind Kind, bool Pascal, QualType Ty, - const SourceLocation *Loc, - unsigned NumConcatenated) + ArrayRef Locs) : Expr(StringLiteralClass, Ty, VK_LValue, OK_Ordinary) { unsigned Length = Str.size(); StringLiteralBits.Kind = llvm::to_underlying(Kind); - StringLiteralBits.NumConcatenated = NumConcatenated; + StringLiteralBits.NumConcatenated = Locs.size(); if (Kind != StringLiteralKind::Unevaluated) { assert(Ctx.getAsConstantArrayType(Ty) && @@ -1169,11 +1168,10 @@ StringLiteral::StringLiteral(const ASTContext &Ctx, StringRef Str, // Initialize the trailing array of SourceLocation. // This is safe since SourceLocation is POD-like. - std::memcpy(getTrailingObjects(), Loc, - NumConcatenated * sizeof(SourceLocation)); + llvm::copy(Locs, getTrailingObjects()); // Initialize the trailing array of char holding the string data. - std::memcpy(getTrailingObjects(), Str.data(), Str.size()); + llvm::copy(Str, getTrailingObjects()); setDependence(ExprDependence::None); } @@ -1188,13 +1186,12 @@ StringLiteral::StringLiteral(EmptyShell Empty, unsigned NumConcatenated, StringLiteral *StringLiteral::Create(const ASTContext &Ctx, StringRef Str, StringLiteralKind Kind, bool Pascal, - QualType Ty, const SourceLocation *Loc, - unsigned NumConcatenated) { + QualType Ty, + ArrayRef Locs) { void *Mem = Ctx.Allocate(totalSizeToAlloc( - 1, NumConcatenated, Str.size()), + 1, Locs.size(), Str.size()), alignof(StringLiteral)); - return new (Mem) - StringLiteral(Ctx, Str, Kind, Pascal, Ty, Loc, NumConcatenated); + return new (Mem) StringLiteral(Ctx, Str, Kind, Pascal, Ty, Locs); } StringLiteral *StringLiteral::CreateEmpty(const ASTContext &Ctx, @@ -4406,7 +4403,7 @@ void ShuffleVectorExpr::setExprs(const ASTContext &C, ArrayRef Exprs) { this->ShuffleVectorExprBits.NumExprs = Exprs.size(); SubExprs = new (C) Stmt *[ShuffleVectorExprBits.NumExprs]; - memcpy(SubExprs, Exprs.data(), sizeof(Expr *) * Exprs.size()); + llvm::copy(Exprs, SubExprs); } GenericSelectionExpr::GenericSelectionExpr( @@ -4591,7 +4588,7 @@ const IdentifierInfo *DesignatedInitExpr::Designator::getFieldName() const { } DesignatedInitExpr::DesignatedInitExpr(const ASTContext &C, QualType Ty, - llvm::ArrayRef Designators, + ArrayRef Designators, SourceLocation EqualOrColonLoc, bool GNUSyntax, ArrayRef IndexExprs, Expr *Init) @@ -4624,12 +4621,12 @@ DesignatedInitExpr::DesignatedInitExpr(const ASTContext &C, QualType Ty, setDependence(computeDependence(this)); } -DesignatedInitExpr * -DesignatedInitExpr::Create(const ASTContext &C, - llvm::ArrayRef Designators, - ArrayRef IndexExprs, - SourceLocation ColonOrEqualLoc, - bool UsesColonSyntax, Expr *Init) { +DesignatedInitExpr *DesignatedInitExpr::Create(const ASTContext &C, + ArrayRef Designators, + ArrayRef IndexExprs, + SourceLocation ColonOrEqualLoc, + bool UsesColonSyntax, + Expr *Init) { void *Mem = C.Allocate(totalSizeToAlloc(IndexExprs.size() + 1), alignof(DesignatedInitExpr)); return new (Mem) DesignatedInitExpr(C, C.VoidTy, Designators, diff --git a/external/llvm-project/clang/lib/AST/ExprCXX.cpp b/external/llvm-project/clang/lib/AST/ExprCXX.cpp index 43b1c39d7379..063eb1738a04 100644 --- a/external/llvm-project/clang/lib/AST/ExprCXX.cpp +++ b/external/llvm-project/clang/lib/AST/ExprCXX.cpp @@ -261,9 +261,8 @@ CXXNewExpr::CXXNewExpr(bool IsGlobalNew, FunctionDecl *OperatorNew, getTrailingObjects()[arraySizeOffset()] = *ArraySize; if (Initializer) getTrailingObjects()[initExprOffset()] = Initializer; - for (unsigned I = 0; I != PlacementArgs.size(); ++I) - getTrailingObjects()[placementNewArgsOffset() + I] = - PlacementArgs[I]; + llvm::copy(PlacementArgs, + getTrailingObjects() + placementNewArgsOffset()); if (IsParenTypeId) getTrailingObjects()[0] = TypeIdParens; @@ -806,8 +805,7 @@ CXXDynamicCastExpr *CXXDynamicCastExpr::Create(const ASTContext &C, QualType T, new (Buffer) CXXDynamicCastExpr(T, VK, K, Op, PathSize, WrittenTy, L, RParenLoc, AngleBrackets); if (PathSize) - llvm::uninitialized_copy(*BasePath, - E->getTrailingObjects()); + llvm::uninitialized_copy(*BasePath, E->getTrailingObjects()); return E; } @@ -869,8 +867,7 @@ CXXReinterpretCastExpr::Create(const ASTContext &C, QualType T, new (Buffer) CXXReinterpretCastExpr(T, VK, K, Op, PathSize, WrittenTy, L, RParenLoc, AngleBrackets); if (PathSize) - llvm::uninitialized_copy(*BasePath, - E->getTrailingObjects()); + llvm::uninitialized_copy(*BasePath, E->getTrailingObjects()); return E; } @@ -1210,10 +1207,8 @@ CXXConstructExpr::CXXConstructExpr( CXXConstructExprBits.Loc = Loc; Stmt **TrailingArgs = getTrailingArgs(); - for (unsigned I = 0, N = Args.size(); I != N; ++I) { - assert(Args[I] && "NULL argument in CXXConstructExpr!"); - TrailingArgs[I] = Args[I]; - } + llvm::copy(Args, TrailingArgs); + assert(llvm::all_of(Args, [](const Stmt *Arg) { return Arg != nullptr; })); // CXXTemporaryObjectExpr does this itself after setting its TypeSourceInfo. if (SC == CXXConstructExprClass) @@ -1474,8 +1469,7 @@ CXXUnresolvedConstructExpr::CXXUnresolvedConstructExpr( RParenLoc(RParenLoc) { CXXUnresolvedConstructExprBits.NumArgs = Args.size(); auto **StoredArgs = getTrailingObjects(); - for (unsigned I = 0; I != Args.size(); ++I) - StoredArgs[I] = Args[I]; + llvm::copy(Args, StoredArgs); setDependence(computeDependence(this)); } @@ -1789,7 +1783,7 @@ SubstNonTypeTemplateParmPackExpr::getParameterPack() const { } TemplateArgument SubstNonTypeTemplateParmPackExpr::getArgumentPack() const { - return TemplateArgument(llvm::ArrayRef(Arguments, NumArguments)); + return TemplateArgument(ArrayRef(Arguments, NumArguments)); } FunctionParmPackExpr::FunctionParmPackExpr(QualType T, ValueDecl *ParamPack, @@ -1887,8 +1881,7 @@ TypeTraitExpr::TypeTraitExpr(QualType T, SourceLocation Loc, TypeTrait Kind, assert(Args.size() == TypeTraitExprBits.NumArgs && "TypeTraitExprBits.NumArgs overflow!"); auto **ToArgs = getTrailingObjects(); - for (unsigned I = 0, N = Args.size(); I != N; ++I) - ToArgs[I] = Args[I]; + llvm::copy(Args, ToArgs); setDependence(computeDependence(this)); diff --git a/external/llvm-project/clang/lib/AST/ExprConcepts.cpp b/external/llvm-project/clang/lib/AST/ExprConcepts.cpp index e6afcdd5dc3e..a2cf431a312a 100644 --- a/external/llvm-project/clang/lib/AST/ExprConcepts.cpp +++ b/external/llvm-project/clang/lib/AST/ExprConcepts.cpp @@ -144,10 +144,8 @@ RequiresExpr::RequiresExpr(ASTContext &C, SourceLocation RequiresKWLoc, if (RequirementContainsError(R)) setDependence(getDependence() | ExprDependence::Error); } - std::copy(LocalParameters.begin(), LocalParameters.end(), - getTrailingObjects()); - std::copy(Requirements.begin(), Requirements.end(), - getTrailingObjects()); + llvm::copy(LocalParameters, getTrailingObjects()); + llvm::copy(Requirements, getTrailingObjects()); RequiresExprBits.IsSatisfied |= Dependent; // FIXME: move the computing dependency logic to ComputeDependence.h if (ContainsUnexpandedParameterPack) diff --git a/external/llvm-project/clang/lib/AST/ExprConstant.cpp b/external/llvm-project/clang/lib/AST/ExprConstant.cpp index f1580255a462..bf9208763b1a 100644 --- a/external/llvm-project/clang/lib/AST/ExprConstant.cpp +++ b/external/llvm-project/clang/lib/AST/ExprConstant.cpp @@ -3977,8 +3977,7 @@ findSubobject(EvalInfo &Info, const Expr *E, const CompleteObject &Obj, if ((ObjType.isConstQualified() || ObjType.isVolatileQualified()) && ObjType->isRecordType() && Info.isEvaluatingCtorDtor( - Obj.Base, - llvm::ArrayRef(Sub.Entries.begin(), Sub.Entries.begin() + I)) != + Obj.Base, ArrayRef(Sub.Entries.begin(), Sub.Entries.begin() + I)) != ConstructionPhase::None) { ObjType = Info.Ctx.getCanonicalType(ObjType); ObjType.removeLocalConst(); @@ -8307,7 +8306,7 @@ class ExprEvaluatorBase const FunctionDecl *FD = nullptr; LValue *This = nullptr, ObjectArg; - auto Args = llvm::ArrayRef(E->getArgs(), E->getNumArgs()); + auto Args = ArrayRef(E->getArgs(), E->getNumArgs()); bool HasQualifier = false; CallRef Call; @@ -10970,7 +10969,7 @@ bool RecordExprEvaluator::VisitCXXConstructExpr(const CXXConstructExpr *E, if (ZeroInit && !ZeroInitialization(E, T)) return false; - auto Args = llvm::ArrayRef(E->getArgs(), E->getNumArgs()); + auto Args = ArrayRef(E->getArgs(), E->getNumArgs()); return HandleConstructorCall(E, This, Args, cast(Definition), Info, Result); @@ -16720,6 +16719,12 @@ static bool EvaluateInPlace(APValue &Result, EvalInfo &Info, const LValue &This, const Expr *E, bool AllowNonLiteralTypes) { assert(!E->isValueDependent()); + // Normally expressions passed to EvaluateInPlace have a type, but not when + // a VarDecl initializer is evaluated before the untyped ParenListExpr is + // replaced with a CXXConstructExpr. This can happen in LLDB. + if (E->getType().isNull()) + return false; + if (!AllowNonLiteralTypes && !CheckLiteralType(Info, E, &This)) return false; diff --git a/external/llvm-project/clang/lib/AST/ExprObjC.cpp b/external/llvm-project/clang/lib/AST/ExprObjC.cpp index 79b5db301d41..3df9c404b5ca 100644 --- a/external/llvm-project/clang/lib/AST/ExprObjC.cpp +++ b/external/llvm-project/clang/lib/AST/ExprObjC.cpp @@ -163,10 +163,8 @@ void ObjCMessageExpr::initArgsAndSelLocs(ArrayRef Args, MyArgs[I] = Args[I]; SelLocsKind = SelLocsK; - if (!isImplicit()) { - if (SelLocsK == SelLoc_NonStandard) - std::copy(SelLocs.begin(), SelLocs.end(), getStoredSelLocs()); - } + if (!isImplicit() && SelLocsK == SelLoc_NonStandard) + llvm::copy(SelLocs, getStoredSelLocs()); } ObjCMessageExpr * diff --git a/external/llvm-project/clang/lib/AST/ExternalASTMerger.cpp b/external/llvm-project/clang/lib/AST/ExternalASTMerger.cpp index 1c903b5104bf..15f8531a3ab0 100644 --- a/external/llvm-project/clang/lib/AST/ExternalASTMerger.cpp +++ b/external/llvm-project/clang/lib/AST/ExternalASTMerger.cpp @@ -239,7 +239,7 @@ class LazyASTImporter : public ASTImporter { ASTImporter &GetReverse() { return Reverse; } }; -bool HasDeclOfSameType(llvm::ArrayRef Decls, const Candidate &C) { +bool HasDeclOfSameType(ArrayRef Decls, const Candidate &C) { if (isa(C.first.get())) return false; return llvm::any_of(Decls, [&](const Candidate &D) { @@ -390,7 +390,8 @@ void ExternalASTMerger::RecordOriginImpl(const DeclContext *ToDC, DCOrigin Origi } ExternalASTMerger::ExternalASTMerger(const ImporterTarget &Target, - llvm::ArrayRef Sources) : LogStream(&llvm::nulls()), Target(Target) { + ArrayRef Sources) + : LogStream(&llvm::nulls()), Target(Target) { SharedState = std::make_shared( *Target.AST.getTranslationUnitDecl()); AddSources(Sources); @@ -404,7 +405,7 @@ Decl *ExternalASTMerger::FindOriginalDecl(Decl *D) { return nullptr; } -void ExternalASTMerger::AddSources(llvm::ArrayRef Sources) { +void ExternalASTMerger::AddSources(ArrayRef Sources) { for (const ImporterSource &S : Sources) { assert(&S.getASTContext() != &Target.AST); // Check that the associated merger actually imports into the source AST. @@ -414,7 +415,7 @@ void ExternalASTMerger::AddSources(llvm::ArrayRef Sources) { } } -void ExternalASTMerger::RemoveSources(llvm::ArrayRef Sources) { +void ExternalASTMerger::RemoveSources(ArrayRef Sources) { if (LoggingEnabled()) for (const ImporterSource &S : Sources) logs() << "(ExternalASTMerger*)" << (void *)this diff --git a/external/llvm-project/clang/lib/AST/ItaniumMangle.cpp b/external/llvm-project/clang/lib/AST/ItaniumMangle.cpp index 487933a748ab..84936b72bb4f 100644 --- a/external/llvm-project/clang/lib/AST/ItaniumMangle.cpp +++ b/external/llvm-project/clang/lib/AST/ItaniumMangle.cpp @@ -6619,7 +6619,7 @@ void CXXNameMangler::mangleValueInTemplateArg(QualType T, const APValue &V, V.getStructField(Fields.back()->getFieldIndex())))) { Fields.pop_back(); } - llvm::ArrayRef Bases(RD->bases_begin(), RD->bases_end()); + ArrayRef Bases(RD->bases_begin(), RD->bases_end()); if (Fields.empty()) { while (!Bases.empty() && isZeroInitialized(Bases.back().getType(), diff --git a/external/llvm-project/clang/lib/AST/OpenACCClause.cpp b/external/llvm-project/clang/lib/AST/OpenACCClause.cpp index 7283ff837b04..60ec10a986e5 100644 --- a/external/llvm-project/clang/lib/AST/OpenACCClause.cpp +++ b/external/llvm-project/clang/lib/AST/OpenACCClause.cpp @@ -109,7 +109,7 @@ OpenACCSelfClause *OpenACCSelfClause::Create(const ASTContext &C, OpenACCSelfClause::OpenACCSelfClause(SourceLocation BeginLoc, SourceLocation LParenLoc, - llvm::ArrayRef VarList, + ArrayRef VarList, SourceLocation EndLoc) : OpenACCClauseWithParams(OpenACCClauseKind::Self, BeginLoc, LParenLoc, EndLoc), diff --git a/external/llvm-project/clang/lib/AST/OpenMPClause.cpp b/external/llvm-project/clang/lib/AST/OpenMPClause.cpp index 0e5052b94416..8b1caa05eec3 100644 --- a/external/llvm-project/clang/lib/AST/OpenMPClause.cpp +++ b/external/llvm-project/clang/lib/AST/OpenMPClause.cpp @@ -370,26 +370,26 @@ OMPOrderedClause *OMPOrderedClause::CreateEmpty(const ASTContext &C, void OMPOrderedClause::setLoopNumIterations(unsigned NumLoop, Expr *NumIterations) { assert(NumLoop < NumberOfLoops && "out of loops number."); - getTrailingObjects()[NumLoop] = NumIterations; + getTrailingObjects()[NumLoop] = NumIterations; } ArrayRef OMPOrderedClause::getLoopNumIterations() const { - return getTrailingObjects(NumberOfLoops); + return getTrailingObjects(NumberOfLoops); } void OMPOrderedClause::setLoopCounter(unsigned NumLoop, Expr *Counter) { assert(NumLoop < NumberOfLoops && "out of loops number."); - getTrailingObjects()[NumberOfLoops + NumLoop] = Counter; + getTrailingObjects()[NumberOfLoops + NumLoop] = Counter; } Expr *OMPOrderedClause::getLoopCounter(unsigned NumLoop) { assert(NumLoop < NumberOfLoops && "out of loops number."); - return getTrailingObjects()[NumberOfLoops + NumLoop]; + return getTrailingObjects()[NumberOfLoops + NumLoop]; } const Expr *OMPOrderedClause::getLoopCounter(unsigned NumLoop) const { assert(NumLoop < NumberOfLoops && "out of loops number."); - return getTrailingObjects()[NumberOfLoops + NumLoop]; + return getTrailingObjects()[NumberOfLoops + NumLoop]; } OMPUpdateClause *OMPUpdateClause::Create(const ASTContext &C, @@ -428,7 +428,7 @@ OMPUpdateClause *OMPUpdateClause::CreateEmpty(const ASTContext &C, void OMPPrivateClause::setPrivateCopies(ArrayRef VL) { assert(VL.size() == varlist_size() && "Number of private copies is not the same as the preallocated buffer"); - std::copy(VL.begin(), VL.end(), varlist_end()); + llvm::copy(VL, varlist_end()); } OMPPrivateClause * @@ -453,13 +453,13 @@ OMPPrivateClause *OMPPrivateClause::CreateEmpty(const ASTContext &C, void OMPFirstprivateClause::setPrivateCopies(ArrayRef VL) { assert(VL.size() == varlist_size() && "Number of private copies is not the same as the preallocated buffer"); - std::copy(VL.begin(), VL.end(), varlist_end()); + llvm::copy(VL, varlist_end()); } void OMPFirstprivateClause::setInits(ArrayRef VL) { assert(VL.size() == varlist_size() && "Number of inits is not the same as the preallocated buffer"); - std::copy(VL.begin(), VL.end(), getPrivateCopies().end()); + llvm::copy(VL, getPrivateCopies().end()); } OMPFirstprivateClause * @@ -486,29 +486,28 @@ OMPFirstprivateClause *OMPFirstprivateClause::CreateEmpty(const ASTContext &C, void OMPLastprivateClause::setPrivateCopies(ArrayRef PrivateCopies) { assert(PrivateCopies.size() == varlist_size() && "Number of private copies is not the same as the preallocated buffer"); - std::copy(PrivateCopies.begin(), PrivateCopies.end(), varlist_end()); + llvm::copy(PrivateCopies, varlist_end()); } void OMPLastprivateClause::setSourceExprs(ArrayRef SrcExprs) { assert(SrcExprs.size() == varlist_size() && "Number of source expressions is " "not the same as the " "preallocated buffer"); - std::copy(SrcExprs.begin(), SrcExprs.end(), getPrivateCopies().end()); + llvm::copy(SrcExprs, getPrivateCopies().end()); } void OMPLastprivateClause::setDestinationExprs(ArrayRef DstExprs) { assert(DstExprs.size() == varlist_size() && "Number of destination " "expressions is not the same as " "the preallocated buffer"); - std::copy(DstExprs.begin(), DstExprs.end(), getSourceExprs().end()); + llvm::copy(DstExprs, getSourceExprs().end()); } void OMPLastprivateClause::setAssignmentOps(ArrayRef AssignmentOps) { assert(AssignmentOps.size() == varlist_size() && "Number of assignment expressions is not the same as the preallocated " "buffer"); - std::copy(AssignmentOps.begin(), AssignmentOps.end(), - getDestinationExprs().end()); + llvm::copy(AssignmentOps, getDestinationExprs().end()); } OMPLastprivateClause *OMPLastprivateClause::Create( @@ -555,32 +554,32 @@ OMPSharedClause *OMPSharedClause::CreateEmpty(const ASTContext &C, unsigned N) { void OMPLinearClause::setPrivates(ArrayRef PL) { assert(PL.size() == varlist_size() && "Number of privates is not the same as the preallocated buffer"); - std::copy(PL.begin(), PL.end(), varlist_end()); + llvm::copy(PL, varlist_end()); } void OMPLinearClause::setInits(ArrayRef IL) { assert(IL.size() == varlist_size() && "Number of inits is not the same as the preallocated buffer"); - std::copy(IL.begin(), IL.end(), getPrivates().end()); + llvm::copy(IL, getPrivates().end()); } void OMPLinearClause::setUpdates(ArrayRef UL) { assert(UL.size() == varlist_size() && "Number of updates is not the same as the preallocated buffer"); - std::copy(UL.begin(), UL.end(), getInits().end()); + llvm::copy(UL, getInits().end()); } void OMPLinearClause::setFinals(ArrayRef FL) { assert(FL.size() == varlist_size() && "Number of final updates is not the same as the preallocated buffer"); - std::copy(FL.begin(), FL.end(), getUpdates().end()); + llvm::copy(FL, getUpdates().end()); } void OMPLinearClause::setUsedExprs(ArrayRef UE) { assert( UE.size() == varlist_size() + 1 && "Number of used expressions is not the same as the preallocated buffer"); - std::copy(UE.begin(), UE.end(), getFinals().end() + 2); + llvm::copy(UE, getFinals().end() + 2); } OMPLinearClause *OMPLinearClause::Create( @@ -659,22 +658,21 @@ void OMPCopyinClause::setSourceExprs(ArrayRef SrcExprs) { assert(SrcExprs.size() == varlist_size() && "Number of source expressions is " "not the same as the " "preallocated buffer"); - std::copy(SrcExprs.begin(), SrcExprs.end(), varlist_end()); + llvm::copy(SrcExprs, varlist_end()); } void OMPCopyinClause::setDestinationExprs(ArrayRef DstExprs) { assert(DstExprs.size() == varlist_size() && "Number of destination " "expressions is not the same as " "the preallocated buffer"); - std::copy(DstExprs.begin(), DstExprs.end(), getSourceExprs().end()); + llvm::copy(DstExprs, getSourceExprs().end()); } void OMPCopyinClause::setAssignmentOps(ArrayRef AssignmentOps) { assert(AssignmentOps.size() == varlist_size() && "Number of assignment expressions is not the same as the preallocated " "buffer"); - std::copy(AssignmentOps.begin(), AssignmentOps.end(), - getDestinationExprs().end()); + llvm::copy(AssignmentOps, getDestinationExprs().end()); } OMPCopyinClause *OMPCopyinClause::Create( @@ -700,22 +698,21 @@ void OMPCopyprivateClause::setSourceExprs(ArrayRef SrcExprs) { assert(SrcExprs.size() == varlist_size() && "Number of source expressions is " "not the same as the " "preallocated buffer"); - std::copy(SrcExprs.begin(), SrcExprs.end(), varlist_end()); + llvm::copy(SrcExprs, varlist_end()); } void OMPCopyprivateClause::setDestinationExprs(ArrayRef DstExprs) { assert(DstExprs.size() == varlist_size() && "Number of destination " "expressions is not the same as " "the preallocated buffer"); - std::copy(DstExprs.begin(), DstExprs.end(), getSourceExprs().end()); + llvm::copy(DstExprs, getSourceExprs().end()); } void OMPCopyprivateClause::setAssignmentOps(ArrayRef AssignmentOps) { assert(AssignmentOps.size() == varlist_size() && "Number of assignment expressions is not the same as the preallocated " "buffer"); - std::copy(AssignmentOps.begin(), AssignmentOps.end(), - getDestinationExprs().end()); + llvm::copy(AssignmentOps, getDestinationExprs().end()); } OMPCopyprivateClause *OMPCopyprivateClause::Create( @@ -741,28 +738,28 @@ OMPCopyprivateClause *OMPCopyprivateClause::CreateEmpty(const ASTContext &C, void OMPReductionClause::setPrivates(ArrayRef Privates) { assert(Privates.size() == varlist_size() && "Number of private copies is not the same as the preallocated buffer"); - std::copy(Privates.begin(), Privates.end(), varlist_end()); + llvm::copy(Privates, varlist_end()); } void OMPReductionClause::setLHSExprs(ArrayRef LHSExprs) { assert( LHSExprs.size() == varlist_size() && "Number of LHS expressions is not the same as the preallocated buffer"); - std::copy(LHSExprs.begin(), LHSExprs.end(), getPrivates().end()); + llvm::copy(LHSExprs, getPrivates().end()); } void OMPReductionClause::setRHSExprs(ArrayRef RHSExprs) { assert( RHSExprs.size() == varlist_size() && "Number of RHS expressions is not the same as the preallocated buffer"); - std::copy(RHSExprs.begin(), RHSExprs.end(), getLHSExprs().end()); + llvm::copy(RHSExprs, getLHSExprs().end()); } void OMPReductionClause::setReductionOps(ArrayRef ReductionOps) { assert(ReductionOps.size() == varlist_size() && "Number of reduction " "expressions is not the same " "as the preallocated buffer"); - std::copy(ReductionOps.begin(), ReductionOps.end(), getRHSExprs().end()); + llvm::copy(ReductionOps, getRHSExprs().end()); } void OMPReductionClause::setInscanCopyOps(ArrayRef Ops) { @@ -843,28 +840,28 @@ OMPReductionClause::CreateEmpty(const ASTContext &C, unsigned N, void OMPTaskReductionClause::setPrivates(ArrayRef Privates) { assert(Privates.size() == varlist_size() && "Number of private copies is not the same as the preallocated buffer"); - std::copy(Privates.begin(), Privates.end(), varlist_end()); + llvm::copy(Privates, varlist_end()); } void OMPTaskReductionClause::setLHSExprs(ArrayRef LHSExprs) { assert( LHSExprs.size() == varlist_size() && "Number of LHS expressions is not the same as the preallocated buffer"); - std::copy(LHSExprs.begin(), LHSExprs.end(), getPrivates().end()); + llvm::copy(LHSExprs, getPrivates().end()); } void OMPTaskReductionClause::setRHSExprs(ArrayRef RHSExprs) { assert( RHSExprs.size() == varlist_size() && "Number of RHS expressions is not the same as the preallocated buffer"); - std::copy(RHSExprs.begin(), RHSExprs.end(), getLHSExprs().end()); + llvm::copy(RHSExprs, getLHSExprs().end()); } void OMPTaskReductionClause::setReductionOps(ArrayRef ReductionOps) { assert(ReductionOps.size() == varlist_size() && "Number of task reduction " "expressions is not the same " "as the preallocated buffer"); - std::copy(ReductionOps.begin(), ReductionOps.end(), getRHSExprs().end()); + llvm::copy(ReductionOps, getRHSExprs().end()); } OMPTaskReductionClause *OMPTaskReductionClause::Create( @@ -896,28 +893,28 @@ OMPTaskReductionClause *OMPTaskReductionClause::CreateEmpty(const ASTContext &C, void OMPInReductionClause::setPrivates(ArrayRef Privates) { assert(Privates.size() == varlist_size() && "Number of private copies is not the same as the preallocated buffer"); - std::copy(Privates.begin(), Privates.end(), varlist_end()); + llvm::copy(Privates, varlist_end()); } void OMPInReductionClause::setLHSExprs(ArrayRef LHSExprs) { assert( LHSExprs.size() == varlist_size() && "Number of LHS expressions is not the same as the preallocated buffer"); - std::copy(LHSExprs.begin(), LHSExprs.end(), getPrivates().end()); + llvm::copy(LHSExprs, getPrivates().end()); } void OMPInReductionClause::setRHSExprs(ArrayRef RHSExprs) { assert( RHSExprs.size() == varlist_size() && "Number of RHS expressions is not the same as the preallocated buffer"); - std::copy(RHSExprs.begin(), RHSExprs.end(), getLHSExprs().end()); + llvm::copy(RHSExprs, getLHSExprs().end()); } void OMPInReductionClause::setReductionOps(ArrayRef ReductionOps) { assert(ReductionOps.size() == varlist_size() && "Number of in reduction " "expressions is not the same " "as the preallocated buffer"); - std::copy(ReductionOps.begin(), ReductionOps.end(), getRHSExprs().end()); + llvm::copy(ReductionOps, getRHSExprs().end()); } void OMPInReductionClause::setTaskgroupDescriptors( @@ -925,8 +922,7 @@ void OMPInReductionClause::setTaskgroupDescriptors( assert(TaskgroupDescriptors.size() == varlist_size() && "Number of in reduction descriptors is not the same as the " "preallocated buffer"); - std::copy(TaskgroupDescriptors.begin(), TaskgroupDescriptors.end(), - getReductionOps().end()); + llvm::copy(TaskgroupDescriptors, getReductionOps().end()); } OMPInReductionClause *OMPInReductionClause::Create( @@ -1322,13 +1318,13 @@ OMPFromClause::CreateEmpty(const ASTContext &C, void OMPUseDevicePtrClause::setPrivateCopies(ArrayRef VL) { assert(VL.size() == varlist_size() && "Number of private copies is not the same as the preallocated buffer"); - std::copy(VL.begin(), VL.end(), varlist_end()); + llvm::copy(VL, varlist_end()); } void OMPUseDevicePtrClause::setInits(ArrayRef VL) { assert(VL.size() == varlist_size() && "Number of inits is not the same as the preallocated buffer"); - std::copy(VL.begin(), VL.end(), getPrivateCopies().end()); + llvm::copy(VL, getPrivateCopies().end()); } OMPUseDevicePtrClause *OMPUseDevicePtrClause::Create( @@ -1543,7 +1539,7 @@ OMPNontemporalClause *OMPNontemporalClause::CreateEmpty(const ASTContext &C, void OMPNontemporalClause::setPrivateRefs(ArrayRef VL) { assert(VL.size() == varlist_size() && "Number of private references is not " "the same as the preallocated buffer"); - std::copy(VL.begin(), VL.end(), varlist_end()); + llvm::copy(VL, varlist_end()); } OMPInclusiveClause *OMPInclusiveClause::Create(const ASTContext &C, @@ -1678,7 +1674,7 @@ OMPInitClause *OMPInitClause::Create(const ASTContext &C, Expr *InteropVar, InteropInfo.IsTarget, InteropInfo.IsTargetSync, StartLoc, LParenLoc, VarLoc, EndLoc, InteropInfo.PreferTypes.size() + 1); Clause->setInteropVar(InteropVar); - llvm::copy(InteropInfo.PreferTypes, Clause->getTrailingObjects() + 1); + llvm::copy(InteropInfo.PreferTypes, Clause->getTrailingObjects() + 1); return Clause; } diff --git a/external/llvm-project/clang/lib/AST/ParentMapContext.cpp b/external/llvm-project/clang/lib/AST/ParentMapContext.cpp index 6337605a0773..68dfe4d5d22c 100644 --- a/external/llvm-project/clang/lib/AST/ParentMapContext.cpp +++ b/external/llvm-project/clang/lib/AST/ParentMapContext.cpp @@ -81,7 +81,8 @@ class ParentMapContext::ParentMap { Items.push_back(Value); } } - llvm::ArrayRef view() const { return Items; } + ArrayRef view() const { return Items; } + private: llvm::SmallVector Items; llvm::SmallPtrSet Dedup; @@ -120,7 +121,7 @@ class ParentMapContext::ParentMap { const MapTy &Map) { auto I = Map.find(Node); if (I == Map.end()) { - return llvm::ArrayRef(); + return ArrayRef(); } if (const auto *V = dyn_cast(I->second)) { return V->view(); diff --git a/external/llvm-project/clang/lib/AST/QualTypeNames.cpp b/external/llvm-project/clang/lib/AST/QualTypeNames.cpp index 4d11a3b62331..39703d6d7b88 100644 --- a/external/llvm-project/clang/lib/AST/QualTypeNames.cpp +++ b/external/llvm-project/clang/lib/AST/QualTypeNames.cpp @@ -140,7 +140,7 @@ static const Type *getFullyQualifiedTemplateType(const ASTContext &Ctx, if (MightHaveChanged) { QualType QT = Ctx.getTemplateSpecializationType( TST->getTemplateName(), FQArgs, - /*CanonicalArgs=*/std::nullopt, TST->desugar()); + /*CanonicalArgs=*/{}, TST->desugar()); // getTemplateSpecializationType returns a fully qualified // version of the specialization itself, so no need to qualify // it. @@ -172,8 +172,7 @@ static const Type *getFullyQualifiedTemplateType(const ASTContext &Ctx, TemplateName TN(TSTDecl->getSpecializedTemplate()); QualType QT = Ctx.getTemplateSpecializationType( TN, FQArgs, - /*CanonicalArgs=*/std::nullopt, - TSTRecord->getCanonicalTypeInternal()); + /*CanonicalArgs=*/{}, TSTRecord->getCanonicalTypeInternal()); // getTemplateSpecializationType returns a fully qualified // version of the specialization itself, so no need to qualify // it. diff --git a/external/llvm-project/clang/lib/AST/Stmt.cpp b/external/llvm-project/clang/lib/AST/Stmt.cpp index 0b0289cd5ec0..4fc4a99ad240 100644 --- a/external/llvm-project/clang/lib/AST/Stmt.cpp +++ b/external/llvm-project/clang/lib/AST/Stmt.cpp @@ -384,8 +384,7 @@ CompoundStmt::CompoundStmt(ArrayRef Stmts, FPOptionsOverride FPFeatures, void CompoundStmt::setStmts(ArrayRef Stmts) { assert(CompoundStmtBits.NumStmts == Stmts.size() && "NumStmts doesn't fit in bits of CompoundStmtBits.NumStmts!"); - - std::copy(Stmts.begin(), Stmts.end(), body_begin()); + llvm::copy(Stmts, body_begin()); } CompoundStmt *CompoundStmt::Create(const ASTContext &C, ArrayRef Stmts, @@ -947,10 +946,10 @@ void MSAsmStmt::initialize(const ASTContext &C, StringRef asmstr, AsmStr = copyIntoContext(C, asmstr); Exprs = new (C) Stmt*[exprs.size()]; - std::copy(exprs.begin(), exprs.end(), Exprs); + llvm::copy(exprs, Exprs); AsmToks = new (C) Token[asmtoks.size()]; - std::copy(asmtoks.begin(), asmtoks.end(), AsmToks); + llvm::copy(asmtoks, AsmToks); Constraints = new (C) StringRef[exprs.size()]; std::transform(constraints.begin(), constraints.end(), Constraints, @@ -1385,7 +1384,7 @@ CapturedStmt::CapturedStmt(Stmt *S, CapturedRegionKind Kind, // Copy all Capture objects. Capture *Buffer = getStoredCaptures(); - std::copy(Captures.begin(), Captures.end(), Buffer); + llvm::copy(Captures, Buffer); } CapturedStmt::CapturedStmt(EmptyShell Empty, unsigned NumCaptures) diff --git a/external/llvm-project/clang/lib/AST/StmtCXX.cpp b/external/llvm-project/clang/lib/AST/StmtCXX.cpp index 0d6fc848f739..6a69fe75136f 100644 --- a/external/llvm-project/clang/lib/AST/StmtCXX.cpp +++ b/external/llvm-project/clang/lib/AST/StmtCXX.cpp @@ -42,7 +42,7 @@ CXXTryStmt::CXXTryStmt(SourceLocation tryLoc, CompoundStmt *tryBlock, : Stmt(CXXTryStmtClass), TryLoc(tryLoc), NumHandlers(handlers.size()) { Stmt **Stmts = getStmts(); Stmts[0] = tryBlock; - std::copy(handlers.begin(), handlers.end(), Stmts + 1); + llvm::copy(handlers, Stmts + 1); } CXXForRangeStmt::CXXForRangeStmt(Stmt *Init, DeclStmt *Range, @@ -123,6 +123,5 @@ CoroutineBodyStmt::CoroutineBodyStmt(CoroutineBodyStmt::CtorArgs const &Args) SubStmts[CoroutineBodyStmt::ReturnStmt] = Args.ReturnStmt; SubStmts[CoroutineBodyStmt::ReturnStmtOnAllocFailure] = Args.ReturnStmtOnAllocFailure; - std::copy(Args.ParamMoves.begin(), Args.ParamMoves.end(), - const_cast(getParamMoves().data())); + llvm::copy(Args.ParamMoves, const_cast(getParamMoves().data())); } diff --git a/external/llvm-project/clang/lib/AST/StmtOpenMP.cpp b/external/llvm-project/clang/lib/AST/StmtOpenMP.cpp index f6f37388fc1d..fbc37f06e6b9 100644 --- a/external/llvm-project/clang/lib/AST/StmtOpenMP.cpp +++ b/external/llvm-project/clang/lib/AST/StmtOpenMP.cpp @@ -471,18 +471,21 @@ OMPUnrollDirective *OMPUnrollDirective::CreateEmpty(const ASTContext &C, OMPReverseDirective * OMPReverseDirective::Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, Stmt *AssociatedStmt, - Stmt *TransformedStmt, Stmt *PreInits) { + unsigned NumLoops, Stmt *TransformedStmt, + Stmt *PreInits) { OMPReverseDirective *Dir = createDirective( - C, {}, AssociatedStmt, TransformedStmtOffset + 1, StartLoc, EndLoc); + C, {}, AssociatedStmt, TransformedStmtOffset + 1, StartLoc, EndLoc, + NumLoops); Dir->setTransformedStmt(TransformedStmt); Dir->setPreInits(PreInits); return Dir; } -OMPReverseDirective *OMPReverseDirective::CreateEmpty(const ASTContext &C) { +OMPReverseDirective *OMPReverseDirective::CreateEmpty(const ASTContext &C, + unsigned NumLoops) { return createEmptyDirective( C, /*NumClauses=*/0, /*HasAssociatedStmt=*/true, - TransformedStmtOffset + 1, SourceLocation(), SourceLocation()); + TransformedStmtOffset + 1, SourceLocation(), SourceLocation(), NumLoops); } OMPInterchangeDirective *OMPInterchangeDirective::Create( diff --git a/external/llvm-project/clang/lib/AST/StmtPrinter.cpp b/external/llvm-project/clang/lib/AST/StmtPrinter.cpp index 28317911d825..f8ec3f65b7eb 100644 --- a/external/llvm-project/clang/lib/AST/StmtPrinter.cpp +++ b/external/llvm-project/clang/lib/AST/StmtPrinter.cpp @@ -298,7 +298,7 @@ void StmtPrinter::VisitLabelStmt(LabelStmt *Node) { } void StmtPrinter::VisitAttributedStmt(AttributedStmt *Node) { - llvm::ArrayRef Attrs = Node->getAttrs(); + ArrayRef Attrs = Node->getAttrs(); for (const auto *Attr : Attrs) { Attr->printPretty(OS, Policy); if (Attr != Attrs.back()) diff --git a/external/llvm-project/clang/lib/AST/StmtProfile.cpp b/external/llvm-project/clang/lib/AST/StmtProfile.cpp index c666d966a6e5..c61450e19f1b 100644 --- a/external/llvm-project/clang/lib/AST/StmtProfile.cpp +++ b/external/llvm-project/clang/lib/AST/StmtProfile.cpp @@ -2189,8 +2189,14 @@ StmtProfiler::VisitCXXPseudoDestructorExpr(const CXXPseudoDestructorExpr *S) { void StmtProfiler::VisitOverloadExpr(const OverloadExpr *S) { VisitExpr(S); - VisitNestedNameSpecifier(S->getQualifier()); - VisitName(S->getName(), /*TreatAsDecl*/ true); + bool DescribingDependentVarTemplate = + S->getNumDecls() == 1 && isa(*S->decls_begin()); + if (DescribingDependentVarTemplate) { + VisitDecl(*S->decls_begin()); + } else { + VisitNestedNameSpecifier(S->getQualifier()); + VisitName(S->getName(), /*TreatAsDecl*/ true); + } ID.AddBoolean(S->hasExplicitTemplateArgs()); if (S->hasExplicitTemplateArgs()) VisitTemplateArguments(S->getTemplateArgs(), S->getNumTemplateArgs()); diff --git a/external/llvm-project/clang/lib/AST/TemplateName.cpp b/external/llvm-project/clang/lib/AST/TemplateName.cpp index c5861ba33f85..5b7abc4d038a 100644 --- a/external/llvm-project/clang/lib/AST/TemplateName.cpp +++ b/external/llvm-project/clang/lib/AST/TemplateName.cpp @@ -59,7 +59,7 @@ void DeducedTemplateStorage::Profile(llvm::FoldingSetNodeID &ID, TemplateArgument SubstTemplateTemplateParmPackStorage::getArgumentPack() const { - return TemplateArgument(llvm::ArrayRef(Arguments, Bits.Data)); + return TemplateArgument(ArrayRef(Arguments, Bits.Data)); } TemplateTemplateParmDecl * diff --git a/external/llvm-project/clang/lib/AST/Type.cpp b/external/llvm-project/clang/lib/AST/Type.cpp index a461dbde4093..2c1158e8f9b9 100644 --- a/external/llvm-project/clang/lib/AST/Type.cpp +++ b/external/llvm-project/clang/lib/AST/Type.cpp @@ -3981,10 +3981,9 @@ CountAttributedType::CountAttributedType( CountAttributedTypeBits.NumCoupledDecls = CoupledDecls.size(); CountAttributedTypeBits.CountInBytes = CountInBytes; CountAttributedTypeBits.OrNull = OrNull; - auto *DeclSlot = getTrailingObjects(); + auto *DeclSlot = getTrailingObjects(); + llvm::copy(CoupledDecls, DeclSlot); Decls = llvm::ArrayRef(DeclSlot, CoupledDecls.size()); - for (unsigned i = 0; i != CoupledDecls.size(); ++i) - DeclSlot[i] = CoupledDecls[i]; } StringRef CountAttributedType::getAttributeName(bool WithMacroPrefix) const { diff --git a/external/llvm-project/clang/lib/Basic/OffloadArch.cpp b/external/llvm-project/clang/lib/Basic/OffloadArch.cpp index a019f0ac18c8..dce9ffaedb90 100644 --- a/external/llvm-project/clang/lib/Basic/OffloadArch.cpp +++ b/external/llvm-project/clang/lib/Basic/OffloadArch.cpp @@ -86,6 +86,7 @@ static const OffloadArchToStringMap ArchNames[] = { {OffloadArch::GFX12_GENERIC, "gfx12-generic", "compute_amdgcn"}, GFX(1200), // gfx1200 GFX(1201), // gfx1201 + GFX(1250), // gfx1250 {OffloadArch::AMDGCNSPIRV, "amdgcnspirv", "compute_amdgcn"}, // Intel CPUs {OffloadArch::GRANITERAPIDS, "graniterapids", ""}, diff --git a/external/llvm-project/clang/lib/Basic/Targets.cpp b/external/llvm-project/clang/lib/Basic/Targets.cpp index 9889141ad208..af1111a86330 100644 --- a/external/llvm-project/clang/lib/Basic/Targets.cpp +++ b/external/llvm-project/clang/lib/Basic/Targets.cpp @@ -164,6 +164,9 @@ std::unique_ptr AllocateTarget(const llvm::Triple &Triple, return std::make_unique>(Triple, Opts); } + case llvm::Triple::Managarm: + return std::make_unique>(Triple, + Opts); case llvm::Triple::NetBSD: return std::make_unique>(Triple, Opts); @@ -466,6 +469,9 @@ std::unique_ptr AllocateTarget(const llvm::Triple &Triple, return std::make_unique>(Triple, Opts); } + case llvm::Triple::Managarm: + return std::make_unique>(Triple, + Opts); default: return std::make_unique(Triple, Opts); } @@ -654,6 +660,9 @@ std::unique_ptr AllocateTarget(const llvm::Triple &Triple, return std::make_unique>(Triple, Opts); case llvm::Triple::Hurd: return std::make_unique>(Triple, Opts); + case llvm::Triple::Managarm: + return std::make_unique>(Triple, + Opts); default: return std::make_unique(Triple, Opts); } diff --git a/external/llvm-project/clang/lib/Basic/Targets/NVPTX.cpp b/external/llvm-project/clang/lib/Basic/Targets/NVPTX.cpp index 3235bf2e710d..54b39fd072a8 100644 --- a/external/llvm-project/clang/lib/Basic/Targets/NVPTX.cpp +++ b/external/llvm-project/clang/lib/Basic/Targets/NVPTX.cpp @@ -238,6 +238,7 @@ void NVPTXTargetInfo::getTargetDefines(const LangOptions &Opts, case OffloadArch::GFX12_GENERIC: case OffloadArch::GFX1200: case OffloadArch::GFX1201: + case OffloadArch::GFX1250: case OffloadArch::AMDGCNSPIRV: case OffloadArch::Generic: case OffloadArch::GRANITERAPIDS: diff --git a/external/llvm-project/clang/lib/Basic/Targets/OSTargets.h b/external/llvm-project/clang/lib/Basic/Targets/OSTargets.h index d148b38d03c7..5dac699c2bb4 100644 --- a/external/llvm-project/clang/lib/Basic/Targets/OSTargets.h +++ b/external/llvm-project/clang/lib/Basic/Targets/OSTargets.h @@ -395,6 +395,36 @@ class LLVM_LIBRARY_VISIBILITY LinuxTargetInfo : public OSTargetInfo { } }; +// Managarm Target +template +class LLVM_LIBRARY_VISIBILITY ManagarmTargetInfo : public OSTargetInfo { +protected: + void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple, + MacroBuilder &Builder) const override { + DefineStd(Builder, "unix", Opts); + Builder.defineMacro("__managarm__"); + if (Opts.POSIXThreads) + Builder.defineMacro("_REENTRANT"); + if (Opts.CPlusPlus) + Builder.defineMacro("_GNU_SOURCE"); + if (this->HasFloat128) + Builder.defineMacro("__FLOAT128__"); + } + +public: + ManagarmTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts) + : OSTargetInfo(Triple, Opts) { + switch (Triple.getArch()) { + default: + break; + case llvm::Triple::x86: + case llvm::Triple::x86_64: + this->HasFloat128 = true; + break; + } + } +}; + // NetBSD Target template class LLVM_LIBRARY_VISIBILITY NetBSDTargetInfo : public OSTargetInfo { diff --git a/external/llvm-project/clang/lib/Basic/Targets/PPC.cpp b/external/llvm-project/clang/lib/Basic/Targets/PPC.cpp index e6ef0ecc526b..77145e2891a8 100644 --- a/external/llvm-project/clang/lib/Basic/Targets/PPC.cpp +++ b/external/llvm-project/clang/lib/Basic/Targets/PPC.cpp @@ -15,6 +15,7 @@ #include "clang/Basic/MacroBuilder.h" #include "clang/Basic/TargetBuiltins.h" #include "llvm/TargetParser/PPCTargetParser.h" +#include using namespace clang; using namespace clang::targets; @@ -516,129 +517,14 @@ static bool ppcUserFeaturesCheck(DiagnosticsEngine &Diags, bool PPCTargetInfo::initFeatureMap( llvm::StringMap &Features, DiagnosticsEngine &Diags, StringRef CPU, const std::vector &FeaturesVec) const { - Features["altivec"] = llvm::StringSwitch(CPU) - .Case("7400", true) - .Case("g4", true) - .Case("7450", true) - .Case("g4+", true) - .Case("970", true) - .Case("g5", true) - .Case("pwr6", true) - .Case("pwr7", true) - .Case("pwr8", true) - .Case("pwr9", true) - .Case("ppc64", true) - .Case("ppc64le", true) - .Default(false); - - Features["power9-vector"] = (CPU == "pwr9"); - Features["crypto"] = llvm::StringSwitch(CPU) - .Case("ppc64le", true) - .Case("pwr9", true) - .Case("pwr8", true) - .Default(false); - Features["power8-vector"] = llvm::StringSwitch(CPU) - .Case("ppc64le", true) - .Case("pwr9", true) - .Case("pwr8", true) - .Default(false); - Features["bpermd"] = llvm::StringSwitch(CPU) - .Case("ppc64le", true) - .Case("pwr9", true) - .Case("pwr8", true) - .Case("pwr7", true) - .Default(false); - Features["extdiv"] = llvm::StringSwitch(CPU) - .Case("ppc64le", true) - .Case("pwr9", true) - .Case("pwr8", true) - .Case("pwr7", true) - .Default(false); - Features["direct-move"] = llvm::StringSwitch(CPU) - .Case("ppc64le", true) - .Case("pwr9", true) - .Case("pwr8", true) - .Default(false); - Features["crbits"] = llvm::StringSwitch(CPU) - .Case("ppc64le", true) - .Case("pwr9", true) - .Case("pwr8", true) - .Default(false); - Features["vsx"] = llvm::StringSwitch(CPU) - .Case("ppc64le", true) - .Case("pwr9", true) - .Case("pwr8", true) - .Case("pwr7", true) - .Default(false); - Features["htm"] = llvm::StringSwitch(CPU) - .Case("ppc64le", true) - .Case("pwr9", true) - .Case("pwr8", true) - .Default(false); - - // ROP Protect is off by default. - Features["rop-protect"] = false; - // Privileged instructions are off by default. - Features["privileged"] = false; - if (getTriple().isOSAIX()) { - // The code generated by the -maix-small-local-[exec|dynamic]-tls option is - // turned off by default. - Features["aix-small-local-exec-tls"] = false; - Features["aix-small-local-dynamic-tls"] = false; - - // Turn off TLS model opt by default. - Features["aix-shared-lib-tls-model-opt"] = false; - } - - Features["spe"] = llvm::StringSwitch(CPU) - .Case("8548", true) - .Case("e500", true) - .Default(false); - - Features["isa-v206-instructions"] = llvm::StringSwitch(CPU) - .Case("ppc64le", true) - .Case("pwr9", true) - .Case("pwr8", true) - .Case("pwr7", true) - .Case("a2", true) - .Default(false); - - Features["isa-v207-instructions"] = llvm::StringSwitch(CPU) - .Case("ppc64le", true) - .Case("pwr9", true) - .Case("pwr8", true) - .Default(false); - - Features["isa-v30-instructions"] = - llvm::StringSwitch(CPU).Case("pwr9", true).Default(false); - - Features["quadword-atomics"] = - getTriple().isArch64Bit() && llvm::StringSwitch(CPU) - .Case("pwr9", true) - .Case("pwr8", true) - .Default(false); - - // Power10 includes all the same features as Power9 plus any features specific - // to the Power10 core. - if (CPU == "pwr10" || CPU == "power10") { - initFeatureMap(Features, Diags, "pwr9", FeaturesVec); - addP10SpecificFeatures(Features); - } - - // Power11 includes all the same features as Power10 plus any features - // specific to the Power11 core. - if (CPU == "pwr11" || CPU == "power11") { - initFeatureMap(Features, Diags, "pwr10", FeaturesVec); - addP11SpecificFeatures(Features); - } + const llvm::Triple &TheTriple = getTriple(); - // Future CPU should include all of the features of Power 11 as well as any - // additional features (yet to be determined) specific to it. - if (CPU == "future") { - initFeatureMap(Features, Diags, "pwr11", FeaturesVec); - addFutureSpecificFeatures(Features); - } + std::optional> FeaturesOpt = + llvm::PPC::getPPCDefaultTargetFeatures(TheTriple, + llvm::PPC::normalizeCPUName(CPU)); + if (FeaturesOpt) + Features = FeaturesOpt.value(); if (!ppcUserFeaturesCheck(Diags, FeaturesVec)) return false; @@ -700,26 +586,6 @@ bool PPCTargetInfo::initFeatureMap( return TargetInfo::initFeatureMap(Features, Diags, CPU, FeaturesVec); } -// Add any Power10 specific features. -void PPCTargetInfo::addP10SpecificFeatures( - llvm::StringMap &Features) const { - Features["htm"] = false; // HTM was removed for P10. - Features["paired-vector-memops"] = true; - Features["mma"] = true; - Features["power10-vector"] = true; - Features["pcrelative-memops"] = true; - Features["prefix-instrs"] = true; - Features["isa-v31-instructions"] = true; -} - -// Add any Power11 specific features. -void PPCTargetInfo::addP11SpecificFeatures( - llvm::StringMap &Features) const {} - -// Add features specific to the "Future" CPU. -void PPCTargetInfo::addFutureSpecificFeatures( - llvm::StringMap &Features) const {} - bool PPCTargetInfo::hasFeature(StringRef Feature) const { return llvm::StringSwitch(Feature) .Case("powerpc", true) diff --git a/external/llvm-project/clang/lib/Basic/Targets/Xtensa.h b/external/llvm-project/clang/lib/Basic/Targets/Xtensa.h index 470835aacff5..f3558ac247be 100644 --- a/external/llvm-project/clang/lib/Basic/Targets/Xtensa.h +++ b/external/llvm-project/clang/lib/Basic/Targets/Xtensa.h @@ -77,7 +77,7 @@ class LLVM_LIBRARY_VISIBILITY XtensaTargetInfo : public TargetInfo { } ArrayRef getGCCRegAliases() const override { - return std::nullopt; + return {}; } bool validateAsmConstraint(const char *&Name, diff --git a/external/llvm-project/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp b/external/llvm-project/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp index c59ac78210f8..cff139a7802d 100644 --- a/external/llvm-project/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp +++ b/external/llvm-project/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp @@ -12,6 +12,7 @@ //===----------------------------------------------------------------------===// #include "CIRGenCall.h" +#include "CIRGenConstantEmitter.h" #include "CIRGenFunction.h" #include "CIRGenModule.h" #include "CIRGenValue.h" @@ -20,10 +21,18 @@ #include "mlir/Support/LLVM.h" #include "clang/AST/Expr.h" #include "clang/AST/GlobalDecl.h" +#include "clang/CIR/MissingFeatures.h" #include "llvm/Support/ErrorHandling.h" using namespace clang; using namespace clang::CIRGen; +using namespace llvm; + +static RValue emitLibraryCall(CIRGenFunction &cgf, const FunctionDecl *fd, + const CallExpr *e, mlir::Operation *calleeValue) { + CIRGenCallee callee = CIRGenCallee::forDirect(calleeValue, GlobalDecl(fd)); + return cgf.emitCall(e->getCallee()->getType(), callee, e, ReturnValueSlot()); +} RValue CIRGenFunction::emitBuiltinExpr(const GlobalDecl &gd, unsigned builtinID, const CallExpr *e, @@ -49,7 +58,80 @@ RValue CIRGenFunction::emitBuiltinExpr(const GlobalDecl &gd, unsigned builtinID, } } + const FunctionDecl *fd = gd.getDecl()->getAsFunction(); + + // If this is an alias for a lib function (e.g. __builtin_sin), emit + // the call using the normal call path, but using the unmangled + // version of the function name. + if (getContext().BuiltinInfo.isLibFunction(builtinID)) + return emitLibraryCall(*this, fd, e, + cgm.getBuiltinLibFunction(fd, builtinID)); + + assert(!cir::MissingFeatures::builtinCallF128()); + + // If the builtin has been declared explicitly with an assembler label, + // disable the specialized emitting below. Ideally we should communicate the + // rename in IR, or at least avoid generating the intrinsic calls that are + // likely to get lowered to the renamed library functions. + unsigned builtinIDIfNoAsmLabel = fd->hasAttr() ? 0 : builtinID; + + assert(!cir::MissingFeatures::builtinCallMathErrno()); + assert(!cir::MissingFeatures::builtinCall()); + mlir::Location loc = getLoc(e->getExprLoc()); - cgm.errorNYI(loc, "non constant foldable builtin calls"); + + switch (builtinIDIfNoAsmLabel) { + default: + break; + + case Builtin::BI__assume: + case Builtin::BI__builtin_assume: { + if (e->getArg(0)->HasSideEffects(getContext())) + return RValue::get(nullptr); + + mlir::Value argValue = emitCheckedArgForAssume(e->getArg(0)); + builder.create(loc, argValue); + return RValue::get(nullptr); + } + + case Builtin::BI__builtin_complex: { + mlir::Value real = emitScalarExpr(e->getArg(0)); + mlir::Value imag = emitScalarExpr(e->getArg(1)); + mlir::Value complex = builder.createComplexCreate(loc, real, imag); + return RValue::get(complex); + } + } + + cgm.errorNYI(e->getSourceRange(), "unimplemented builtin call"); return getUndefRValue(e->getType()); } + +/// Given a builtin id for a function like "__builtin_fabsf", return a Function* +/// for "fabsf". +cir::FuncOp CIRGenModule::getBuiltinLibFunction(const FunctionDecl *fd, + unsigned builtinID) { + assert(astContext.BuiltinInfo.isLibFunction(builtinID)); + + // Get the name, skip over the __builtin_ prefix (if necessary). We may have + // to build this up so provide a small stack buffer to handle the vast + // majority of names. + llvm::SmallString<64> name; + + assert(!cir::MissingFeatures::asmLabelAttr()); + name = astContext.BuiltinInfo.getName(builtinID).substr(10); + + GlobalDecl d(fd); + mlir::Type type = convertType(fd->getType()); + return getOrCreateCIRFunction(name, type, d, /*forVTable=*/false); +} + +mlir::Value CIRGenFunction::emitCheckedArgForAssume(const Expr *e) { + mlir::Value argValue = evaluateExprAsBool(e); + if (!sanOpts.has(SanitizerKind::Builtin)) + return argValue; + + assert(!cir::MissingFeatures::sanitizers()); + cgm.errorNYI(e->getSourceRange(), + "emitCheckedArgForAssume: sanitizers are NYI"); + return {}; +} diff --git a/external/llvm-project/clang/lib/CIR/CodeGen/CIRGenCall.cpp b/external/llvm-project/clang/lib/CIR/CodeGen/CIRGenCall.cpp index 0d9064425fa9..9c9c96604c16 100644 --- a/external/llvm-project/clang/lib/CIR/CodeGen/CIRGenCall.cpp +++ b/external/llvm-project/clang/lib/CIR/CodeGen/CIRGenCall.cpp @@ -77,6 +77,35 @@ void CIRGenFunction::emitAggregateStore(mlir::Value value, Address dest) { builder.createStore(*currSrcLoc, value, dest); } +/// Construct the CIR attribute list of a function or call. +void CIRGenModule::constructAttributeList(CIRGenCalleeInfo calleeInfo, + cir::SideEffect &sideEffect) { + assert(!cir::MissingFeatures::opCallCallConv()); + sideEffect = cir::SideEffect::All; + + assert(!cir::MissingFeatures::opCallAttrs()); + + const Decl *targetDecl = calleeInfo.getCalleeDecl().getDecl(); + + if (targetDecl) { + assert(!cir::MissingFeatures::opCallAttrs()); + + // 'const', 'pure' and 'noalias' attributed functions are also nounwind. + if (targetDecl->hasAttr()) { + // gcc specifies that 'const' functions have greater restrictions than + // 'pure' functions, so they also cannot have infinite loops. + sideEffect = cir::SideEffect::Const; + } else if (targetDecl->hasAttr()) { + // gcc specifies that 'pure' functions cannot have infinite loops. + sideEffect = cir::SideEffect::Pure; + } + + assert(!cir::MissingFeatures::opCallAttrs()); + } + + assert(!cir::MissingFeatures::opCallAttrs()); +} + /// Returns the canonical formal type of the given C++ method. static CanQual getFormalType(const CXXMethodDecl *md) { return md->getType() @@ -386,7 +415,8 @@ static cir::CIRCallOpInterface emitCallLikeOp(CIRGenFunction &cgf, mlir::Location callLoc, cir::FuncType indirectFuncTy, mlir::Value indirectFuncVal, cir::FuncOp directFuncOp, - const SmallVectorImpl &cirCallArgs) { + const SmallVectorImpl &cirCallArgs, + cir::SideEffect sideEffect) { CIRGenBuilderTy &builder = cgf.getBuilder(); assert(!cir::MissingFeatures::opCallSurroundingTry()); @@ -397,11 +427,11 @@ emitCallLikeOp(CIRGenFunction &cgf, mlir::Location callLoc, if (indirectFuncTy) { // TODO(cir): Set calling convention for indirect calls. assert(!cir::MissingFeatures::opCallCallConv()); - return builder.createIndirectCallOp(callLoc, indirectFuncVal, - indirectFuncTy, cirCallArgs); + return builder.createIndirectCallOp( + callLoc, indirectFuncVal, indirectFuncTy, cirCallArgs, sideEffect); } - return builder.createCallOp(callLoc, directFuncOp, cirCallArgs); + return builder.createCallOp(callLoc, directFuncOp, cirCallArgs, sideEffect); } const CIRGenFunctionInfo & @@ -443,7 +473,7 @@ RValue CIRGenFunction::emitCall(const CIRGenFunctionInfo &funcInfo, mlir::Value v; if (arg.isAggregate()) cgm.errorNYI(loc, "emitCall: aggregate call argument"); - v = arg.getKnownRValue().getScalarVal(); + v = arg.getKnownRValue().getValue(); // We might have to widen integers, but we should never truncate. if (argType != v.getType() && mlir::isa(v.getType())) @@ -513,8 +543,9 @@ RValue CIRGenFunction::emitCall(const CIRGenFunctionInfo &funcInfo, funcName = calleeFuncOp.getName(); assert(!cir::MissingFeatures::opCallCallConv()); - assert(!cir::MissingFeatures::opCallSideEffect()); assert(!cir::MissingFeatures::opCallAttrs()); + cir::SideEffect sideEffect; + cgm.constructAttributeList(callee.getAbstractInfo(), sideEffect); assert(!cir::MissingFeatures::invokeOp()); @@ -538,8 +569,9 @@ RValue CIRGenFunction::emitCall(const CIRGenFunctionInfo &funcInfo, assert(!cir::MissingFeatures::opCallAttrs()); mlir::Location callLoc = loc; - cir::CIRCallOpInterface theCall = emitCallLikeOp( - *this, loc, indirectFuncTy, indirectFuncVal, directFuncOp, cirCallArgs); + cir::CIRCallOpInterface theCall = + emitCallLikeOp(*this, loc, indirectFuncTy, indirectFuncVal, directFuncOp, + cirCallArgs, sideEffect); if (callOp) *callOp = theCall; diff --git a/external/llvm-project/clang/lib/CIR/CodeGen/CIRGenCall.h b/external/llvm-project/clang/lib/CIR/CodeGen/CIRGenCall.h index 0353848f3ec0..56c76c51a46d 100644 --- a/external/llvm-project/clang/lib/CIR/CodeGen/CIRGenCall.h +++ b/external/llvm-project/clang/lib/CIR/CodeGen/CIRGenCall.h @@ -105,6 +105,12 @@ class CIRGenCallee { /// callee CIRGenCallee prepareConcreteCallee(CIRGenFunction &cgf) const; + CIRGenCalleeInfo getAbstractInfo() const { + assert(!cir::MissingFeatures::opCallVirtual()); + assert(isOrdinary()); + return abstractInfo; + } + mlir::Operation *getFunctionPointer() const { assert(isOrdinary()); return reinterpret_cast(kindOrFunctionPtr); diff --git a/external/llvm-project/clang/lib/CIR/CodeGen/CIRGenExpr.cpp b/external/llvm-project/clang/lib/CIR/CodeGen/CIRGenExpr.cpp index 2e43f10be132..c31754dc11d6 100644 --- a/external/llvm-project/clang/lib/CIR/CodeGen/CIRGenExpr.cpp +++ b/external/llvm-project/clang/lib/CIR/CodeGen/CIRGenExpr.cpp @@ -219,7 +219,7 @@ void CIRGenFunction::emitStoreThroughLValue(RValue src, LValue dst, const mlir::Value vector = builder.createLoad(loc, dst.getVectorAddress()); const mlir::Value newVector = builder.create( - loc, vector, src.getScalarVal(), dst.getVectorIdx()); + loc, vector, src.getValue(), dst.getVectorIdx()); builder.createStore(loc, newVector, dst.getVectorAddress()); return; } @@ -232,7 +232,7 @@ void CIRGenFunction::emitStoreThroughLValue(RValue src, LValue dst, assert(!cir::MissingFeatures::opLoadStoreObjC()); assert(src.isScalar() && "Can't emit an aggregate store with this method"); - emitStoreOfScalar(src.getScalarVal(), dst, isInit); + emitStoreOfScalar(src.getValue(), dst, isInit); } static LValue emitGlobalVarDeclLValue(CIRGenFunction &cgf, const Expr *e, @@ -949,7 +949,7 @@ LValue CIRGenFunction::emitCallExprLValue(const CallExpr *e) { "Can't have a scalar return unless the return type is a " "reference type!"); - return makeNaturalAlignPointeeAddrLValue(rv.getScalarVal(), e->getType()); + return makeNaturalAlignPointeeAddrLValue(rv.getValue(), e->getType()); } LValue CIRGenFunction::emitBinaryOperatorLValue(const BinaryOperator *e) { @@ -997,10 +997,9 @@ LValue CIRGenFunction::emitBinaryOperatorLValue(const BinaryOperator *e) { } case cir::TEK_Complex: { - assert(!cir::MissingFeatures::complexType()); - cgm.errorNYI(e->getSourceRange(), "complex l-values"); - return {}; + return emitComplexAssignmentLValue(e); } + case cir::TEK_Aggregate: cgm.errorNYI(e->getSourceRange(), "aggregate lvalues"); return {}; diff --git a/external/llvm-project/clang/lib/CIR/CodeGen/CIRGenExprComplex.cpp b/external/llvm-project/clang/lib/CIR/CodeGen/CIRGenExprComplex.cpp index 2ffe75a388e9..eaa199abc165 100644 --- a/external/llvm-project/clang/lib/CIR/CodeGen/CIRGenExprComplex.cpp +++ b/external/llvm-project/clang/lib/CIR/CodeGen/CIRGenExprComplex.cpp @@ -15,14 +15,37 @@ class ComplexExprEmitter : public StmtVisitor { explicit ComplexExprEmitter(CIRGenFunction &cgf) : cgf(cgf), builder(cgf.getBuilder()) {} + //===--------------------------------------------------------------------===// + // Utilities + //===--------------------------------------------------------------------===// + + LValue emitBinAssignLValue(const BinaryOperator *e, mlir::Value &val); + + mlir::Value emitCast(CastKind ck, Expr *op, QualType destTy); + + mlir::Value emitConstant(const CIRGenFunction::ConstantEmission &constant, + Expr *e); + + /// Given an expression with complex type that represents a value l-value, + /// this method emits the address of the l-value, then loads and returns the + /// result. + mlir::Value emitLoadOfLValue(const Expr *e) { + return emitLoadOfLValue(cgf.emitLValue(e), e->getExprLoc()); + } + + mlir::Value emitLoadOfLValue(LValue lv, SourceLocation loc); /// Store the specified real/imag parts into the /// specified value pointer. void emitStoreOfComplex(mlir::Location loc, mlir::Value val, LValue lv, bool isInit); - mlir::Value VisitInitListExpr(InitListExpr *e); + mlir::Value VisitBinAssign(const BinaryOperator *e); + mlir::Value VisitCallExpr(const CallExpr *e); + mlir::Value VisitDeclRefExpr(DeclRefExpr *e); + mlir::Value VisitImplicitCastExpr(ImplicitCastExpr *e); + mlir::Value VisitInitListExpr(const InitListExpr *e); + mlir::Value VisitImaginaryLiteral(const ImaginaryLiteral *il); }; - } // namespace static const ComplexType *getComplexType(QualType type) { @@ -32,11 +55,61 @@ static const ComplexType *getComplexType(QualType type) { return cast(cast(type)->getValueType()); } +LValue ComplexExprEmitter::emitBinAssignLValue(const BinaryOperator *e, + mlir::Value &value) { + assert(cgf.getContext().hasSameUnqualifiedType(e->getLHS()->getType(), + e->getRHS()->getType()) && + "Invalid assignment"); + + // Emit the RHS. __block variables need the RHS evaluated first. + value = Visit(e->getRHS()); + + // Compute the address to store into. + LValue lhs = cgf.emitLValue(e->getLHS()); + + // Store the result value into the LHS lvalue. + emitStoreOfComplex(cgf.getLoc(e->getExprLoc()), value, lhs, /*isInit*/ false); + return lhs; +} + +mlir::Value ComplexExprEmitter::emitCast(CastKind ck, Expr *op, + QualType destTy) { + switch (ck) { + case CK_LValueToRValue: + return Visit(op); + default: + cgf.cgm.errorNYI("ComplexType Cast"); + break; + } + return {}; +} + +mlir::Value ComplexExprEmitter::emitConstant( + const CIRGenFunction::ConstantEmission &constant, Expr *e) { + assert(constant && "not a constant"); + if (constant.isReference()) + return emitLoadOfLValue(constant.getReferenceLValue(cgf, e), + e->getExprLoc()); + + mlir::TypedAttr valueAttr = constant.getValue(); + return builder.getConstant(cgf.getLoc(e->getSourceRange()), valueAttr); +} + +mlir::Value ComplexExprEmitter::emitLoadOfLValue(LValue lv, + SourceLocation loc) { + assert(lv.isSimple() && "non-simple complex l-value?"); + if (lv.getType()->isAtomicType()) + cgf.cgm.errorNYI(loc, "emitLoadOfLValue with Atomic LV"); + + const Address srcAddr = lv.getAddress(); + return builder.createLoad(cgf.getLoc(loc), srcAddr); +} + void ComplexExprEmitter::emitStoreOfComplex(mlir::Location loc, mlir::Value val, LValue lv, bool isInit) { if (lv.getType()->isAtomicType() || (!isInit && cgf.isLValueSuitableForInlineAtomic(lv))) { - cgf.cgm.errorNYI("StoreOfComplex with Atomic LV"); + cgf.cgm.errorNYI(loc, "StoreOfComplex with Atomic LV"); return; } @@ -44,7 +117,44 @@ void ComplexExprEmitter::emitStoreOfComplex(mlir::Location loc, mlir::Value val, builder.createStore(loc, val, destAddr); } -mlir::Value ComplexExprEmitter::VisitInitListExpr(InitListExpr *e) { +mlir::Value ComplexExprEmitter::VisitBinAssign(const BinaryOperator *e) { + mlir::Value value; + LValue lv = emitBinAssignLValue(e, value); + + // The result of an assignment in C is the assigned r-value. + if (!cgf.getLangOpts().CPlusPlus) + return value; + + // If the lvalue is non-volatile, return the computed value of the + // assignment. + if (!lv.isVolatile()) + return value; + + return emitLoadOfLValue(lv, e->getExprLoc()); +} + +mlir::Value ComplexExprEmitter::VisitCallExpr(const CallExpr *e) { + if (e->getCallReturnType(cgf.getContext())->isReferenceType()) + return emitLoadOfLValue(e); + + return cgf.emitCallExpr(e).getValue(); +} + +mlir::Value ComplexExprEmitter::VisitDeclRefExpr(DeclRefExpr *e) { + if (CIRGenFunction::ConstantEmission constant = cgf.tryEmitAsConstant(e)) + return emitConstant(constant, e); + return emitLoadOfLValue(e); +} + +mlir::Value ComplexExprEmitter::VisitImplicitCastExpr(ImplicitCastExpr *e) { + // Unlike for scalars, we don't have to worry about function->ptr demotion + // here. + if (e->changesVolatileQualification()) + return emitLoadOfLValue(e); + return emitCast(e->getCastKind(), e->getSubExpr(), e->getType()); +} + +mlir::Value ComplexExprEmitter::VisitInitListExpr(const InitListExpr *e) { mlir::Location loc = cgf.getLoc(e->getExprLoc()); if (e->getNumInits() == 2) { mlir::Value real = cgf.emitScalarExpr(e->getInit(0)); @@ -66,6 +176,45 @@ mlir::Value ComplexExprEmitter::VisitInitListExpr(InitListExpr *e) { return builder.create(loc, complexAttr); } +mlir::Value +ComplexExprEmitter::VisitImaginaryLiteral(const ImaginaryLiteral *il) { + auto ty = mlir::cast(cgf.convertType(il->getType())); + mlir::Type elementTy = ty.getElementType(); + mlir::Location loc = cgf.getLoc(il->getExprLoc()); + + mlir::TypedAttr realValueAttr; + mlir::TypedAttr imagValueAttr; + + if (mlir::isa(elementTy)) { + llvm::APInt imagValue = cast(il->getSubExpr())->getValue(); + realValueAttr = cir::IntAttr::get(elementTy, 0); + imagValueAttr = cir::IntAttr::get(elementTy, imagValue); + } else { + assert(mlir::isa(elementTy) && + "Expected complex element type to be floating-point"); + + llvm::APFloat imagValue = + cast(il->getSubExpr())->getValue(); + realValueAttr = cir::FPAttr::get( + elementTy, llvm::APFloat::getZero(imagValue.getSemantics())); + imagValueAttr = cir::FPAttr::get(elementTy, imagValue); + } + + auto complexAttr = cir::ConstComplexAttr::get(realValueAttr, imagValueAttr); + return builder.create(loc, complexAttr); +} + +LValue CIRGenFunction::emitComplexAssignmentLValue(const BinaryOperator *e) { + assert(e->getOpcode() == BO_Assign && "Expected assign op"); + + mlir::Value value; // ignored + LValue lvalue = ComplexExprEmitter(*this).emitBinAssignLValue(e, value); + if (getLangOpts().OpenMP) + cgm.errorNYI("emitComplexAssignmentLValue OpenMP"); + + return lvalue; +} + mlir::Value CIRGenFunction::emitComplexExpr(const Expr *e) { assert(e && getComplexType(e->getType()) && "Invalid complex expression to emit"); diff --git a/external/llvm-project/clang/lib/CIR/CodeGen/CIRGenExprConstant.cpp b/external/llvm-project/clang/lib/CIR/CodeGen/CIRGenExprConstant.cpp index c41ab54be09c..8b817f3f3d8d 100644 --- a/external/llvm-project/clang/lib/CIR/CodeGen/CIRGenExprConstant.cpp +++ b/external/llvm-project/clang/lib/CIR/CodeGen/CIRGenExprConstant.cpp @@ -254,8 +254,8 @@ class ConstExprEmitter } mlir::Attribute VisitStringLiteral(StringLiteral *e, QualType t) { - cgm.errorNYI(e->getBeginLoc(), "ConstExprEmitter::VisitStringLiteral"); - return {}; + // This is a string literal initializing an array in an initializer. + return cgm.getConstantArrayFromStringLiteral(e); } mlir::Attribute VisitObjCEncodeExpr(ObjCEncodeExpr *e, QualType t) { @@ -329,6 +329,222 @@ emitArrayConstant(CIRGenModule &cgm, mlir::Type desiredType, return {}; } +//===----------------------------------------------------------------------===// +// ConstantLValueEmitter +//===----------------------------------------------------------------------===// + +namespace { +/// A struct which can be used to peephole certain kinds of finalization +/// that normally happen during l-value emission. +struct ConstantLValue { + llvm::PointerUnion value; + bool hasOffsetApplied; + + ConstantLValue(std::nullptr_t) : value(nullptr), hasOffsetApplied(false) {} + ConstantLValue() : value(nullptr), hasOffsetApplied(false) {} +}; + +/// A helper class for emitting constant l-values. +class ConstantLValueEmitter + : public ConstStmtVisitor { + CIRGenModule &cgm; + ConstantEmitter &emitter; + const APValue &value; + QualType destType; + + // Befriend StmtVisitorBase so that we don't have to expose Visit*. + friend StmtVisitorBase; + +public: + ConstantLValueEmitter(ConstantEmitter &emitter, const APValue &value, + QualType destType) + : cgm(emitter.cgm), emitter(emitter), value(value), destType(destType) {} + + mlir::Attribute tryEmit(); + +private: + mlir::Attribute tryEmitAbsolute(mlir::Type destTy); + ConstantLValue tryEmitBase(const APValue::LValueBase &base); + + ConstantLValue VisitStmt(const Stmt *s) { return nullptr; } + ConstantLValue VisitConstantExpr(const ConstantExpr *e); + ConstantLValue VisitCompoundLiteralExpr(const CompoundLiteralExpr *e); + ConstantLValue VisitStringLiteral(const StringLiteral *e); + ConstantLValue VisitObjCBoxedExpr(const ObjCBoxedExpr *e); + ConstantLValue VisitObjCEncodeExpr(const ObjCEncodeExpr *e); + ConstantLValue VisitObjCStringLiteral(const ObjCStringLiteral *e); + ConstantLValue VisitPredefinedExpr(const PredefinedExpr *e); + ConstantLValue VisitAddrLabelExpr(const AddrLabelExpr *e); + ConstantLValue VisitCallExpr(const CallExpr *e); + ConstantLValue VisitBlockExpr(const BlockExpr *e); + ConstantLValue VisitCXXTypeidExpr(const CXXTypeidExpr *e); + ConstantLValue + VisitMaterializeTemporaryExpr(const MaterializeTemporaryExpr *e); +}; + +} // namespace + +mlir::Attribute ConstantLValueEmitter::tryEmit() { + const APValue::LValueBase &base = value.getLValueBase(); + + // The destination type should be a pointer or reference + // type, but it might also be a cast thereof. + // + // FIXME: the chain of casts required should be reflected in the APValue. + // We need this in order to correctly handle things like a ptrtoint of a + // non-zero null pointer and addrspace casts that aren't trivially + // represented in LLVM IR. + mlir::Type destTy = cgm.getTypes().convertTypeForMem(destType); + assert(mlir::isa(destTy)); + + // If there's no base at all, this is a null or absolute pointer, + // possibly cast back to an integer type. + if (!base) + return tryEmitAbsolute(destTy); + + // Otherwise, try to emit the base. + ConstantLValue result = tryEmitBase(base); + + // If that failed, we're done. + llvm::PointerUnion &value = result.value; + if (!value) + return {}; + + // Apply the offset if necessary and not already done. + if (!result.hasOffsetApplied) { + cgm.errorNYI("ConstantLValueEmitter: apply offset"); + return {}; + } + + // Convert to the appropriate type; this could be an lvalue for + // an integer. FIXME: performAddrSpaceCast + if (mlir::isa(destTy)) { + if (auto attr = mlir::dyn_cast(value)) + return attr; + cgm.errorNYI("ConstantLValueEmitter: non-attribute pointer"); + return {}; + } + + cgm.errorNYI("ConstantLValueEmitter: other?"); + return {}; +} + +/// Try to emit an absolute l-value, such as a null pointer or an integer +/// bitcast to pointer type. +mlir::Attribute ConstantLValueEmitter::tryEmitAbsolute(mlir::Type destTy) { + // If we're producing a pointer, this is easy. + auto destPtrTy = mlir::cast(destTy); + return cgm.getBuilder().getConstPtrAttr( + destPtrTy, value.getLValueOffset().getQuantity()); +} + +ConstantLValue +ConstantLValueEmitter::tryEmitBase(const APValue::LValueBase &base) { + // Handle values. + if (const ValueDecl *d = base.dyn_cast()) { + // The constant always points to the canonical declaration. We want to look + // at properties of the most recent declaration at the point of emission. + d = cast(d->getMostRecentDecl()); + + if (d->hasAttr()) { + cgm.errorNYI(d->getSourceRange(), + "ConstantLValueEmitter: emit pointer base for weakref"); + return {}; + } + + if (auto *fd = dyn_cast(d)) { + cgm.errorNYI(fd->getSourceRange(), + "ConstantLValueEmitter: function decl"); + return {}; + } + + if (auto *vd = dyn_cast(d)) { + cgm.errorNYI(vd->getSourceRange(), "ConstantLValueEmitter: var decl"); + return {}; + } + } + + // Handle typeid(T). + if (base.dyn_cast()) { + cgm.errorNYI("ConstantLValueEmitter: typeid"); + return {}; + } + + // Otherwise, it must be an expression. + return Visit(base.get()); +} + +ConstantLValue ConstantLValueEmitter::VisitConstantExpr(const ConstantExpr *e) { + cgm.errorNYI(e->getSourceRange(), "ConstantLValueEmitter: constant expr"); + return {}; +} + +ConstantLValue +ConstantLValueEmitter::VisitCompoundLiteralExpr(const CompoundLiteralExpr *e) { + cgm.errorNYI(e->getSourceRange(), "ConstantLValueEmitter: compound literal"); + return {}; +} + +ConstantLValue +ConstantLValueEmitter::VisitStringLiteral(const StringLiteral *e) { + cgm.errorNYI(e->getSourceRange(), "ConstantLValueEmitter: string literal"); + return {}; +} + +ConstantLValue +ConstantLValueEmitter::VisitObjCEncodeExpr(const ObjCEncodeExpr *e) { + cgm.errorNYI(e->getSourceRange(), "ConstantLValueEmitter: objc encode expr"); + return {}; +} + +ConstantLValue +ConstantLValueEmitter::VisitObjCStringLiteral(const ObjCStringLiteral *e) { + cgm.errorNYI(e->getSourceRange(), + "ConstantLValueEmitter: objc string literal"); + return {}; +} + +ConstantLValue +ConstantLValueEmitter::VisitObjCBoxedExpr(const ObjCBoxedExpr *e) { + cgm.errorNYI(e->getSourceRange(), "ConstantLValueEmitter: objc boxed expr"); + return {}; +} + +ConstantLValue +ConstantLValueEmitter::VisitPredefinedExpr(const PredefinedExpr *e) { + cgm.errorNYI(e->getSourceRange(), "ConstantLValueEmitter: predefined expr"); + return {}; +} + +ConstantLValue +ConstantLValueEmitter::VisitAddrLabelExpr(const AddrLabelExpr *e) { + cgm.errorNYI(e->getSourceRange(), "ConstantLValueEmitter: addr label expr"); + return {}; +} + +ConstantLValue ConstantLValueEmitter::VisitCallExpr(const CallExpr *e) { + cgm.errorNYI(e->getSourceRange(), "ConstantLValueEmitter: call expr"); + return {}; +} + +ConstantLValue ConstantLValueEmitter::VisitBlockExpr(const BlockExpr *e) { + cgm.errorNYI(e->getSourceRange(), "ConstantLValueEmitter: block expr"); + return {}; +} + +ConstantLValue +ConstantLValueEmitter::VisitCXXTypeidExpr(const CXXTypeidExpr *e) { + cgm.errorNYI(e->getSourceRange(), "ConstantLValueEmitter: cxx typeid expr"); + return {}; +} + +ConstantLValue ConstantLValueEmitter::VisitMaterializeTemporaryExpr( + const MaterializeTemporaryExpr *e) { + cgm.errorNYI(e->getSourceRange(), + "ConstantLValueEmitter: materialize temporary expr"); + return {}; +} + //===----------------------------------------------------------------------===// // ConstantEmitter //===----------------------------------------------------------------------===// @@ -556,23 +772,8 @@ mlir::Attribute ConstantEmitter::tryEmitPrivate(const APValue &value, cgm.errorNYI("ConstExprEmitter::tryEmitPrivate member pointer"); return {}; } - case APValue::LValue: { - - if (value.getLValueBase()) { - cgm.errorNYI("non-null pointer initialization"); - } else { - - mlir::Type desiredType = cgm.convertType(destType); - if (const cir::PointerType ptrType = - mlir::dyn_cast(desiredType)) { - return builder.getConstPtrAttr(ptrType, - value.getLValueOffset().getQuantity()); - } else { - llvm_unreachable("non-pointer variable initialized with a pointer"); - } - } - return {}; - } + case APValue::LValue: + return ConstantLValueEmitter(*this, value, destType).tryEmit(); case APValue::Struct: case APValue::Union: cgm.errorNYI("ConstExprEmitter::tryEmitPrivate struct or union"); diff --git a/external/llvm-project/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp b/external/llvm-project/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp index 75b4d2a637e6..8d0db5cd0a1e 100644 --- a/external/llvm-project/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp +++ b/external/llvm-project/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp @@ -131,11 +131,11 @@ class ScalarExprEmitter : public StmtVisitor { mlir::Value emitLoadOfLValue(const Expr *e) { LValue lv = cgf.emitLValue(e); // FIXME: add some akin to EmitLValueAlignmentAssumption(E, V); - return cgf.emitLoadOfLValue(lv, e->getExprLoc()).getScalarVal(); + return cgf.emitLoadOfLValue(lv, e->getExprLoc()).getValue(); } mlir::Value emitLoadOfLValue(LValue lv, SourceLocation loc) { - return cgf.emitLoadOfLValue(lv, loc).getScalarVal(); + return cgf.emitLoadOfLValue(lv, loc).getValue(); } // l-values @@ -400,10 +400,10 @@ class ScalarExprEmitter : public StmtVisitor { cgf.cgm.errorNYI(e->getSourceRange(), "Atomic inc/dec"); // TODO(cir): This is not correct, but it will produce reasonable code // until atomic operations are implemented. - value = cgf.emitLoadOfLValue(lv, e->getExprLoc()).getScalarVal(); + value = cgf.emitLoadOfLValue(lv, e->getExprLoc()).getValue(); input = value; } else { - value = cgf.emitLoadOfLValue(lv, e->getExprLoc()).getScalarVal(); + value = cgf.emitLoadOfLValue(lv, e->getExprLoc()).getValue(); input = value; } @@ -1805,7 +1805,7 @@ mlir::Value ScalarExprEmitter::VisitCallExpr(const CallExpr *e) { if (e->getCallReturnType(cgf.getContext())->isReferenceType()) return emitLoadOfLValue(e); - auto v = cgf.emitCallExpr(e).getScalarVal(); + auto v = cgf.emitCallExpr(e).getValue(); assert(!cir::MissingFeatures::emitLValueAlignmentAssumption()); return v; } diff --git a/external/llvm-project/clang/lib/CIR/CodeGen/CIRGenFunction.h b/external/llvm-project/clang/lib/CIR/CodeGen/CIRGenFunction.h index de6ef2a69faf..82aa7ec9cb22 100644 --- a/external/llvm-project/clang/lib/CIR/CodeGen/CIRGenFunction.h +++ b/external/llvm-project/clang/lib/CIR/CodeGen/CIRGenFunction.h @@ -772,6 +772,10 @@ class CIRGenFunction : public CIRGenTypeCache { LValue emitCastLValue(const CastExpr *e); + /// Emits an argument for a call to a `__builtin_assume`. If the builtin + /// sanitizer is enabled, a runtime check is also emitted. + mlir::Value emitCheckedArgForAssume(const Expr *e); + LValue emitCompoundAssignmentLValue(const clang::CompoundAssignOperator *e); void emitConstructorBody(FunctionArgList &args); @@ -866,6 +870,8 @@ class CIRGenFunction : public CIRGenTypeCache { /// returning the result. mlir::Value emitComplexExpr(const Expr *e); + LValue emitComplexAssignmentLValue(const BinaryOperator *e); + void emitCompoundStmt(const clang::CompoundStmt &s); void emitCompoundStmtWithoutScope(const clang::CompoundStmt &s); diff --git a/external/llvm-project/clang/lib/CIR/CodeGen/CIRGenModule.h b/external/llvm-project/clang/lib/CIR/CodeGen/CIRGenModule.h index 03606dba200f..71806e3c5de2 100644 --- a/external/llvm-project/clang/lib/CIR/CodeGen/CIRGenModule.h +++ b/external/llvm-project/clang/lib/CIR/CodeGen/CIRGenModule.h @@ -14,6 +14,7 @@ #define LLVM_CLANG_LIB_CIR_CODEGEN_CIRGENMODULE_H #include "CIRGenBuilder.h" +#include "CIRGenCall.h" #include "CIRGenTypeCache.h" #include "CIRGenTypes.h" #include "CIRGenValue.h" @@ -158,6 +159,15 @@ class CIRGenModule : public CIRGenTypeCache { const CXXRecordDecl *derivedClass, llvm::iterator_range path); + /// Get the CIR attributes and calling convention to use for a particular + /// function type. + /// + /// \param calleeInfo - The callee information these attributes are being + /// constructed for. If valid, the attributes applied to this decl may + /// contribute to the function attributes and calling convention. + void constructAttributeList(CIRGenCalleeInfo calleeInfo, + cir::SideEffect &sideEffect); + /// Return a constant array for the given string. mlir::Attribute getConstantArrayFromStringLiteral(const StringLiteral *e); @@ -301,6 +311,10 @@ class CIRGenModule : public CIRGenTypeCache { cir::FuncType funcType, const clang::FunctionDecl *funcDecl); + /// Given a builtin id for a function like "__builtin_fabsf", return a + /// Function* for "fabsf". + cir::FuncOp getBuiltinLibFunction(const FunctionDecl *fd, unsigned builtinID); + mlir::IntegerAttr getSize(CharUnits size) { return builder.getSizeFromCharUnits(size); } diff --git a/external/llvm-project/clang/lib/CIR/CodeGen/CIRGenRecordLayout.h b/external/llvm-project/clang/lib/CIR/CodeGen/CIRGenRecordLayout.h index ac8832b8c9b2..b28afe42c39a 100644 --- a/external/llvm-project/clang/lib/CIR/CodeGen/CIRGenRecordLayout.h +++ b/external/llvm-project/clang/lib/CIR/CodeGen/CIRGenRecordLayout.h @@ -14,6 +14,106 @@ namespace clang::CIRGen { +/// Record with information about how a bitfield should be accessed. This is +/// very similar to what LLVM codegen does, once CIR evolves it's possible we +/// can use a more higher level representation. +/// +/// Often we lay out a sequence of bitfields as a contiguous sequence of bits. +/// When the AST record layout does this, we represent it in CIR as a +/// `!cir.record` type, which directly reflects the structure's layout, +/// including bitfield packing and padding, using CIR types such as +/// `!cir.bool`, `!s8i`, `!u16i`. +/// +/// To access a particular bitfield in CIR, we use the operations +/// `cir.get_bitfield` (`GetBitfieldOp`) or `cir.set_bitfield` +/// (`SetBitfieldOp`). These operations rely on the `bitfield_info` +/// attribute, which provides detailed metadata required for access, +/// such as the size and offset of the bitfield, the type and size of +/// the underlying storage, and whether the value is signed. +/// The CIRGenRecordLayout also has a bitFields map which encodes which +/// byte-sequence this bitfield falls within. Let's assume the following C +/// struct: +/// +/// struct S { +/// char a, b, c; +/// unsigned bits : 3; +/// unsigned more_bits : 4; +/// unsigned still_more_bits : 7; +/// }; +/// +/// This will end up as the following cir.record. The bitfield members are +/// represented by one !u16i value, and the array provides padding to align the +/// struct to a 4-byte alignment. +/// +/// !rec_S = !cir.record}> +/// +/// When generating code to access more_bits, we'll generate something +/// essentially like this: +/// +/// #bfi_more_bits = #cir.bitfield_info +/// +/// cir.func @store_field() { +/// %0 = cir.alloca !rec_S, !cir.ptr, ["s"] {alignment = 4 : i64} +/// %1 = cir.const #cir.int<2> : !s32i +/// %2 = cir.cast(integral, %1 : !s32i), !u32i +/// %3 = cir.get_member %0[3] {name = "more_bits"} : !cir.ptr -> +/// !cir.ptr +/// %4 = cir.set_bitfield(#bfi_more_bits, %3 : +/// !cir.ptr, %2 : !u32i) -> !u32i +/// cir.return +/// } +/// +struct CIRGenBitFieldInfo { + /// The offset within a contiguous run of bitfields that are represented as + /// a single "field" within the cir.record type. This offset is in bits. + unsigned offset : 16; + + /// The total size of the bit-field, in bits. + unsigned size : 15; + + /// Whether the bit-field is signed. + unsigned isSigned : 1; + + /// The storage size in bits which should be used when accessing this + /// bitfield. + unsigned storageSize; + + /// The offset of the bitfield storage from the start of the record. + clang::CharUnits storageOffset; + + /// The offset within a contiguous run of bitfields that are represented as a + /// single "field" within the cir.record type, taking into account the AAPCS + /// rules for volatile bitfields. This offset is in bits. + unsigned volatileOffset : 16; + + /// The storage size in bits which should be used when accessing this + /// bitfield. + unsigned volatileStorageSize; + + /// The offset of the bitfield storage from the start of the record. + clang::CharUnits volatileStorageOffset; + + /// The name of a bitfield + llvm::StringRef name; + + // The actual storage type for the bitfield + mlir::Type storageType; + + CIRGenBitFieldInfo() + : offset(), size(), isSigned(), storageSize(), volatileOffset(), + volatileStorageSize() {} + + CIRGenBitFieldInfo(unsigned offset, unsigned size, bool isSigned, + unsigned storageSize, clang::CharUnits storageOffset) + : offset(offset), size(size), isSigned(isSigned), + storageSize(storageSize), storageOffset(storageOffset) {} + + void print(llvm::raw_ostream &os) const; + LLVM_DUMP_METHOD void dump() const; +}; + /// This class handles record and union layout info while lowering AST types /// to CIR types. /// @@ -41,6 +141,10 @@ class CIRGenRecordLayout { // for both virtual and non-virtual bases. llvm::DenseMap nonVirtualBases; + /// Map from (bit-field) record field to the corresponding CIR record type + /// field no. This info is populated by record builder. + llvm::DenseMap bitFields; + /// False if any direct or indirect subobject of this class, when considered /// as a complete object, requires a non-zero bitpattern when /// zero-initialized. @@ -83,6 +187,18 @@ class CIRGenRecordLayout { /// Check whether this struct can be C++ zero-initialized /// with a zeroinitializer when considered as a base subobject. bool isZeroInitializableAsBase() const { return zeroInitializableAsBase; } + + /// Return the BitFieldInfo that corresponds to the field FD. + const CIRGenBitFieldInfo &getBitFieldInfo(const clang::FieldDecl *fd) const { + fd = fd->getCanonicalDecl(); + assert(fd->isBitField() && "Invalid call for non-bit-field decl!"); + llvm::DenseMap::const_iterator + it = bitFields.find(fd); + assert(it != bitFields.end() && "Unable to find bitfield info"); + return it->second; + } + void print(raw_ostream &os) const; + LLVM_DUMP_METHOD void dump() const; }; } // namespace clang::CIRGen diff --git a/external/llvm-project/clang/lib/CIR/CodeGen/CIRGenRecordLayoutBuilder.cpp b/external/llvm-project/clang/lib/CIR/CodeGen/CIRGenRecordLayoutBuilder.cpp index 0aeef7fd89ae..faeee88bba3c 100644 --- a/external/llvm-project/clang/lib/CIR/CodeGen/CIRGenRecordLayoutBuilder.cpp +++ b/external/llvm-project/clang/lib/CIR/CodeGen/CIRGenRecordLayoutBuilder.cpp @@ -20,6 +20,7 @@ #include "clang/AST/RecordLayout.h" #include "clang/CIR/Dialect/IR/CIRAttrs.h" #include "clang/CIR/Dialect/IR/CIRDataLayout.h" +#include "clang/CIR/MissingFeatures.h" #include "llvm/Support/Casting.h" #include @@ -66,6 +67,10 @@ struct CIRRecordLowering final { return MemberInfo(offset, MemberInfo::InfoKind::Field, data); } + // Layout routines. + void setBitFieldInfo(const FieldDecl *fd, CharUnits startOffset, + mlir::Type storageType); + void lower(); void lowerUnion(); @@ -77,6 +82,9 @@ struct CIRRecordLowering final { void accumulateBases(const CXXRecordDecl *cxxRecordDecl); void accumulateVPtrs(); void accumulateFields(); + RecordDecl::field_iterator + accumulateBitFields(RecordDecl::field_iterator field, + RecordDecl::field_iterator fieldEnd); CharUnits bitsToCharUnits(uint64_t bitOffset) { return astContext.toCharUnitsFromBits(bitOffset); @@ -87,6 +95,9 @@ struct CIRRecordLowering final { CharUnits getSize(mlir::Type Ty) { return CharUnits::fromQuantity(dataLayout.layout.getTypeSize(Ty)); } + CharUnits getSizeInBits(mlir::Type ty) { + return CharUnits::fromQuantity(dataLayout.layout.getTypeSizeInBits(ty)); + } CharUnits getAlignment(mlir::Type Ty) { return CharUnits::fromQuantity(dataLayout.layout.getTypeABIAlignment(Ty)); } @@ -124,6 +135,17 @@ struct CIRRecordLowering final { mlir::Type getStorageType(const CXXRecordDecl *RD) { return cirGenTypes.getCIRGenRecordLayout(RD).getBaseSubobjectCIRType(); } + // This is different from LLVM traditional codegen because CIRGen uses arrays + // of bytes instead of arbitrary-sized integers. This is important for packed + // structures support. + mlir::Type getBitfieldStorageType(unsigned numBits) { + unsigned alignedBits = llvm::alignTo(numBits, astContext.getCharWidth()); + if (cir::isValidFundamentalIntWidth(alignedBits)) + return builder.getUIntNTy(alignedBits); + + mlir::Type type = getCharType(); + return cir::ArrayType::get(type, alignedBits / astContext.getCharWidth()); + } mlir::Type getStorageType(const FieldDecl *fieldDecl) { mlir::Type type = cirGenTypes.convertTypeForMem(fieldDecl->getType()); @@ -157,6 +179,7 @@ struct CIRRecordLowering final { std::vector members; // Output fields, consumed by CIRGenTypes::computeRecordLayout llvm::SmallVector fieldTypes; + llvm::DenseMap bitFields; llvm::DenseMap fieldIdxMap; llvm::DenseMap nonVirtualBases; cir::CIRDataLayout dataLayout; @@ -186,6 +209,33 @@ CIRRecordLowering::CIRRecordLowering(CIRGenTypes &cirGenTypes, zeroInitializable(true), zeroInitializableAsBase(true), packed(packed), padded(false) {} +void CIRRecordLowering::setBitFieldInfo(const FieldDecl *fd, + CharUnits startOffset, + mlir::Type storageType) { + CIRGenBitFieldInfo &info = bitFields[fd->getCanonicalDecl()]; + info.isSigned = fd->getType()->isSignedIntegerOrEnumerationType(); + info.offset = + (unsigned)(getFieldBitOffset(fd) - astContext.toBits(startOffset)); + info.size = fd->getBitWidthValue(); + info.storageSize = getSizeInBits(storageType).getQuantity(); + info.storageOffset = startOffset; + info.storageType = storageType; + info.name = fd->getName(); + + if (info.size > info.storageSize) + info.size = info.storageSize; + // Reverse the bit offsets for big endian machines. Since bitfields are laid + // out as packed bits within an integer-sized unit, we can imagine the bits + // counting from the most-significant-bit instead of the + // least-significant-bit. + if (dataLayout.isBigEndian()) + info.offset = info.storageSize - (info.offset + info.size); + + info.volatileStorageSize = 0; + info.volatileOffset = 0; + info.volatileStorageOffset = CharUnits::Zero(); +} + void CIRRecordLowering::lower() { if (recordDecl->isUnion()) { lowerUnion(); @@ -233,6 +283,8 @@ void CIRRecordLowering::fillOutputFields() { fieldTypes.size() - 1; // A field without storage must be a bitfield. assert(!cir::MissingFeatures::bitfields()); + if (!member.data) + setBitFieldInfo(member.fieldDecl, member.offset, fieldTypes.back()); } else if (member.kind == MemberInfo::InfoKind::Base) { nonVirtualBases[member.cxxRecordDecl] = fieldTypes.size() - 1; } @@ -240,16 +292,217 @@ void CIRRecordLowering::fillOutputFields() { } } +RecordDecl::field_iterator +CIRRecordLowering::accumulateBitFields(RecordDecl::field_iterator field, + RecordDecl::field_iterator fieldEnd) { + assert(!cir::MissingFeatures::isDiscreteBitFieldABI()); + + CharUnits regSize = + bitsToCharUnits(astContext.getTargetInfo().getRegisterWidth()); + unsigned charBits = astContext.getCharWidth(); + + // Data about the start of the span we're accumulating to create an access + // unit from. 'Begin' is the first bitfield of the span. If 'begin' is + // 'fieldEnd', we've not got a current span. The span starts at the + // 'beginOffset' character boundary. 'bitSizeSinceBegin' is the size (in bits) + // of the span -- this might include padding when we've advanced to a + // subsequent bitfield run. + RecordDecl::field_iterator begin = fieldEnd; + CharUnits beginOffset; + uint64_t bitSizeSinceBegin; + + // The (non-inclusive) end of the largest acceptable access unit we've found + // since 'begin'. If this is 'begin', we're gathering the initial set of + // bitfields of a new span. 'bestEndOffset' is the end of that acceptable + // access unit -- it might extend beyond the last character of the bitfield + // run, using available padding characters. + RecordDecl::field_iterator bestEnd = begin; + CharUnits bestEndOffset; + bool bestClipped; // Whether the representation must be in a byte array. + + for (;;) { + // atAlignedBoundary is true if 'field' is the (potential) start of a new + // span (or the end of the bitfields). When true, limitOffset is the + // character offset of that span and barrier indicates whether the new + // span cannot be merged into the current one. + bool atAlignedBoundary = false; + bool barrier = false; // a barrier can be a zero Bit Width or non bit member + if (field != fieldEnd && field->isBitField()) { + uint64_t bitOffset = getFieldBitOffset(*field); + if (begin == fieldEnd) { + // Beginning a new span. + begin = field; + bestEnd = begin; + + assert((bitOffset % charBits) == 0 && "Not at start of char"); + beginOffset = bitsToCharUnits(bitOffset); + bitSizeSinceBegin = 0; + } else if ((bitOffset % charBits) != 0) { + // Bitfield occupies the same character as previous bitfield, it must be + // part of the same span. This can include zero-length bitfields, should + // the target not align them to character boundaries. Such non-alignment + // is at variance with the standards, which require zero-length + // bitfields be a barrier between access units. But of course we can't + // achieve that in the middle of a character. + assert(bitOffset == + astContext.toBits(beginOffset) + bitSizeSinceBegin && + "Concatenating non-contiguous bitfields"); + } else { + // Bitfield potentially begins a new span. This includes zero-length + // bitfields on non-aligning targets that lie at character boundaries + // (those are barriers to merging). + if (field->isZeroLengthBitField()) + barrier = true; + atAlignedBoundary = true; + } + } else { + // We've reached the end of the bitfield run. Either we're done, or this + // is a barrier for the current span. + if (begin == fieldEnd) + break; + + barrier = true; + atAlignedBoundary = true; + } + + // 'installBest' indicates whether we should create an access unit for the + // current best span: fields ['begin', 'bestEnd') occupying characters + // ['beginOffset', 'bestEndOffset'). + bool installBest = false; + if (atAlignedBoundary) { + // 'field' is the start of a new span or the end of the bitfields. The + // just-seen span now extends to 'bitSizeSinceBegin'. + + // Determine if we can accumulate that just-seen span into the current + // accumulation. + CharUnits accessSize = bitsToCharUnits(bitSizeSinceBegin + charBits - 1); + if (bestEnd == begin) { + // This is the initial run at the start of a new span. By definition, + // this is the best seen so far. + bestEnd = field; + bestEndOffset = beginOffset + accessSize; + // Assume clipped until proven not below. + bestClipped = true; + if (!bitSizeSinceBegin) + // A zero-sized initial span -- this will install nothing and reset + // for another. + installBest = true; + } else if (accessSize > regSize) { + // Accumulating the just-seen span would create a multi-register access + // unit, which would increase register pressure. + installBest = true; + } + + if (!installBest) { + // Determine if accumulating the just-seen span will create an expensive + // access unit or not. + mlir::Type type = getUIntNType(astContext.toBits(accessSize)); + if (!astContext.getTargetInfo().hasCheapUnalignedBitFieldAccess()) + cirGenTypes.getCGModule().errorNYI( + field->getSourceRange(), "NYI CheapUnalignedBitFieldAccess"); + + if (!installBest) { + // Find the next used storage offset to determine what the limit of + // the current span is. That's either the offset of the next field + // with storage (which might be field itself) or the end of the + // non-reusable tail padding. + CharUnits limitOffset; + for (auto probe = field; probe != fieldEnd; ++probe) + if (!isEmptyFieldForLayout(astContext, *probe)) { + // A member with storage sets the limit. + assert((getFieldBitOffset(*probe) % charBits) == 0 && + "Next storage is not byte-aligned"); + limitOffset = bitsToCharUnits(getFieldBitOffset(*probe)); + goto FoundLimit; + } + assert(!cir::MissingFeatures::cxxSupport()); + limitOffset = astRecordLayout.getDataSize(); + FoundLimit: + CharUnits typeSize = getSize(type); + if (beginOffset + typeSize <= limitOffset) { + // There is space before limitOffset to create a naturally-sized + // access unit. + bestEndOffset = beginOffset + typeSize; + bestEnd = field; + bestClipped = false; + } + if (barrier) { + // The next field is a barrier that we cannot merge across. + installBest = true; + } else if (cirGenTypes.getCGModule() + .getCodeGenOpts() + .FineGrainedBitfieldAccesses) { + assert(!cir::MissingFeatures::nonFineGrainedBitfields()); + cirGenTypes.getCGModule().errorNYI(field->getSourceRange(), + "NYI FineGrainedBitfield"); + } else { + // Otherwise, we're not installing. Update the bit size + // of the current span to go all the way to limitOffset, which is + // the (aligned) offset of next bitfield to consider. + bitSizeSinceBegin = astContext.toBits(limitOffset - beginOffset); + } + } + } + } + + if (installBest) { + assert((field == fieldEnd || !field->isBitField() || + (getFieldBitOffset(*field) % charBits) == 0) && + "Installing but not at an aligned bitfield or limit"); + CharUnits accessSize = bestEndOffset - beginOffset; + if (!accessSize.isZero()) { + // Add the storage member for the access unit to the record. The + // bitfields get the offset of their storage but come afterward and + // remain there after a stable sort. + mlir::Type type; + if (bestClipped) { + assert(getSize(getUIntNType(astContext.toBits(accessSize))) > + accessSize && + "Clipped access need not be clipped"); + type = getByteArrayType(accessSize); + } else { + type = getUIntNType(astContext.toBits(accessSize)); + assert(getSize(type) == accessSize && + "Unclipped access must be clipped"); + } + members.push_back(makeStorageInfo(beginOffset, type)); + for (; begin != bestEnd; ++begin) + if (!begin->isZeroLengthBitField()) + members.push_back(MemberInfo( + beginOffset, MemberInfo::InfoKind::Field, nullptr, *begin)); + } + // Reset to start a new span. + field = bestEnd; + begin = fieldEnd; + } else { + assert(field != fieldEnd && field->isBitField() && + "Accumulating past end of bitfields"); + assert(!barrier && "Accumulating across barrier"); + // Accumulate this bitfield into the current (potential) span. + bitSizeSinceBegin += field->getBitWidthValue(); + ++field; + } + } + + return field; +} + void CIRRecordLowering::accumulateFields() { - for (const FieldDecl *field : recordDecl->fields()) { + for (RecordDecl::field_iterator field = recordDecl->field_begin(), + fieldEnd = recordDecl->field_end(); + field != fieldEnd;) { if (field->isBitField()) { - cirGenTypes.getCGModule().errorNYI(recordDecl->getSourceRange(), - "accumulate bitfields"); - ++field; + RecordDecl::field_iterator start = field; + // Iterate to gather the list of bitfields. + for (++field; field != fieldEnd && field->isBitField(); ++field) + ; + field = accumulateBitFields(start, field); + assert((field == fieldEnd || !field->isBitField()) && + "Failed to accumulate all the bitfields"); } else if (!field->isZeroSize(astContext)) { - members.push_back(MemberInfo(bitsToCharUnits(getFieldBitOffset(field)), + members.push_back(MemberInfo(bitsToCharUnits(getFieldBitOffset(*field)), MemberInfo::InfoKind::Field, - getStorageType(field), field)); + getStorageType(*field), *field)); ++field; } else { // TODO(cir): do we want to do anything special about zero size members? @@ -383,15 +636,59 @@ CIRGenTypes::computeRecordLayout(const RecordDecl *rd, cir::RecordType *ty) { // Add all the field numbers. rl->fieldIdxMap.swap(lowering.fieldIdxMap); + rl->bitFields.swap(lowering.bitFields); + // Dump the layout, if requested. if (getASTContext().getLangOpts().DumpRecordLayouts) { - cgm.errorNYI(rd->getSourceRange(), "computeRecordLayout: dump layout"); + llvm::outs() << "\n*** Dumping CIRgen Record Layout\n"; + llvm::outs() << "Record: "; + rd->dump(llvm::outs()); + llvm::outs() << "\nLayout: "; + rl->print(llvm::outs()); } // TODO: implement verification return rl; } +void CIRGenRecordLayout::print(raw_ostream &os) const { + os << "> bitInfo; + for (auto &[decl, info] : bitFields) { + const RecordDecl *rd = decl->getParent(); + unsigned index = 0; + for (RecordDecl::field_iterator it = rd->field_begin(); *it != decl; ++it) + ++index; + bitInfo.push_back(std::make_pair(index, &info)); + } + llvm::array_pod_sort(bitInfo.begin(), bitInfo.end()); + for (std::pair &info : bitInfo) { + os.indent(4); + info.second->print(os); + os << "\n"; + } + os << " ]>\n"; +} + +void CIRGenBitFieldInfo::print(raw_ostream &os) const { + os << ""; +} + +void CIRGenRecordLayout::dump() const { print(llvm::errs()); } + +void CIRGenBitFieldInfo::dump() const { print(llvm::errs()); } + void CIRRecordLowering::lowerUnion() { CharUnits layoutSize = astRecordLayout.getSize(); mlir::Type storageType = nullptr; diff --git a/external/llvm-project/clang/lib/CIR/CodeGen/CIRGenStmt.cpp b/external/llvm-project/clang/lib/CIR/CodeGen/CIRGenStmt.cpp index 019a44636ce3..9193f6f1cd99 100644 --- a/external/llvm-project/clang/lib/CIR/CodeGen/CIRGenStmt.cpp +++ b/external/llvm-project/clang/lib/CIR/CodeGen/CIRGenStmt.cpp @@ -391,8 +391,7 @@ mlir::LogicalResult CIRGenFunction::emitReturnStmt(const ReturnStmt &s) { // If this function returns a reference, take the address of the // expression rather than the value. RValue result = emitReferenceBindingToExpr(rv); - builder.CIRBaseBuilderTy::createStore(loc, result.getScalarVal(), - *fnRetAlloca); + builder.CIRBaseBuilderTy::createStore(loc, result.getValue(), *fnRetAlloca); } else { mlir::Value value = nullptr; switch (CIRGenFunction::getEvaluationKind(rv->getType())) { diff --git a/external/llvm-project/clang/lib/CIR/CodeGen/CIRGenTypes.cpp b/external/llvm-project/clang/lib/CIR/CodeGen/CIRGenTypes.cpp index bab47924dd71..621eb66962bf 100644 --- a/external/llvm-project/clang/lib/CIR/CodeGen/CIRGenTypes.cpp +++ b/external/llvm-project/clang/lib/CIR/CodeGen/CIRGenTypes.cpp @@ -416,6 +416,22 @@ mlir::Type CIRGenTypes::convertType(QualType type) { break; } + case Type::IncompleteArray: { + const IncompleteArrayType *arrTy = cast(ty); + if (arrTy->getIndexTypeCVRQualifiers() != 0) + cgm.errorNYI(SourceLocation(), "non trivial array types", type); + + mlir::Type elemTy = convertTypeForMem(arrTy->getElementType()); + // int X[] -> [0 x int], unless the element type is not sized. If it is + // unsized (e.g. an incomplete record) just use [0 x i8]. + if (!builder.isSized(elemTy)) { + elemTy = cgm.SInt8Ty; + } + + resultType = cir::ArrayType::get(elemTy, 0); + break; + } + case Type::ConstantArray: { const ConstantArrayType *arrTy = cast(ty); mlir::Type elemTy = convertTypeForMem(arrTy->getElementType()); diff --git a/external/llvm-project/clang/lib/CIR/CodeGen/CIRGenValue.h b/external/llvm-project/clang/lib/CIR/CodeGen/CIRGenValue.h index c1e08ba1e9b6..a5a457ddafa9 100644 --- a/external/llvm-project/clang/lib/CIR/CodeGen/CIRGenValue.h +++ b/external/llvm-project/clang/lib/CIR/CodeGen/CIRGenValue.h @@ -33,11 +33,7 @@ class RValue { enum Flavor { Scalar, Complex, Aggregate }; union { - // Stores first and second value. - struct { - mlir::Value first; - mlir::Value second; - } vals; + mlir::Value value; // Stores aggregate address. Address aggregateAddr; @@ -47,7 +43,7 @@ class RValue { unsigned flavor : 2; public: - RValue() : vals{nullptr, nullptr}, flavor(Scalar) {} + RValue() : value(nullptr), flavor(Scalar) {} bool isScalar() const { return flavor == Scalar; } bool isComplex() const { return flavor == Complex; } @@ -56,14 +52,9 @@ class RValue { bool isVolatileQualified() const { return isVolatile; } /// Return the value of this scalar value. - mlir::Value getScalarVal() const { + mlir::Value getValue() const { assert(isScalar() && "Not a scalar!"); - return vals.first; - } - - /// Return the real/imag components of this complex value. - std::pair getComplexVal() const { - return std::make_pair(vals.first, vals.second); + return value; } /// Return the value of the address of the aggregate. @@ -83,23 +74,20 @@ class RValue { static RValue get(mlir::Value v) { RValue er; - er.vals.first = v; + er.value = v; er.flavor = Scalar; er.isVolatile = false; return er; } - static RValue getComplex(mlir::Value v1, mlir::Value v2) { + static RValue getComplex(mlir::Value v) { RValue er; - er.vals = {v1, v2}; + er.value = v; er.flavor = Complex; er.isVolatile = false; return er; } - static RValue getComplex(const std::pair &c) { - return getComplex(c.first, c.second); - } - // FIXME: Aggregate rvalues need to retain information about whether they are + // volatile or not. Remove default to find all places that probably get this // wrong. @@ -194,9 +182,7 @@ class LValue { bool isSimple() const { return lvType == Simple; } bool isVectorElt() const { return lvType == VectorElt; } bool isBitField() const { return lvType == BitField; } - - // TODO: Add support for volatile - bool isVolatile() const { return false; } + bool isVolatile() const { return quals.hasVolatile(); } unsigned getVRQualifiers() const { return quals.getCVRQualifiers() & ~clang::Qualifiers::Const; diff --git a/external/llvm-project/clang/lib/CIR/CodeGen/TargetInfo.cpp b/external/llvm-project/clang/lib/CIR/CodeGen/TargetInfo.cpp index 551341ff20c0..d2d32bbd9403 100644 --- a/external/llvm-project/clang/lib/CIR/CodeGen/TargetInfo.cpp +++ b/external/llvm-project/clang/lib/CIR/CodeGen/TargetInfo.cpp @@ -3,6 +3,43 @@ using namespace clang; using namespace clang::CIRGen; + +bool clang::CIRGen::isEmptyRecordForLayout(const ASTContext &context, + QualType t) { + const RecordType *rt = t->getAs(); + if (!rt) + return false; + + const RecordDecl *rd = rt->getDecl(); + + // If this is a C++ record, check the bases first. + if (const CXXRecordDecl *cxxrd = dyn_cast(rd)) { + if (cxxrd->isDynamicClass()) + return false; + + for (const auto &I : cxxrd->bases()) + if (!isEmptyRecordForLayout(context, I.getType())) + return false; + } + + for (const auto *I : rd->fields()) + if (!isEmptyFieldForLayout(context, I)) + return false; + + return true; +} + +bool clang::CIRGen::isEmptyFieldForLayout(const ASTContext &context, + const FieldDecl *fd) { + if (fd->isZeroLengthBitField()) + return true; + + if (fd->isUnnamedBitField()) + return false; + + return isEmptyRecordForLayout(context, fd->getType()); +} + namespace { class X8664ABIInfo : public ABIInfo { diff --git a/external/llvm-project/clang/lib/CIR/CodeGen/TargetInfo.h b/external/llvm-project/clang/lib/CIR/CodeGen/TargetInfo.h index d31d1ee82d90..a5c548aa2c7c 100644 --- a/external/llvm-project/clang/lib/CIR/CodeGen/TargetInfo.h +++ b/external/llvm-project/clang/lib/CIR/CodeGen/TargetInfo.h @@ -22,6 +22,16 @@ namespace clang::CIRGen { +/// isEmptyFieldForLayout - Return true if the field is "empty", that is, +/// either a zero-width bit-field or an isEmptyRecordForLayout. +bool isEmptyFieldForLayout(const ASTContext &context, const FieldDecl *fd); + +/// isEmptyRecordForLayout - Return true if a structure contains only empty +/// base classes (per isEmptyRecordForLayout) and fields (per +/// isEmptyFieldForLayout). Note, C++ record fields are considered empty +/// if the [[no_unique_address]] attribute would have made them empty. +bool isEmptyRecordForLayout(const ASTContext &context, QualType t); + class TargetCIRGenInfo { std::unique_ptr info; diff --git a/external/llvm-project/clang/lib/CIR/Dialect/IR/CIRDialect.cpp b/external/llvm-project/clang/lib/CIR/Dialect/IR/CIRDialect.cpp index 5578d4f5825a..27f4ecb5ab85 100644 --- a/external/llvm-project/clang/lib/CIR/Dialect/IR/CIRDialect.cpp +++ b/external/llvm-project/clang/lib/CIR/Dialect/IR/CIRDialect.cpp @@ -92,6 +92,46 @@ Operation *cir::CIRDialect::materializeConstant(mlir::OpBuilder &builder, // Helpers //===----------------------------------------------------------------------===// +// Parses one of the keywords provided in the list `keywords` and returns the +// position of the parsed keyword in the list. If none of the keywords from the +// list is parsed, returns -1. +static int parseOptionalKeywordAlternative(AsmParser &parser, + ArrayRef keywords) { + for (auto en : llvm::enumerate(keywords)) { + if (succeeded(parser.parseOptionalKeyword(en.value()))) + return en.index(); + } + return -1; +} + +namespace { +template struct EnumTraits {}; + +#define REGISTER_ENUM_TYPE(Ty) \ + template <> struct EnumTraits { \ + static llvm::StringRef stringify(cir::Ty value) { \ + return stringify##Ty(value); \ + } \ + static unsigned getMaxEnumVal() { return cir::getMaxEnumValFor##Ty(); } \ + } + +REGISTER_ENUM_TYPE(SideEffect); +} // namespace + +/// Parse an enum from the keyword, return failure if the keyword is not found. +template +static ParseResult parseCIRKeyword(AsmParser &parser, RetTy &result) { + llvm::SmallVector names; + for (unsigned i = 0, e = EnumTraits::getMaxEnumVal(); i <= e; ++i) + names.push_back(EnumTraits::stringify(static_cast(i))); + + int index = parseOptionalKeywordAlternative(parser, names); + if (index == -1) + return failure(); + result = static_cast(index); + return success(); +} + // Check if a region's termination omission is valid and, if so, creates and // inserts the omitted terminator into the region. static LogicalResult ensureRegionTerm(OpAsmParser &parser, Region ®ion, @@ -534,6 +574,18 @@ static mlir::ParseResult parseCallCommon(mlir::OpAsmParser &parser, if (parser.parseRParen()) return mlir::failure(); + if (parser.parseOptionalKeyword("side_effect").succeeded()) { + if (parser.parseLParen().failed()) + return failure(); + cir::SideEffect sideEffect; + if (parseCIRKeyword(parser, sideEffect).failed()) + return failure(); + if (parser.parseRParen().failed()) + return failure(); + auto attr = cir::SideEffectAttr::get(parser.getContext(), sideEffect); + result.addAttribute("side_effect", attr); + } + if (parser.parseOptionalAttrDict(result.attributes)) return ::mlir::failure(); @@ -556,7 +608,8 @@ static mlir::ParseResult parseCallCommon(mlir::OpAsmParser &parser, static void printCallCommon(mlir::Operation *op, mlir::FlatSymbolRefAttr calleeSym, mlir::Value indirectCallee, - mlir::OpAsmPrinter &printer) { + mlir::OpAsmPrinter &printer, + cir::SideEffect sideEffect) { printer << ' '; auto callLikeOp = mlir::cast(op); @@ -572,7 +625,13 @@ static void printCallCommon(mlir::Operation *op, } printer << "(" << ops << ")"; - printer.printOptionalAttrDict(op->getAttrs(), {"callee"}); + if (sideEffect != cir::SideEffect::All) { + printer << " side_effect("; + printer << stringifySideEffect(sideEffect); + printer << ")"; + } + + printer.printOptionalAttrDict(op->getAttrs(), {"callee", "side_effect"}); printer << " : "; printer.printFunctionalType(op->getOperands().getTypes(), @@ -586,7 +645,8 @@ mlir::ParseResult cir::CallOp::parse(mlir::OpAsmParser &parser, void cir::CallOp::print(mlir::OpAsmPrinter &p) { mlir::Value indirectCallee = isIndirect() ? getIndirectCall() : nullptr; - printCallCommon(*this, getCalleeAttr(), indirectCallee, p); + cir::SideEffect sideEffect = getSideEffect(); + printCallCommon(*this, getCalleeAttr(), indirectCallee, p, sideEffect); } static LogicalResult @@ -1314,25 +1374,6 @@ void cir::FuncOp::print(OpAsmPrinter &p) { } } -//===----------------------------------------------------------------------===// -// CIR defined traits -//===----------------------------------------------------------------------===// - -LogicalResult -mlir::OpTrait::impl::verifySameFirstOperandAndResultType(Operation *op) { - if (failed(verifyAtLeastNOperands(op, 1)) || failed(verifyOneResult(op))) - return failure(); - - const Type type = op->getResult(0).getType(); - const Type opType = op->getOperand(0).getType(); - - if (type != opType) - return op->emitOpError() - << "requires the same type for first operand and result"; - - return success(); -} - // TODO(CIR): The properties of functions that require verification haven't // been implemented yet. mlir::LogicalResult cir::FuncOp::verify() { return success(); } @@ -1589,6 +1630,104 @@ OpFoldResult cir::VecExtractOp::fold(FoldAdaptor adaptor) { return elements[index]; } +//===----------------------------------------------------------------------===// +// VecCmpOp +//===----------------------------------------------------------------------===// + +OpFoldResult cir::VecCmpOp::fold(FoldAdaptor adaptor) { + auto lhsVecAttr = + mlir::dyn_cast_if_present(adaptor.getLhs()); + auto rhsVecAttr = + mlir::dyn_cast_if_present(adaptor.getRhs()); + if (!lhsVecAttr || !rhsVecAttr) + return {}; + + mlir::Type inputElemTy = + mlir::cast(lhsVecAttr.getType()).getElementType(); + if (!isAnyIntegerOrFloatingPointType(inputElemTy)) + return {}; + + cir::CmpOpKind opKind = adaptor.getKind(); + mlir::ArrayAttr lhsVecElhs = lhsVecAttr.getElts(); + mlir::ArrayAttr rhsVecElhs = rhsVecAttr.getElts(); + uint64_t vecSize = lhsVecElhs.size(); + + SmallVector elements(vecSize); + bool isIntAttr = vecSize && mlir::isa(lhsVecElhs[0]); + for (uint64_t i = 0; i < vecSize; i++) { + mlir::Attribute lhsAttr = lhsVecElhs[i]; + mlir::Attribute rhsAttr = rhsVecElhs[i]; + int cmpResult = 0; + switch (opKind) { + case cir::CmpOpKind::lt: { + if (isIntAttr) { + cmpResult = mlir::cast(lhsAttr).getSInt() < + mlir::cast(rhsAttr).getSInt(); + } else { + cmpResult = mlir::cast(lhsAttr).getValue() < + mlir::cast(rhsAttr).getValue(); + } + break; + } + case cir::CmpOpKind::le: { + if (isIntAttr) { + cmpResult = mlir::cast(lhsAttr).getSInt() <= + mlir::cast(rhsAttr).getSInt(); + } else { + cmpResult = mlir::cast(lhsAttr).getValue() <= + mlir::cast(rhsAttr).getValue(); + } + break; + } + case cir::CmpOpKind::gt: { + if (isIntAttr) { + cmpResult = mlir::cast(lhsAttr).getSInt() > + mlir::cast(rhsAttr).getSInt(); + } else { + cmpResult = mlir::cast(lhsAttr).getValue() > + mlir::cast(rhsAttr).getValue(); + } + break; + } + case cir::CmpOpKind::ge: { + if (isIntAttr) { + cmpResult = mlir::cast(lhsAttr).getSInt() >= + mlir::cast(rhsAttr).getSInt(); + } else { + cmpResult = mlir::cast(lhsAttr).getValue() >= + mlir::cast(rhsAttr).getValue(); + } + break; + } + case cir::CmpOpKind::eq: { + if (isIntAttr) { + cmpResult = mlir::cast(lhsAttr).getSInt() == + mlir::cast(rhsAttr).getSInt(); + } else { + cmpResult = mlir::cast(lhsAttr).getValue() == + mlir::cast(rhsAttr).getValue(); + } + break; + } + case cir::CmpOpKind::ne: { + if (isIntAttr) { + cmpResult = mlir::cast(lhsAttr).getSInt() != + mlir::cast(rhsAttr).getSInt(); + } else { + cmpResult = mlir::cast(lhsAttr).getValue() != + mlir::cast(rhsAttr).getValue(); + } + break; + } + } + + elements[i] = cir::IntAttr::get(getType().getElementType(), cmpResult); + } + + return cir::ConstVectorAttr::get( + getType(), mlir::ArrayAttr::get(getContext(), elements)); +} + //===----------------------------------------------------------------------===// // VecShuffleOp //===----------------------------------------------------------------------===// diff --git a/external/llvm-project/clang/lib/CIR/Dialect/Transforms/CIRCanonicalize.cpp b/external/llvm-project/clang/lib/CIR/Dialect/Transforms/CIRCanonicalize.cpp index 20c634d6c66f..f07e234e5e84 100644 --- a/external/llvm-project/clang/lib/CIR/Dialect/Transforms/CIRCanonicalize.cpp +++ b/external/llvm-project/clang/lib/CIR/Dialect/Transforms/CIRCanonicalize.cpp @@ -141,7 +141,7 @@ void CIRCanonicalizePass::runOnOperation() { // Many operations are here to perform a manual `fold` in // applyOpPatternsGreedily. if (isa(op)) ops.push_back(op); }); diff --git a/external/llvm-project/clang/lib/CIR/Dialect/Transforms/CIRSimplify.cpp b/external/llvm-project/clang/lib/CIR/Dialect/Transforms/CIRSimplify.cpp index 67ed4124f26c..3b7f08c44140 100644 --- a/external/llvm-project/clang/lib/CIR/Dialect/Transforms/CIRSimplify.cpp +++ b/external/llvm-project/clang/lib/CIR/Dialect/Transforms/CIRSimplify.cpp @@ -260,6 +260,31 @@ struct SimplifySwitch : public OpRewritePattern { } }; +struct SimplifyVecSplat : public OpRewritePattern { + using OpRewritePattern::OpRewritePattern; + LogicalResult matchAndRewrite(VecSplatOp op, + PatternRewriter &rewriter) const override { + mlir::Value splatValue = op.getValue(); + auto constant = + mlir::dyn_cast_if_present(splatValue.getDefiningOp()); + if (!constant) + return mlir::failure(); + + auto value = constant.getValue(); + if (!mlir::isa_and_nonnull(value) && + !mlir::isa_and_nonnull(value)) + return mlir::failure(); + + cir::VectorType resultType = op.getResult().getType(); + SmallVector elements(resultType.getSize(), value); + auto constVecAttr = cir::ConstVectorAttr::get( + resultType, mlir::ArrayAttr::get(getContext(), elements)); + + rewriter.replaceOpWithNewOp(op, constVecAttr); + return mlir::success(); + } +}; + //===----------------------------------------------------------------------===// // CIRSimplifyPass //===----------------------------------------------------------------------===// @@ -275,7 +300,8 @@ void populateMergeCleanupPatterns(RewritePatternSet &patterns) { patterns.add< SimplifyTernary, SimplifySelect, - SimplifySwitch + SimplifySwitch, + SimplifyVecSplat >(patterns.getContext()); // clang-format on } @@ -288,7 +314,7 @@ void CIRSimplifyPass::runOnOperation() { // Collect operations to apply patterns. llvm::SmallVector ops; getOperation()->walk([&](Operation *op) { - if (isa(op)) + if (isa(op)) ops.push_back(op); }); diff --git a/external/llvm-project/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp b/external/llvm-project/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp index 6a4e4e4a7df3..5f41e340e247 100644 --- a/external/llvm-project/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp +++ b/external/llvm-project/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp @@ -220,6 +220,39 @@ mlir::Value lowerCirAttrAsValue(mlir::Operation *parentOp, return value; } +void convertSideEffectForCall(mlir::Operation *callOp, + cir::SideEffect sideEffect, + mlir::LLVM::MemoryEffectsAttr &memoryEffect, + bool &noUnwind, bool &willReturn) { + using mlir::LLVM::ModRefInfo; + + switch (sideEffect) { + case cir::SideEffect::All: + memoryEffect = {}; + noUnwind = false; + willReturn = false; + break; + + case cir::SideEffect::Pure: + memoryEffect = mlir::LLVM::MemoryEffectsAttr::get( + callOp->getContext(), /*other=*/ModRefInfo::Ref, + /*argMem=*/ModRefInfo::Ref, + /*inaccessibleMem=*/ModRefInfo::Ref); + noUnwind = true; + willReturn = true; + break; + + case cir::SideEffect::Const: + memoryEffect = mlir::LLVM::MemoryEffectsAttr::get( + callOp->getContext(), /*other=*/ModRefInfo::NoModRef, + /*argMem=*/ModRefInfo::NoModRef, + /*inaccessibleMem=*/ModRefInfo::NoModRef); + noUnwind = true; + willReturn = true; + break; + } +} + /// IntAttr visitor. mlir::Value CIRAttrToValue::visitCirAttr(cir::IntAttr intAttr) { mlir::Location loc = parentOp->getLoc(); @@ -407,6 +440,14 @@ struct ConvertCIRToLLVMPass StringRef getArgument() const override { return "cir-flat-to-llvm"; } }; +mlir::LogicalResult CIRToLLVMAssumeOpLowering::matchAndRewrite( + cir::AssumeOp op, OpAdaptor adaptor, + mlir::ConversionPatternRewriter &rewriter) const { + auto cond = adaptor.getPredicate(); + rewriter.replaceOpWithNewOp(op, cond); + return mlir::success(); +} + mlir::LogicalResult CIRToLLVMBrCondOpLowering::matchAndRewrite( cir::BrCondOp brOp, OpAdaptor adaptor, mlir::ConversionPatternRewriter &rewriter) const { @@ -737,12 +778,18 @@ rewriteCallOrInvoke(mlir::Operation *op, mlir::ValueRange callOperands, mlir::FlatSymbolRefAttr calleeAttr) { llvm::SmallVector llvmResults; mlir::ValueTypeRange cirResults = op->getResultTypes(); + auto call = cast(op); if (converter->convertTypes(cirResults, llvmResults).failed()) return mlir::failure(); assert(!cir::MissingFeatures::opCallCallConv()); - assert(!cir::MissingFeatures::opCallSideEffect()); + + mlir::LLVM::MemoryEffectsAttr memoryEffects; + bool noUnwind = false; + bool willReturn = false; + convertSideEffectForCall(op, call.getSideEffect(), memoryEffects, noUnwind, + willReturn); mlir::LLVM::LLVMFunctionType llvmFnTy; if (calleeAttr) { // direct call @@ -767,10 +814,14 @@ rewriteCallOrInvoke(mlir::Operation *op, mlir::ValueRange callOperands, assert(!cir::MissingFeatures::opCallLandingPad()); assert(!cir::MissingFeatures::opCallContinueBlock()); assert(!cir::MissingFeatures::opCallCallConv()); - assert(!cir::MissingFeatures::opCallSideEffect()); - rewriter.replaceOpWithNewOp(op, llvmFnTy, calleeAttr, - callOperands); + auto newOp = rewriter.replaceOpWithNewOp( + op, llvmFnTy, calleeAttr, callOperands); + if (memoryEffects) + newOp.setMemoryEffectsAttr(memoryEffects); + newOp.setNoUnwind(noUnwind); + newOp.setWillReturn(willReturn); + return mlir::success(); } @@ -928,9 +979,7 @@ mlir::LogicalResult CIRToLLVMConstantOpLowering::matchAndRewrite( } attr = rewriter.getArrayAttr(components); - } - - else { + } else { return op.emitError() << "unsupported constant type " << op.getType(); } @@ -1811,6 +1860,7 @@ void ConvertCIRToLLVMPass::runOnOperation() { dl); patterns.add< // clang-format off + CIRToLLVMAssumeOpLowering, CIRToLLVMBaseClassAddrOpLowering, CIRToLLVMBinOpLowering, CIRToLLVMBrCondOpLowering, diff --git a/external/llvm-project/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.h b/external/llvm-project/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.h index a80981806354..ae7247332c66 100644 --- a/external/llvm-project/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.h +++ b/external/llvm-project/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.h @@ -29,6 +29,21 @@ mlir::Value lowerCirAttrAsValue(mlir::Operation *parentOp, mlir::Attribute attr, mlir::LLVM::Linkage convertLinkage(cir::GlobalLinkageKind linkage); +void convertSideEffectForCall(mlir::Operation *callOp, + cir::SideEffect sideEffect, + mlir::LLVM::MemoryEffectsAttr &memoryEffect, + bool &noUnwind, bool &willReturn); + +class CIRToLLVMAssumeOpLowering + : public mlir::OpConversionPattern { +public: + using mlir::OpConversionPattern::OpConversionPattern; + + mlir::LogicalResult + matchAndRewrite(cir::AssumeOp op, OpAdaptor, + mlir::ConversionPatternRewriter &) const override; +}; + class CIRToLLVMBrCondOpLowering : public mlir::OpConversionPattern { public: diff --git a/external/llvm-project/clang/lib/CodeGen/CGBlocks.cpp b/external/llvm-project/clang/lib/CodeGen/CGBlocks.cpp index 729758ddce56..f3ddf7bf9a46 100644 --- a/external/llvm-project/clang/lib/CodeGen/CGBlocks.cpp +++ b/external/llvm-project/clang/lib/CodeGen/CGBlocks.cpp @@ -1415,10 +1415,10 @@ llvm::Function *CodeGenFunction::GenerateBlockFunction( // Arrange for local static and local extern declarations to appear // to be local to this function as well, in case they're directly // referenced in a block. - for (DeclMapTy::const_iterator i = ldm.begin(), e = ldm.end(); i != e; ++i) { - const auto *var = dyn_cast(i->first); + for (const auto &KV : ldm) { + const auto *var = dyn_cast(KV.first); if (var && !var->hasLocalStorage()) - setAddrOfLocalVar(var, i->second); + setAddrOfLocalVar(var, KV.second); } // Begin building the function declaration. diff --git a/external/llvm-project/clang/lib/CodeGen/CGBuiltin.cpp b/external/llvm-project/clang/lib/CodeGen/CGBuiltin.cpp index 803fafcf8bc9..f7016d87b6e7 100644 --- a/external/llvm-project/clang/lib/CodeGen/CGBuiltin.cpp +++ b/external/llvm-project/clang/lib/CodeGen/CGBuiltin.cpp @@ -2032,7 +2032,7 @@ Value *CodeGenFunction::EmitCheckedArgForAssume(const Expr *E) { std::make_pair(ArgValue, CheckOrdinal), CheckHandler, {EmitCheckSourceLocation(E->getExprLoc()), llvm::ConstantInt::get(Builder.getInt8Ty(), BCK_AssumePassedFalse)}, - std::nullopt); + {}); return ArgValue; } diff --git a/external/llvm-project/clang/lib/CodeGen/CGCall.cpp b/external/llvm-project/clang/lib/CodeGen/CGCall.cpp index 4fa3ce84e96b..e455e29f3fbd 100644 --- a/external/llvm-project/clang/lib/CodeGen/CGCall.cpp +++ b/external/llvm-project/clang/lib/CodeGen/CGCall.cpp @@ -83,17 +83,8 @@ unsigned CodeGenTypes::ClangCallConvToLLVMCallConv(CallingConv CC) { return llvm::CallingConv::AArch64_SVE_VectorCall; case CC_SpirFunction: return llvm::CallingConv::SPIR_FUNC; - case CC_DeviceKernel: { - if (CGM.getLangOpts().OpenCL) - return CGM.getTargetCodeGenInfo().getOpenCLKernelCallingConv(); - if (CGM.getTriple().isSPIROrSPIRV()) - return llvm::CallingConv::SPIR_KERNEL; - if (CGM.getTriple().isAMDGPU()) - return llvm::CallingConv::AMDGPU_KERNEL; - if (CGM.getTriple().isNVPTX()) - return llvm::CallingConv::PTX_Kernel; - llvm_unreachable("Unknown kernel calling convention"); - } + case CC_DeviceKernel: + return CGM.getTargetCodeGenInfo().getDeviceKernelCallingConv(); case CC_PreserveMost: return llvm::CallingConv::PreserveMost; case CC_PreserveAll: diff --git a/external/llvm-project/clang/lib/CodeGen/CGCleanup.cpp b/external/llvm-project/clang/lib/CodeGen/CGCleanup.cpp index 4ed2c5183c47..28ac9bf39635 100644 --- a/external/llvm-project/clang/lib/CodeGen/CGCleanup.cpp +++ b/external/llvm-project/clang/lib/CodeGen/CGCleanup.cpp @@ -962,8 +962,8 @@ void CodeGenFunction::PopCleanupBlock(bool FallthroughIsBranchThrough, // Append the prepared cleanup prologue from above. llvm::BasicBlock *NormalExit = Builder.GetInsertBlock(); - for (unsigned I = 0, E = InstsToAppend.size(); I != E; ++I) - InstsToAppend[I]->insertInto(NormalExit, NormalExit->end()); + for (llvm::Instruction *Inst : InstsToAppend) + Inst->insertInto(NormalExit, NormalExit->end()); // Optimistically hope that any fixups will continue falling through. for (unsigned I = FixupDepth, E = EHStack.getNumBranchFixups(); diff --git a/external/llvm-project/clang/lib/CodeGen/CGDeclCXX.cpp b/external/llvm-project/clang/lib/CodeGen/CGDeclCXX.cpp index 69d77f283db3..7ae99935c8ad 100644 --- a/external/llvm-project/clang/lib/CodeGen/CGDeclCXX.cpp +++ b/external/llvm-project/clang/lib/CodeGen/CGDeclCXX.cpp @@ -1121,9 +1121,9 @@ CodeGenFunction::GenerateCXXGlobalInitFunc(llvm::Function *Fn, EmitObjCAutoreleasePoolCleanup(token); } - for (unsigned i = 0, e = Decls.size(); i != e; ++i) - if (Decls[i]) - EmitRuntimeCall(Decls[i]); + for (llvm::Function *Decl : Decls) + if (Decl) + EmitRuntimeCall(Decl); Scope.ForceCleanup(); diff --git a/external/llvm-project/clang/lib/CodeGen/CGException.cpp b/external/llvm-project/clang/lib/CodeGen/CGException.cpp index e0367282355c..ad138b9876e8 100644 --- a/external/llvm-project/clang/lib/CodeGen/CGException.cpp +++ b/external/llvm-project/clang/lib/CodeGen/CGException.cpp @@ -319,9 +319,9 @@ static bool PersonalityHasOnlyCXXUses(llvm::Constant *Fn) { llvm::Function *F = dyn_cast(U); if (!F) return false; - for (auto BB = F->begin(), E = F->end(); BB != E; ++BB) { - if (BB->isLandingPad()) - if (!LandingPadHasOnlyCXXUses(BB->getLandingPadInst())) + for (llvm::BasicBlock &BB : *F) { + if (BB.isLandingPad()) + if (!LandingPadHasOnlyCXXUses(BB.getLandingPadInst())) return false; } } @@ -937,8 +937,8 @@ llvm::BasicBlock *CodeGenFunction::EmitLandingPad() { filterTypes[0]->getType() : Int8PtrTy, filterTypes.size()); - for (unsigned i = 0, e = filterTypes.size(); i != e; ++i) - Filters.push_back(cast(filterTypes[i])); + for (llvm::Value *filterType : filterTypes) + Filters.push_back(cast(filterType)); llvm::Constant *FilterArray = llvm::ConstantArray::get(AType, Filters); LPadInst->addClause(FilterArray); diff --git a/external/llvm-project/clang/lib/CodeGen/CGExpr.cpp b/external/llvm-project/clang/lib/CodeGen/CGExpr.cpp index 5793c9fbdd93..650123fe4e2e 100644 --- a/external/llvm-project/clang/lib/CodeGen/CGExpr.cpp +++ b/external/llvm-project/clang/lib/CodeGen/CGExpr.cpp @@ -3801,8 +3801,8 @@ void CodeGenFunction::EmitCheck( ArgTypes.push_back(Args.back()->getType()); } - for (size_t i = 0, n = DynamicArgs.size(); i != n; ++i) { - Args.push_back(EmitCheckValue(DynamicArgs[i])); + for (llvm::Value *DynamicArg : DynamicArgs) { + Args.push_back(EmitCheckValue(DynamicArg)); ArgTypes.push_back(IntPtrTy); } } @@ -4932,8 +4932,8 @@ EmitExtVectorElementExpr(const ExtVectorElementExpr *E) { llvm::Constant *BaseElts = Base.getExtVectorElts(); SmallVector CElts; - for (unsigned i = 0, e = Indices.size(); i != e; ++i) - CElts.push_back(BaseElts->getAggregateElement(Indices[i])); + for (unsigned Index : Indices) + CElts.push_back(BaseElts->getAggregateElement(Index)); llvm::Constant *CV = llvm::ConstantVector::get(CElts); return LValue::MakeExtVectorElt(Base.getExtVectorAddress(), CV, type, Base.getBaseInfo(), TBAAAccessInfo()); @@ -6675,8 +6675,8 @@ static LValueOrRValue emitPseudoObjectExpr(CodeGenFunction &CGF, } // Unbind all the opaques now. - for (unsigned i = 0, e = opaques.size(); i != e; ++i) - opaques[i].unbind(CGF); + for (CodeGenFunction::OpaqueValueMappingData &opaque : opaques) + opaque.unbind(CGF); return result; } diff --git a/external/llvm-project/clang/lib/CodeGen/CGExprConstant.cpp b/external/llvm-project/clang/lib/CodeGen/CGExprConstant.cpp index 0ca5a415eb73..008120e4b0b5 100644 --- a/external/llvm-project/clang/lib/CodeGen/CGExprConstant.cpp +++ b/external/llvm-project/clang/lib/CodeGen/CGExprConstant.cpp @@ -870,9 +870,7 @@ bool ConstStructBuilder::Build(const APValue &Val, const RecordDecl *RD, } llvm::stable_sort(Bases); - for (unsigned I = 0, N = Bases.size(); I != N; ++I) { - BaseInfo &Base = Bases[I]; - + for (const BaseInfo &Base : Bases) { bool IsPrimaryBase = Layout.getPrimaryBase() == Base.Decl; Build(Val.getStructBase(Base.Index), Base.Decl, IsPrimaryBase, VTableClass, Offset + Base.Offset); diff --git a/external/llvm-project/clang/lib/CodeGen/CGHLSLBuiltins.cpp b/external/llvm-project/clang/lib/CodeGen/CGHLSLBuiltins.cpp index ccf45c0c6ff1..58165185b671 100644 --- a/external/llvm-project/clang/lib/CodeGen/CGHLSLBuiltins.cpp +++ b/external/llvm-project/clang/lib/CodeGen/CGHLSLBuiltins.cpp @@ -12,6 +12,7 @@ #include "CGBuiltin.h" #include "CGHLSLRuntime.h" +#include "CodeGenFunction.h" using namespace clang; using namespace CodeGen; @@ -214,6 +215,44 @@ static Intrinsic::ID getWaveActiveMaxIntrinsic(llvm::Triple::ArchType Arch, } } +// Returns the mangled name for a builtin function that the SPIR-V backend +// will expand into a spec Constant. +static std::string getSpecConstantFunctionName(clang::QualType SpecConstantType, + ASTContext &Context) { + // The parameter types for our conceptual intrinsic function. + QualType ClangParamTypes[] = {Context.IntTy, SpecConstantType}; + + // Create a temporary FunctionDecl for the builtin fuction. It won't be + // added to the AST. + FunctionProtoType::ExtProtoInfo EPI; + QualType FnType = + Context.getFunctionType(SpecConstantType, ClangParamTypes, EPI); + DeclarationName FuncName = &Context.Idents.get("__spirv_SpecConstant"); + FunctionDecl *FnDeclForMangling = FunctionDecl::Create( + Context, Context.getTranslationUnitDecl(), SourceLocation(), + SourceLocation(), FuncName, FnType, /*TSI=*/nullptr, SC_Extern); + + // Attach the created parameter declarations to the function declaration. + SmallVector ParamDecls; + for (QualType ParamType : ClangParamTypes) { + ParmVarDecl *PD = ParmVarDecl::Create( + Context, FnDeclForMangling, SourceLocation(), SourceLocation(), + /*IdentifierInfo*/ nullptr, ParamType, /*TSI*/ nullptr, SC_None, + /*DefaultArg*/ nullptr); + ParamDecls.push_back(PD); + } + FnDeclForMangling->setParams(ParamDecls); + + // Get the mangled name. + std::string Name; + llvm::raw_string_ostream MangledNameStream(Name); + std::unique_ptr Mangler(Context.createMangleContext()); + Mangler->mangleName(FnDeclForMangling, MangledNameStream); + MangledNameStream.flush(); + + return Name; +} + Value *CodeGenFunction::EmitHLSLBuiltinExpr(unsigned BuiltinID, const CallExpr *E, ReturnValueSlot ReturnValue) { @@ -637,35 +676,23 @@ Value *CodeGenFunction::EmitHLSLBuiltinExpr(unsigned BuiltinID, case Builtin::BI__builtin_hlsl_wave_active_sum: { // Due to the use of variadic arguments, explicitly retreive argument Value *OpExpr = EmitScalarExpr(E->getArg(0)); - llvm::FunctionType *FT = llvm::FunctionType::get( - OpExpr->getType(), ArrayRef{OpExpr->getType()}, false); Intrinsic::ID IID = getWaveActiveSumIntrinsic( getTarget().getTriple().getArch(), CGM.getHLSLRuntime(), E->getArg(0)->getType()); - // Get overloaded name - std::string Name = - Intrinsic::getName(IID, ArrayRef{OpExpr->getType()}, &CGM.getModule()); - return EmitRuntimeCall(CGM.CreateRuntimeFunction(FT, Name, {}, - /*Local=*/false, - /*AssumeConvergent=*/true), + return EmitRuntimeCall(Intrinsic::getOrInsertDeclaration( + &CGM.getModule(), IID, {OpExpr->getType()}), ArrayRef{OpExpr}, "hlsl.wave.active.sum"); } case Builtin::BI__builtin_hlsl_wave_active_max: { // Due to the use of variadic arguments, explicitly retreive argument Value *OpExpr = EmitScalarExpr(E->getArg(0)); - llvm::FunctionType *FT = llvm::FunctionType::get( - OpExpr->getType(), ArrayRef{OpExpr->getType()}, false); Intrinsic::ID IID = getWaveActiveMaxIntrinsic( getTarget().getTriple().getArch(), CGM.getHLSLRuntime(), E->getArg(0)->getType()); - // Get overloaded name - std::string Name = - Intrinsic::getName(IID, ArrayRef{OpExpr->getType()}, &CGM.getModule()); - return EmitRuntimeCall(CGM.CreateRuntimeFunction(FT, Name, {}, - /*Local=*/false, - /*AssumeConvergent=*/true), + return EmitRuntimeCall(Intrinsic::getOrInsertDeclaration( + &CGM.getModule(), IID, {OpExpr->getType()}), ArrayRef{OpExpr}, "hlsl.wave.active.max"); } case Builtin::BI__builtin_hlsl_wave_get_lane_index: { @@ -700,18 +727,11 @@ Value *CodeGenFunction::EmitHLSLBuiltinExpr(unsigned BuiltinID, // create our function type. Value *OpExpr = EmitScalarExpr(E->getArg(0)); Value *OpIndex = EmitScalarExpr(E->getArg(1)); - llvm::FunctionType *FT = llvm::FunctionType::get( - OpExpr->getType(), ArrayRef{OpExpr->getType(), OpIndex->getType()}, - false); - - // Get overloaded name - std::string Name = - Intrinsic::getName(CGM.getHLSLRuntime().getWaveReadLaneAtIntrinsic(), - ArrayRef{OpExpr->getType()}, &CGM.getModule()); - return EmitRuntimeCall(CGM.CreateRuntimeFunction(FT, Name, {}, - /*Local=*/false, - /*AssumeConvergent=*/true), - ArrayRef{OpExpr, OpIndex}, "hlsl.wave.readlane"); + return EmitRuntimeCall( + Intrinsic::getOrInsertDeclaration( + &CGM.getModule(), CGM.getHLSLRuntime().getWaveReadLaneAtIntrinsic(), + {OpExpr->getType()}), + ArrayRef{OpExpr, OpIndex}, "hlsl.wave.readlane"); } case Builtin::BI__builtin_hlsl_elementwise_sign: { auto *Arg0 = E->getArg(0); @@ -773,6 +793,42 @@ Value *CodeGenFunction::EmitHLSLBuiltinExpr(unsigned BuiltinID, return EmitRuntimeCall( Intrinsic::getOrInsertDeclaration(&CGM.getModule(), ID)); } + case Builtin::BI__builtin_get_spirv_spec_constant_bool: + case Builtin::BI__builtin_get_spirv_spec_constant_short: + case Builtin::BI__builtin_get_spirv_spec_constant_ushort: + case Builtin::BI__builtin_get_spirv_spec_constant_int: + case Builtin::BI__builtin_get_spirv_spec_constant_uint: + case Builtin::BI__builtin_get_spirv_spec_constant_longlong: + case Builtin::BI__builtin_get_spirv_spec_constant_ulonglong: + case Builtin::BI__builtin_get_spirv_spec_constant_half: + case Builtin::BI__builtin_get_spirv_spec_constant_float: + case Builtin::BI__builtin_get_spirv_spec_constant_double: { + llvm::Function *SpecConstantFn = getSpecConstantFunction(E->getType()); + llvm::Value *SpecId = EmitScalarExpr(E->getArg(0)); + llvm::Value *DefaultVal = EmitScalarExpr(E->getArg(1)); + llvm::Value *Args[] = {SpecId, DefaultVal}; + return Builder.CreateCall(SpecConstantFn, Args); + } } return nullptr; } + +llvm::Function *clang::CodeGen::CodeGenFunction::getSpecConstantFunction( + const clang::QualType &SpecConstantType) { + + // Find or create the declaration for the function. + llvm::Module *M = &CGM.getModule(); + std::string MangledName = + getSpecConstantFunctionName(SpecConstantType, getContext()); + llvm::Function *SpecConstantFn = M->getFunction(MangledName); + + if (!SpecConstantFn) { + llvm::Type *IntType = ConvertType(getContext().IntTy); + llvm::Type *RetTy = ConvertType(SpecConstantType); + llvm::Type *ArgTypes[] = {IntType, RetTy}; + llvm::FunctionType *FnTy = llvm::FunctionType::get(RetTy, ArgTypes, false); + SpecConstantFn = llvm::Function::Create( + FnTy, llvm::GlobalValue::ExternalLinkage, MangledName, M); + } + return SpecConstantFn; +} diff --git a/external/llvm-project/clang/lib/CodeGen/CGHLSLRuntime.cpp b/external/llvm-project/clang/lib/CodeGen/CGHLSLRuntime.cpp index 571ff53b7d64..3103f1798e14 100644 --- a/external/llvm-project/clang/lib/CodeGen/CGHLSLRuntime.cpp +++ b/external/llvm-project/clang/lib/CodeGen/CGHLSLRuntime.cpp @@ -72,12 +72,17 @@ void addRootSignature(ArrayRef Elements, llvm::hlsl::rootsig::MetadataBuilder Builder(Ctx, Elements); MDNode *RootSignature = Builder.BuildRootSignature(); - MDNode *FnPairing = - MDNode::get(Ctx, {ValueAsMetadata::get(Fn), RootSignature}); + + // TODO: We need to wire the root signature version up through the frontend + // rather than hardcoding it. + ConstantAsMetadata *Version = + ConstantAsMetadata::get(ConstantInt::get(llvm::Type::getInt32Ty(Ctx), 2)); + MDNode *MDVals = + MDNode::get(Ctx, {ValueAsMetadata::get(Fn), RootSignature, Version}); StringRef RootSignatureValKey = "dx.rootsignatures"; auto *RootSignatureValMD = M.getOrInsertNamedMetadata(RootSignatureValKey); - RootSignatureValMD->addOperand(FnPairing); + RootSignatureValMD->addOperand(MDVals); } } // namespace @@ -375,6 +380,7 @@ static llvm::Value *createSPIRVBuiltinLoad(IRBuilder<> &B, llvm::Module &M, llvm::GlobalVariable::GeneralDynamicTLSModel, /* AddressSpace */ 7, /* isExternallyInitialized= */ true); addSPIRVBuiltinDecoration(GV, BuiltInID); + GV->setVisibility(llvm::GlobalValue::HiddenVisibility); return B.CreateLoad(Ty, GV); } @@ -471,14 +477,6 @@ void CGHLSLRuntime::emitEntryFunction(const FunctionDecl *FD, } } -void CGHLSLRuntime::setHLSLFunctionAttributes(const FunctionDecl *FD, - llvm::Function *Fn) { - if (FD->isInExportDeclContext()) { - const StringRef ExportAttrKindStr = "hlsl.export"; - Fn->addFnAttr(ExportAttrKindStr); - } -} - static void gatherFunctions(SmallVectorImpl &Fns, llvm::Module &M, bool CtorOrDtor) { const auto *GV = diff --git a/external/llvm-project/clang/lib/CodeGen/CGObjC.cpp b/external/llvm-project/clang/lib/CodeGen/CGObjC.cpp index 8a1b44a0c157..6f87444d3f67 100644 --- a/external/llvm-project/clang/lib/CodeGen/CGObjC.cpp +++ b/external/llvm-project/clang/lib/CodeGen/CGObjC.cpp @@ -3173,8 +3173,8 @@ ARCExprEmitter::visitPseudoObjectExpr(const PseudoObjectExpr *E) { } // Unbind all the opaques now. - for (unsigned i = 0, e = opaques.size(); i != e; ++i) - opaques[i].unbind(CGF); + for (CodeGenFunction::OpaqueValueMappingData &opaque : opaques) + opaque.unbind(CGF); return result; } diff --git a/external/llvm-project/clang/lib/CodeGen/CGObjCGNU.cpp b/external/llvm-project/clang/lib/CodeGen/CGObjCGNU.cpp index 3fc837c12a92..d828702cbb87 100644 --- a/external/llvm-project/clang/lib/CodeGen/CGObjCGNU.cpp +++ b/external/llvm-project/clang/lib/CodeGen/CGObjCGNU.cpp @@ -1103,8 +1103,7 @@ class CGObjCGNUstep2 : public CGObjCGNUstep { bool isNamed = !isNonASCII; if (isNamed) { StringName = ".objc_str_"; - for (int i=0,e=Str.size() ; i &Types = SelectorTable[Sel]; llvm::GlobalAlias *SelValue = nullptr; - for (SmallVectorImpl::iterator i = Types.begin(), - e = Types.end() ; i!=e ; i++) { - if (i->first == TypeEncoding) { - SelValue = i->second; + for (const TypedSelector &Type : Types) { + if (Type.first == TypeEncoding) { + SelValue = Type.second; break; } } @@ -3333,13 +3331,12 @@ CGObjCGNU::GenerateProtocolList(ArrayRef Protocols) { ProtocolList.addInt(LongTy, Protocols.size()); auto Elements = ProtocolList.beginArray(PtrToInt8Ty); - for (const std::string *iter = Protocols.begin(), *endIter = Protocols.end(); - iter != endIter ; iter++) { + for (const std::string &Protocol : Protocols) { llvm::Constant *protocol = nullptr; - llvm::StringMap::iterator value = - ExistingProtocols.find(*iter); + llvm::StringMap::iterator value = + ExistingProtocols.find(Protocol); if (value == ExistingProtocols.end()) { - protocol = GenerateEmptyProtocol(*iter); + protocol = GenerateEmptyProtocol(Protocol); } else { protocol = value->getValue(); } diff --git a/external/llvm-project/clang/lib/CodeGen/CGObjCMac.cpp b/external/llvm-project/clang/lib/CodeGen/CGObjCMac.cpp index 1c23a8b4db91..a52c92cdbc83 100644 --- a/external/llvm-project/clang/lib/CodeGen/CGObjCMac.cpp +++ b/external/llvm-project/clang/lib/CodeGen/CGObjCMac.cpp @@ -2702,8 +2702,8 @@ llvm::Constant *CGObjCCommonMac::getBitmapBlockLayout(bool ComputeByrefLayout) { unsigned char inst = (BLOCK_LAYOUT_OPERATOR << 4) | 0; Layout.push_back(inst); std::string BitMap; - for (unsigned i = 0, e = Layout.size(); i != e; i++) - BitMap += Layout[i]; + for (unsigned char C : Layout) + BitMap += C; if (CGM.getLangOpts().ObjCGCBitmapPrint) { if (ComputeByrefLayout) @@ -4225,9 +4225,8 @@ FragileHazards::FragileHazards(CodeGenFunction &CGF) : CGF(CGF) { return; // Collect all the blocks in the function. - for (llvm::Function::iterator I = CGF.CurFn->begin(), E = CGF.CurFn->end(); - I != E; ++I) - BlocksBeforeTry.insert(&*I); + for (llvm::BasicBlock &BB : *CGF.CurFn) + BlocksBeforeTry.insert(&BB); llvm::FunctionType *AsmFnTy = GetAsmFnType(); @@ -4299,9 +4298,7 @@ void FragileHazards::emitHazardsInNewBlocks() { CGBuilderTy Builder(CGF, CGF.getLLVMContext()); // Iterate through all blocks, skipping those prior to the try. - for (llvm::Function::iterator FI = CGF.CurFn->begin(), FE = CGF.CurFn->end(); - FI != FE; ++FI) { - llvm::BasicBlock &BB = *FI; + for (llvm::BasicBlock &BB : *CGF.CurFn) { if (BlocksBeforeTry.count(&BB)) continue; @@ -4348,10 +4345,9 @@ void FragileHazards::collectLocals() { // Collect all the allocas currently in the function. This is // probably way too aggressive. llvm::BasicBlock &Entry = CGF.CurFn->getEntryBlock(); - for (llvm::BasicBlock::iterator I = Entry.begin(), E = Entry.end(); I != E; - ++I) - if (isa(*I) && !AllocasToIgnore.count(&*I)) - Locals.push_back(&*I); + for (llvm::Instruction &I : Entry) + if (isa(I) && !AllocasToIgnore.count(&I)) + Locals.push_back(&I); } llvm::FunctionType *FragileHazards::GetAsmFnType() { diff --git a/external/llvm-project/clang/lib/CodeGen/CGObjCRuntime.cpp b/external/llvm-project/clang/lib/CodeGen/CGObjCRuntime.cpp index dfb0fd14d93a..6e2f32022a01 100644 --- a/external/llvm-project/clang/lib/CodeGen/CGObjCRuntime.cpp +++ b/external/llvm-project/clang/lib/CodeGen/CGObjCRuntime.cpp @@ -220,9 +220,7 @@ void CGObjCRuntime::EmitTryCatchStmt(CodeGenFunction &CGF, CGBuilderTy::InsertPoint SavedIP = CGF.Builder.saveAndClearIP(); // Emit the handlers. - for (unsigned I = 0, E = Handlers.size(); I != E; ++I) { - CatchHandler &Handler = Handlers[I]; - + for (CatchHandler &Handler : Handlers) { CGF.EmitBlock(Handler.Block); CodeGenFunction::LexicalScope Cleanups(CGF, Handler.Body->getSourceRange()); diff --git a/external/llvm-project/clang/lib/CodeGen/CGOpenMPRuntime.cpp b/external/llvm-project/clang/lib/CodeGen/CGOpenMPRuntime.cpp index 75c4442d3fe9..11d305df5165 100644 --- a/external/llvm-project/clang/lib/CodeGen/CGOpenMPRuntime.cpp +++ b/external/llvm-project/clang/lib/CodeGen/CGOpenMPRuntime.cpp @@ -4214,8 +4214,7 @@ void CGOpenMPRuntime::emitDepobjElements(CodeGenFunction &CGF, CGF, cast_or_null( Data.IteratorExpr ? Data.IteratorExpr->IgnoreParenImpCasts() : nullptr)); - for (unsigned I = 0, End = Data.DepExprs.size(); I < End; ++I) { - const Expr *E = Data.DepExprs[I]; + for (const Expr *E : Data.DepExprs) { llvm::Value *NumDeps; LValue Base; LValue DepobjLVal = CGF.EmitLValue(E->IgnoreParenImpCasts()); @@ -4335,31 +4334,26 @@ std::pair CGOpenMPRuntime::emitDependClause( /*isSigned=*/false); } unsigned Pos = 0; - for (unsigned I = 0, End = Dependencies.size(); I < End; ++I) { - if (Dependencies[I].DepKind == OMPC_DEPEND_depobj || - Dependencies[I].IteratorExpr) + for (const OMPTaskDataTy::DependData &Dep : Dependencies) { + if (Dep.DepKind == OMPC_DEPEND_depobj || Dep.IteratorExpr) continue; - emitDependData(CGF, KmpDependInfoTy, &Pos, Dependencies[I], - DependenciesArray); + emitDependData(CGF, KmpDependInfoTy, &Pos, Dep, DependenciesArray); } // Copy regular dependencies with iterators. LValue PosLVal = CGF.MakeAddrLValue( CGF.CreateMemTemp(C.getSizeType(), "dep.counter.addr"), C.getSizeType()); CGF.EmitStoreOfScalar(llvm::ConstantInt::get(CGF.SizeTy, Pos), PosLVal); - for (unsigned I = 0, End = Dependencies.size(); I < End; ++I) { - if (Dependencies[I].DepKind == OMPC_DEPEND_depobj || - !Dependencies[I].IteratorExpr) + for (const OMPTaskDataTy::DependData &Dep : Dependencies) { + if (Dep.DepKind == OMPC_DEPEND_depobj || !Dep.IteratorExpr) continue; - emitDependData(CGF, KmpDependInfoTy, &PosLVal, Dependencies[I], - DependenciesArray); + emitDependData(CGF, KmpDependInfoTy, &PosLVal, Dep, DependenciesArray); } // Copy final depobj arrays without iterators. if (HasDepobjDeps) { - for (unsigned I = 0, End = Dependencies.size(); I < End; ++I) { - if (Dependencies[I].DepKind != OMPC_DEPEND_depobj) + for (const OMPTaskDataTy::DependData &Dep : Dependencies) { + if (Dep.DepKind != OMPC_DEPEND_depobj) continue; - emitDepobjElements(CGF, KmpDependInfoTy, PosLVal, Dependencies[I], - DependenciesArray); + emitDepobjElements(CGF, KmpDependInfoTy, PosLVal, Dep, DependenciesArray); } } DependenciesArray = CGF.Builder.CreatePointerBitCastOrAddrSpaceCast( diff --git a/external/llvm-project/clang/lib/CodeGen/CGOpenMPRuntimeGPU.cpp b/external/llvm-project/clang/lib/CodeGen/CGOpenMPRuntimeGPU.cpp index 2dc5689f5284..8091e4e9e1b0 100644 --- a/external/llvm-project/clang/lib/CodeGen/CGOpenMPRuntimeGPU.cpp +++ b/external/llvm-project/clang/lib/CodeGen/CGOpenMPRuntimeGPU.cpp @@ -2573,6 +2573,7 @@ void CGOpenMPRuntimeGPU::processRequiresDirective(const OMPRequiresDecl *D) { case OffloadArch::GFX12_GENERIC: case OffloadArch::GFX1200: case OffloadArch::GFX1201: + case OffloadArch::GFX1250: case OffloadArch::AMDGCNSPIRV: case OffloadArch::Generic: case OffloadArch::GRANITERAPIDS: diff --git a/external/llvm-project/clang/lib/CodeGen/CGRecordLayoutBuilder.cpp b/external/llvm-project/clang/lib/CodeGen/CGRecordLayoutBuilder.cpp index c37e63f4e767..ba471f8629c8 100644 --- a/external/llvm-project/clang/lib/CodeGen/CGRecordLayoutBuilder.cpp +++ b/external/llvm-project/clang/lib/CodeGen/CGRecordLayoutBuilder.cpp @@ -971,18 +971,16 @@ void CGRecordLowering::determinePacked(bool NVBaseType) { CharUnits NVAlignment = CharUnits::One(); CharUnits NVSize = !NVBaseType && RD ? Layout.getNonVirtualSize() : CharUnits::Zero(); - for (std::vector::const_iterator Member = Members.begin(), - MemberEnd = Members.end(); - Member != MemberEnd; ++Member) { - if (!Member->Data) + for (const MemberInfo &Member : Members) { + if (!Member.Data) continue; // If any member falls at an offset that it not a multiple of its alignment, // then the entire record must be packed. - if (Member->Offset % getAlignment(Member->Data)) + if (Member.Offset % getAlignment(Member.Data)) Packed = true; - if (Member->Offset < NVSize) - NVAlignment = std::max(NVAlignment, getAlignment(Member->Data)); - Alignment = std::max(Alignment, getAlignment(Member->Data)); + if (Member.Offset < NVSize) + NVAlignment = std::max(NVAlignment, getAlignment(Member.Data)); + Alignment = std::max(Alignment, getAlignment(Member.Data)); } // If the size of the record (the capstone's offset) is not a multiple of the // record's alignment, it must be packed. @@ -1001,45 +999,39 @@ void CGRecordLowering::determinePacked(bool NVBaseType) { void CGRecordLowering::insertPadding() { std::vector > Padding; CharUnits Size = CharUnits::Zero(); - for (std::vector::const_iterator Member = Members.begin(), - MemberEnd = Members.end(); - Member != MemberEnd; ++Member) { - if (!Member->Data) + for (const MemberInfo &Member : Members) { + if (!Member.Data) continue; - CharUnits Offset = Member->Offset; + CharUnits Offset = Member.Offset; assert(Offset >= Size); // Insert padding if we need to. if (Offset != - Size.alignTo(Packed ? CharUnits::One() : getAlignment(Member->Data))) + Size.alignTo(Packed ? CharUnits::One() : getAlignment(Member.Data))) Padding.push_back(std::make_pair(Size, Offset - Size)); - Size = Offset + getSize(Member->Data); + Size = Offset + getSize(Member.Data); } if (Padding.empty()) return; // Add the padding to the Members list and sort it. - for (std::vector >::const_iterator - Pad = Padding.begin(), PadEnd = Padding.end(); - Pad != PadEnd; ++Pad) - Members.push_back(StorageInfo(Pad->first, getByteArrayType(Pad->second))); + for (const auto &Pad : Padding) + Members.push_back(StorageInfo(Pad.first, getByteArrayType(Pad.second))); llvm::stable_sort(Members); } void CGRecordLowering::fillOutputFields() { - for (std::vector::const_iterator Member = Members.begin(), - MemberEnd = Members.end(); - Member != MemberEnd; ++Member) { - if (Member->Data) - FieldTypes.push_back(Member->Data); - if (Member->Kind == MemberInfo::Field) { - if (Member->FD) - Fields[Member->FD->getCanonicalDecl()] = FieldTypes.size() - 1; + for (const MemberInfo &Member : Members) { + if (Member.Data) + FieldTypes.push_back(Member.Data); + if (Member.Kind == MemberInfo::Field) { + if (Member.FD) + Fields[Member.FD->getCanonicalDecl()] = FieldTypes.size() - 1; // A field without storage must be a bitfield. - if (!Member->Data) - setBitFieldInfo(Member->FD, Member->Offset, FieldTypes.back()); - } else if (Member->Kind == MemberInfo::Base) - NonVirtualBases[Member->RD] = FieldTypes.size() - 1; - else if (Member->Kind == MemberInfo::VBase) - VirtualBases[Member->RD] = FieldTypes.size() - 1; + if (!Member.Data) + setBitFieldInfo(Member.FD, Member.Offset, FieldTypes.back()); + } else if (Member.Kind == MemberInfo::Base) + NonVirtualBases[Member.RD] = FieldTypes.size() - 1; + else if (Member.Kind == MemberInfo::VBase) + VirtualBases[Member.RD] = FieldTypes.size() - 1; } } @@ -1223,20 +1215,18 @@ void CGRecordLayout::print(raw_ostream &OS) const { // Print bit-field infos in declaration order. std::vector > BFIs; - for (llvm::DenseMap::const_iterator - it = BitFields.begin(), ie = BitFields.end(); - it != ie; ++it) { - const RecordDecl *RD = it->first->getParent(); + for (const auto &BitField : BitFields) { + const RecordDecl *RD = BitField.first->getParent(); unsigned Index = 0; - for (RecordDecl::field_iterator - it2 = RD->field_begin(); *it2 != it->first; ++it2) + for (RecordDecl::field_iterator it2 = RD->field_begin(); + *it2 != BitField.first; ++it2) ++Index; - BFIs.push_back(std::make_pair(Index, &it->second)); + BFIs.push_back(std::make_pair(Index, &BitField.second)); } llvm::array_pod_sort(BFIs.begin(), BFIs.end()); - for (unsigned i = 0, e = BFIs.size(); i != e; ++i) { + for (auto &BFI : BFIs) { OS.indent(4); - BFIs[i].second->print(OS); + BFI.second->print(OS); OS << "\n"; } diff --git a/external/llvm-project/clang/lib/CodeGen/CGStmt.cpp b/external/llvm-project/clang/lib/CodeGen/CGStmt.cpp index f92d052c253f..72b92d25f015 100644 --- a/external/llvm-project/clang/lib/CodeGen/CGStmt.cpp +++ b/external/llvm-project/clang/lib/CodeGen/CGStmt.cpp @@ -1834,10 +1834,9 @@ void CodeGenFunction::LexicalScope::rescopeLabels() { = CGF.EHStack.getInnermostNormalCleanup(); // Change the scope depth of all the labels. - for (SmallVectorImpl::const_iterator - i = Labels.begin(), e = Labels.end(); i != e; ++i) { - assert(CGF.LabelMap.count(*i)); - JumpDest &dest = CGF.LabelMap.find(*i)->second; + for (const LabelDecl *Label : Labels) { + assert(CGF.LabelMap.count(Label)); + JumpDest &dest = CGF.LabelMap.find(Label)->second; assert(dest.getScopeDepth().isValid()); assert(innermostScope.encloses(dest.getScopeDepth())); dest.setScopeDepth(innermostScope); @@ -3566,8 +3565,8 @@ void CodeGenFunction::EmitSwitchStmt(const SwitchStmt &S) { // Okay, we can dead code eliminate everything except this case. Emit the // specified series of statements and we're good. - for (unsigned i = 0, e = CaseStmts.size(); i != e; ++i) - EmitStmt(CaseStmts[i]); + for (const Stmt *CaseStmt : CaseStmts) + EmitStmt(CaseStmt); incrementProfileCounter(&S); PGO->markStmtMaybeUsed(S.getBody()); diff --git a/external/llvm-project/clang/lib/CodeGen/CodeGenFunction.cpp b/external/llvm-project/clang/lib/CodeGen/CodeGenFunction.cpp index 13d0633e9b1c..70a09795d02f 100644 --- a/external/llvm-project/clang/lib/CodeGen/CodeGenFunction.cpp +++ b/external/llvm-project/clang/lib/CodeGen/CodeGenFunction.cpp @@ -1267,7 +1267,6 @@ void CodeGenFunction::StartFunction(GlobalDecl GD, QualType RetTy, if (FD->hasAttr()) { CGM.getHLSLRuntime().emitEntryFunction(FD, Fn); } - CGM.getHLSLRuntime().setHLSLFunctionAttributes(FD, Fn); } EmitFunctionProlog(*CurFnInfo, CurFn, Args); diff --git a/external/llvm-project/clang/lib/CodeGen/CodeGenFunction.h b/external/llvm-project/clang/lib/CodeGen/CodeGenFunction.h index 5842ebaaf9b3..90909034cc7d 100644 --- a/external/llvm-project/clang/lib/CodeGen/CodeGenFunction.h +++ b/external/llvm-project/clang/lib/CodeGen/CodeGenFunction.h @@ -4958,6 +4958,12 @@ class CodeGenFunction : public CodeGenTypeCache { llvm::Value *EmitAMDGPUBuiltinExpr(unsigned BuiltinID, const CallExpr *E); llvm::Value *EmitHLSLBuiltinExpr(unsigned BuiltinID, const CallExpr *E, ReturnValueSlot ReturnValue); + + // Returns a builtin function that the SPIR-V backend will expand into a spec + // constant. + llvm::Function * + getSpecConstantFunction(const clang::QualType &SpecConstantType); + llvm::Value *EmitDirectXBuiltinExpr(unsigned BuiltinID, const CallExpr *E); llvm::Value *EmitSPIRVBuiltinExpr(unsigned BuiltinID, const CallExpr *E); llvm::Value *EmitScalarOrConstFoldImmArg(unsigned ICEArguments, unsigned Idx, diff --git a/external/llvm-project/clang/lib/CodeGen/CodeGenModule.cpp b/external/llvm-project/clang/lib/CodeGen/CodeGenModule.cpp index a4eda9984217..79d0e218f35d 100644 --- a/external/llvm-project/clang/lib/CodeGen/CodeGenModule.cpp +++ b/external/llvm-project/clang/lib/CodeGen/CodeGenModule.cpp @@ -973,7 +973,7 @@ void CodeGenModule::Release() { llvm::ConstantArray::get(ATy, UsedArray), "__clang_gpu_used_external"); addCompilerUsedGlobal(GV); } - if (LangOpts.HIP && !getLangOpts().OffloadingNewDriver) { + if (LangOpts.HIP) { // Emit a unique ID so that host and device binaries from the same // compilation unit can be associated. auto *GV = new llvm::GlobalVariable( @@ -1323,8 +1323,10 @@ void CodeGenModule::Release() { 1); // Enable unwind v2 (epilog). - if (CodeGenOpts.WinX64EHUnwindV2) - getModule().addModuleFlag(llvm::Module::Warning, "winx64-eh-unwindv2", 1); + if (CodeGenOpts.getWinX64EHUnwindV2() != llvm::WinX64EHUnwindV2Mode::Disabled) + getModule().addModuleFlag( + llvm::Module::Warning, "winx64-eh-unwindv2", + static_cast(CodeGenOpts.getWinX64EHUnwindV2())); // Indicate whether this Module was compiled with -fopenmp if (getLangOpts().OpenMP && !getLangOpts().OpenMPSimd) @@ -1670,6 +1672,11 @@ void CodeGenModule::setGlobalVisibility(llvm::GlobalValue *GV, return; } + if (Context.getLangOpts().HLSL && !D->isInExportDeclContext()) { + GV->setVisibility(llvm::GlobalValue::HiddenVisibility); + return; + } + if (GV->hasDLLExportStorageClass() || GV->hasDLLImportStorageClass()) { // Reject incompatible dlllstorage and visibility annotations. if (!LV.isVisibilityExplicit()) diff --git a/external/llvm-project/clang/lib/CodeGen/MicrosoftCXXABI.cpp b/external/llvm-project/clang/lib/CodeGen/MicrosoftCXXABI.cpp index 514cc1d9015e..a18155983429 100644 --- a/external/llvm-project/clang/lib/CodeGen/MicrosoftCXXABI.cpp +++ b/external/llvm-project/clang/lib/CodeGen/MicrosoftCXXABI.cpp @@ -1836,9 +1836,9 @@ llvm::GlobalVariable *MicrosoftCXXABI::getAddrOfVTable(const CXXRecordDecl *RD, // Create all the vftables at once in order to make sure each vftable has // a unique mangled name. llvm::StringSet<> ObservedMangledNames; - for (size_t J = 0, F = VFPtrs.size(); J != F; ++J) { + for (const auto &VFPtr : VFPtrs) { SmallString<256> Name; - mangleVFTableName(getMangleContext(), RD, *VFPtrs[J], Name); + mangleVFTableName(getMangleContext(), RD, *VFPtr, Name); if (!ObservedMangledNames.insert(Name.str()).second) llvm_unreachable("Already saw this mangling before?"); } diff --git a/external/llvm-project/clang/lib/CodeGen/ModuleBuilder.cpp b/external/llvm-project/clang/lib/CodeGen/ModuleBuilder.cpp index 09a7d79ae4af..8c1fee8c974f 100644 --- a/external/llvm-project/clang/lib/CodeGen/ModuleBuilder.cpp +++ b/external/llvm-project/clang/lib/CodeGen/ModuleBuilder.cpp @@ -186,8 +186,8 @@ namespace { HandlingTopLevelDeclRAII HandlingDecl(*this); // Make sure to emit all elements of a Decl. - for (DeclGroupRef::iterator I = DG.begin(), E = DG.end(); I != E; ++I) - Builder->EmitTopLevelDecl(*I); + for (auto &I : DG) + Builder->EmitTopLevelDecl(I); return true; } diff --git a/external/llvm-project/clang/lib/CodeGen/TargetBuiltins/ARM.cpp b/external/llvm-project/clang/lib/CodeGen/TargetBuiltins/ARM.cpp index dab311903f6d..6738d4be6dd2 100644 --- a/external/llvm-project/clang/lib/CodeGen/TargetBuiltins/ARM.cpp +++ b/external/llvm-project/clang/lib/CodeGen/TargetBuiltins/ARM.cpp @@ -4560,10 +4560,10 @@ Value *CodeGenFunction::EmitAArch64SVEBuiltinExpr(unsigned BuiltinID, Ops.insert(&Ops[1], Builder.getInt32(/*SV_ALL*/ 31)); // Predicates must match the main datatype. - for (unsigned i = 0, e = Ops.size(); i != e; ++i) - if (auto PredTy = dyn_cast(Ops[i]->getType())) + for (Value *&Op : Ops) + if (auto PredTy = dyn_cast(Op->getType())) if (PredTy->getElementType()->isIntegerTy(1)) - Ops[i] = EmitSVEPredicateCast(Ops[i], getSVEType(TypeFlags)); + Op = EmitSVEPredicateCast(Op, getSVEType(TypeFlags)); // Splat scalar operand to vector (intrinsics with _n infix) if (TypeFlags.hasSplatOperand()) { @@ -4936,10 +4936,10 @@ Value *CodeGenFunction::EmitAArch64SMEBuiltinExpr(unsigned BuiltinID, } // Predicates must match the main datatype. - for (unsigned i = 0, e = Ops.size(); i != e; ++i) - if (auto PredTy = dyn_cast(Ops[i]->getType())) + for (Value *&Op : Ops) + if (auto PredTy = dyn_cast(Op->getType())) if (PredTy->getElementType()->isIntegerTy(1)) - Ops[i] = EmitSVEPredicateCast(Ops[i], getSVEType(TypeFlags)); + Op = EmitSVEPredicateCast(Op, getSVEType(TypeFlags)); Function *F = TypeFlags.isOverloadNone() @@ -8036,8 +8036,8 @@ BuildVector(ArrayRef Ops) { // If this is a constant vector, create a ConstantVector. if (AllConstants) { SmallVector CstOps; - for (unsigned i = 0, e = Ops.size(); i != e; ++i) - CstOps.push_back(cast(Ops[i])); + for (llvm::Value *Op : Ops) + CstOps.push_back(cast(Op)); return llvm::ConstantVector::get(CstOps); } diff --git a/external/llvm-project/clang/lib/CodeGen/TargetInfo.cpp b/external/llvm-project/clang/lib/CodeGen/TargetInfo.cpp index f3df92c44bb6..277d69daf493 100644 --- a/external/llvm-project/clang/lib/CodeGen/TargetInfo.cpp +++ b/external/llvm-project/clang/lib/CodeGen/TargetInfo.cpp @@ -103,18 +103,21 @@ TargetCodeGenInfo::getDependentLibraryOption(llvm::StringRef Lib, Opt += Lib; } -unsigned TargetCodeGenInfo::getOpenCLKernelCallingConv() const { - // OpenCL kernels are called via an explicit runtime API with arguments - // set with clSetKernelArg(), not as normal sub-functions. - // Return SPIR_KERNEL by default as the kernel calling convention to - // ensure the fingerprint is fixed such way that each OpenCL argument - // gets one matching argument in the produced kernel function argument - // list to enable feasible implementation of clSetKernelArg() with - // aggregates etc. In case we would use the default C calling conv here, - // clSetKernelArg() might break depending on the target-specific - // conventions; different targets might split structs passed as values - // to multiple function arguments etc. - return llvm::CallingConv::SPIR_KERNEL; +unsigned TargetCodeGenInfo::getDeviceKernelCallingConv() const { + if (getABIInfo().getContext().getLangOpts().OpenCL) { + // Device kernels are called via an explicit runtime API with arguments, + // such as set with clSetKernelArg() for OpenCL, not as normal + // sub-functions. Return SPIR_KERNEL by default as the kernel calling + // convention to ensure the fingerprint is fixed such way that each kernel + // argument gets one matching argument in the produced kernel function + // argument list to enable feasible implementation of clSetKernelArg() with + // aggregates etc. In case we would use the default C calling conv here, + // clSetKernelArg() might break depending on the target-specific + // conventions; different targets might split structs passed as values + // to multiple function arguments etc. + return llvm::CallingConv::SPIR_KERNEL; + } + llvm_unreachable("Unknown kernel calling convention"); } void TargetCodeGenInfo::setOCLKernelStubCallingConvention( diff --git a/external/llvm-project/clang/lib/CodeGen/TargetInfo.h b/external/llvm-project/clang/lib/CodeGen/TargetInfo.h index 2783e222eb80..b4057d369f98 100644 --- a/external/llvm-project/clang/lib/CodeGen/TargetInfo.h +++ b/external/llvm-project/clang/lib/CodeGen/TargetInfo.h @@ -298,8 +298,8 @@ class TargetCodeGenInfo { llvm::StringRef Value, llvm::SmallString<32> &Opt) const {} - /// Get LLVM calling convention for OpenCL kernel. - virtual unsigned getOpenCLKernelCallingConv() const; + /// Get LLVM calling convention for device kernels. + virtual unsigned getDeviceKernelCallingConv() const; /// Get target specific null pointer. /// \param T is the LLVM type of the null pointer. diff --git a/external/llvm-project/clang/lib/CodeGen/Targets/AMDGPU.cpp b/external/llvm-project/clang/lib/CodeGen/Targets/AMDGPU.cpp index 8660373c3927..47a552a7bf49 100644 --- a/external/llvm-project/clang/lib/CodeGen/Targets/AMDGPU.cpp +++ b/external/llvm-project/clang/lib/CodeGen/Targets/AMDGPU.cpp @@ -304,7 +304,7 @@ class AMDGPUTargetCodeGenInfo : public TargetCodeGenInfo { void setTargetAttributes(const Decl *D, llvm::GlobalValue *GV, CodeGen::CodeGenModule &M) const override; - unsigned getOpenCLKernelCallingConv() const override; + unsigned getDeviceKernelCallingConv() const override; llvm::Constant *getNullPointer(const CodeGen::CodeGenModule &CGM, llvm::PointerType *T, QualType QT) const override; @@ -431,7 +431,7 @@ void AMDGPUTargetCodeGenInfo::setTargetAttributes( F->addFnAttr("amdgpu-ieee", "false"); } -unsigned AMDGPUTargetCodeGenInfo::getOpenCLKernelCallingConv() const { +unsigned AMDGPUTargetCodeGenInfo::getDeviceKernelCallingConv() const { return llvm::CallingConv::AMDGPU_KERNEL; } diff --git a/external/llvm-project/clang/lib/CodeGen/Targets/NVPTX.cpp b/external/llvm-project/clang/lib/CodeGen/Targets/NVPTX.cpp index ad802c9131de..82bdfe2666b5 100644 --- a/external/llvm-project/clang/lib/CodeGen/Targets/NVPTX.cpp +++ b/external/llvm-project/clang/lib/CodeGen/Targets/NVPTX.cpp @@ -78,7 +78,7 @@ class NVPTXTargetCodeGenInfo : public TargetCodeGenInfo { return true; } - unsigned getOpenCLKernelCallingConv() const override { + unsigned getDeviceKernelCallingConv() const override { return llvm::CallingConv::PTX_Kernel; } diff --git a/external/llvm-project/clang/lib/CodeGen/Targets/SPIR.cpp b/external/llvm-project/clang/lib/CodeGen/Targets/SPIR.cpp index 2f1e43cdc8cc..afa23bffcd07 100644 --- a/external/llvm-project/clang/lib/CodeGen/Targets/SPIR.cpp +++ b/external/llvm-project/clang/lib/CodeGen/Targets/SPIR.cpp @@ -51,7 +51,7 @@ class CommonSPIRTargetCodeGenInfo : public TargetCodeGenInfo { getABIInfo().getDataLayout().getAllocaAddrSpace()); } - unsigned getOpenCLKernelCallingConv() const override; + unsigned getDeviceKernelCallingConv() const override; llvm::Type *getOpenCLType(CodeGenModule &CGM, const Type *T) const override; llvm::Type * getHLSLType(CodeGenModule &CGM, const Type *Ty, @@ -219,7 +219,7 @@ void computeSPIRKernelABIInfo(CodeGenModule &CGM, CGFunctionInfo &FI) { } } -unsigned CommonSPIRTargetCodeGenInfo::getOpenCLKernelCallingConv() const { +unsigned CommonSPIRTargetCodeGenInfo::getDeviceKernelCallingConv() const { return llvm::CallingConv::SPIR_KERNEL; } diff --git a/external/llvm-project/clang/lib/CodeGen/Targets/X86.cpp b/external/llvm-project/clang/lib/CodeGen/Targets/X86.cpp index b36a6e139665..0f59caac2323 100644 --- a/external/llvm-project/clang/lib/CodeGen/Targets/X86.cpp +++ b/external/llvm-project/clang/lib/CodeGen/Targets/X86.cpp @@ -1462,9 +1462,8 @@ class X86_64TargetCodeGenInfo : public TargetCodeGenInfo { // defines varargs anyway. if (fnType->getCallConv() == CC_C) { bool HasAVXType = false; - for (CallArgList::const_iterator - it = args.begin(), ie = args.end(); it != ie; ++it) { - if (getABIInfo().isPassedUsingAVXType(it->Ty)) { + for (const CallArg &arg : args) { + if (getABIInfo().isPassedUsingAVXType(arg.Ty)) { HasAVXType = true; break; } diff --git a/external/llvm-project/clang/lib/Driver/CMakeLists.txt b/external/llvm-project/clang/lib/Driver/CMakeLists.txt index f049a2c076e6..2e3333bbb95f 100644 --- a/external/llvm-project/clang/lib/Driver/CMakeLists.txt +++ b/external/llvm-project/clang/lib/Driver/CMakeLists.txt @@ -68,6 +68,7 @@ add_clang_library(clangDriver ToolChains/HLSL.cpp ToolChains/Hurd.cpp ToolChains/Linux.cpp + ToolChains/Managarm.cpp ToolChains/MipsLinux.cpp ToolChains/MinGW.cpp ToolChains/MSP430.cpp diff --git a/external/llvm-project/clang/lib/Driver/Driver.cpp b/external/llvm-project/clang/lib/Driver/Driver.cpp index 879eb803f3d7..5a2390a654a4 100644 --- a/external/llvm-project/clang/lib/Driver/Driver.cpp +++ b/external/llvm-project/clang/lib/Driver/Driver.cpp @@ -33,6 +33,7 @@ #include "ToolChains/Linux.h" #include "ToolChains/MSP430.h" #include "ToolChains/MSVC.h" +#include "ToolChains/Managarm.h" #include "ToolChains/MinGW.h" #include "ToolChains/MipsLinux.h" #include "ToolChains/NaCl.h" @@ -4340,6 +4341,14 @@ void Driver::handleArguments(Compilation &C, DerivedArgList &Args, YcArg = YuArg = nullptr; } + if (Args.hasArg(options::OPT_include_pch) && + Args.hasArg(options::OPT_ignore_pch)) { + // If -ignore-pch is used, -include-pch is disabled. Since -emit-pch is + // CC1option, it will not be added to command argments if -ignore-pch is + // used. + Args.eraseArg(options::OPT_include_pch); + } + bool LinkOnly = phases::Link == FinalPhase && Inputs.size() > 0; for (auto &I : Inputs) { types::ID InputType = I.first; @@ -6903,6 +6912,9 @@ const ToolChain &Driver::getToolChain(const ArgList &Args, case llvm::Triple::Fuchsia: TC = std::make_unique(*this, Target, Args); break; + case llvm::Triple::Managarm: + TC = std::make_unique(*this, Target, Args); + break; case llvm::Triple::Solaris: TC = std::make_unique(*this, Target, Args); break; @@ -6910,11 +6922,17 @@ const ToolChain &Driver::getToolChain(const ArgList &Args, TC = std::make_unique(*this, Target, Args); break; case llvm::Triple::AMDHSA: { - bool DL = - usesInput(Args, types::isOpenCL) || usesInput(Args, types::isLLVMIR); - TC = DL ? std::make_unique(*this, Target, Args) - : std::make_unique(*this, Target, - Args); + if (Target.getArch() == llvm::Triple::spirv64) { + TC = std::make_unique(*this, Target, + Args); + } else { + bool DL = usesInput(Args, types::isOpenCL) || + usesInput(Args, types::isLLVMIR); + TC = DL ? std::make_unique(*this, Target, + Args) + : std::make_unique(*this, Target, + Args); + } break; } case llvm::Triple::AMDPAL: diff --git a/external/llvm-project/clang/lib/Driver/ToolChains/AMDGPU.cpp b/external/llvm-project/clang/lib/Driver/ToolChains/AMDGPU.cpp index b53f75fc3ff5..d20d11e3bc9d 100644 --- a/external/llvm-project/clang/lib/Driver/ToolChains/AMDGPU.cpp +++ b/external/llvm-project/clang/lib/Driver/ToolChains/AMDGPU.cpp @@ -526,7 +526,8 @@ void RocmInstallationDetector::AddHIPIncludeArgs(const ArgList &DriverArgs, "hipstdpar_lib.hpp"}); }; - if (DriverArgs.hasArg(options::OPT_nogpuinc)) { + if (!DriverArgs.hasFlag(options::OPT_offload_inc, options::OPT_no_offload_inc, + true)) { if (HasHipStdPar) HandleHipStdPar(); diff --git a/external/llvm-project/clang/lib/Driver/ToolChains/Clang.cpp b/external/llvm-project/clang/lib/Driver/ToolChains/Clang.cpp index 92acddf6e8e2..bb0f6533ac92 100644 --- a/external/llvm-project/clang/lib/Driver/ToolChains/Clang.cpp +++ b/external/llvm-project/clang/lib/Driver/ToolChains/Clang.cpp @@ -965,7 +965,8 @@ void Clang::AddPreprocessingOptions(Compilation &C, const JobAction &JA, // openmp_wrappers folder which contains alternative system headers. if (JA.isDeviceOffloading(Action::OFK_OpenMP) && !Args.hasArg(options::OPT_nostdinc) && - !Args.hasArg(options::OPT_nogpuinc) && + Args.hasFlag(options::OPT_offload_inc, options::OPT_no_offload_inc, + true) && getToolChain().getTriple().isGPU()) { if (!Args.hasArg(options::OPT_nobuiltininc)) { // Add openmp_wrappers/* to our system include path. This lets us wrap @@ -1159,7 +1160,8 @@ void Clang::AddPreprocessingOptions(Compilation &C, const JobAction &JA, // TODO: This should be moved to `AddClangSystemIncludeArgs` by passing the // OffloadKind as an argument. if (!Args.hasArg(options::OPT_nostdinc) && - !Args.hasArg(options::OPT_nogpuinc) && + Args.hasFlag(options::OPT_offload_inc, options::OPT_no_offload_inc, + true) && !Args.hasArg(options::OPT_nobuiltininc)) { // Without an offloading language we will include these headers directly. // Offloading languages will instead only use the declarations stored in @@ -5281,7 +5283,7 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, CmdArgs.push_back("-emit-module-interface"); else if (JA.getType() == types::TY_HeaderUnit) CmdArgs.push_back("-emit-header-unit"); - else + else if (!Args.hasArg(options::OPT_ignore_pch)) CmdArgs.push_back("-emit-pch"); } else if (isa(JA)) { CmdArgs.push_back("-verify-pch"); @@ -5341,7 +5343,8 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, } else if (JA.getType() == types::TY_PP_Asm) { CmdArgs.push_back("-S"); } else if (JA.getType() == types::TY_AST) { - CmdArgs.push_back("-emit-pch"); + if (!Args.hasArg(options::OPT_ignore_pch)) + CmdArgs.push_back("-emit-pch"); } else if (JA.getType() == types::TY_ModuleFile) { CmdArgs.push_back("-module-file-info"); } else if (JA.getType() == types::TY_RewrittenObjC) { @@ -5784,11 +5787,18 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, Triple.getArch() != llvm::Triple::x86_64) D.Diag(diag::err_drv_unsupported_opt_for_target) << Name << Triple.getArchName(); - } else if (Name == "libmvec" || Name == "AMDLIBM") { + } else if (Name == "AMDLIBM") { if (Triple.getArch() != llvm::Triple::x86 && Triple.getArch() != llvm::Triple::x86_64) D.Diag(diag::err_drv_unsupported_opt_for_target) << Name << Triple.getArchName(); + } else if (Name == "libmvec") { + if (Triple.getArch() != llvm::Triple::x86 && + Triple.getArch() != llvm::Triple::x86_64 && + Triple.getArch() != llvm::Triple::aarch64 && + Triple.getArch() != llvm::Triple::aarch64_be) + D.Diag(diag::err_drv_unsupported_opt_for_target) + << Name << Triple.getArchName(); } else if (Name == "SLEEF" || Name == "ArmPL") { if (Triple.getArch() != llvm::Triple::aarch64 && Triple.getArch() != llvm::Triple::aarch64_be && @@ -7532,8 +7542,7 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, } // Unwind v2 (epilog) information for x64 Windows. - Args.addOptInFlag(CmdArgs, options::OPT_fwinx64_eh_unwindv2, - options::OPT_fno_winx64_eh_unwindv2); + Args.AddLastArg(CmdArgs, options::OPT_winx64_eh_unwindv2); // C++ "sane" operator new. Args.addOptOutFlag(CmdArgs, options::OPT_fassume_sane_operator_new, @@ -7720,7 +7729,13 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, if (Args.hasArg(options::OPT_fretain_comments_from_system_headers)) CmdArgs.push_back("-fretain-comments-from-system-headers"); - Args.AddLastArg(CmdArgs, options::OPT_fextend_variable_liveness_EQ); + if (Arg *A = Args.getLastArg(options::OPT_fextend_variable_liveness_EQ)) { + A->render(Args, CmdArgs); + } else if (Arg *A = Args.getLastArg(options::OPT_O_Group); + A && A->containsValue("g")) { + // Set -fextend-variable-liveness=all by default at -Og. + CmdArgs.push_back("-fextend-variable-liveness=all"); + } // Forward -fcomment-block-commands to -cc1. Args.AddAllArgs(CmdArgs, options::OPT_fcomment_block_commands); @@ -8598,8 +8613,10 @@ void Clang::AddClangCLArgs(const ArgList &Args, types::ID InputType, CmdArgs.push_back("-fms-kernel"); // Unwind v2 (epilog) information for x64 Windows. - if (Args.hasArg(options::OPT__SLASH_d2epilogunwind)) - CmdArgs.push_back("-fwinx64-eh-unwindv2"); + if (Args.hasArg(options::OPT__SLASH_d2epilogunwindrequirev2)) + CmdArgs.push_back("-fwinx64-eh-unwindv2=required"); + else if (Args.hasArg(options::OPT__SLASH_d2epilogunwind)) + CmdArgs.push_back("-fwinx64-eh-unwindv2=best-effort"); for (const Arg *A : Args.filtered(options::OPT__SLASH_guard)) { StringRef GuardArgs = A->getValue(); @@ -9397,6 +9414,9 @@ void LinkerWrapper::ConstructJob(Compilation &C, const JobAction &JA, CmdArgs.push_back( Args.MakeArgString("--device-linker=" + TC->getTripleString() + "=-plugin-opt=-avail-extern-to-local")); + CmdArgs.push_back(Args.MakeArgString( + "--device-linker=" + TC->getTripleString() + + "=-plugin-opt=-avail-extern-gv-in-addrspace-to-local=3")); if (Kind == Action::OFK_OpenMP) { CmdArgs.push_back( Args.MakeArgString("--device-linker=" + TC->getTripleString() + diff --git a/external/llvm-project/clang/lib/Driver/ToolChains/CommonArgs.cpp b/external/llvm-project/clang/lib/Driver/ToolChains/CommonArgs.cpp index a73392da1f77..71de2a7e25da 100644 --- a/external/llvm-project/clang/lib/Driver/ToolChains/CommonArgs.cpp +++ b/external/llvm-project/clang/lib/Driver/ToolChains/CommonArgs.cpp @@ -2394,6 +2394,13 @@ static void AddLibgcc(const ToolChain &TC, const Driver &D, if (LGT == LibGccType::SharedLibGcc || (LGT == LibGccType::UnspecifiedLibGcc && D.CCCIsCXX())) CmdArgs.push_back("-lgcc"); + // compiler-rt is needed after libgcc for flang on AArch64 for the + // __trampoline_setup symbol + if (D.IsFlangMode() && TC.getArch() == llvm::Triple::aarch64) { + CmdArgs.push_back("--as-needed"); + CmdArgs.push_back(TC.getCompilerRTArgString(Args, "builtins")); + CmdArgs.push_back("--no-as-needed"); + } } void tools::AddRunTimeLibs(const ToolChain &TC, const Driver &D, diff --git a/external/llvm-project/clang/lib/Driver/ToolChains/Cuda.cpp b/external/llvm-project/clang/lib/Driver/ToolChains/Cuda.cpp index e2194655dfab..32745cbbc5ed 100644 --- a/external/llvm-project/clang/lib/Driver/ToolChains/Cuda.cpp +++ b/external/llvm-project/clang/lib/Driver/ToolChains/Cuda.cpp @@ -303,7 +303,8 @@ void CudaInstallationDetector::AddCudaIncludeArgs( CC1Args.push_back(DriverArgs.MakeArgString(P)); } - if (DriverArgs.hasArg(options::OPT_nogpuinc)) + if (!DriverArgs.hasFlag(options::OPT_offload_inc, options::OPT_no_offload_inc, + true)) return; if (!isValid()) { @@ -944,7 +945,8 @@ llvm::DenormalMode CudaToolChain::getDefaultDenormalModeForType( void CudaToolChain::AddCudaIncludeArgs(const ArgList &DriverArgs, ArgStringList &CC1Args) const { // Check our CUDA version if we're going to include the CUDA headers. - if (!DriverArgs.hasArg(options::OPT_nogpuinc) && + if (DriverArgs.hasFlag(options::OPT_offload_inc, options::OPT_no_offload_inc, + true) && !DriverArgs.hasArg(options::OPT_no_cuda_version_check)) { StringRef Arch = DriverArgs.getLastArgValue(options::OPT_march_EQ); assert(!Arch.empty() && "Must have an explicit GPU arch."); @@ -1017,7 +1019,9 @@ void CudaToolChain::AddClangSystemIncludeArgs(const ArgList &DriverArgs, ArgStringList &CC1Args) const { HostTC.AddClangSystemIncludeArgs(DriverArgs, CC1Args); - if (!DriverArgs.hasArg(options::OPT_nogpuinc) && CudaInstallation.isValid()) + if (DriverArgs.hasFlag(options::OPT_offload_inc, options::OPT_no_offload_inc, + true) && + CudaInstallation.isValid()) CC1Args.append( {"-internal-isystem", DriverArgs.MakeArgString(CudaInstallation.getIncludePath())}); diff --git a/external/llvm-project/clang/lib/Driver/ToolChains/Fuchsia.cpp b/external/llvm-project/clang/lib/Driver/ToolChains/Fuchsia.cpp index 1c165bbfe84f..146dc8bbd531 100644 --- a/external/llvm-project/clang/lib/Driver/ToolChains/Fuchsia.cpp +++ b/external/llvm-project/clang/lib/Driver/ToolChains/Fuchsia.cpp @@ -91,7 +91,9 @@ void fuchsia::Linker::ConstructJob(Compilation &C, const JobAction &JA, CmdArgs.push_back("--execute-only"); std::string CPU = getCPUName(D, Args, Triple); - if (CPU.empty() || CPU == "generic" || CPU == "cortex-a53") + if (Args.hasFlag(options::OPT_mfix_cortex_a53_843419, + options::OPT_mno_fix_cortex_a53_843419, true) && + (CPU.empty() || CPU == "generic" || CPU == "cortex-a53")) CmdArgs.push_back("--fix-cortex-a53-843419"); } diff --git a/external/llvm-project/clang/lib/Driver/ToolChains/Gnu.cpp b/external/llvm-project/clang/lib/Driver/ToolChains/Gnu.cpp index ffd04fad0aa6..fce00cf06bfa 100644 --- a/external/llvm-project/clang/lib/Driver/ToolChains/Gnu.cpp +++ b/external/llvm-project/clang/lib/Driver/ToolChains/Gnu.cpp @@ -227,6 +227,8 @@ static const char *getLDMOption(const llvm::Triple &T, const ArgList &Args) { return "elf_iamcu"; return "elf_i386"; case llvm::Triple::aarch64: + if (T.isOSManagarm()) + return "aarch64managarm"; return "aarch64linux"; case llvm::Triple::aarch64_be: return "aarch64linuxb"; @@ -403,7 +405,9 @@ void tools::gnutools::Linker::ConstructJob(Compilation &C, const JobAction &JA, // Most Android ARM64 targets should enable the linker fix for erratum // 843419. Only non-Cortex-A53 devices are allowed to skip this flag. - if (Arch == llvm::Triple::aarch64 && (isAndroid || isOHOSFamily)) { + if (Arch == llvm::Triple::aarch64 && (isAndroid || isOHOSFamily) && + Args.hasFlag(options::OPT_mfix_cortex_a53_843419, + options::OPT_mno_fix_cortex_a53_843419, true)) { std::string CPU = getCPUName(D, Args, Triple); if (CPU.empty() || CPU == "generic" || CPU == "cortex-a53") CmdArgs.push_back("--fix-cortex-a53-843419"); diff --git a/external/llvm-project/clang/lib/Driver/ToolChains/HIPAMD.cpp b/external/llvm-project/clang/lib/Driver/ToolChains/HIPAMD.cpp index 3b0a7b613146..891789472b0c 100644 --- a/external/llvm-project/clang/lib/Driver/ToolChains/HIPAMD.cpp +++ b/external/llvm-project/clang/lib/Driver/ToolChains/HIPAMD.cpp @@ -104,6 +104,8 @@ void AMDGCN::Linker::constructLldCommand(Compilation &C, const JobAction &JA, if (IsThinLTO) { LldArgs.push_back(Args.MakeArgString("-plugin-opt=-force-import-all")); LldArgs.push_back(Args.MakeArgString("-plugin-opt=-avail-extern-to-local")); + LldArgs.push_back(Args.MakeArgString( + "-plugin-opt=-avail-extern-gv-in-addrspace-to-local=3")); } if (Arg *A = Args.getLastArgNoClaim(options::OPT_g_Group)) @@ -431,3 +433,15 @@ void HIPAMDToolChain::checkTargetID( getDriver().Diag(clang::diag::err_drv_bad_target_id) << *PTID.OptionalTargetID; } + +SPIRVAMDToolChain::SPIRVAMDToolChain(const Driver &D, + const llvm::Triple &Triple, + const ArgList &Args) + : ROCMToolChain(D, Triple, Args) { + getProgramPaths().push_back(getDriver().Dir); +} + +Tool *SPIRVAMDToolChain::buildLinker() const { + assert(getTriple().getArch() == llvm::Triple::spirv64); + return new tools::AMDGCN::Linker(*this); +} diff --git a/external/llvm-project/clang/lib/Driver/ToolChains/HIPAMD.h b/external/llvm-project/clang/lib/Driver/ToolChains/HIPAMD.h index e26934bd39b1..f8e46b1f1668 100644 --- a/external/llvm-project/clang/lib/Driver/ToolChains/HIPAMD.h +++ b/external/llvm-project/clang/lib/Driver/ToolChains/HIPAMD.h @@ -102,6 +102,15 @@ class LLVM_LIBRARY_VISIBILITY HIPAMDToolChain final : public ROCMToolChain { Tool *buildLinker() const override; }; +class LLVM_LIBRARY_VISIBILITY SPIRVAMDToolChain final : public ROCMToolChain { +public: + SPIRVAMDToolChain(const Driver &D, const llvm::Triple &Triple, + const llvm::opt::ArgList &Args); + +protected: + Tool *buildLinker() const override; +}; + } // end namespace toolchains } // end namespace driver } // end namespace clang diff --git a/external/llvm-project/clang/lib/Driver/ToolChains/HIPSPV.cpp b/external/llvm-project/clang/lib/Driver/ToolChains/HIPSPV.cpp index ec29c62976e1..c86790f66a79 100644 --- a/external/llvm-project/clang/lib/Driver/ToolChains/HIPSPV.cpp +++ b/external/llvm-project/clang/lib/Driver/ToolChains/HIPSPV.cpp @@ -187,7 +187,8 @@ void HIPSPVToolChain::AddIAMCUIncludeArgs(const ArgList &Args, void HIPSPVToolChain::AddHIPIncludeArgs(const ArgList &DriverArgs, ArgStringList &CC1Args) const { - if (DriverArgs.hasArg(options::OPT_nogpuinc)) + if (!DriverArgs.hasFlag(options::OPT_offload_inc, options::OPT_no_offload_inc, + true)) return; StringRef hipPath = DriverArgs.getLastArgValue(options::OPT_hip_path_EQ); diff --git a/external/llvm-project/clang/lib/Driver/ToolChains/Linux.cpp b/external/llvm-project/clang/lib/Driver/ToolChains/Linux.cpp index 082da1feca75..322d973f15e6 100644 --- a/external/llvm-project/clang/lib/Driver/ToolChains/Linux.cpp +++ b/external/llvm-project/clang/lib/Driver/ToolChains/Linux.cpp @@ -977,9 +977,11 @@ void Linux::AddHIPRuntimeLibArgs(const ArgList &Args, Args.MakeArgString(StringRef("-L") + RocmInstallation->getLibPath())); if (Args.hasFlag(options::OPT_frtlib_add_rpath, - options::OPT_fno_rtlib_add_rpath, false)) - CmdArgs.append( - {"-rpath", Args.MakeArgString(RocmInstallation->getLibPath())}); + options::OPT_fno_rtlib_add_rpath, false)) { + SmallString<0> p = RocmInstallation->getLibPath(); + llvm::sys::path::remove_dots(p, true); + CmdArgs.append({"-rpath", Args.MakeArgString(p)}); + } CmdArgs.push_back("-lamdhip64"); } diff --git a/external/llvm-project/clang/lib/Driver/ToolChains/Managarm.cpp b/external/llvm-project/clang/lib/Driver/ToolChains/Managarm.cpp new file mode 100644 index 000000000000..ff455f2c6ec7 --- /dev/null +++ b/external/llvm-project/clang/lib/Driver/ToolChains/Managarm.cpp @@ -0,0 +1,218 @@ +//===----------------------------------------------------------------------===// +// +// 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 "Managarm.h" +#include "Arch/ARM.h" +#include "Arch/RISCV.h" +#include "clang/Config/config.h" +#include "clang/Driver/CommonArgs.h" +#include "clang/Driver/Driver.h" +#include "clang/Driver/Options.h" +#include "clang/Driver/SanitizerArgs.h" +#include "llvm/Option/ArgList.h" +#include "llvm/Support/Path.h" + +using namespace clang::driver; +using namespace clang::driver::toolchains; +using namespace clang; +using namespace llvm::opt; + +using tools::addPathIfExists; + +std::string Managarm::getMultiarchTriple(const Driver &D, + const llvm::Triple &TargetTriple, + StringRef SysRoot) const { + switch (TargetTriple.getArch()) { + default: + return TargetTriple.str(); + case llvm::Triple::x86_64: + return "x86_64-managarm-" + TargetTriple.getEnvironmentName().str(); + case llvm::Triple::aarch64: + return "aarch64-managarm-" + TargetTriple.getEnvironmentName().str(); + case llvm::Triple::riscv64: + return "riscv64-managarm-" + TargetTriple.getEnvironmentName().str(); + } +} + +static StringRef getOSLibDir(const llvm::Triple &Triple, const ArgList &Args) { + // It happens that only x86, PPC and SPARC use the 'lib32' variant of + // oslibdir, and using that variant while targeting other architectures causes + // problems because the libraries are laid out in shared system roots that + // can't cope with a 'lib32' library search path being considered. So we only + // enable them when we know we may need it. + // + // FIXME: This is a bit of a hack. We should really unify this code for + // reasoning about oslibdir spellings with the lib dir spellings in the + // GCCInstallationDetector, but that is a more significant refactoring. + if (Triple.getArch() == llvm::Triple::x86 || Triple.isPPC32() || + Triple.getArch() == llvm::Triple::sparc) + return "lib32"; + + if (Triple.getArch() == llvm::Triple::x86_64 && Triple.isX32()) + return "libx32"; + + if (Triple.getArch() == llvm::Triple::riscv32) + return "lib32"; + + return Triple.isArch32Bit() ? "lib" : "lib64"; +} + +Managarm::Managarm(const Driver &D, const llvm::Triple &Triple, + const ArgList &Args) + : Generic_ELF(D, Triple, Args) { + GCCInstallation.init(Triple, Args); + Multilibs = GCCInstallation.getMultilibs(); + SelectedMultilibs.assign({GCCInstallation.getMultilib()}); + std::string SysRoot = computeSysRoot(); + + ToolChain::path_list &PPaths = getProgramPaths(); + + Generic_GCC::PushPPaths(PPaths); + +#ifdef ENABLE_LINKER_BUILD_ID + ExtraOpts.push_back("--build-id"); +#endif + + // The selection of paths to try here is designed to match the patterns which + // the GCC driver itself uses, as this is part of the GCC-compatible driver. + // This was determined by running GCC in a fake filesystem, creating all + // possible permutations of these directories, and seeing which ones it added + // to the link paths. + path_list &Paths = getFilePaths(); + + const std::string OSLibDir = std::string(getOSLibDir(Triple, Args)); + const std::string MultiarchTriple = getMultiarchTriple(D, Triple, SysRoot); + + Generic_GCC::AddMultilibPaths(D, SysRoot, OSLibDir, MultiarchTriple, Paths); + + addPathIfExists(D, concat(SysRoot, "/lib", MultiarchTriple), Paths); + addPathIfExists(D, concat(SysRoot, "/lib/..", OSLibDir), Paths); + addPathIfExists(D, concat(SysRoot, "/usr/lib", MultiarchTriple), Paths); + addPathIfExists(D, concat(SysRoot, "/usr", OSLibDir), Paths); + + Generic_GCC::AddMultiarchPaths(D, SysRoot, OSLibDir, Paths); + + addPathIfExists(D, concat(SysRoot, "/lib"), Paths); + addPathIfExists(D, concat(SysRoot, "/usr/lib"), Paths); +} + +bool Managarm::HasNativeLLVMSupport() const { return true; } + +Tool *Managarm::buildLinker() const { + return new tools::gnutools::Linker(*this); +} + +Tool *Managarm::buildAssembler() const { + return new tools::gnutools::Assembler(*this); +} + +std::string Managarm::computeSysRoot() const { + if (!getDriver().SysRoot.empty()) + return getDriver().SysRoot; + return std::string(); +} + +std::string Managarm::getDynamicLinker(const ArgList &Args) const { + switch (getTriple().getArch()) { + case llvm::Triple::aarch64: + return "/lib/aarch64-managarm/ld.so"; + case llvm::Triple::riscv64: { + StringRef ABIName = tools::riscv::getRISCVABI(Args, getTriple()); + return ("/lib/riscv64-managarm/ld-riscv64-" + ABIName + ".so").str(); + } + case llvm::Triple::x86_64: + return "/lib/x86_64-managarm/ld.so"; + default: + llvm_unreachable("unsupported architecture"); + } +} + +void Managarm::AddClangSystemIncludeArgs(const ArgList &DriverArgs, + ArgStringList &CC1Args) const { + const Driver &D = getDriver(); + std::string SysRoot = computeSysRoot(); + + if (DriverArgs.hasArg(clang::driver::options::OPT_nostdinc)) + return; + + if (!DriverArgs.hasArg(options::OPT_nostdlibinc)) + addSystemInclude(DriverArgs, CC1Args, SysRoot + "/usr/local/include"); + + // Add 'include' in the resource directory, which is similar to + // GCC_INCLUDE_DIR (private headers) in GCC. + if (!DriverArgs.hasArg(options::OPT_nobuiltininc)) { + SmallString<128> ResourceDirInclude(D.ResourceDir); + llvm::sys::path::append(ResourceDirInclude, "include"); + addSystemInclude(DriverArgs, CC1Args, ResourceDirInclude); + } + + if (DriverArgs.hasArg(options::OPT_nostdlibinc)) + return; + + // TOOL_INCLUDE_DIR + AddMultilibIncludeArgs(DriverArgs, CC1Args); + + // Check for configure-time C include directories. + StringRef CIncludeDirs(C_INCLUDE_DIRS); + if (CIncludeDirs != "") { + SmallVector dirs; + CIncludeDirs.split(dirs, ":"); + for (StringRef dir : dirs) { + StringRef Prefix = + llvm::sys::path::is_absolute(dir) ? StringRef(SysRoot) : ""; + addExternCSystemInclude(DriverArgs, CC1Args, Prefix + dir); + } + return; + } + + // On systems using multiarch, add /usr/include/$triple before + // /usr/include. + std::string MultiarchIncludeDir = getMultiarchTriple(D, getTriple(), SysRoot); + if (!MultiarchIncludeDir.empty()) + addExternCSystemInclude( + DriverArgs, CC1Args, + concat(SysRoot, "/usr/include", MultiarchIncludeDir)); + + // Add an include of '/include' directly. This isn't provided by default by + // system GCCs, but is often used with cross-compiling GCCs, and harmless to + // add even when Clang is acting as-if it were a system compiler. + addExternCSystemInclude(DriverArgs, CC1Args, concat(SysRoot, "/include")); + + addExternCSystemInclude(DriverArgs, CC1Args, concat(SysRoot, "/usr/include")); +} + +void Managarm::addLibStdCxxIncludePaths( + const llvm::opt::ArgList &DriverArgs, + llvm::opt::ArgStringList &CC1Args) const { + // We need a detected GCC installation on Managarm to provide libstdc++'s + // headers. + if (!GCCInstallation.isValid()) + return; + + StringRef TripleStr = GCCInstallation.getTriple().str(); + + // Try generic GCC detection. + Generic_GCC::addGCCLibStdCxxIncludePaths(DriverArgs, CC1Args, TripleStr); +} + +SanitizerMask Managarm::getSupportedSanitizers() const { + const bool IsX86_64 = getTriple().getArch() == llvm::Triple::x86_64; + SanitizerMask Res = ToolChain::getSupportedSanitizers(); + Res |= SanitizerKind::PointerCompare; + Res |= SanitizerKind::PointerSubtract; + Res |= SanitizerKind::KernelAddress; + Res |= SanitizerKind::Vptr; + if (IsX86_64) + Res |= SanitizerKind::KernelMemory; + return Res; +} + +void Managarm::addExtraOpts(llvm::opt::ArgStringList &CmdArgs) const { + for (const auto &Opt : ExtraOpts) + CmdArgs.push_back(Opt.c_str()); +} diff --git a/external/llvm-project/clang/lib/Driver/ToolChains/Managarm.h b/external/llvm-project/clang/lib/Driver/ToolChains/Managarm.h new file mode 100644 index 000000000000..2082e2c615f2 --- /dev/null +++ b/external/llvm-project/clang/lib/Driver/ToolChains/Managarm.h @@ -0,0 +1,55 @@ +//===--- Managarm.h - Managarm ToolChain Implementations --------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_MANAGARM_H +#define LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_MANAGARM_H + +#include "Gnu.h" +#include "clang/Driver/ToolChain.h" + +namespace clang { +namespace driver { +namespace toolchains { + +class LLVM_LIBRARY_VISIBILITY Managarm : public Generic_ELF { +public: + Managarm(const Driver &D, const llvm::Triple &Triple, + const llvm::opt::ArgList &Args); + + bool HasNativeLLVMSupport() const override; + + std::string getMultiarchTriple(const Driver &D, + const llvm::Triple &TargetTriple, + StringRef SysRoot) const override; + + void + AddClangSystemIncludeArgs(const llvm::opt::ArgList &DriverArgs, + llvm::opt::ArgStringList &CC1Args) const override; + void + addLibStdCxxIncludePaths(const llvm::opt::ArgList &DriverArgs, + llvm::opt::ArgStringList &CC1Args) const override; + SanitizerMask getSupportedSanitizers() const override; + std::string computeSysRoot() const override; + + std::string getDynamicLinker(const llvm::opt::ArgList &Args) const override; + + void addExtraOpts(llvm::opt::ArgStringList &CmdArgs) const override; + + std::vector ExtraOpts; + +protected: + Tool *buildAssembler() const override; + Tool *buildLinker() const override; +}; + +} // end namespace toolchains +} // end namespace driver +} // end namespace clang + +#endif // LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_MANAGARM_H diff --git a/external/llvm-project/clang/lib/ExtractAPI/DeclarationFragments.cpp b/external/llvm-project/clang/lib/ExtractAPI/DeclarationFragments.cpp index d7eebcbc3c2f..348e7588690a 100644 --- a/external/llvm-project/clang/lib/ExtractAPI/DeclarationFragments.cpp +++ b/external/llvm-project/clang/lib/ExtractAPI/DeclarationFragments.cpp @@ -883,6 +883,9 @@ DeclarationFragments DeclarationFragmentsBuilder::getFragmentsForCXXMethod( if (Method->isVolatile()) Fragments.append("volatile", DeclarationFragments::FragmentKind::Keyword) .appendSpace(); + if (Method->isVirtual()) + Fragments.append("virtual", DeclarationFragments::FragmentKind::Keyword) + .appendSpace(); // Build return type DeclarationFragments After; diff --git a/external/llvm-project/clang/lib/ExtractAPI/Serialization/SymbolGraphSerializer.cpp b/external/llvm-project/clang/lib/ExtractAPI/Serialization/SymbolGraphSerializer.cpp index 139023f32e8d..d3df9eb604f2 100644 --- a/external/llvm-project/clang/lib/ExtractAPI/Serialization/SymbolGraphSerializer.cpp +++ b/external/llvm-project/clang/lib/ExtractAPI/Serialization/SymbolGraphSerializer.cpp @@ -341,6 +341,22 @@ Object serializeNames(const APIRecord *Record) { serializeArray(Names, "subHeading", serializeDeclarationFragments(Record->SubHeading)); DeclarationFragments NavigatorFragments; + // The +/- prefix for Objective-C methods is important information, and + // should be included in the navigator fragment. The entire subheading is + // not included as it can contain too much information for other records. + switch (Record->getKind()) { + case APIRecord::RK_ObjCClassMethod: + NavigatorFragments.append("+ ", DeclarationFragments::FragmentKind::Text, + /*PreciseIdentifier*/ ""); + break; + case APIRecord::RK_ObjCInstanceMethod: + NavigatorFragments.append("- ", DeclarationFragments::FragmentKind::Text, + /*PreciseIdentifier*/ ""); + break; + default: + break; + } + NavigatorFragments.append(Record->Name, DeclarationFragments::FragmentKind::Identifier, /*PreciseIdentifier*/ ""); diff --git a/external/llvm-project/clang/lib/Headers/CMakeLists.txt b/external/llvm-project/clang/lib/Headers/CMakeLists.txt index b7fa5bc3560b..16eab67bbab0 100644 --- a/external/llvm-project/clang/lib/Headers/CMakeLists.txt +++ b/external/llvm-project/clang/lib/Headers/CMakeLists.txt @@ -344,6 +344,7 @@ set(cuda_wrapper_files ) set(cuda_wrapper_bits_files + cuda_wrappers/bits/c++config.h cuda_wrappers/bits/shared_ptr_base.h cuda_wrappers/bits/basic_string.h cuda_wrappers/bits/basic_string.tcc diff --git a/external/llvm-project/clang/lib/Headers/__clang_cuda_intrinsics.h b/external/llvm-project/clang/lib/Headers/__clang_cuda_intrinsics.h index 8b230af6f664..cca97cb21ef5 100644 --- a/external/llvm-project/clang/lib/Headers/__clang_cuda_intrinsics.h +++ b/external/llvm-project/clang/lib/Headers/__clang_cuda_intrinsics.h @@ -479,6 +479,293 @@ inline __device__ unsigned __funnelshift_rc(unsigned low32, unsigned high32, return ret; } +#if defined(__cplusplus) && (__cplusplus >= 201103L) + +#pragma push_macro("__INTRINSIC_LOAD") +#define __INTRINSIC_LOAD(__FnName, __AsmOp, __DeclType, __TmpType, __AsmType, \ + __Clobber) \ + inline __device__ __DeclType __FnName(const __DeclType *__ptr) { \ + __TmpType __ret; \ + asm(__AsmOp " %0, [%1];" : __AsmType(__ret) : "l"(__ptr)__Clobber); \ + return (__DeclType)__ret; \ + } + +#pragma push_macro("__INTRINSIC_LOAD2") +#define __INTRINSIC_LOAD2(__FnName, __AsmOp, __DeclType, __TmpType, __AsmType, \ + __Clobber) \ + inline __device__ __DeclType __FnName(const __DeclType *__ptr) { \ + __DeclType __ret; \ + __TmpType __tmp; \ + asm(__AsmOp " {%0,%1}, [%2];" \ + : __AsmType(__tmp.x), __AsmType(__tmp.y) \ + : "l"(__ptr)__Clobber); \ + using __ElementType = decltype(__ret.x); \ + __ret.x = (__ElementType)(__tmp.x); \ + __ret.y = (__ElementType)__tmp.y; \ + return __ret; \ + } + +#pragma push_macro("__INTRINSIC_LOAD4") +#define __INTRINSIC_LOAD4(__FnName, __AsmOp, __DeclType, __TmpType, __AsmType, \ + __Clobber) \ + inline __device__ __DeclType __FnName(const __DeclType *__ptr) { \ + __DeclType __ret; \ + __TmpType __tmp; \ + asm(__AsmOp " {%0,%1,%2,%3}, [%4];" \ + : __AsmType(__tmp.x), __AsmType(__tmp.y), __AsmType(__tmp.z), \ + __AsmType(__tmp.w) \ + : "l"(__ptr)__Clobber); \ + using __ElementType = decltype(__ret.x); \ + __ret.x = (__ElementType)__tmp.x; \ + __ret.y = (__ElementType)__tmp.y; \ + __ret.z = (__ElementType)__tmp.z; \ + __ret.w = (__ElementType)__tmp.w; \ + return __ret; \ + } + +__INTRINSIC_LOAD(__ldcg, "ld.global.cg.s8", char, unsigned int, "=r", ); +__INTRINSIC_LOAD(__ldcg, "ld.global.cg.s8", signed char, unsigned int, "=r", ); +__INTRINSIC_LOAD(__ldcg, "ld.global.cg.s16", short, unsigned short, "=h", ); +__INTRINSIC_LOAD(__ldcg, "ld.global.cg.s32", int, unsigned int, "=r", ); +__INTRINSIC_LOAD(__ldcg, "ld.global.cg.s64", long long, unsigned long long, + "=l", ); + +__INTRINSIC_LOAD2(__ldcg, "ld.global.cg.v2.s8", char2, int2, "=r", ); +__INTRINSIC_LOAD4(__ldcg, "ld.global.cg.v4.s8", char4, int4, "=r", ); +__INTRINSIC_LOAD2(__ldcg, "ld.global.cg.v2.s16", short2, short2, "=h", ); +__INTRINSIC_LOAD4(__ldcg, "ld.global.cg.v4.s16", short4, short4, "=h", ); +__INTRINSIC_LOAD2(__ldcg, "ld.global.cg.v2.s32", int2, int2, "=r", ); +__INTRINSIC_LOAD4(__ldcg, "ld.global.cg.v4.s32", int4, int4, "=r", ); +__INTRINSIC_LOAD2(__ldcg, "ld.global.cg.v2.s64 ", longlong2, longlong2, "=l", ); + +__INTRINSIC_LOAD(__ldcg, "ld.global.cg.u8", unsigned char, unsigned int, + "=r", ); +__INTRINSIC_LOAD(__ldcg, "ld.global.cg.u16", unsigned short, unsigned short, + "=h", ); +__INTRINSIC_LOAD(__ldcg, "ld.global.cg.u32", unsigned int, unsigned int, + "=r", ); +__INTRINSIC_LOAD(__ldcg, "ld.global.cg.u64", unsigned long long, + unsigned long long, "=l", ); + +__INTRINSIC_LOAD2(__ldcg, "ld.global.cg.v2.u8", uchar2, int2, "=r", ); +__INTRINSIC_LOAD4(__ldcg, "ld.global.cg.v4.u8", uchar4, int4, "=r", ); +__INTRINSIC_LOAD2(__ldcg, "ld.global.cg.v2.u16", ushort2, ushort2, "=h", ); +__INTRINSIC_LOAD4(__ldcg, "ld.global.cg.v4.u16", ushort4, ushort4, "=h", ); +__INTRINSIC_LOAD2(__ldcg, "ld.global.cg.v2.u32", uint2, uint2, "=r", ); +__INTRINSIC_LOAD4(__ldcg, "ld.global.cg.v4.u32", uint4, uint4, "=r", ); +__INTRINSIC_LOAD2(__ldcg, "ld.global.cg.v2.u64", ulonglong2, ulonglong2, + "=l", ); + +__INTRINSIC_LOAD(__ldcg, "ld.global.cg.f32", float, float, "=f", ); +__INTRINSIC_LOAD(__ldcg, "ld.global.cg.f64", double, double, "=d", ); +__INTRINSIC_LOAD2(__ldcg, "ld.global.cg.v2.f32", float2, float2, "=f", ); +__INTRINSIC_LOAD4(__ldcg, "ld.global.cg.v4.f32", float4, float4, "=f", ); +__INTRINSIC_LOAD2(__ldcg, "ld.global.cg.v2.f64", double2, double2, "=d", ); + +inline __device__ long __ldcg(const long *__ptr) { + unsigned long __ret; + if (sizeof(long) == 8) { + asm("ld.global.cg.s64 %0, [%1];" : "=l"(__ret) : "l"(__ptr)); + } else { + asm("ld.global.cg.s32 %0, [%1];" : "=r"(__ret) : "l"(__ptr)); + } + return (long)__ret; +} + +__INTRINSIC_LOAD(__ldcv, "ld.global.cv.u8", unsigned char, unsigned int, + "=r", : "memory"); +__INTRINSIC_LOAD(__ldcv, "ld.global.cv.u16", unsigned short, unsigned short, + "=h", : "memory"); +__INTRINSIC_LOAD(__ldcv, "ld.global.cv.u32", unsigned int, unsigned int, + "=r", : "memory"); +__INTRINSIC_LOAD(__ldcv, "ld.global.cv.u64", unsigned long long, + unsigned long long, "=l", : "memory"); + +__INTRINSIC_LOAD(__ldcv, "ld.global.cv.s8", char, unsigned int, + "=r", : "memory"); +__INTRINSIC_LOAD(__ldcv, "ld.global.cv.s8", signed char, unsigned int, + "=r", : "memory"); +__INTRINSIC_LOAD(__ldcv, "ld.global.cv.s16", short, unsigned short, + "=h", : "memory"); +__INTRINSIC_LOAD(__ldcv, "ld.global.cv.s32", int, unsigned int, + "=r", : "memory"); +__INTRINSIC_LOAD(__ldcv, "ld.global.cv.s64", long long, unsigned long long, + "=l", : "memory"); + +__INTRINSIC_LOAD2(__ldcv, "ld.global.cv.v2.u8", uchar2, uint2, + "=r", : "memory"); +__INTRINSIC_LOAD4(__ldcv, "ld.global.cv.v4.u8", uchar4, uint4, + "=r", : "memory"); +__INTRINSIC_LOAD2(__ldcv, "ld.global.cv.v2.u16", ushort2, ushort2, + "=h", : "memory"); +__INTRINSIC_LOAD4(__ldcv, "ld.global.cv.v4.u16", ushort4, ushort4, + "=h", : "memory"); +__INTRINSIC_LOAD2(__ldcv, "ld.global.cv.v2.u32", uint2, uint2, + "=r", : "memory"); +__INTRINSIC_LOAD4(__ldcv, "ld.global.cv.v4.u32", uint4, uint4, + "=r", : "memory"); +__INTRINSIC_LOAD2(__ldcv, "ld.global.cv.v2.u64", ulonglong2, ulonglong2, + "=l", : "memory"); + +__INTRINSIC_LOAD2(__ldcv, "ld.global.cv.v2.s8", char2, int2, "=r", : "memory"); +__INTRINSIC_LOAD4(__ldcv, "ld.global.cv.v4.s8", char4, int4, "=r", : "memory"); +__INTRINSIC_LOAD2(__ldcv, "ld.global.cv.v2.s16", short2, short2, + "=h", : "memory"); +__INTRINSIC_LOAD4(__ldcv, "ld.global.cv.v4.s16", short4, short4, + "=h", : "memory"); +__INTRINSIC_LOAD2(__ldcv, "ld.global.cv.v2.s32", int2, int2, "=r", : "memory"); +__INTRINSIC_LOAD4(__ldcv, "ld.global.cv.v4.s32", int4, int4, "=r", : "memory"); +__INTRINSIC_LOAD2(__ldcv, "ld.global.cv.v2.s64", longlong2, longlong2, + "=l", : "memory"); + +__INTRINSIC_LOAD(__ldcv, "ld.global.cv.f32", float, float, "=f", : "memory"); +__INTRINSIC_LOAD(__ldcv, "ld.global.cv.f64", double, double, "=d", : "memory"); + +__INTRINSIC_LOAD2(__ldcv, "ld.global.cv.v2.f32", float2, float2, + "=f", : "memory"); +__INTRINSIC_LOAD4(__ldcv, "ld.global.cv.v4.f32", float4, float4, + "=f", : "memory"); +__INTRINSIC_LOAD2(__ldcv, "ld.global.cv.v2.f64", double2, double2, + "=d", : "memory"); + +inline __device__ long __ldcv(const long *__ptr) { + unsigned long __ret; + if (sizeof(long) == 8) { + asm("ld.global.cv.s64 %0, [%1];" : "=l"(__ret) : "l"(__ptr)); + } else { + asm("ld.global.cv.s32 %0, [%1];" : "=r"(__ret) : "l"(__ptr)); + } + return (long)__ret; +} + +__INTRINSIC_LOAD(__ldcs, "ld.global.cs.s8", char, unsigned int, "=r", ); +__INTRINSIC_LOAD(__ldcs, "ld.global.cs.s8", signed char, signed int, "=r", ); +__INTRINSIC_LOAD(__ldcs, "ld.global.cs.s16", short, unsigned short, "=h", ); +__INTRINSIC_LOAD(__ldcs, "ld.global.cs.s32", int, unsigned int, "=r", ); +__INTRINSIC_LOAD(__ldcs, "ld.global.cs.s64", long long, unsigned long long, + "=l", ); + +__INTRINSIC_LOAD2(__ldcs, "ld.global.cs.v2.s8", char2, int2, "=r", ); +__INTRINSIC_LOAD4(__ldcs, "ld.global.cs.v4.s8", char4, int4, "=r", ); +__INTRINSIC_LOAD2(__ldcs, "ld.global.cs.v2.s16", short2, short2, "=h", ); +__INTRINSIC_LOAD4(__ldcs, "ld.global.cs.v4.s16", short4, short4, "=h", ); +__INTRINSIC_LOAD2(__ldcs, "ld.global.cs.v2.s32", int2, int2, "=r", ); +__INTRINSIC_LOAD4(__ldcs, "ld.global.cs.v4.s32", int4, int4, "=r", ); +__INTRINSIC_LOAD2(__ldcs, "ld.global.cs.v2.s64", longlong2, longlong2, "=l", ); + +__INTRINSIC_LOAD(__ldcs, "ld.global.cs.u8", unsigned char, unsigned int, + "=r", ); +__INTRINSIC_LOAD(__ldcs, "ld.global.cs.u16", unsigned short, unsigned short, + "=h", ); +__INTRINSIC_LOAD(__ldcs, "ld.global.cs.u32", unsigned int, unsigned int, + "=r", ); +__INTRINSIC_LOAD(__ldcs, "ld.global.cs.u64", unsigned long long, + unsigned long long, "=l", ); + +__INTRINSIC_LOAD2(__ldcs, "ld.global.cs.v2.u8", uchar2, uint2, "=r", ); +__INTRINSIC_LOAD4(__ldcs, "ld.global.cs.v4.u8", uchar4, uint4, "=r", ); +__INTRINSIC_LOAD2(__ldcs, "ld.global.cs.v2.u16", ushort2, ushort2, "=h", ); +__INTRINSIC_LOAD4(__ldcs, "ld.global.cs.v4.u16", ushort4, ushort4, "=h", ); +__INTRINSIC_LOAD2(__ldcs, "ld.global.cs.v2.u32", uint2, uint2, "=r", ); +__INTRINSIC_LOAD4(__ldcs, "ld.global.cs.v4.u32", uint4, uint4, "=r", ); +__INTRINSIC_LOAD2(__ldcs, "ld.global.cs.v2.u64", ulonglong2, ulonglong2, + "=l", ); + +__INTRINSIC_LOAD(__ldcs, "ld.global.cs.f32", float, float, "=f", ); +__INTRINSIC_LOAD(__ldcs, "ld.global.cs.f64", double, double, "=d", ); +__INTRINSIC_LOAD2(__ldcs, "ld.global.cs.v2.f32", float2, float2, "=f", ); +__INTRINSIC_LOAD4(__ldcs, "ld.global.cs.v4.f32", float4, float4, "=f", ); +__INTRINSIC_LOAD2(__ldcs, "ld.global.cs.v2.f64", double2, double2, "=d", ); + +#pragma pop_macro("__INTRINSIC_LOAD") +#pragma pop_macro("__INTRINSIC_LOAD2") +#pragma pop_macro("__INTRINSIC_LOAD4") + +inline __device__ long __ldcs(const long *__ptr) { + unsigned long __ret; + if (sizeof(long) == 8) { + asm("ld.global.cs.s64 %0, [%1];" : "=l"(__ret) : "l"(__ptr)); + } else { + asm("ld.global.cs.s32 %0, [%1];" : "=r"(__ret) : "l"(__ptr)); + } + return (long)__ret; +} + +#pragma push_macro("__INTRINSIC_STORE") +#define __INTRINSIC_STORE(__FnName, __AsmOp, __DeclType, __TmpType, __AsmType) \ + inline __device__ void __FnName(__DeclType *__ptr, __DeclType __value) { \ + __TmpType __tmp = (__TmpType)__value; \ + asm(__AsmOp " [%0], %1;" ::"l"(__ptr), __AsmType(__tmp) : "memory"); \ + } + +#pragma push_macro("__INTRINSIC_STORE2") +#define __INTRINSIC_STORE2(__FnName, __AsmOp, __DeclType, __TmpType, \ + __AsmType) \ + inline __device__ void __FnName(__DeclType *__ptr, __DeclType __value) { \ + __TmpType __tmp; \ + using __ElementType = decltype(__tmp.x); \ + __tmp.x = (__ElementType)(__value.x); \ + __tmp.y = (__ElementType)(__value.y); \ + asm(__AsmOp " [%0], {%1,%2};" ::"l"(__ptr), __AsmType(__tmp.x), \ + __AsmType(__tmp.y) \ + : "memory"); \ + } + +#pragma push_macro("__INTRINSIC_STORE4") +#define __INTRINSIC_STORE4(__FnName, __AsmOp, __DeclType, __TmpType, \ + __AsmType) \ + inline __device__ void __FnName(__DeclType *__ptr, __DeclType __value) { \ + __TmpType __tmp; \ + using __ElementType = decltype(__tmp.x); \ + __tmp.x = (__ElementType)(__value.x); \ + __tmp.y = (__ElementType)(__value.y); \ + __tmp.z = (__ElementType)(__value.z); \ + __tmp.w = (__ElementType)(__value.w); \ + asm(__AsmOp " [%0], {%1,%2,%3,%4};" ::"l"(__ptr), __AsmType(__tmp.x), \ + __AsmType(__tmp.y), __AsmType(__tmp.z), __AsmType(__tmp.w) \ + : "memory"); \ + } + +__INTRINSIC_STORE(__stwt, "st.global.wt.s8", char, int, "r"); +__INTRINSIC_STORE(__stwt, "st.global.wt.s8", signed char, int, "r"); +__INTRINSIC_STORE(__stwt, "st.global.wt.s16", short, short, "h"); +__INTRINSIC_STORE(__stwt, "st.global.wt.s32", int, int, "r"); +__INTRINSIC_STORE(__stwt, "st.global.wt.s64", long long, long long, "l"); + +__INTRINSIC_STORE2(__stwt, "st.global.wt.v2.s8", char2, int2, "r"); +__INTRINSIC_STORE4(__stwt, "st.global.wt.v4.s8", char4, int4, "r"); +__INTRINSIC_STORE2(__stwt, "st.global.wt.v2.s16", short2, short2, "h"); +__INTRINSIC_STORE4(__stwt, "st.global.wt.v4.s16", short4, short4, "h"); +__INTRINSIC_STORE2(__stwt, "st.global.wt.v2.s32", int2, int2, "r"); +__INTRINSIC_STORE4(__stwt, "st.global.wt.v4.s32", int4, int4, "r"); +__INTRINSIC_STORE2(__stwt, "st.global.wt.v2.s64", longlong2, longlong2, "l"); + +__INTRINSIC_STORE(__stwt, "st.global.wt.u8", unsigned char, int, "r"); +__INTRINSIC_STORE(__stwt, "st.global.wt.u16", unsigned short, unsigned short, + "h"); +__INTRINSIC_STORE(__stwt, "st.global.wt.u32", unsigned int, unsigned int, "r"); +__INTRINSIC_STORE(__stwt, "st.global.wt.u64", unsigned long long, + unsigned long long, "l"); + +__INTRINSIC_STORE2(__stwt, "st.global.wt.v2.u8", uchar2, uchar2, "r"); +__INTRINSIC_STORE4(__stwt, "st.global.wt.v4.u8", uchar4, uint4, "r"); +__INTRINSIC_STORE2(__stwt, "st.global.wt.v2.u16", ushort2, ushort2, "h"); +__INTRINSIC_STORE4(__stwt, "st.global.wt.v4.u16", ushort4, ushort4, "h"); +__INTRINSIC_STORE2(__stwt, "st.global.wt.v2.u32", uint2, uint2, "r"); +__INTRINSIC_STORE4(__stwt, "st.global.wt.v4.u32", uint4, uint4, "r"); +__INTRINSIC_STORE2(__stwt, "st.global.wt.v2.u64", ulonglong2, ulonglong2, "l"); + +__INTRINSIC_STORE(__stwt, "st.global.wt.f32", float, float, "f"); +__INTRINSIC_STORE(__stwt, "st.global.wt.f64", double, double, "d"); +__INTRINSIC_STORE2(__stwt, "st.global.wt.v2.f32", float2, float2, "f"); +__INTRINSIC_STORE4(__stwt, "st.global.wt.v4.f32", float4, float4, "f"); +__INTRINSIC_STORE2(__stwt, "st.global.wt.v2.f64", double2, double2, "d"); + +#pragma pop_macro("__INTRINSIC_STORE") +#pragma pop_macro("__INTRINSIC_STORE2") +#pragma pop_macro("__INTRINSIC_STORE4") + +#endif // defined(__cplusplus) && (__cplusplus >= 201103L) #endif // !defined(__CUDA_ARCH__) || __CUDA_ARCH__ >= 320 #if CUDA_VERSION >= 11000 diff --git a/external/llvm-project/clang/lib/Headers/bmiintrin.h b/external/llvm-project/clang/lib/Headers/bmiintrin.h index 59c5ece3977f..8024da55379c 100644 --- a/external/llvm-project/clang/lib/Headers/bmiintrin.h +++ b/external/llvm-project/clang/lib/Headers/bmiintrin.h @@ -161,8 +161,6 @@ _mm_tzcnt_64(unsigned long long __X) { #undef __RELAXED_FN_ATTRS -#if !defined(__SCE__) || __has_feature(modules) || defined(__BMI__) - /* Define the default attributes for the functions in this file. */ #if defined(__cplusplus) && (__cplusplus >= 201103L) #define __DEFAULT_FN_ATTRS \ @@ -603,6 +601,4 @@ __blsr_u64(unsigned long long __X) { #undef __DEFAULT_FN_ATTRS -#endif /* !defined(__SCE__) || __has_feature(modules) || defined(__BMI__) */ - #endif /* __BMIINTRIN_H */ diff --git a/external/llvm-project/clang/lib/Headers/cuda_wrappers/bits/c++config.h b/external/llvm-project/clang/lib/Headers/cuda_wrappers/bits/c++config.h new file mode 100644 index 000000000000..27083253181d --- /dev/null +++ b/external/llvm-project/clang/lib/Headers/cuda_wrappers/bits/c++config.h @@ -0,0 +1,61 @@ +// libstdc++ uses the non-constexpr function std::__glibcxx_assert_fail() +// to trigger compilation errors when the __glibcxx_assert(cond) macro +// is used in a constexpr context. +// Compilation fails when using code from the libstdc++ (such as std::array) on +// device code, since these assertions invoke a non-constexpr host function from +// device code. +// +// To work around this issue, we declare our own device version of the function + +#ifndef __CLANG_CUDA_WRAPPERS_BITS_CPP_CONFIG +#define __CLANG_CUDA_WRAPPERS_BITS_CPP_CONFIG + +#include_next + +#ifdef _LIBCPP_BEGIN_NAMESPACE_STD +_LIBCPP_BEGIN_NAMESPACE_STD +#else +namespace std { +#ifdef _GLIBCXX_BEGIN_NAMESPACE_VERSION +_GLIBCXX_BEGIN_NAMESPACE_VERSION +#endif + +#pragma push_macro("CUDA_NOEXCEPT") +#if __cplusplus >= 201103L +#define CUDA_NOEXCEPT noexcept +#else +#define CUDA_NOEXCEPT +#endif + +__attribute__((device, noreturn)) inline void +__glibcxx_assert_fail(const char *file, int line, const char *function, + const char *condition) CUDA_NOEXCEPT { +#ifdef _GLIBCXX_VERBOSE_ASSERT + if (file && function && condition) + __builtin_printf("%s:%d: %s: Assertion '%s' failed.\n", file, line, + function, condition); + else if (function) + __builtin_printf("%s: Undefined behavior detected.\n", function); +#endif + __builtin_abort(); +} + +#endif +__attribute__((device, noreturn, __always_inline__, + __visibility__("default"))) inline void +__glibcxx_assert_fail() CUDA_NOEXCEPT { + __builtin_abort(); +} + +#pragma pop_macro("CUDA_NOEXCEPT") + +#ifdef _LIBCPP_END_NAMESPACE_STD +_LIBCPP_END_NAMESPACE_STD +#else +#ifdef _GLIBCXX_BEGIN_NAMESPACE_VERSION +_GLIBCXX_END_NAMESPACE_VERSION +#endif +} // namespace std +#endif + +#endif diff --git a/external/llvm-project/clang/lib/Headers/immintrin.h b/external/llvm-project/clang/lib/Headers/immintrin.h index 19c5987257a2..35f012cc7004 100644 --- a/external/llvm-project/clang/lib/Headers/immintrin.h +++ b/external/llvm-project/clang/lib/Headers/immintrin.h @@ -16,231 +16,112 @@ #include -#if !defined(__SCE__) || __has_feature(modules) || defined(__MMX__) #include -#endif -#if !defined(__SCE__) || __has_feature(modules) || defined(__SSE__) #include -#endif -#if !defined(__SCE__) || __has_feature(modules) || defined(__SSE2__) #include -#endif -#if !defined(__SCE__) || __has_feature(modules) || defined(__SSE3__) #include -#endif -#if !defined(__SCE__) || __has_feature(modules) || defined(__SSSE3__) #include -#endif -#if !defined(__SCE__) || __has_feature(modules) || \ - (defined(__SSE4_2__) || defined(__SSE4_1__)) #include -#endif -#if !defined(__SCE__) || __has_feature(modules) || \ - (defined(__AES__) || defined(__PCLMUL__)) #include -#endif -#if !defined(__SCE__) || __has_feature(modules) || defined(__CLFLUSHOPT__) #include -#endif -#if !defined(__SCE__) || __has_feature(modules) || defined(__CLWB__) #include -#endif -#if !defined(__SCE__) || __has_feature(modules) || defined(__AVX__) #include -#endif -#if !defined(__SCE__) || __has_feature(modules) || defined(__AVX2__) #include -#endif -#if !defined(__SCE__) || __has_feature(modules) || defined(__F16C__) #include -#endif -/* No feature check desired due to internal checks */ #include -#if !defined(__SCE__) || __has_feature(modules) || defined(__BMI2__) #include -#endif -#if !defined(__SCE__) || __has_feature(modules) || defined(__LZCNT__) #include -#endif -#if !defined(__SCE__) || __has_feature(modules) || defined(__POPCNT__) #include -#endif -#if !defined(__SCE__) || __has_feature(modules) || defined(__FMA__) #include -#endif -#if !defined(__SCE__) || __has_feature(modules) || defined(__AVX512F__) #include -#endif -#if !defined(__SCE__) || __has_feature(modules) || defined(__AVX512VL__) #include -#endif -#if !defined(__SCE__) || __has_feature(modules) || defined(__AVX512BW__) #include -#endif -#if !defined(__SCE__) || __has_feature(modules) || defined(__AVX512BITALG__) #include -#endif -#if !defined(__SCE__) || __has_feature(modules) || defined(__AVX512CD__) #include -#endif -#if !defined(__SCE__) || __has_feature(modules) || defined(__AVX512VPOPCNTDQ__) #include -#endif -#if !defined(__SCE__) || __has_feature(modules) || \ - (defined(__AVX512VL__) && defined(__AVX512VPOPCNTDQ__)) #include -#endif -#if !defined(__SCE__) || __has_feature(modules) || defined(__AVX512VNNI__) #include -#endif -#if !defined(__SCE__) || __has_feature(modules) || \ - (defined(__AVX512VL__) && defined(__AVX512VNNI__)) #include -#endif -#if !defined(__SCE__) || __has_feature(modules) || defined(__AVXVNNI__) #include -#endif -#if !defined(__SCE__) || __has_feature(modules) || defined(__AVX512DQ__) #include -#endif -#if !defined(__SCE__) || __has_feature(modules) || \ - (defined(__AVX512VL__) && defined(__AVX512BITALG__)) #include -#endif -#if !defined(__SCE__) || __has_feature(modules) || \ - (defined(__AVX512VL__) && defined(__AVX512BW__)) #include -#endif -#if !defined(__SCE__) || __has_feature(modules) || \ - (defined(__AVX512VL__) && defined(__AVX512CD__)) #include -#endif -#if !defined(__SCE__) || __has_feature(modules) || \ - (defined(__AVX512VL__) && defined(__AVX512DQ__)) #include -#endif -#if !defined(__SCE__) || __has_feature(modules) || defined(__AVX512IFMA__) #include -#endif -#if !defined(__SCE__) || __has_feature(modules) || \ - (defined(__AVX512IFMA__) && defined(__AVX512VL__)) #include -#endif -#if !defined(__SCE__) || __has_feature(modules) || defined(__AVXIFMA__) #include -#endif -#if !defined(__SCE__) || __has_feature(modules) || defined(__AVX512VBMI__) #include -#endif -#if !defined(__SCE__) || __has_feature(modules) || \ - (defined(__AVX512VBMI__) && defined(__AVX512VL__)) #include -#endif -#if !defined(__SCE__) || __has_feature(modules) || defined(__AVX512VBMI2__) #include -#endif -#if !defined(__SCE__) || __has_feature(modules) || \ - (defined(__AVX512VBMI2__) && defined(__AVX512VL__)) #include -#endif -#if !defined(__SCE__) || __has_feature(modules) || defined(__AVX512FP16__) #include -#endif -#if !defined(__SCE__) || __has_feature(modules) || \ - (defined(__AVX512VL__) && defined(__AVX512FP16__)) #include -#endif -#if !defined(__SCE__) || __has_feature(modules) || defined(__AVX512BF16__) #include -#endif -#if !defined(__SCE__) || __has_feature(modules) || \ - (defined(__AVX512VL__) && defined(__AVX512BF16__)) #include -#endif -#if !defined(__SCE__) || __has_feature(modules) || defined(__PKU__) #include -#endif -#if !defined(__SCE__) || __has_feature(modules) || defined(__VPCLMULQDQ__) #include -#endif -#if !defined(__SCE__) || __has_feature(modules) || defined(__VAES__) #include -#endif -#if !defined(__SCE__) || __has_feature(modules) || defined(__GFNI__) #include -#endif -#if !defined(__SCE__) || __has_feature(modules) || defined(__AVXVNNIINT8__) #include -#endif -#if !defined(__SCE__) || __has_feature(modules) || defined(__AVXNECONVERT__) #include -#endif -#if !defined(__SCE__) || __has_feature(modules) || defined(__SHA512__) #include -#endif -#if !defined(__SCE__) || __has_feature(modules) || defined(__SM3__) #include -#endif -#if !defined(__SCE__) || __has_feature(modules) || defined(__SM4__) #include -#endif -#if !defined(__SCE__) || __has_feature(modules) || defined(__AVXVNNIINT16__) #include -#endif -#if !defined(__SCE__) || __has_feature(modules) || defined(__RDPID__) /// Reads the value of the IA32_TSC_AUX MSR (0xc0000103). /// /// \headerfile @@ -252,9 +133,7 @@ static __inline__ unsigned int __attribute__((__always_inline__, __nodebug__, __ _rdpid_u32(void) { return __builtin_ia32_rdpid(); } -#endif // __RDPID__ -#if !defined(__SCE__) || __has_feature(modules) || defined(__RDRND__) /// Returns a 16-bit hardware-generated random value. /// /// \headerfile @@ -314,9 +193,7 @@ _rdrand64_step(unsigned long long *__p) } #endif } -#endif /* __RDRND__ */ -#if !defined(__SCE__) || __has_feature(modules) || defined(__FSGSBASE__) #ifdef __x86_64__ /// Reads the FS base register. /// @@ -427,9 +304,6 @@ _writegsbase_u64(unsigned long long __V) } #endif -#endif /* __FSGSBASE__ */ - -#if !defined(__SCE__) || __has_feature(modules) || defined(__MOVBE__) /* The structs used below are to force the load/store to be unaligned. This * is accomplished with the __packed__ attribute. The __may_alias__ prevents @@ -543,172 +417,86 @@ _storebe_i64(void * __P, long long __D) { ((struct __storeu_i64*)__P)->__v = __builtin_bswap64((unsigned long long)__D); } #endif -#endif /* __MOVBE */ -#if !defined(__SCE__) || __has_feature(modules) || defined(__RTM__) #include #include -#endif -#if !defined(__SCE__) || __has_feature(modules) || defined(__SHA__) #include -#endif -#if !defined(__SCE__) || __has_feature(modules) || defined(__FXSR__) #include -#endif /* No feature check desired due to internal MSC_VER checks */ #include -#if !defined(__SCE__) || __has_feature(modules) || defined(__XSAVEOPT__) #include -#endif -#if !defined(__SCE__) || __has_feature(modules) || defined(__XSAVEC__) #include -#endif -#if !defined(__SCE__) || __has_feature(modules) || defined(__XSAVES__) #include -#endif -#if !defined(__SCE__) || __has_feature(modules) || defined(__SHSTK__) #include -#endif /* Intrinsics inside adcintrin.h are available at all times. */ #include -#if !defined(__SCE__) || __has_feature(modules) || defined(__ADX__) #include -#endif -#if !defined(__SCE__) || __has_feature(modules) || defined(__RDSEED__) #include -#endif -#if !defined(__SCE__) || __has_feature(modules) || defined(__WBNOINVD__) #include -#endif -#if !defined(__SCE__) || __has_feature(modules) || defined(__CLDEMOTE__) #include -#endif -#if !defined(__SCE__) || __has_feature(modules) || defined(__WAITPKG__) #include -#endif -#if !defined(__SCE__) || __has_feature(modules) || defined(__MOVDIRI__) || \ - defined(__MOVDIR64B__) #include -#endif -#if !defined(__SCE__) || __has_feature(modules) || defined(__MOVRS__) #include -#endif -#if !defined(__SCE__) || __has_feature(modules) || \ - (defined(__AVX10_2__) && defined(__MOVRS__)) #include -#endif -#if !defined(__SCE__) || __has_feature(modules) || \ - (defined(__AVX10_2_512__) && defined(__MOVRS__)) #include -#endif -#if !defined(__SCE__) || __has_feature(modules) || defined(__PCONFIG__) #include -#endif -#if !defined(__SCE__) || __has_feature(modules) || defined(__SGX__) #include -#endif -#if !defined(__SCE__) || __has_feature(modules) || defined(__PTWRITE__) #include -#endif -#if !defined(__SCE__) || __has_feature(modules) || defined(__INVPCID__) #include -#endif -#if !defined(__SCE__) || __has_feature(modules) || defined(__KL__) || \ - defined(__WIDEKL__) #include -#endif -#if !defined(__SCE__) || __has_feature(modules) || defined(__AMX_TILE__) || \ - defined(__AMX_INT8__) || defined(__AMX_BF16__) #include -#endif -#if !defined(__SCE__) || __has_feature(modules) || defined(__AMX_FP16__) #include -#endif -#if !defined(__SCE__) || __has_feature(modules) || defined(__AMX_COMPLEX__) #include -#endif -#if !defined(__SCE__) || __has_feature(modules) || defined(__AMX_FP8__) #include -#endif -#if !defined(__SCE__) || __has_feature(modules) || defined(__AMX_TRANSPOSE__) #include -#endif -#if !defined(__SCE__) || __has_feature(modules) || defined(__AMX_MOVRS__) #include -#endif -#if !defined(__SCE__) || __has_feature(modules) || \ - (defined(__AMX_MOVRS__) && defined(__AMX_TRANSPOSE__)) #include -#endif -#if !defined(__SCE__) || __has_feature(modules) || defined(__AMX_AVX512__) #include -#endif -#if !defined(__SCE__) || __has_feature(modules) || defined(__AMX_TF32__) #include -#endif -#if !defined(__SCE__) || __has_feature(modules) || \ - (defined(__AMX_TF32__) && defined(__AMX_TRANSPOSE__)) #include -#endif -#if !defined(__SCE__) || __has_feature(modules) || \ - (defined(__AMX_BF16__) && defined(__AMX_TRANSPOSE__)) #include -#endif -#if !defined(__SCE__) || __has_feature(modules) || \ - (defined(__AMX_FP16__) && defined(__AMX_TRANSPOSE__)) #include -#endif -#if !defined(__SCE__) || __has_feature(modules) || \ - (defined(__AMX_COMPLEX__) && defined(__AMX_TRANSPOSE__)) #include -#endif -#if !defined(__SCE__) || __has_feature(modules) || \ - defined(__AVX512VP2INTERSECT__) #include -#endif -#if !defined(__SCE__) || __has_feature(modules) || \ - (defined(__AVX512VL__) && defined(__AVX512VP2INTERSECT__)) #include -#endif -#if !defined(__SCE__) || __has_feature(modules) || defined(__AVX10_2__) #include #include #include @@ -716,33 +504,21 @@ _storebe_i64(void * __P, long long __D) { #include #include #include -#endif -#if !defined(__SCE__) || __has_feature(modules) || defined(__AVX10_2_512__) #include #include #include #include #include #include -#endif -#if !defined(__SCE__) || __has_feature(modules) || \ - (defined(__AVX10_2_512__) && defined(__SM4__)) #include -#endif -#if !defined(__SCE__) || __has_feature(modules) || defined(__ENQCMD__) #include -#endif -#if !defined(__SCE__) || __has_feature(modules) || defined(__SERIALIZE__) #include -#endif -#if !defined(__SCE__) || __has_feature(modules) || defined(__TSXLDTRK__) #include -#endif #if defined(_MSC_VER) && __has_extension(gnu_asm) /* Define the default attributes for these intrinsics */ diff --git a/external/llvm-project/clang/lib/Headers/keylockerintrin.h b/external/llvm-project/clang/lib/Headers/keylockerintrin.h index f76e91b4d4b3..4e9e6bec20c0 100644 --- a/external/llvm-project/clang/lib/Headers/keylockerintrin.h +++ b/external/llvm-project/clang/lib/Headers/keylockerintrin.h @@ -28,8 +28,6 @@ #ifndef _KEYLOCKERINTRIN_H #define _KEYLOCKERINTRIN_H -#if !defined(__SCE__) || __has_feature(modules) || defined(__KL__) - /* Define the default attributes for the functions in this file. */ #define __DEFAULT_FN_ATTRS \ __attribute__((__always_inline__, __nodebug__, __target__("kl"),\ @@ -326,10 +324,6 @@ _mm_aesdec256kl_u8(__m128i* __odata, __m128i __idata, const void *__h) { #undef __DEFAULT_FN_ATTRS -#endif /* !defined(__SCE__ || __has_feature(modules) || defined(__KL__) */ - -#if !defined(__SCE__) || __has_feature(modules) || defined(__WIDEKL__) - /* Define the default attributes for the functions in this file. */ #define __DEFAULT_FN_ATTRS \ __attribute__((__always_inline__, __nodebug__, __target__("kl,widekl"),\ @@ -521,7 +515,4 @@ _mm_aesdecwide256kl_u8(__m128i __odata[8], const __m128i __idata[8], const void* #undef __DEFAULT_FN_ATTRS -#endif /* !defined(__SCE__) || __has_feature(modules) || defined(__WIDEKL__) \ - */ - #endif /* _KEYLOCKERINTRIN_H */ diff --git a/external/llvm-project/clang/lib/Headers/x86gprintrin.h b/external/llvm-project/clang/lib/Headers/x86gprintrin.h index 3d5cc606d7e6..8d513ceffb6d 100644 --- a/external/llvm-project/clang/lib/Headers/x86gprintrin.h +++ b/external/llvm-project/clang/lib/Headers/x86gprintrin.h @@ -10,33 +10,19 @@ #ifndef __X86GPRINTRIN_H #define __X86GPRINTRIN_H -#if !defined(__SCE__) || __has_feature(modules) || defined(__HRESET__) #include -#endif -#if !defined(__SCE__) || __has_feature(modules) || defined(__UINTR__) #include -#endif -#if !defined(__SCE__) || __has_feature(modules) || defined(__USERMSR__) #include -#endif -#if !defined(__SCE__) || __has_feature(modules) || defined(__CRC32__) #include -#endif -#if !defined(__SCE__) || __has_feature(modules) || defined(__PRFCHI__) #include -#endif -#if !defined(__SCE__) || __has_feature(modules) || defined(__RAOINT__) #include -#endif -#if !defined(__SCE__) || __has_feature(modules) || defined(__CMPCCXADD__) #include -#endif #if defined(__i386__) #define __SAVE_GPRBX "mov {%%ebx, %%eax |eax, ebx};" diff --git a/external/llvm-project/clang/lib/Headers/x86intrin.h b/external/llvm-project/clang/lib/Headers/x86intrin.h index f42e9e580f88..aaa84365ce3e 100644 --- a/external/llvm-project/clang/lib/Headers/x86intrin.h +++ b/external/llvm-project/clang/lib/Headers/x86intrin.h @@ -14,40 +14,22 @@ #include -#if !defined(__SCE__) || __has_feature(modules) || defined(__PRFCHW__) #include -#endif -#if !defined(__SCE__) || __has_feature(modules) || defined(__SSE4A__) #include -#endif -#if !defined(__SCE__) || __has_feature(modules) || defined(__FMA4__) #include -#endif -#if !defined(__SCE__) || __has_feature(modules) || defined(__XOP__) #include -#endif -#if !defined(__SCE__) || __has_feature(modules) || defined(__TBM__) #include -#endif -#if !defined(__SCE__) || __has_feature(modules) || defined(__LWP__) #include -#endif -#if !defined(__SCE__) || __has_feature(modules) || defined(__MWAITX__) #include -#endif -#if !defined(__SCE__) || __has_feature(modules) || defined(__CLZERO__) #include -#endif -#if !defined(__SCE__) || __has_feature(modules) || defined(__RDPRU__) #include -#endif #endif /* __X86INTRIN_H */ diff --git a/external/llvm-project/clang/lib/Lex/InitHeaderSearch.cpp b/external/llvm-project/clang/lib/Lex/InitHeaderSearch.cpp index 641e3beebc08..3e22b4001bde 100644 --- a/external/llvm-project/clang/lib/Lex/InitHeaderSearch.cpp +++ b/external/llvm-project/clang/lib/Lex/InitHeaderSearch.cpp @@ -221,6 +221,7 @@ bool InitHeaderSearch::ShouldAddDefaultIncludePaths( case llvm::Triple::Hurd: case llvm::Triple::Linux: case llvm::Triple::LiteOS: + case llvm::Triple::Managarm: case llvm::Triple::NaCl: case llvm::Triple::NetBSD: case llvm::Triple::OpenBSD: diff --git a/external/llvm-project/clang/lib/Lex/Lexer.cpp b/external/llvm-project/clang/lib/Lex/Lexer.cpp index 93200458f04b..f4d16ecce393 100644 --- a/external/llvm-project/clang/lib/Lex/Lexer.cpp +++ b/external/llvm-project/clang/lib/Lex/Lexer.cpp @@ -174,6 +174,8 @@ void Lexer::InitLexer(const char *BufStart, const char *BufPtr, ExtendedTokenMode = 0; NewLinePtr = nullptr; + + IsFirstPPToken = true; } /// Lexer constructor - Create a new lexer object for the specified buffer @@ -3200,18 +3202,19 @@ bool Lexer::LexEndOfFile(Token &Result, const char *CurPtr) { return PP->HandleEndOfFile(Result, isPragmaLexer()); } -/// isNextPPTokenLParen - Return 1 if the next unexpanded token lexed from -/// the specified lexer will return a tok::l_paren token, 0 if it is something -/// else and 2 if there are no more tokens in the buffer controlled by the -/// lexer. -unsigned Lexer::isNextPPTokenLParen() { +/// peekNextPPToken - Return std::nullopt if there are no more tokens in the +/// buffer controlled by this lexer, otherwise return the next unexpanded +/// token. +std::optional Lexer::peekNextPPToken() { assert(!LexingRawMode && "How can we expand a macro from a skipping buffer?"); if (isDependencyDirectivesLexer()) { if (NextDepDirectiveTokenIndex == DepDirectives.front().Tokens.size()) - return 2; - return DepDirectives.front().Tokens[NextDepDirectiveTokenIndex].is( - tok::l_paren); + return std::nullopt; + Token Result; + (void)convertDependencyDirectiveToken( + DepDirectives.front().Tokens[NextDepDirectiveTokenIndex], Result); + return Result; } // Switch to 'skipping' mode. This will ensure that we can lex a token @@ -3240,8 +3243,8 @@ unsigned Lexer::isNextPPTokenLParen() { LexingRawMode = false; if (Tok.is(tok::eof)) - return 2; - return Tok.is(tok::l_paren); + return std::nullopt; + return Tok; } /// Find the end of a version control conflict marker. @@ -3725,6 +3728,11 @@ bool Lexer::Lex(Token &Result) { HasLeadingEmptyMacro = false; } + if (IsFirstPPToken) { + Result.setFlag(Token::FirstPPToken); + IsFirstPPToken = false; + } + bool atPhysicalStartOfLine = IsAtPhysicalStartOfLine; IsAtPhysicalStartOfLine = false; bool isRawLex = isLexingRawMode(); @@ -3732,6 +3740,10 @@ bool Lexer::Lex(Token &Result) { bool returnedToken = LexTokenInternal(Result, atPhysicalStartOfLine); // (After the LexTokenInternal call, the lexer might be destroyed.) assert((returnedToken || !isRawLex) && "Raw lex must succeed"); + + if (returnedToken && Result.isFirstPPToken() && PP && + !PP->hasSeenMainFileFirstPPToken()) + PP->HandleMainFileFirstPPToken(Result); return returnedToken; } @@ -4535,6 +4547,8 @@ const char *Lexer::convertDependencyDirectiveToken( Result.setFlag((Token::TokenFlags)DDTok.Flags); Result.setLength(DDTok.Length); BufferPtr = TokPtr + DDTok.Length; + if (PP && !PP->hasSeenMainFileFirstPPToken() && Result.isFirstPPToken()) + PP->HandleMainFileFirstPPToken(Result); return TokPtr; } diff --git a/external/llvm-project/clang/lib/Lex/PPDirectives.cpp b/external/llvm-project/clang/lib/Lex/PPDirectives.cpp index 04a30f66fb73..c8974e5a3528 100644 --- a/external/llvm-project/clang/lib/Lex/PPDirectives.cpp +++ b/external/llvm-project/clang/lib/Lex/PPDirectives.cpp @@ -183,9 +183,9 @@ static bool isReservedCXXAttributeName(Preprocessor &PP, IdentifierInfo *II) { AttributeCommonInfo::AttrArgsInfo AttrArgsInfo = AttributeCommonInfo::getCXX11AttrArgsInfo(II); if (AttrArgsInfo == AttributeCommonInfo::AttrArgsInfo::Required) - return PP.isNextPPTokenLParen(); + return PP.isNextPPTokenOneOf(); - return !PP.isNextPPTokenLParen() || + return !PP.isNextPPTokenOneOf() || AttrArgsInfo == AttributeCommonInfo::AttrArgsInfo::Optional; } return false; @@ -1242,6 +1242,9 @@ void Preprocessor::HandleDirective(Token &Result) { // pp-directive. bool ReadAnyTokensBeforeDirective =CurPPLexer->MIOpt.getHasReadAnyTokensVal(); + if (!hasSeenMainFileFirstPPToken()) + HandleMainFileFirstPPToken(Result); + // Save the '#' token in case we need to return it later. Token SavedHash = Result; diff --git a/external/llvm-project/clang/lib/Lex/PPMacroExpansion.cpp b/external/llvm-project/clang/lib/Lex/PPMacroExpansion.cpp index 37ac1bf07e9c..709cf3bb87c8 100644 --- a/external/llvm-project/clang/lib/Lex/PPMacroExpansion.cpp +++ b/external/llvm-project/clang/lib/Lex/PPMacroExpansion.cpp @@ -418,44 +418,6 @@ static bool isTrivialSingleTokenExpansion(const MacroInfo *MI, return !llvm::is_contained(MI->params(), II); } -/// isNextPPTokenLParen - Determine whether the next preprocessor token to be -/// lexed is a '('. If so, consume the token and return true, if not, this -/// method should have no observable side-effect on the lexed tokens. -bool Preprocessor::isNextPPTokenLParen() { - // Do some quick tests for rejection cases. - unsigned Val; - if (CurLexer) - Val = CurLexer->isNextPPTokenLParen(); - else - Val = CurTokenLexer->isNextTokenLParen(); - - if (Val == 2) { - // We have run off the end. If it's a source file we don't - // examine enclosing ones (C99 5.1.1.2p4). Otherwise walk up the - // macro stack. - if (CurPPLexer) - return false; - for (const IncludeStackInfo &Entry : llvm::reverse(IncludeMacroStack)) { - if (Entry.TheLexer) - Val = Entry.TheLexer->isNextPPTokenLParen(); - else - Val = Entry.TheTokenLexer->isNextTokenLParen(); - - if (Val != 2) - break; - - // Ran off the end of a source file? - if (Entry.ThePPLexer) - return false; - } - } - - // Okay, if we know that the token is a '(', lex it and return. Otherwise we - // have found something that isn't a '(' or we found the end of the - // translation unit. In either case, return false. - return Val == 1; -} - /// HandleMacroExpandedIdentifier - If an identifier token is read that is to be /// expanded as a macro, handle it and return the next token as 'Identifier'. bool Preprocessor::HandleMacroExpandedIdentifier(Token &Identifier, @@ -469,6 +431,9 @@ bool Preprocessor::HandleMacroExpandedIdentifier(Token &Identifier, // to disable the optimization in this case. if (CurPPLexer) CurPPLexer->MIOpt.ExpandedMacro(); + if (!hasSeenMainFileFirstPPToken()) + HandleMainFileFirstPPToken(Identifier); + // If this is a builtin macro, like __LINE__ or _Pragma, handle it specially. if (MI->isBuiltinMacro()) { if (Callbacks) diff --git a/external/llvm-project/clang/lib/Lex/Preprocessor.cpp b/external/llvm-project/clang/lib/Lex/Preprocessor.cpp index 21fc7a2b6fae..7fecbe9eee53 100644 --- a/external/llvm-project/clang/lib/Lex/Preprocessor.cpp +++ b/external/llvm-project/clang/lib/Lex/Preprocessor.cpp @@ -247,6 +247,8 @@ void Preprocessor::DumpToken(const Token &Tok, bool DumpFlags) const { llvm::errs() << " [LeadingSpace]"; if (Tok.isExpandDisabled()) llvm::errs() << " [ExpandDisabled]"; + if (Tok.isFirstPPToken()) + llvm::errs() << " [First pp-token]"; if (Tok.needsCleaning()) { const char *Start = SourceMgr.getCharacterData(Tok.getLocation()); llvm::errs() << " [UnClean='" << StringRef(Start, Tok.getLength()) @@ -811,14 +813,14 @@ bool Preprocessor::HandleIdentifier(Token &Identifier) { if (!Identifier.isExpandDisabled() && MI->isEnabled()) { // C99 6.10.3p10: If the preprocessing token immediately after the // macro name isn't a '(', this macro should not be expanded. - if (!MI->isFunctionLike() || isNextPPTokenLParen()) + if (!MI->isFunctionLike() || isNextPPTokenOneOf()) return HandleMacroExpandedIdentifier(Identifier, MD); } else { // C99 6.10.3.4p2 says that a disabled macro may never again be // expanded, even if it's in a context where it could be expanded in the // future. Identifier.setFlag(Token::DisableExpand); - if (MI->isObjectLike() || isNextPPTokenLParen()) + if (MI->isObjectLike() || isNextPPTokenOneOf()) Diag(Identifier, diag::pp_disabled_macro_expansion); } } diff --git a/external/llvm-project/clang/lib/Lex/TokenLexer.cpp b/external/llvm-project/clang/lib/Lex/TokenLexer.cpp index 6e93416e01c0..fbb8c4262d6d 100644 --- a/external/llvm-project/clang/lib/Lex/TokenLexer.cpp +++ b/external/llvm-project/clang/lib/Lex/TokenLexer.cpp @@ -921,13 +921,13 @@ bool TokenLexer::pasteTokens(Token &LHSTok, ArrayRef TokenStream, } /// isNextTokenLParen - If the next token lexed will pop this macro off the -/// expansion stack, return 2. If the next unexpanded token is a '(', return -/// 1, otherwise return 0. -unsigned TokenLexer::isNextTokenLParen() const { +/// expansion stack, return std::nullopt, otherwise return the next unexpanded +/// token. +std::optional TokenLexer::peekNextPPToken() const { // Out of tokens? if (isAtEnd()) - return 2; - return Tokens[CurTokenIdx].is(tok::l_paren); + return std::nullopt; + return Tokens[CurTokenIdx]; } /// isParsingPreprocessorDirective - Return true if we are in the middle of a diff --git a/external/llvm-project/clang/lib/Parse/CMakeLists.txt b/external/llvm-project/clang/lib/Parse/CMakeLists.txt index 00fde537bb9c..e6cbf3b868b7 100644 --- a/external/llvm-project/clang/lib/Parse/CMakeLists.txt +++ b/external/llvm-project/clang/lib/Parse/CMakeLists.txt @@ -1,4 +1,5 @@ set(LLVM_LINK_COMPONENTS + FrontendHLSL FrontendOpenMP MC MCParser diff --git a/external/llvm-project/clang/lib/Parse/ParseDecl.cpp b/external/llvm-project/clang/lib/Parse/ParseDecl.cpp index 02f33511dbd6..7e739e09b15e 100644 --- a/external/llvm-project/clang/lib/Parse/ParseDecl.cpp +++ b/external/llvm-project/clang/lib/Parse/ParseDecl.cpp @@ -7048,7 +7048,8 @@ void Parser::ParseParenDeclarator(Declarator &D) { // paren, because we haven't seen the identifier yet. isGrouping = true; } else if (Tok.is(tok::r_paren) || // 'int()' is a function. - (getLangOpts().CPlusPlus && Tok.is(tok::ellipsis) && + ((getLangOpts().CPlusPlus || getLangOpts().C23) && + Tok.is(tok::ellipsis) && NextToken().is(tok::r_paren)) || // C++ int(...) isDeclarationSpecifier( ImplicitTypenameContext::No) || // 'int(int)' is a function. diff --git a/external/llvm-project/clang/lib/Parse/ParseDeclCXX.cpp b/external/llvm-project/clang/lib/Parse/ParseDeclCXX.cpp index a5c76501c7c1..c1493a5bfd3b 100644 --- a/external/llvm-project/clang/lib/Parse/ParseDeclCXX.cpp +++ b/external/llvm-project/clang/lib/Parse/ParseDeclCXX.cpp @@ -29,6 +29,7 @@ #include "clang/Sema/ParsedTemplate.h" #include "clang/Sema/Scope.h" #include "clang/Sema/SemaCodeCompletion.h" +#include "clang/Sema/SemaHLSL.h" #include "llvm/Support/TimeProfiler.h" #include @@ -4903,7 +4904,7 @@ void Parser::ParseMicrosoftUuidAttributeArgs(ParsedAttributes &Attrs) { } } -void Parser::ParseMicrosoftRootSignatureAttributeArgs(ParsedAttributes &Attrs) { +void Parser::ParseHLSLRootSignatureAttributeArgs(ParsedAttributes &Attrs) { assert(Tok.is(tok::identifier) && "Expected an identifier to denote which MS attribute to consider"); IdentifierInfo *RootSignatureIdent = Tok.getIdentifierInfo(); @@ -4945,18 +4946,14 @@ void Parser::ParseMicrosoftRootSignatureAttributeArgs(ParsedAttributes &Attrs) { // Construct our identifier StringRef Signature = StrLiteral.value()->getString(); - auto Hash = llvm::hash_value(Signature); - std::string IdStr = "__hlsl_rootsig_decl_" + std::to_string(Hash); - IdentifierInfo *DeclIdent = &(Actions.getASTContext().Idents.get(IdStr)); - - LookupResult R(Actions, DeclIdent, SourceLocation(), - Sema::LookupOrdinaryName); - // Check if we have already found a decl of the same name, if we haven't - // then parse the root signature string and construct the in-memory elements - if (!Actions.LookupQualifiedName(R, Actions.CurContext)) { + auto [DeclIdent, Found] = + Actions.HLSL().ActOnStartRootSignatureDecl(Signature); + // If we haven't found an already defined DeclIdent then parse the root + // signature string and construct the in-memory elements + if (!Found) { + // Offset location 1 to account for '"' SourceLocation SignatureLoc = - StrLiteral.value()->getExprLoc().getLocWithOffset( - 1); // offset 1 for '"' + StrLiteral.value()->getExprLoc().getLocWithOffset(1); // Invoke the root signature parser to construct the in-memory constructs hlsl::RootSignatureLexer Lexer(Signature, SignatureLoc); SmallVector RootElements; @@ -4966,12 +4963,9 @@ void Parser::ParseMicrosoftRootSignatureAttributeArgs(ParsedAttributes &Attrs) { return; } - // Create the Root Signature - auto *SignatureDecl = HLSLRootSignatureDecl::Create( - Actions.getASTContext(), /*DeclContext=*/Actions.CurContext, - RootSignatureLoc, DeclIdent, RootElements); - SignatureDecl->setImplicit(); - Actions.PushOnScopeChains(SignatureDecl, getCurScope()); + // Construct the declaration. + Actions.HLSL().ActOnFinishRootSignatureDecl(RootSignatureLoc, DeclIdent, + RootElements); } // Create the arg for the ParsedAttr @@ -5014,7 +5008,7 @@ void Parser::ParseMicrosoftAttributes(ParsedAttributes &Attrs) { if (Tok.getIdentifierInfo()->getName() == "uuid") ParseMicrosoftUuidAttributeArgs(Attrs); else if (Tok.getIdentifierInfo()->getName() == "RootSignature") - ParseMicrosoftRootSignatureAttributeArgs(Attrs); + ParseHLSLRootSignatureAttributeArgs(Attrs); else { IdentifierInfo *II = Tok.getIdentifierInfo(); SourceLocation NameLoc = Tok.getLocation(); diff --git a/external/llvm-project/clang/lib/Parse/Parser.cpp b/external/llvm-project/clang/lib/Parse/Parser.cpp index 788ed79e0c1f..18f399aca59e 100644 --- a/external/llvm-project/clang/lib/Parse/Parser.cpp +++ b/external/llvm-project/clang/lib/Parse/Parser.cpp @@ -2340,7 +2340,8 @@ void Parser::ParseMicrosoftIfExistsExternalDeclaration() { Parser::DeclGroupPtrTy Parser::ParseModuleDecl(Sema::ModuleImportState &ImportState) { - SourceLocation StartLoc = Tok.getLocation(); + Token Introducer = Tok; + SourceLocation StartLoc = Introducer.getLocation(); Sema::ModuleDeclKind MDK = TryConsumeToken(tok::kw_export) ? Sema::ModuleDeclKind::Interface @@ -2359,7 +2360,7 @@ Parser::ParseModuleDecl(Sema::ModuleImportState &ImportState) { // Parse a global-module-fragment, if present. if (getLangOpts().CPlusPlusModules && Tok.is(tok::semi)) { SourceLocation SemiLoc = ConsumeToken(); - if (ImportState != Sema::ModuleImportState::FirstDecl) { + if (!Introducer.isFirstPPToken()) { Diag(StartLoc, diag::err_global_module_introducer_not_at_start) << SourceRange(StartLoc, SemiLoc); return nullptr; @@ -2416,7 +2417,7 @@ Parser::ParseModuleDecl(Sema::ModuleImportState &ImportState) { ExpectAndConsumeSemi(diag::err_module_expected_semi); return Actions.ActOnModuleDecl(StartLoc, ModuleLoc, MDK, Path, Partition, - ImportState); + ImportState, Introducer.isFirstPPToken()); } Decl *Parser::ParseModuleImport(SourceLocation AtLoc, diff --git a/external/llvm-project/clang/lib/Sema/MultiplexExternalSemaSource.cpp b/external/llvm-project/clang/lib/Sema/MultiplexExternalSemaSource.cpp index fbfb242598c2..9f19f13592e8 100644 --- a/external/llvm-project/clang/lib/Sema/MultiplexExternalSemaSource.cpp +++ b/external/llvm-project/clang/lib/Sema/MultiplexExternalSemaSource.cpp @@ -115,6 +115,14 @@ bool MultiplexExternalSemaSource::wasThisDeclarationADefinition( return false; } +bool MultiplexExternalSemaSource::hasInitializerWithSideEffects( + const VarDecl *VD) const { + for (const auto &S : Sources) + if (S->hasInitializerWithSideEffects(VD)) + return true; + return false; +} + bool MultiplexExternalSemaSource::FindExternalVisibleDeclsByName( const DeclContext *DC, DeclarationName Name, const DeclContext *OriginalDC) { diff --git a/external/llvm-project/clang/lib/Sema/SemaCast.cpp b/external/llvm-project/clang/lib/Sema/SemaCast.cpp index 14e16bc39eb3..e15a43c11651 100644 --- a/external/llvm-project/clang/lib/Sema/SemaCast.cpp +++ b/external/llvm-project/clang/lib/Sema/SemaCast.cpp @@ -161,12 +161,14 @@ namespace { Self.CheckCastAlign(SrcExpr.get(), DestType, OpRange); } - void checkObjCConversion(CheckedConversionKind CCK) { + void checkObjCConversion(CheckedConversionKind CCK, + bool IsReinterpretCast = false) { assert(Self.getLangOpts().allowsNonTrivialObjCLifetimeQualifiers()); Expr *src = SrcExpr.get(); - if (Self.ObjC().CheckObjCConversion(OpRange, DestType, src, CCK) == - SemaObjC::ACR_unbridged) + if (Self.ObjC().CheckObjCConversion( + OpRange, DestType, src, CCK, true, false, BO_PtrMemD, + IsReinterpretCast) == SemaObjC::ACR_unbridged) IsARCUnbridgedCast = true; SrcExpr = src; } @@ -1263,7 +1265,8 @@ void CastOperation::CheckReinterpretCast() { if (isValidCast(tcr)) { if (Self.getLangOpts().allowsNonTrivialObjCLifetimeQualifiers()) - checkObjCConversion(CheckedConversionKind::OtherCast); + checkObjCConversion(CheckedConversionKind::OtherCast, + /*IsReinterpretCast=*/true); DiagnoseReinterpretUpDownCast(Self, SrcExpr.get(), DestType, OpRange); if (unsigned DiagID = checkCastFunctionType(Self, SrcExpr, DestType)) diff --git a/external/llvm-project/clang/lib/Sema/SemaConcept.cpp b/external/llvm-project/clang/lib/Sema/SemaConcept.cpp index a4f660c39b4b..1594b4423e4d 100644 --- a/external/llvm-project/clang/lib/Sema/SemaConcept.cpp +++ b/external/llvm-project/clang/lib/Sema/SemaConcept.cpp @@ -1081,10 +1081,10 @@ static bool CheckFunctionConstraintsWithoutInstantiation( // FIXME: Add TemplateArgs through the 'Innermost' parameter once // the refactoring of getTemplateInstantiationArgs() relands. MultiLevelTemplateArgumentList MLTAL; - MLTAL.addOuterTemplateArguments(Template, std::nullopt, /*Final=*/false); + MLTAL.addOuterTemplateArguments(Template, {}, /*Final=*/false); SemaRef.getTemplateInstantiationArgs( MLTAL, /*D=*/FD, FD, - /*Final=*/false, /*Innermost=*/std::nullopt, /*RelativeToPrimary=*/true, + /*Final=*/false, /*Innermost=*/{}, /*RelativeToPrimary=*/true, /*Pattern=*/nullptr, /*ForConstraintInstantiation=*/true); MLTAL.replaceInnermostTemplateArguments(Template, TemplateArgs); diff --git a/external/llvm-project/clang/lib/Sema/SemaDecl.cpp b/external/llvm-project/clang/lib/Sema/SemaDecl.cpp index 5cffd82e3372..e1cccf068b5a 100644 --- a/external/llvm-project/clang/lib/Sema/SemaDecl.cpp +++ b/external/llvm-project/clang/lib/Sema/SemaDecl.cpp @@ -62,6 +62,7 @@ #include "llvm/ADT/SmallPtrSet.h" #include "llvm/ADT/SmallString.h" #include "llvm/ADT/StringExtras.h" +#include "llvm/Frontend/HLSL/HLSLRootSignature.h" #include "llvm/Support/SaveAndRestore.h" #include "llvm/TargetParser/Triple.h" #include @@ -2889,6 +2890,8 @@ static bool mergeDeclAttribute(Sema &S, NamedDecl *D, NewAttr = S.HLSL().mergeWaveSizeAttr(D, *WS, WS->getMin(), WS->getMax(), WS->getPreferred(), WS->getSpelledArgsCount()); + else if (const auto *CI = dyn_cast(Attr)) + NewAttr = S.HLSL().mergeVkConstantIdAttr(D, *CI, CI->getId()); else if (const auto *SA = dyn_cast(Attr)) NewAttr = S.HLSL().mergeShaderAttr(D, *SA, SA->getType()); else if (isa(Attr)) @@ -13756,6 +13759,10 @@ void Sema::AddInitializerToDecl(Decl *RealDecl, Expr *Init, bool DirectInit) { return; } + if (getLangOpts().HLSL) + if (!HLSL().handleInitialization(VDecl, Init)) + return; + // Get the decls type and save a reference for later, since // CheckInitializerTypes may change it. QualType DclT = VDecl->getType(), SavT = DclT; @@ -13962,31 +13969,10 @@ void Sema::AddInitializerToDecl(Decl *RealDecl, Expr *Init, bool DirectInit) { // We allow integer constant expressions in all cases. } else if (DclT->isIntegralOrEnumerationType()) { - // Check whether the expression is a constant expression. - SourceLocation Loc; if (getLangOpts().CPlusPlus11 && DclT.isVolatileQualified()) // In C++11, a non-constexpr const static data member with an // in-class initializer cannot be volatile. Diag(VDecl->getLocation(), diag::err_in_class_initializer_volatile); - else if (Init->isValueDependent()) - ; // Nothing to check. - else if (Init->isIntegerConstantExpr(Context, &Loc)) - ; // Ok, it's an ICE! - else if (Init->getType()->isScopedEnumeralType() && - Init->isCXX11ConstantExpr(Context)) - ; // Ok, it is a scoped-enum constant expression. - else if (Init->isEvaluatable(Context)) { - // If we can constant fold the initializer through heroics, accept it, - // but report this as a use of an extension for -pedantic. - Diag(Loc, diag::ext_in_class_initializer_non_constant) - << Init->getSourceRange(); - } else { - // Otherwise, this is some crazy unknown case. Report the issue at the - // location provided by the isIntegerConstantExpr failed check. - Diag(Loc, diag::err_in_class_initializer_non_constant) - << Init->getSourceRange(); - VDecl->setInvalidDecl(); - } // We allow foldable floating-point constants as an extension. } else if (DclT->isFloatingType()) { // also permits complex, which is ok @@ -14199,6 +14185,13 @@ void Sema::ActOnUninitializedDecl(Decl *RealDecl) { } } + // HLSL variable with the `vk::constant_id` attribute must be initialized. + if (!Var->isInvalidDecl() && Var->hasAttr()) { + Diag(Var->getLocation(), diag::err_specialization_const); + Var->setInvalidDecl(); + return; + } + if (!Var->isInvalidDecl() && RealDecl->hasAttr()) { if (Var->getStorageClass() == SC_Extern) { Diag(Var->getLocation(), diag::err_loader_uninitialized_extern_decl) @@ -14714,6 +14707,17 @@ void Sema::CheckCompleteVariableDeclaration(VarDecl *var) { // Compute and cache the constant value, and remember that we have a // constant initializer. if (HasConstInit) { + if (var->isStaticDataMember() && !var->isInline() && + var->getLexicalDeclContext()->isRecord() && + type->isIntegralOrEnumerationType()) { + // In C++98, in-class initialization for a static data member must + // be an integer constant expression. + SourceLocation Loc; + if (!Init->isIntegerConstantExpr(Context, &Loc)) { + Diag(Loc, diag::ext_in_class_initializer_non_constant) + << Init->getSourceRange(); + } + } (void)var->checkForConstantInitialization(Notes); Notes.clear(); } else if (CacheCulprit) { @@ -14749,6 +14753,13 @@ void Sema::CheckCompleteVariableDeclaration(VarDecl *var) { << Attr->getRange() << Attr->isConstinit(); for (auto &it : Notes) Diag(it.first, it.second); + } else if (var->isStaticDataMember() && !var->isInline() && + var->getLexicalDeclContext()->isRecord()) { + Diag(var->getLocation(), diag::err_in_class_initializer_non_constant) + << Init->getSourceRange(); + for (auto &it : Notes) + Diag(it.first, it.second); + var->setInvalidDecl(); } else if (IsGlobal && !getDiagnostics().isIgnored(diag::warn_global_constructor, var->getLocation())) { diff --git a/external/llvm-project/clang/lib/Sema/SemaDeclAttr.cpp b/external/llvm-project/clang/lib/Sema/SemaDeclAttr.cpp index 1c2fa80e782d..eba29e609cb0 100644 --- a/external/llvm-project/clang/lib/Sema/SemaDeclAttr.cpp +++ b/external/llvm-project/clang/lib/Sema/SemaDeclAttr.cpp @@ -7590,6 +7590,9 @@ ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D, const ParsedAttr &AL, case ParsedAttr::AT_HLSLVkExtBuiltinInput: S.HLSL().handleVkExtBuiltinInputAttr(D, AL); break; + case ParsedAttr::AT_HLSLVkConstantId: + S.HLSL().handleVkConstantIdAttr(D, AL); + break; case ParsedAttr::AT_HLSLSV_GroupThreadID: S.HLSL().handleSV_GroupThreadIDAttr(D, AL); break; diff --git a/external/llvm-project/clang/lib/Sema/SemaExpr.cpp b/external/llvm-project/clang/lib/Sema/SemaExpr.cpp index 4ef3de1e270c..5dccaaecd13e 100644 --- a/external/llvm-project/clang/lib/Sema/SemaExpr.cpp +++ b/external/llvm-project/clang/lib/Sema/SemaExpr.cpp @@ -2070,9 +2070,9 @@ ExprResult Sema::ActOnUnevaluatedStringLiteral(ArrayRef StringToks) { for (const Token &Tok : StringToks) StringTokLocs.push_back(Tok.getLocation()); - StringLiteral *Lit = StringLiteral::Create( - Context, Literal.GetString(), StringLiteralKind::Unevaluated, false, {}, - &StringTokLocs[0], StringTokLocs.size()); + StringLiteral *Lit = StringLiteral::Create(Context, Literal.GetString(), + StringLiteralKind::Unevaluated, + false, {}, StringTokLocs); if (!Literal.getUDSuffix().empty()) { SourceLocation UDSuffixLoc = @@ -2206,10 +2206,8 @@ Sema::ActOnStringLiteral(ArrayRef StringToks, Scope *UDLScope) { Context.getStringLiteralArrayType(CharTy, Literal.GetNumStringChars()); // Pass &StringTokLocs[0], StringTokLocs.size() to factory! - StringLiteral *Lit = StringLiteral::Create(Context, Literal.GetString(), - Kind, Literal.Pascal, StrTy, - &StringTokLocs[0], - StringTokLocs.size()); + StringLiteral *Lit = StringLiteral::Create( + Context, Literal.GetString(), Kind, Literal.Pascal, StrTy, StringTokLocs); if (Literal.getUDSuffix().empty()) return Lit; @@ -3793,7 +3791,7 @@ ExprResult Sema::ActOnNumericConstant(const Token &Tok, Scope *UDLScope) { Expr *Lit = StringLiteral::Create(Context, StringRef(TokSpelling.data(), Length), StringLiteralKind::Ordinary, - /*Pascal*/ false, StrTy, &TokLoc, 1); + /*Pascal*/ false, StrTy, TokLoc); return BuildLiteralOperatorCall(R, OpNameInfo, Lit, TokLoc); } @@ -7192,6 +7190,7 @@ Sema::BuildCompoundLiteralExpr(SourceLocation LParenLoc, TypeSourceInfo *TInfo, // void func(char *para[(int [1]){ 0 }[0]); const Scope *S = getCurScope(); bool IsFileScope = !CurContext->isFunctionOrMethod() && + !S->isInCFunctionScope() && (!S || !S->isFunctionPrototypeScope()); // In C, compound literals are l-values for some reason. @@ -21368,7 +21367,7 @@ ExprResult Sema::CheckPlaceholderExpr(Expr *E) { } if (TST.isNull()) TST = Context.getTemplateSpecializationType( - TN, ULE->template_arguments(), /*CanonicalArgs=*/std::nullopt, + TN, ULE->template_arguments(), /*CanonicalArgs=*/{}, HasAnyDependentTA ? Context.DependentTy : Context.IntTy); QualType ET = Context.getElaboratedType(ElaboratedTypeKeyword::None, NNS, TST); diff --git a/external/llvm-project/clang/lib/Sema/SemaExprObjC.cpp b/external/llvm-project/clang/lib/Sema/SemaExprObjC.cpp index 3505d9f38d23..e0662d82914f 100644 --- a/external/llvm-project/clang/lib/Sema/SemaExprObjC.cpp +++ b/external/llvm-project/clang/lib/Sema/SemaExprObjC.cpp @@ -74,8 +74,7 @@ ExprResult SemaObjC::ParseObjCStringLiteral(SourceLocation *AtLocs, CAT->getElementType(), llvm::APInt(32, StrBuf.size() + 1), nullptr, CAT->getSizeModifier(), CAT->getIndexTypeCVRQualifiers()); S = StringLiteral::Create(Context, StrBuf, StringLiteralKind::Ordinary, - /*Pascal=*/false, StrTy, &StrLocs[0], - StrLocs.size()); + /*Pascal=*/false, StrTy, StrLocs); } return BuildObjCStringLiteral(AtLocs[0], S); @@ -4390,7 +4389,7 @@ SemaObjC::ARCConversionResult SemaObjC::CheckObjCConversion(SourceRange castRange, QualType castType, Expr *&castExpr, CheckedConversionKind CCK, bool Diagnose, bool DiagnoseCFAudited, - BinaryOperatorKind Opc) { + BinaryOperatorKind Opc, bool IsReinterpretCast) { ASTContext &Context = getASTContext(); QualType castExprType = castExpr->getType(); @@ -4450,13 +4449,17 @@ SemaObjC::CheckObjCConversion(SourceRange castRange, QualType castType, // must be explicit. // Allow conversions between pointers to lifetime types and coreFoundation // pointers too, but only when the conversions are explicit. + // Allow conversions requested with a reinterpret_cast that converts an + // expression of type T* to type U*. if (exprACTC == ACTC_indirectRetainable && (castACTC == ACTC_voidPtr || - (castACTC == ACTC_coreFoundation && SemaRef.isCast(CCK)))) + (castACTC == ACTC_coreFoundation && SemaRef.isCast(CCK)) || + (IsReinterpretCast && effCastType->isAnyPointerType()))) return ACR_okay; if (castACTC == ACTC_indirectRetainable && - (exprACTC == ACTC_voidPtr || exprACTC == ACTC_coreFoundation) && - SemaRef.isCast(CCK)) + (((exprACTC == ACTC_voidPtr || exprACTC == ACTC_coreFoundation) && + SemaRef.isCast(CCK)) || + (IsReinterpretCast && castExprType->isAnyPointerType()))) return ACR_okay; switch (ARCCastChecker(Context, exprACTC, castACTC, false).Visit(castExpr)) { diff --git a/external/llvm-project/clang/lib/Sema/SemaHLSL.cpp b/external/llvm-project/clang/lib/Sema/SemaHLSL.cpp index ba491b613429..b5975c2e5782 100644 --- a/external/llvm-project/clang/lib/Sema/SemaHLSL.cpp +++ b/external/llvm-project/clang/lib/Sema/SemaHLSL.cpp @@ -39,6 +39,7 @@ #include "llvm/ADT/StringExtras.h" #include "llvm/ADT/StringRef.h" #include "llvm/ADT/Twine.h" +#include "llvm/Frontend/HLSL/HLSLRootSignatureUtils.h" #include "llvm/Support/Casting.h" #include "llvm/Support/DXILABI.h" #include "llvm/Support/ErrorHandling.h" @@ -119,6 +120,40 @@ static ResourceClass getResourceClass(RegisterType RT) { llvm_unreachable("unexpected RegisterType value"); } +static Builtin::ID getSpecConstBuiltinId(QualType Type) { + const auto *BT = dyn_cast(Type); + if (!BT) { + if (!Type->isEnumeralType()) + return Builtin::NotBuiltin; + return Builtin::BI__builtin_get_spirv_spec_constant_int; + } + + switch (BT->getKind()) { + case BuiltinType::Bool: + return Builtin::BI__builtin_get_spirv_spec_constant_bool; + case BuiltinType::Short: + return Builtin::BI__builtin_get_spirv_spec_constant_short; + case BuiltinType::Int: + return Builtin::BI__builtin_get_spirv_spec_constant_int; + case BuiltinType::LongLong: + return Builtin::BI__builtin_get_spirv_spec_constant_longlong; + case BuiltinType::UShort: + return Builtin::BI__builtin_get_spirv_spec_constant_ushort; + case BuiltinType::UInt: + return Builtin::BI__builtin_get_spirv_spec_constant_uint; + case BuiltinType::ULongLong: + return Builtin::BI__builtin_get_spirv_spec_constant_ulonglong; + case BuiltinType::Half: + return Builtin::BI__builtin_get_spirv_spec_constant_half; + case BuiltinType::Float: + return Builtin::BI__builtin_get_spirv_spec_constant_float; + case BuiltinType::Double: + return Builtin::BI__builtin_get_spirv_spec_constant_double; + default: + return Builtin::NotBuiltin; + } +} + DeclBindingInfo *ResourceBindings::addDeclBindingInfo(const VarDecl *VD, ResourceClass ResClass) { assert(getDeclBindingInfo(VD, ResClass) == nullptr && @@ -607,6 +642,41 @@ HLSLWaveSizeAttr *SemaHLSL::mergeWaveSizeAttr(Decl *D, return Result; } +HLSLVkConstantIdAttr * +SemaHLSL::mergeVkConstantIdAttr(Decl *D, const AttributeCommonInfo &AL, + int Id) { + + auto &TargetInfo = getASTContext().getTargetInfo(); + if (TargetInfo.getTriple().getArch() != llvm::Triple::spirv) { + Diag(AL.getLoc(), diag::warn_attribute_ignored) << AL; + return nullptr; + } + + auto *VD = cast(D); + + if (getSpecConstBuiltinId(VD->getType()) == Builtin::NotBuiltin) { + Diag(VD->getLocation(), diag::err_specialization_const); + return nullptr; + } + + if (!VD->getType().isConstQualified()) { + Diag(VD->getLocation(), diag::err_specialization_const); + return nullptr; + } + + if (HLSLVkConstantIdAttr *CI = D->getAttr()) { + if (CI->getId() != Id) { + Diag(CI->getLocation(), diag::err_hlsl_attribute_param_mismatch) << AL; + Diag(AL.getLoc(), diag::note_conflicting_attribute); + } + return nullptr; + } + + HLSLVkConstantIdAttr *Result = + ::new (getASTContext()) HLSLVkConstantIdAttr(getASTContext(), AL, Id); + return Result; +} + HLSLShaderAttr * SemaHLSL::mergeShaderAttr(Decl *D, const AttributeCommonInfo &AL, llvm::Triple::EnvironmentType ShaderType) { @@ -978,6 +1048,159 @@ void SemaHLSL::emitLogicalOperatorFixIt(Expr *LHS, Expr *RHS, << NewFnName << FixItHint::CreateReplacement(FullRange, OS.str()); } +std::pair +SemaHLSL::ActOnStartRootSignatureDecl(StringRef Signature) { + llvm::hash_code Hash = llvm::hash_value(Signature); + std::string IdStr = "__hlsl_rootsig_decl_" + std::to_string(Hash); + IdentifierInfo *DeclIdent = &(getASTContext().Idents.get(IdStr)); + + // Check if we have already found a decl of the same name. + LookupResult R(SemaRef, DeclIdent, SourceLocation(), + Sema::LookupOrdinaryName); + bool Found = SemaRef.LookupQualifiedName(R, SemaRef.CurContext); + return {DeclIdent, Found}; +} + +void SemaHLSL::ActOnFinishRootSignatureDecl( + SourceLocation Loc, IdentifierInfo *DeclIdent, + SmallVector &Elements) { + + auto *SignatureDecl = HLSLRootSignatureDecl::Create( + SemaRef.getASTContext(), /*DeclContext=*/SemaRef.CurContext, Loc, + DeclIdent, Elements); + + if (handleRootSignatureDecl(SignatureDecl, Loc)) + return; + + SignatureDecl->setImplicit(); + SemaRef.PushOnScopeChains(SignatureDecl, SemaRef.getCurScope()); +} + +bool SemaHLSL::handleRootSignatureDecl(HLSLRootSignatureDecl *D, + SourceLocation Loc) { + // The following conducts analysis on resource ranges to detect and report + // any overlaps in resource ranges. + // + // A resource range overlaps with another resource range if they have: + // - equivalent ResourceClass (SRV, UAV, CBuffer, Sampler) + // - equivalent resource space + // - overlapping visbility + // + // The following algorithm is implemented in the following steps: + // + // 1. Collect RangeInfo from relevant RootElements: + // - RangeInfo will retain the interval, ResourceClass, Space and Visibility + // 2. Sort the RangeInfo's such that they are grouped together by + // ResourceClass and Space (GroupT defined below) + // 3. Iterate through the collected RangeInfos by their groups + // - For each group we will have a ResourceRange for each visibility + // - As we iterate through we will: + // A: Insert the current RangeInfo into the corresponding Visibility + // ResourceRange + // B: Check for overlap with any overlapping Visibility ResourceRange + using RangeInfo = llvm::hlsl::rootsig::RangeInfo; + using ResourceRange = llvm::hlsl::rootsig::ResourceRange; + using GroupT = std::pair; + + // 1. Collect RangeInfos + llvm::SmallVector Infos; + for (const llvm::hlsl::rootsig::RootElement &Elem : D->getRootElements()) { + if (const auto *Descriptor = + std::get_if(&Elem)) { + RangeInfo Info; + Info.LowerBound = Descriptor->Reg.Number; + Info.UpperBound = Info.LowerBound; // use inclusive ranges [] + + Info.Class = + llvm::dxil::ResourceClass(llvm::to_underlying(Descriptor->Type)); + Info.Space = Descriptor->Space; + Info.Visibility = Descriptor->Visibility; + Infos.push_back(Info); + } + } + + // 2. Sort the RangeInfo's by their GroupT to form groupings + std::sort(Infos.begin(), Infos.end(), [](RangeInfo A, RangeInfo B) { + return std::tie(A.Class, A.Space) < std::tie(B.Class, B.Space); + }); + + // 3. First we will init our state to track: + if (Infos.size() == 0) + return false; // No ranges to overlap + GroupT CurGroup = {Infos[0].Class, Infos[0].Space}; + bool HadOverlap = false; + + // Create a ResourceRange for each Visibility + ResourceRange::MapT::Allocator Allocator; + std::array Ranges = { + ResourceRange(Allocator), // All + ResourceRange(Allocator), // Vertex + ResourceRange(Allocator), // Hull + ResourceRange(Allocator), // Domain + ResourceRange(Allocator), // Geometry + ResourceRange(Allocator), // Pixel + ResourceRange(Allocator), // Amplification + ResourceRange(Allocator), // Mesh + }; + + // Reset the ResourceRanges for when we iterate through a new group + auto ClearRanges = [&Ranges]() { + for (ResourceRange &Range : Ranges) + Range.clear(); + }; + + // Helper to report diagnostics + auto ReportOverlap = [this, Loc, &HadOverlap](const RangeInfo *Info, + const RangeInfo *OInfo) { + HadOverlap = true; + auto CommonVis = + Info->Visibility == llvm::hlsl::rootsig::ShaderVisibility::All + ? OInfo->Visibility + : Info->Visibility; + this->Diag(Loc, diag::err_hlsl_resource_range_overlap) + << llvm::to_underlying(Info->Class) << Info->LowerBound + << Info->UpperBound << llvm::to_underlying(OInfo->Class) + << OInfo->LowerBound << OInfo->UpperBound << Info->Space << CommonVis; + }; + + // 3: Iterate through collected RangeInfos + for (const RangeInfo &Info : Infos) { + GroupT InfoGroup = {Info.Class, Info.Space}; + // Reset our ResourceRanges when we enter a new group + if (CurGroup != InfoGroup) { + ClearRanges(); + CurGroup = InfoGroup; + } + + // 3A: Insert range info into corresponding Visibility ResourceRange + ResourceRange &VisRange = Ranges[llvm::to_underlying(Info.Visibility)]; + if (std::optional Overlapping = VisRange.insert(Info)) + ReportOverlap(&Info, Overlapping.value()); + + // 3B: Check for overlap in all overlapping Visibility ResourceRanges + // + // If the range that we are inserting has ShaderVisiblity::All it needs to + // check for an overlap in all other visibility types as well. + // Otherwise, the range that is inserted needs to check that it does not + // overlap with ShaderVisibility::All. + // + // OverlapRanges will be an ArrayRef to all non-all visibility + // ResourceRanges in the former case and it will be an ArrayRef to just the + // all visiblity ResourceRange in the latter case. + ArrayRef OverlapRanges = + Info.Visibility == llvm::hlsl::rootsig::ShaderVisibility::All + ? ArrayRef{Ranges}.drop_front() + : ArrayRef{Ranges}.take_front(); + + for (const ResourceRange &Range : OverlapRanges) + if (std::optional Overlapping = + Range.getOverlapping(Info)) + ReportOverlap(&Info, Overlapping.value()); + } + + return HadOverlap; +} + void SemaHLSL::handleRootSignatureAttr(Decl *D, const ParsedAttr &AL) { if (AL.getNumArgs() != 1) { Diag(AL.getLoc(), diag::err_attribute_wrong_number_arguments) << AL << 1; @@ -999,7 +1222,6 @@ void SemaHLSL::handleRootSignatureAttr(Decl *D, const ParsedAttr &AL) { if (SemaRef.LookupQualifiedName(R, D->getDeclContext())) if (auto *SignatureDecl = dyn_cast(R.getFoundDecl())) { - // Perform validation of constructs here D->addAttr(::new (getASTContext()) RootSignatureAttr( getASTContext(), AL, Ident, SignatureDecl)); } @@ -1008,12 +1230,15 @@ void SemaHLSL::handleRootSignatureAttr(Decl *D, const ParsedAttr &AL) { void SemaHLSL::handleNumThreadsAttr(Decl *D, const ParsedAttr &AL) { llvm::VersionTuple SMVersion = getASTContext().getTargetInfo().getTriple().getOSVersion(); + bool IsDXIL = getASTContext().getTargetInfo().getTriple().getArch() == + llvm::Triple::dxil; + uint32_t ZMax = 1024; uint32_t ThreadMax = 1024; - if (SMVersion.getMajor() <= 4) { + if (IsDXIL && SMVersion.getMajor() <= 4) { ZMax = 1; ThreadMax = 768; - } else if (SMVersion.getMajor() == 5) { + } else if (IsDXIL && SMVersion.getMajor() == 5) { ZMax = 64; ThreadMax = 1024; } @@ -1132,6 +1357,15 @@ void SemaHLSL::handleVkExtBuiltinInputAttr(Decl *D, const ParsedAttr &AL) { HLSLVkExtBuiltinInputAttr(getASTContext(), AL, ID)); } +void SemaHLSL::handleVkConstantIdAttr(Decl *D, const ParsedAttr &AL) { + uint32_t Id; + if (!SemaRef.checkUInt32Argument(AL, AL.getArgAsExpr(0), Id)) + return; + HLSLVkConstantIdAttr *NewAttr = mergeVkConstantIdAttr(D, AL, Id); + if (NewAttr) + D->addAttr(NewAttr); +} + bool SemaHLSL::diagnoseInputIDType(QualType T, const ParsedAttr &AL) { const auto *VT = T->getAs(); @@ -2206,8 +2440,9 @@ static void SetElementTypeAsReturnType(Sema *S, CallExpr *TheCall, QualType ReturnType) { auto *VecTyA = TheCall->getArg(0)->getType()->getAs(); if (VecTyA) - ReturnType = S->Context.getVectorType(ReturnType, VecTyA->getNumElements(), - VectorKind::Generic); + ReturnType = + S->Context.getExtVectorType(ReturnType, VecTyA->getNumElements()); + TheCall->setType(ReturnType); } @@ -2520,8 +2755,7 @@ bool SemaHLSL::CheckBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall) { if (auto *VecTy = EltTy->getAs()) { EltTy = VecTy->getElementType(); - ResTy = SemaRef.Context.getVectorType(ResTy, VecTy->getNumElements(), - VecTy->getVectorKind()); + ResTy = SemaRef.Context.getExtVectorType(ResTy, VecTy->getNumElements()); } if (!EltTy->isIntegerType()) { @@ -3181,6 +3415,7 @@ static bool IsDefaultBufferConstantDecl(VarDecl *VD) { return VD->getDeclContext()->isTranslationUnit() && QT.getAddressSpace() == LangAS::Default && VD->getStorageClass() != SC_Static && + !VD->hasAttr() && !isInvalidConstantBufferLeafElementType(QT.getTypePtr()); } @@ -3248,7 +3483,8 @@ void SemaHLSL::ActOnVariableDeclarator(VarDecl *VD) { const Type *VarType = VD->getType().getTypePtr(); while (VarType->isArrayType()) VarType = VarType->getArrayElementTypeNoTypeQual(); - if (VarType->isHLSLResourceRecord()) { + if (VarType->isHLSLResourceRecord() || + VD->hasAttr()) { // Make the variable for resources static. The global externally visible // storage is accessed through the handle, which is a member. The variable // itself is not externally visible. @@ -3671,3 +3907,41 @@ bool SemaHLSL::transformInitList(const InitializedEntity &Entity, Init->updateInit(Ctx, I, NewInit->getInit(I)); return true; } + +bool SemaHLSL::handleInitialization(VarDecl *VDecl, Expr *&Init) { + const HLSLVkConstantIdAttr *ConstIdAttr = + VDecl->getAttr(); + if (!ConstIdAttr) + return true; + + ASTContext &Context = SemaRef.getASTContext(); + + APValue InitValue; + if (!Init->isCXX11ConstantExpr(Context, &InitValue)) { + Diag(VDecl->getLocation(), diag::err_specialization_const); + VDecl->setInvalidDecl(); + return false; + } + + Builtin::ID BID = getSpecConstBuiltinId(VDecl->getType()); + + // Argument 1: The ID from the attribute + int ConstantID = ConstIdAttr->getId(); + llvm::APInt IDVal(Context.getIntWidth(Context.IntTy), ConstantID); + Expr *IdExpr = IntegerLiteral::Create(Context, IDVal, Context.IntTy, + ConstIdAttr->getLocation()); + + SmallVector Args = {IdExpr, Init}; + Expr *C = SemaRef.BuildBuiltinCallExpr(Init->getExprLoc(), BID, Args); + if (C->getType()->getCanonicalTypeUnqualified() != + VDecl->getType()->getCanonicalTypeUnqualified()) { + C = SemaRef + .BuildCStyleCastExpr(SourceLocation(), + Context.getTrivialTypeSourceInfo( + Init->getType(), Init->getExprLoc()), + SourceLocation(), C) + .get(); + } + Init = C; + return true; +} diff --git a/external/llvm-project/clang/lib/Sema/SemaLookup.cpp b/external/llvm-project/clang/lib/Sema/SemaLookup.cpp index 5ad9dd8ed0d3..aa7191d2814f 100644 --- a/external/llvm-project/clang/lib/Sema/SemaLookup.cpp +++ b/external/llvm-project/clang/lib/Sema/SemaLookup.cpp @@ -1565,6 +1565,21 @@ void Sema::makeMergedDefinitionVisible(NamedDecl *ND) { if (auto *TD = dyn_cast(ND)) for (auto *Param : *TD->getTemplateParameters()) makeMergedDefinitionVisible(Param); + + // If we import a named module which contains a header, and then we include a + // header which contains a definition of enums, we will skip parsing the enums + // in the current TU. But we need to ensure the visibility of the enum + // contants, since they are able to be found with the parents of their + // parents. + if (auto *ED = dyn_cast(ND); + ED && ED->isFromGlobalModule() && !ED->isScoped()) { + for (auto *ECD : ED->enumerators()) { + ECD->setVisibleDespiteOwningModule(); + DeclContext *RedeclCtx = ED->getDeclContext()->getRedeclContext(); + if (RedeclCtx->lookup(ECD->getDeclName()).empty()) + RedeclCtx->makeDeclVisibleInContext(ECD); + } + } } /// Find the module in which the given declaration was defined. @@ -2185,22 +2200,10 @@ bool LookupResult::isAvailableForLookup(Sema &SemaRef, NamedDecl *ND) { // Class and enumeration member names can be found by name lookup in any // context in which a definition of the type is reachable. // - // FIXME: The current implementation didn't consider about scope. For example, - // ``` - // // m.cppm - // export module m; - // enum E1 { e1 }; - // // Use.cpp - // import m; - // void test() { - // auto a = E1::e1; // Error as expected. - // auto b = e1; // Should be error. namespace-scope name e1 is not visible - // } - // ``` - // For the above example, the current implementation would emit error for `a` - // correctly. However, the implementation wouldn't diagnose about `b` now. - // Since we only check the reachability for the parent only. - // See clang/test/CXX/module/module.interface/p7.cpp for example. + // NOTE: The above wording may be problematic. See + // https://github.com/llvm/llvm-project/issues/131058 But it is much complext + // to adjust it in Sema's lookup process. Now we hacked it in ASTWriter. See + // the comments in ASTDeclContextNameLookupTrait::getLookupVisibility. if (auto *TD = dyn_cast(DC)) return SemaRef.hasReachableDefinition(TD); diff --git a/external/llvm-project/clang/lib/Sema/SemaModule.cpp b/external/llvm-project/clang/lib/Sema/SemaModule.cpp index 9fcaad48d305..fe70ce3fba6a 100644 --- a/external/llvm-project/clang/lib/Sema/SemaModule.cpp +++ b/external/llvm-project/clang/lib/Sema/SemaModule.cpp @@ -136,6 +136,7 @@ makeTransitiveImportsVisible(ASTContext &Ctx, VisibleModuleSet &VisibleModules, "modules only."); llvm::SmallVector Worklist; + llvm::SmallSet Visited; Worklist.push_back(Imported); Module *FoundPrimaryModuleInterface = @@ -144,18 +145,22 @@ makeTransitiveImportsVisible(ASTContext &Ctx, VisibleModuleSet &VisibleModules, while (!Worklist.empty()) { Module *Importing = Worklist.pop_back_val(); - if (VisibleModules.isVisible(Importing)) + if (Visited.count(Importing)) continue; + Visited.insert(Importing); // FIXME: The ImportLoc here is not meaningful. It may be problematic if we // use the sourcelocation loaded from the visible modules. VisibleModules.setVisible(Importing, ImportLoc); if (isImportingModuleUnitFromSameModule(Ctx, Importing, CurrentModule, - FoundPrimaryModuleInterface)) + FoundPrimaryModuleInterface)) { for (Module *TransImported : Importing->Imports) - if (!VisibleModules.isVisible(TransImported)) - Worklist.push_back(TransImported); + Worklist.push_back(TransImported); + + for (auto [Exports, _] : Importing->Exports) + Worklist.push_back(Exports); + } } } @@ -258,11 +263,11 @@ static bool DiagReservedModuleName(Sema &S, const IdentifierInfo *II, Sema::DeclGroupPtrTy Sema::ActOnModuleDecl(SourceLocation StartLoc, SourceLocation ModuleLoc, ModuleDeclKind MDK, ModuleIdPath Path, - ModuleIdPath Partition, ModuleImportState &ImportState) { + ModuleIdPath Partition, ModuleImportState &ImportState, + bool IntroducerIsFirstPPToken) { assert(getLangOpts().CPlusPlusModules && "should only have module decl in standard C++ modules"); - bool IsFirstDecl = ImportState == ModuleImportState::FirstDecl; bool SeenGMF = ImportState == ModuleImportState::GlobalFragment; // If any of the steps here fail, we count that as invalidating C++20 // module state; @@ -328,14 +333,11 @@ Sema::ActOnModuleDecl(SourceLocation StartLoc, SourceLocation ModuleLoc, SeenGMF == (bool)this->TheGlobalModuleFragment) && "mismatched global module state"); - // In C++20, the module-declaration must be the first declaration if there - // is no global module fragment. - if (getLangOpts().CPlusPlusModules && !IsFirstDecl && !SeenGMF) { + // In C++20, A module directive may only appear as the first preprocessing + // tokens in a file (excluding the global module fragment.). + if (getLangOpts().CPlusPlusModules && !IntroducerIsFirstPPToken && !SeenGMF) { Diag(ModuleLoc, diag::err_module_decl_not_at_start); - SourceLocation BeginLoc = - ModuleScopes.empty() - ? SourceMgr.getLocForStartOfFile(SourceMgr.getMainFileID()) - : ModuleScopes.back().BeginLoc; + SourceLocation BeginLoc = PP.getMainFileFirstPPToken().getLocation(); if (BeginLoc.isValid()) { Diag(BeginLoc, diag::note_global_module_introducer_missing) << FixItHint::CreateInsertion(BeginLoc, "module;\n"); diff --git a/external/llvm-project/clang/lib/Sema/SemaOpenMP.cpp b/external/llvm-project/clang/lib/Sema/SemaOpenMP.cpp index 00fb04786410..0022f18444cc 100644 --- a/external/llvm-project/clang/lib/Sema/SemaOpenMP.cpp +++ b/external/llvm-project/clang/lib/Sema/SemaOpenMP.cpp @@ -15583,7 +15583,7 @@ StmtResult SemaOpenMP::ActOnOpenMPReverseDirective(Stmt *AStmt, // instantiated. if (SemaRef.CurContext->isDependentContext()) return OMPReverseDirective::Create(Context, StartLoc, EndLoc, AStmt, - nullptr, nullptr); + NumLoops, nullptr, nullptr); assert(LoopHelpers.size() == NumLoops && "Expecting a single-dimensional loop iteration space"); @@ -15742,7 +15742,7 @@ StmtResult SemaOpenMP::ActOnOpenMPReverseDirective(Stmt *AStmt, ForStmt(Context, Init.get(), Cond.get(), nullptr, Incr.get(), ReversedBody, LoopHelper.Init->getBeginLoc(), LoopHelper.Init->getBeginLoc(), LoopHelper.Inc->getEndLoc()); - return OMPReverseDirective::Create(Context, StartLoc, EndLoc, AStmt, + return OMPReverseDirective::Create(Context, StartLoc, EndLoc, AStmt, NumLoops, ReversedFor, buildPreInits(Context, PreInits)); } diff --git a/external/llvm-project/clang/lib/Sema/TreeTransform.h b/external/llvm-project/clang/lib/Sema/TreeTransform.h index 3e33fb73e01b..26bee7a96de2 100644 --- a/external/llvm-project/clang/lib/Sema/TreeTransform.h +++ b/external/llvm-project/clang/lib/Sema/TreeTransform.h @@ -16222,7 +16222,7 @@ TreeTransform::TransformSizeOfPackExpr(SizeOfPackExpr *E) { return getDerived().RebuildSizeOfPackExpr( E->getOperatorLoc(), E->getPack(), E->getPackLoc(), E->getRParenLoc(), /*Length=*/static_cast(Args.size()), - /*PartialArgs=*/std::nullopt); + /*PartialArgs=*/{}); } template diff --git a/external/llvm-project/clang/lib/Serialization/ASTReader.cpp b/external/llvm-project/clang/lib/Serialization/ASTReader.cpp index acda5a7c879d..6f082fe840b4 100644 --- a/external/llvm-project/clang/lib/Serialization/ASTReader.cpp +++ b/external/llvm-project/clang/lib/Serialization/ASTReader.cpp @@ -4097,8 +4097,8 @@ llvm::Error ASTReader::ReadASTBlock(ModuleFile &F, uint64_t TULocalOffset = TULocalLocalOffset ? BaseOffset + TULocalLocalOffset : 0; - DelayedNamespaceOffsetMap[ID] = {LexicalOffset, VisibleOffset, - ModuleLocalOffset, TULocalOffset}; + DelayedNamespaceOffsetMap[ID] = { + {VisibleOffset, TULocalOffset, ModuleLocalOffset}, LexicalOffset}; assert(!GetExistingDecl(ID) && "We shouldn't load the namespace in the front of delayed " @@ -8544,17 +8544,21 @@ bool ASTReader::FindExternalVisibleDeclsByName(const DeclContext *DC, SmallVector Decls; llvm::SmallPtrSet Found; + auto Find = [&, this](auto &&Table, auto &&Key) { + for (GlobalDeclID ID : Table.find(Key)) { + NamedDecl *ND = cast(GetDecl(ID)); + if (ND->getDeclName() == Name && Found.insert(ND).second) + Decls.push_back(ND); + } + }; + Deserializing LookupResults(this); // FIXME: Clear the redundancy with templated lambda in C++20 when that's // available. if (auto It = Lookups.find(DC); It != Lookups.end()) { ++NumVisibleDeclContextsRead; - for (GlobalDeclID ID : It->second.Table.find(Name)) { - NamedDecl *ND = cast(GetDecl(ID)); - if (ND->getDeclName() == Name && Found.insert(ND).second) - Decls.push_back(ND); - } + Find(It->second.Table, Name); } if (auto *NamedModule = @@ -8562,21 +8566,13 @@ bool ASTReader::FindExternalVisibleDeclsByName(const DeclContext *DC, : nullptr) { if (auto It = ModuleLocalLookups.find(DC); It != ModuleLocalLookups.end()) { ++NumModuleLocalVisibleDeclContexts; - for (GlobalDeclID ID : It->second.Table.find({Name, NamedModule})) { - NamedDecl *ND = cast(GetDecl(ID)); - if (ND->getDeclName() == Name && Found.insert(ND).second) - Decls.push_back(ND); - } + Find(It->second.Table, std::make_pair(Name, NamedModule)); } } if (auto It = TULocalLookups.find(DC); It != TULocalLookups.end()) { ++NumTULocalVisibleDeclContexts; - for (GlobalDeclID ID : It->second.Table.find(Name)) { - NamedDecl *ND = cast(GetDecl(ID)); - if (ND->getDeclName() == Name && Found.insert(ND).second) - Decls.push_back(ND); - } + Find(It->second.Table, Name); } SetExternalVisibleDeclsForName(DC, Name, Decls); @@ -9726,6 +9722,10 @@ bool ASTReader::wasThisDeclarationADefinition(const FunctionDecl *FD) { return ThisDeclarationWasADefinitionSet.contains(FD); } +bool ASTReader::hasInitializerWithSideEffects(const VarDecl *VD) const { + return InitSideEffectVars.count(VD); +} + Selector ASTReader::getLocalSelector(ModuleFile &M, unsigned LocalID) { return DecodeSelector(getGlobalSelectorID(M, LocalID)); } diff --git a/external/llvm-project/clang/lib/Serialization/ASTReaderDecl.cpp b/external/llvm-project/clang/lib/Serialization/ASTReaderDecl.cpp index a1368a48351c..0ffd78424be0 100644 --- a/external/llvm-project/clang/lib/Serialization/ASTReaderDecl.cpp +++ b/external/llvm-project/clang/lib/Serialization/ASTReaderDecl.cpp @@ -414,9 +414,7 @@ class ASTDeclReader : public DeclVisitor { void VisitOpenACCDeclareDecl(OpenACCDeclareDecl *D); void VisitOpenACCRoutineDecl(OpenACCRoutineDecl *D); - void VisitDeclContext(DeclContext *DC, uint64_t &LexicalOffset, - uint64_t &VisibleOffset, uint64_t &ModuleLocalOffset, - uint64_t &TULocalOffset); + void VisitDeclContext(DeclContext *DC, LookupBlockOffsets &Offsets); template RedeclarableResult VisitRedeclarable(Redeclarable *D); @@ -666,22 +664,21 @@ void ASTDeclReader::VisitPragmaCommentDecl(PragmaCommentDecl *D) { D->setLocation(readSourceLocation()); D->CommentKind = (PragmaMSCommentKind)Record.readInt(); std::string Arg = readString(); - memcpy(D->getTrailingObjects(), Arg.data(), Arg.size()); - D->getTrailingObjects()[Arg.size()] = '\0'; + memcpy(D->getTrailingObjects(), Arg.data(), Arg.size()); + D->getTrailingObjects()[Arg.size()] = '\0'; } void ASTDeclReader::VisitPragmaDetectMismatchDecl(PragmaDetectMismatchDecl *D) { VisitDecl(D); D->setLocation(readSourceLocation()); std::string Name = readString(); - memcpy(D->getTrailingObjects(), Name.data(), Name.size()); - D->getTrailingObjects()[Name.size()] = '\0'; + memcpy(D->getTrailingObjects(), Name.data(), Name.size()); + D->getTrailingObjects()[Name.size()] = '\0'; D->ValueStart = Name.size() + 1; std::string Value = readString(); - memcpy(D->getTrailingObjects() + D->ValueStart, Value.data(), - Value.size()); - D->getTrailingObjects()[D->ValueStart + Value.size()] = '\0'; + memcpy(D->getTrailingObjects() + D->ValueStart, Value.data(), Value.size()); + D->getTrailingObjects()[D->ValueStart + Value.size()] = '\0'; } void ASTDeclReader::VisitTranslationUnitDecl(TranslationUnitDecl *TU) { @@ -1631,6 +1628,9 @@ RedeclarableResult ASTDeclReader::VisitVarDeclImpl(VarDecl *VD) { VD->NonParmVarDeclBits.PreviousDeclInSameBlockScope = VarDeclBits.getNextBit(); + if (VarDeclBits.getNextBit()) + Reader.InitSideEffectVars.insert(VD); + VD->NonParmVarDeclBits.EscapingByref = VarDeclBits.getNextBit(); HasDeducedType = VarDeclBits.getNextBit(); VD->NonParmVarDeclBits.ImplicitParamKind = @@ -1748,7 +1748,7 @@ void ASTDeclReader::VisitParmVarDecl(ParmVarDecl *PD) { void ASTDeclReader::VisitDecompositionDecl(DecompositionDecl *DD) { VisitVarDecl(DD); - auto **BDs = DD->getTrailingObjects(); + auto **BDs = DD->getTrailingObjects(); for (unsigned I = 0; I != DD->NumBindings; ++I) { BDs[I] = readDeclAs(); BDs[I]->setDecomposedDecl(DD); @@ -1875,12 +1875,8 @@ void ASTDeclReader::VisitNamespaceDecl(NamespaceDecl *D) { void ASTDeclReader::VisitHLSLBufferDecl(HLSLBufferDecl *D) { VisitNamedDecl(D); - uint64_t LexicalOffset = 0; - uint64_t VisibleOffset = 0; - uint64_t ModuleLocalOffset = 0; - uint64_t TULocalOffset = 0; - VisitDeclContext(D, LexicalOffset, VisibleOffset, ModuleLocalOffset, - TULocalOffset); + LookupBlockOffsets Offsets; + VisitDeclContext(D, Offsets); D->IsCBuffer = Record.readBool(); D->KwLoc = readSourceLocation(); D->LBraceLoc = readSourceLocation(); @@ -1923,7 +1919,7 @@ void ASTDeclReader::VisitUsingEnumDecl(UsingEnumDecl *D) { void ASTDeclReader::VisitUsingPackDecl(UsingPackDecl *D) { VisitNamedDecl(D); D->InstantiatedFrom = readDeclAs(); - auto **Expansions = D->getTrailingObjects(); + auto **Expansions = D->getTrailingObjects(); for (unsigned I = 0; I != D->NumExpansions; ++I) Expansions[I] = readDeclAs(); mergeMergeable(D); @@ -2364,7 +2360,7 @@ void ASTDeclReader::VisitImportDecl(ImportDecl *D) { VisitDecl(D); D->ImportedModule = readModule(); D->setImportComplete(Record.readInt()); - auto *StoredLocs = D->getTrailingObjects(); + auto *StoredLocs = D->getTrailingObjects(); for (unsigned I = 0, N = Record.back(); I != N; ++I) StoredLocs[I] = readSourceLocation(); Record.skipInts(1); // The number of stored source locations. @@ -2382,8 +2378,7 @@ void ASTDeclReader::VisitFriendDecl(FriendDecl *D) { else D->Friend = readTypeSourceInfo(); for (unsigned i = 0; i != D->NumTPLists; ++i) - D->getTrailingObjects()[i] = - Record.readTemplateParameterList(); + D->getTrailingObjects()[i] = Record.readTemplateParameterList(); D->NextFriend = readDeclID().getRawValue(); D->UnsupportedFriend = (Record.readInt() != 0); D->FriendLoc = readSourceLocation(); @@ -2751,7 +2746,7 @@ void ASTDeclReader::VisitTemplateTemplateParmDecl(TemplateTemplateParmDecl *D) { D->setDepth(Record.readInt()); D->setPosition(Record.readInt()); if (D->isExpandedParameterPack()) { - auto **Data = D->getTrailingObjects(); + auto **Data = D->getTrailingObjects(); for (unsigned I = 0, N = D->getNumExpansionTemplateParameters(); I != N; ++I) Data[I] = Record.readTemplateParameterList(); @@ -2794,14 +2789,12 @@ void ASTDeclReader::VisitLifetimeExtendedTemporaryDecl( mergeMergeable(D); } -void ASTDeclReader::VisitDeclContext(DeclContext *DC, uint64_t &LexicalOffset, - uint64_t &VisibleOffset, - uint64_t &ModuleLocalOffset, - uint64_t &TULocalOffset) { - LexicalOffset = ReadLocalOffset(); - VisibleOffset = ReadLocalOffset(); - ModuleLocalOffset = ReadLocalOffset(); - TULocalOffset = ReadLocalOffset(); +void ASTDeclReader::VisitDeclContext(DeclContext *DC, + LookupBlockOffsets &Offsets) { + Offsets.LexicalOffset = ReadLocalOffset(); + Offsets.VisibleOffset = ReadLocalOffset(); + Offsets.ModuleLocalOffset = ReadLocalOffset(); + Offsets.TULocalOffset = ReadLocalOffset(); } template @@ -4249,42 +4242,37 @@ Decl *ASTReader::ReadDeclRecord(GlobalDeclID ID) { // If this declaration is also a declaration context, get the // offsets for its tables of lexical and visible declarations. if (auto *DC = dyn_cast(D)) { - uint64_t LexicalOffset = 0; - uint64_t VisibleOffset = 0; - uint64_t ModuleLocalOffset = 0; - uint64_t TULocalOffset = 0; + LookupBlockOffsets Offsets; - Reader.VisitDeclContext(DC, LexicalOffset, VisibleOffset, ModuleLocalOffset, - TULocalOffset); + Reader.VisitDeclContext(DC, Offsets); // Get the lexical and visible block for the delayed namespace. // It is sufficient to judge if ID is in DelayedNamespaceOffsetMap. // But it may be more efficient to filter the other cases. - if (!LexicalOffset && !VisibleOffset && !ModuleLocalOffset && - isa(D)) + if (!Offsets && isa(D)) if (auto Iter = DelayedNamespaceOffsetMap.find(ID); - Iter != DelayedNamespaceOffsetMap.end()) { - LexicalOffset = Iter->second.LexicalOffset; - VisibleOffset = Iter->second.VisibleOffset; - ModuleLocalOffset = Iter->second.ModuleLocalOffset; - TULocalOffset = Iter->second.TULocalOffset; - } + Iter != DelayedNamespaceOffsetMap.end()) + Offsets = Iter->second; - if (LexicalOffset && - ReadLexicalDeclContextStorage(*Loc.F, DeclsCursor, LexicalOffset, DC)) - return nullptr; - if (VisibleOffset && ReadVisibleDeclContextStorage( - *Loc.F, DeclsCursor, VisibleOffset, ID, - VisibleDeclContextStorageKind::GenerallyVisible)) + if (Offsets.VisibleOffset && + ReadVisibleDeclContextStorage( + *Loc.F, DeclsCursor, Offsets.VisibleOffset, ID, + VisibleDeclContextStorageKind::GenerallyVisible)) return nullptr; - if (ModuleLocalOffset && + if (Offsets.ModuleLocalOffset && ReadVisibleDeclContextStorage( - *Loc.F, DeclsCursor, ModuleLocalOffset, ID, + *Loc.F, DeclsCursor, Offsets.ModuleLocalOffset, ID, VisibleDeclContextStorageKind::ModuleLocalVisible)) return nullptr; - if (TULocalOffset && ReadVisibleDeclContextStorage( - *Loc.F, DeclsCursor, TULocalOffset, ID, - VisibleDeclContextStorageKind::TULocalVisible)) + if (Offsets.TULocalOffset && + ReadVisibleDeclContextStorage( + *Loc.F, DeclsCursor, Offsets.TULocalOffset, ID, + VisibleDeclContextStorageKind::TULocalVisible)) + return nullptr; + + if (Offsets.LexicalOffset && + ReadLexicalDeclContextStorage(*Loc.F, DeclsCursor, + Offsets.LexicalOffset, DC)) return nullptr; } assert(Record.getIdx() == Record.size()); diff --git a/external/llvm-project/clang/lib/Serialization/ASTReaderStmt.cpp b/external/llvm-project/clang/lib/Serialization/ASTReaderStmt.cpp index 65102b64030c..8945407cf666 100644 --- a/external/llvm-project/clang/lib/Serialization/ASTReaderStmt.cpp +++ b/external/llvm-project/clang/lib/Serialization/ASTReaderStmt.cpp @@ -719,7 +719,7 @@ void ASTStmtReader::VisitParenListExpr(ParenListExpr *E) { unsigned NumExprs = Record.readInt(); assert((NumExprs == E->getNumExprs()) && "Wrong NumExprs!"); for (unsigned I = 0; I != NumExprs; ++I) - E->getTrailingObjects()[I] = Record.readSubStmt(); + E->getTrailingObjects()[I] = Record.readSubStmt(); E->LParenLoc = readSourceLocation(); E->RParenLoc = readSourceLocation(); } @@ -1892,7 +1892,7 @@ void ASTStmtReader::VisitCXXDefaultArgExpr(CXXDefaultArgExpr *E) { E->CXXDefaultArgExprBits.Loc = readSourceLocation(); E->CXXDefaultArgExprBits.HasRewrittenInit = Record.readInt(); if (E->CXXDefaultArgExprBits.HasRewrittenInit) - *E->getTrailingObjects() = Record.readSubExpr(); + *E->getTrailingObjects() = Record.readSubExpr(); } void ASTStmtReader::VisitCXXDefaultInitExpr(CXXDefaultInitExpr *E) { @@ -1902,7 +1902,7 @@ void ASTStmtReader::VisitCXXDefaultInitExpr(CXXDefaultInitExpr *E) { E->UsedContext = readDeclAs(); E->CXXDefaultInitExprBits.Loc = readSourceLocation(); if (E->CXXDefaultInitExprBits.HasRewrittenInit) - *E->getTrailingObjects() = Record.readSubExpr(); + *E->getTrailingObjects() = Record.readSubExpr(); } void ASTStmtReader::VisitCXXBindTemporaryExpr(CXXBindTemporaryExpr *E) { @@ -1999,7 +1999,7 @@ void ASTStmtReader::VisitExprWithCleanups(ExprWithCleanups *E) { Obj = cast(Record.readSubExpr()); else llvm_unreachable("unexpected cleanup object type"); - E->getTrailingObjects()[i] = Obj; + E->getTrailingObjects()[i] = Obj; } E->ExprWithCleanupsBits.CleanupsHaveSideEffects = Record.readInt(); @@ -2198,9 +2198,8 @@ void ASTStmtReader::VisitSizeOfPackExpr(SizeOfPackExpr *E) { E->Pack = Record.readDeclAs(); if (E->isPartiallySubstituted()) { assert(E->Length == NumPartialArgs); - for (auto *I = E->getTrailingObjects(), - *E = I + NumPartialArgs; - I != E; ++I) + for (auto *I = E->getTrailingObjects(), *E = I + NumPartialArgs; I != E; + ++I) new (I) TemplateArgument(Record.readTemplateArgument()); } else if (!E->isValueDependent()) { E->Length = Record.readInt(); @@ -2215,7 +2214,7 @@ void ASTStmtReader::VisitPackIndexingExpr(PackIndexingExpr *E) { E->RSquareLoc = readSourceLocation(); E->SubExprs[0] = Record.readStmt(); E->SubExprs[1] = Record.readStmt(); - auto **Exprs = E->getTrailingObjects(); + auto **Exprs = E->getTrailingObjects(); for (unsigned I = 0; I < E->PackIndexingExprBits.TransformedExpressions; ++I) Exprs[I] = Record.readExpr(); } @@ -2252,7 +2251,7 @@ void ASTStmtReader::VisitFunctionParmPackExpr(FunctionParmPackExpr *E) { E->NumParameters = Record.readInt(); E->ParamPack = readDeclAs(); E->NameLoc = readSourceLocation(); - auto **Parms = E->getTrailingObjects(); + auto **Parms = E->getTrailingObjects(); for (unsigned i = 0, n = E->NumParameters; i != n; ++i) Parms[i] = readDeclAs(); } @@ -2289,7 +2288,7 @@ void ASTStmtReader::VisitCXXParenListInitExpr(CXXParenListInitExpr *E) { E->LParenLoc = readSourceLocation(); E->RParenLoc = readSourceLocation(); for (unsigned I = 0; I < ExpectedNumExprs; I++) - E->getTrailingObjects()[I] = Record.readSubExpr(); + E->getTrailingObjects()[I] = Record.readSubExpr(); bool HasArrayFillerOrUnionDecl = Record.readBool(); if (HasArrayFillerOrUnionDecl) { @@ -3602,11 +3601,10 @@ Stmt *ASTReader::ReadStmtFromStream(ModuleFile &F) { } case STMT_OMP_REVERSE_DIRECTIVE: { - assert(Record[ASTStmtReader::NumStmtFields] == 1 && - "Reverse directive accepts only a single loop"); + unsigned NumLoops = Record[ASTStmtReader::NumStmtFields]; assert(Record[ASTStmtReader::NumStmtFields + 1] == 0 && "Reverse directive has no clauses"); - S = OMPReverseDirective::CreateEmpty(Context); + S = OMPReverseDirective::CreateEmpty(Context, NumLoops); break; } diff --git a/external/llvm-project/clang/lib/Serialization/ASTWriter.cpp b/external/llvm-project/clang/lib/Serialization/ASTWriter.cpp index ab1b5b333e06..c6487c5366a2 100644 --- a/external/llvm-project/clang/lib/Serialization/ASTWriter.cpp +++ b/external/llvm-project/clang/lib/Serialization/ASTWriter.cpp @@ -4089,11 +4089,9 @@ class ASTDeclContextNameLookupTraitBase { using hash_value_type = unsigned; using offset_type = unsigned; -protected: explicit ASTDeclContextNameLookupTraitBase(ASTWriter &Writer) : Writer(Writer) {} -public: data_type getData(const DeclIDsTy &LocalIDs) { unsigned Start = DeclIDs.size(); for (auto ID : LocalIDs) @@ -4231,6 +4229,38 @@ class ModuleLevelNameLookupTrait : public ASTDeclContextNameLookupTraitBase { } }; +class ASTDeclContextNameTrivialLookupTrait + : public ASTDeclContextNameLookupTraitBase { +public: + using key_type = DeclarationNameKey; + using key_type_ref = key_type; + +public: + using ASTDeclContextNameLookupTraitBase::ASTDeclContextNameLookupTraitBase; + + using ASTDeclContextNameLookupTraitBase::getData; + + static bool EqualKey(key_type_ref a, key_type_ref b) { return a == b; } + + hash_value_type ComputeHash(key_type Name) { return Name.getHash(); } + + std::pair EmitKeyDataLength(raw_ostream &Out, + DeclarationNameKey Name, + data_type_ref Lookup) { + auto [KeyLen, DataLen] = EmitKeyDataLengthBase(Out, Name, Lookup); + return emitULEBKeyDataLength(KeyLen, DataLen, Out); + } + + void EmitKey(raw_ostream &Out, DeclarationNameKey Name, unsigned) { + return EmitKeyBase(Out, Name); + } + + void EmitData(raw_ostream &Out, key_type_ref, data_type Lookup, + unsigned DataLen) { + EmitDataBase(Out, Lookup, DataLen); + } +}; + static bool isModuleLocalDecl(NamedDecl *D) { // For decls not in a file context, they should have the same visibility // with their parent. @@ -4273,25 +4303,73 @@ static bool isTULocalInNamedModules(NamedDecl *D) { return D->getLinkageInternal() == Linkage::Internal; } -// Trait used for the on-disk hash table used in the method pool. -template -class ASTDeclContextNameLookupTrait : public ASTDeclContextNameLookupTraitBase { +class ASTDeclContextNameLookupTrait + : public ASTDeclContextNameTrivialLookupTrait { public: + using TULocalDeclsMapTy = llvm::DenseMap; + using ModuleLevelDeclsMapTy = llvm::DenseMap; - using key_type = DeclarationNameKey; - using key_type_ref = key_type; +private: + enum class LookupVisibility { + GenerallyVisibile, + // The decls can only be found by other TU in the same module. + // Note a clang::Module models a module unit instead of logical module + // in C++20. + ModuleLocalVisible, + // The decls can only be found by the TU itself that defines it. + TULocal, + }; - using TULocalDeclsMapTy = llvm::DenseMap; + LookupVisibility getLookupVisibility(NamedDecl *D) const { + // Only named modules have other lookup visibility. + if (!Writer.isWritingStdCXXNamedModules()) + return LookupVisibility::GenerallyVisibile; + + if (isModuleLocalDecl(D)) + return LookupVisibility::ModuleLocalVisible; + if (isTULocalInNamedModules(D)) + return LookupVisibility::TULocal; + + // A trick to handle enum constants. The enum constants is special since + // they can be found directly without their parent context. This makes it + // tricky to decide if an EnumConstantDecl is visible or not by their own + // visibilities. E.g., for a class member, we can assume it is visible if + // the user get its parent somehow. But for an enum constant, the users may + // access if without its parent context. Although we can fix the problem in + // Sema lookup process, it might be too complex, we just make a trick here. + // Note that we only removes enum constant from the lookup table from its + // parent of parent. We DON'T remove the enum constant from its parent. So + // we don't need to care about merging problems here. + if (auto *ECD = dyn_cast(D); + ECD && DC.isFileContext() && ECD->getOwningModule() && + ECD->getTopLevelOwningNamedModule()->isNamedModule()) { + if (llvm::all_of( + DC.noload_lookup( + cast(ECD->getDeclContext())->getDeclName()), + [](auto *Found) { + return Found->isInvisibleOutsideTheOwningModule(); + })) + return ECD->isFromExplicitGlobalModule() || + ECD->isInAnonymousNamespace() + ? LookupVisibility::TULocal + : LookupVisibility::ModuleLocalVisible; + } -private: + return LookupVisibility::GenerallyVisibile; + } + + DeclContext &DC; ModuleLevelDeclsMapTy ModuleLocalDeclsMap; TULocalDeclsMapTy TULocalDeclsMap; public: - explicit ASTDeclContextNameLookupTrait(ASTWriter &Writer) - : ASTDeclContextNameLookupTraitBase(Writer) {} + using ASTDeclContextNameTrivialLookupTrait:: + ASTDeclContextNameTrivialLookupTrait; + + ASTDeclContextNameLookupTrait(ASTWriter &Writer, DeclContext &DC) + : ASTDeclContextNameTrivialLookupTrait(Writer), DC(DC) {} template data_type getData(const Coll &Decls) { unsigned Start = DeclIDs.size(); @@ -4312,7 +4390,8 @@ class ASTDeclContextNameLookupTrait : public ASTDeclContextNameLookupTraitBase { auto ID = Writer.GetDeclRef(DeclForLocalLookup); - if (isModuleLocalDecl(D)) { + switch (getLookupVisibility(DeclForLocalLookup)) { + case LookupVisibility::ModuleLocalVisible: if (UnsignedOrNone PrimaryModuleHash = getPrimaryModuleHash(D->getOwningModule())) { auto Key = std::make_pair(D->getDeclName(), *PrimaryModuleHash); @@ -4323,17 +4402,18 @@ class ASTDeclContextNameLookupTrait : public ASTDeclContextNameLookupTraitBase { Iter->second.push_back(ID); continue; } + break; + case LookupVisibility::TULocal: { + auto Iter = TULocalDeclsMap.find(D->getDeclName()); + if (Iter == TULocalDeclsMap.end()) + TULocalDeclsMap.insert({D->getDeclName(), DeclIDsTy{ID}}); + else + Iter->second.push_back(ID); + continue; } - - if constexpr (CollectingTULocalDecls) { - if (isTULocalInNamedModules(D)) { - auto Iter = TULocalDeclsMap.find(D->getDeclName()); - if (Iter == TULocalDeclsMap.end()) - TULocalDeclsMap.insert({D->getDeclName(), DeclIDsTy{ID}}); - else - Iter->second.push_back(ID); - continue; - } + case LookupVisibility::GenerallyVisibile: + // Generally visible decls go into the general lookup table. + break; } DeclIDs.push_back(ID); @@ -4341,33 +4421,11 @@ class ASTDeclContextNameLookupTrait : public ASTDeclContextNameLookupTraitBase { return std::make_pair(Start, DeclIDs.size()); } - using ASTDeclContextNameLookupTraitBase::getData; - const ModuleLevelDeclsMapTy &getModuleLocalDecls() { return ModuleLocalDeclsMap; } const TULocalDeclsMapTy &getTULocalDecls() { return TULocalDeclsMap; } - - static bool EqualKey(key_type_ref a, key_type_ref b) { return a == b; } - - hash_value_type ComputeHash(key_type Name) { return Name.getHash(); } - - std::pair EmitKeyDataLength(raw_ostream &Out, - DeclarationNameKey Name, - data_type_ref Lookup) { - auto [KeyLen, DataLen] = EmitKeyDataLengthBase(Out, Name, Lookup); - return emitULEBKeyDataLength(KeyLen, DataLen, Out); - } - - void EmitKey(raw_ostream &Out, DeclarationNameKey Name, unsigned) { - return EmitKeyBase(Out, Name); - } - - void EmitData(raw_ostream &Out, key_type_ref, data_type Lookup, - unsigned DataLen) { - EmitDataBase(Out, Lookup, DataLen); - } }; } // namespace @@ -4581,11 +4639,10 @@ void ASTWriter::GenerateNameLookupTable( assert(DC == DC->getPrimaryContext() && "only primary DC has lookup table"); // Create the on-disk hash table representation. - MultiOnDiskHashTableGenerator< - reader::ASTDeclContextNameLookupTrait, - ASTDeclContextNameLookupTrait> + MultiOnDiskHashTableGenerator Generator; - ASTDeclContextNameLookupTrait Trait(*this); + ASTDeclContextNameLookupTrait Trait(*this, *DC); // The first step is to collect the declaration names which we need to // serialize into the name lookup table, and to collect them in a stable @@ -4743,12 +4800,10 @@ void ASTWriter::GenerateNameLookupTable( const auto &TULocalDecls = Trait.getTULocalDecls(); if (!TULocalDecls.empty() && !isGeneratingReducedBMI()) { - MultiOnDiskHashTableGenerator< - reader::ASTDeclContextNameLookupTrait, - ASTDeclContextNameLookupTrait> + MultiOnDiskHashTableGenerator TULookupGenerator; - ASTDeclContextNameLookupTrait TULocalTrait( - *this); + ASTDeclContextNameTrivialLookupTrait TULocalTrait(*this); for (const auto &TULocalIter : TULocalDecls) { const auto &Key = TULocalIter.first; @@ -4767,14 +4822,9 @@ void ASTWriter::GenerateNameLookupTable( /// /// \returns the offset of the DECL_CONTEXT_VISIBLE block within the /// bitstream, or 0 if no block was written. -void ASTWriter::WriteDeclContextVisibleBlock(ASTContext &Context, - DeclContext *DC, - uint64_t &VisibleBlockOffset, - uint64_t &ModuleLocalBlockOffset, - uint64_t &TULocalBlockOffset) { - assert(VisibleBlockOffset == 0); - assert(ModuleLocalBlockOffset == 0); - assert(TULocalBlockOffset == 0); +void ASTWriter::WriteDeclContextVisibleBlock( + ASTContext &Context, DeclContext *DC, VisibleLookupBlockOffsets &Offsets) { + assert(!Offsets); // If we imported a key declaration of this namespace, write the visible // lookup results as an update record for it rather than including them @@ -4858,7 +4908,7 @@ void ASTWriter::WriteDeclContextVisibleBlock(ASTContext &Context, if (!Map || Map->empty()) return; - VisibleBlockOffset = Stream.GetCurrentBitNo(); + Offsets.VisibleOffset = Stream.GetCurrentBitNo(); // Create the on-disk hash table in a buffer. SmallString<4096> LookupTable; SmallString<4096> ModuleLocalLookupTable; @@ -4873,8 +4923,8 @@ void ASTWriter::WriteDeclContextVisibleBlock(ASTContext &Context, ++NumVisibleDeclContexts; if (!ModuleLocalLookupTable.empty()) { - ModuleLocalBlockOffset = Stream.GetCurrentBitNo(); - assert(ModuleLocalBlockOffset > VisibleBlockOffset); + Offsets.ModuleLocalOffset = Stream.GetCurrentBitNo(); + assert(Offsets.ModuleLocalOffset > Offsets.VisibleOffset); // Write the lookup table RecordData::value_type ModuleLocalRecord[] = { DECL_CONTEXT_MODULE_LOCAL_VISIBLE}; @@ -4884,7 +4934,7 @@ void ASTWriter::WriteDeclContextVisibleBlock(ASTContext &Context, } if (!TULookupTable.empty()) { - TULocalBlockOffset = Stream.GetCurrentBitNo(); + Offsets.TULocalOffset = Stream.GetCurrentBitNo(); // Write the lookup table RecordData::value_type TULocalDeclsRecord[] = { DECL_CONTEXT_TU_LOCAL_VISIBLE}; @@ -5167,8 +5217,9 @@ void ASTRecordWriter::AddAttr(const Attr *A) { // FIXME: Clang can't handle the serialization/deserialization of // preferred_name properly now. See // https://github.com/llvm/llvm-project/issues/56490 for example. - if (!A || (isa(A) && - Writer->isWritingStdCXXNamedModules())) + if (!A || + (isa(A) && (Writer->isWritingStdCXXNamedModules() || + Writer->isWritingStdCXXHeaderUnit()))) return Record.push_back(0); Record.push_back(A->getKind() + 1); // FIXME: stable encoding, target attrs @@ -6202,31 +6253,26 @@ void ASTWriter::WriteDeclAndTypes(ASTContext &Context) { assert(DelayedNamespace.empty() || GeneratingReducedBMI); RecordData DelayedNamespaceRecord; for (NamespaceDecl *NS : DelayedNamespace) { - uint64_t LexicalOffset = WriteDeclContextLexicalBlock(Context, NS); - uint64_t VisibleOffset = 0; - uint64_t ModuleLocalOffset = 0; - uint64_t TULocalOffset = 0; - WriteDeclContextVisibleBlock(Context, NS, VisibleOffset, ModuleLocalOffset, - TULocalOffset); + LookupBlockOffsets Offsets; - // Write the offset relative to current block. - if (LexicalOffset) - LexicalOffset -= DeclTypesBlockStartOffset; + Offsets.LexicalOffset = WriteDeclContextLexicalBlock(Context, NS); + WriteDeclContextVisibleBlock(Context, NS, Offsets); - if (VisibleOffset) - VisibleOffset -= DeclTypesBlockStartOffset; + if (Offsets.LexicalOffset) + Offsets.LexicalOffset -= DeclTypesBlockStartOffset; - if (ModuleLocalOffset) - ModuleLocalOffset -= DeclTypesBlockStartOffset; + // Write the offset relative to current block. + if (Offsets.VisibleOffset) + Offsets.VisibleOffset -= DeclTypesBlockStartOffset; + + if (Offsets.ModuleLocalOffset) + Offsets.ModuleLocalOffset -= DeclTypesBlockStartOffset; - if (TULocalOffset) - TULocalOffset -= DeclTypesBlockStartOffset; + if (Offsets.TULocalOffset) + Offsets.TULocalOffset -= DeclTypesBlockStartOffset; AddDeclRef(NS, DelayedNamespaceRecord); - DelayedNamespaceRecord.push_back(LexicalOffset); - DelayedNamespaceRecord.push_back(VisibleOffset); - DelayedNamespaceRecord.push_back(ModuleLocalOffset); - DelayedNamespaceRecord.push_back(TULocalOffset); + AddLookupOffsets(Offsets, DelayedNamespaceRecord); } // The process of writing lexical and visible block for delayed namespace @@ -6817,6 +6863,14 @@ TypeID ASTWriter::GetOrCreateTypeID(ASTContext &Context, QualType T) { }); } +void ASTWriter::AddLookupOffsets(const LookupBlockOffsets &Offsets, + RecordDataImpl &Record) { + Record.push_back(Offsets.LexicalOffset); + Record.push_back(Offsets.VisibleOffset); + Record.push_back(Offsets.ModuleLocalOffset); + Record.push_back(Offsets.TULocalOffset); +} + void ASTWriter::AddEmittedDeclRef(const Decl *D, RecordDataImpl &Record) { if (!wasDeclEmitted(D)) return; diff --git a/external/llvm-project/clang/lib/Serialization/ASTWriterDecl.cpp b/external/llvm-project/clang/lib/Serialization/ASTWriterDecl.cpp index 052cb5a253bf..2e390dbe79ec 100644 --- a/external/llvm-project/clang/lib/Serialization/ASTWriterDecl.cpp +++ b/external/llvm-project/clang/lib/Serialization/ASTWriterDecl.cpp @@ -1306,6 +1306,7 @@ void ASTDeclWriter::VisitVarDecl(VarDecl *D) { VarDeclBits.addBit(D->isConstexpr()); VarDeclBits.addBit(D->isInitCapture()); VarDeclBits.addBit(D->isPreviousDeclInSameBlockScope()); + VarDeclBits.addBit(D->hasInitWithSideEffects()); VarDeclBits.addBit(D->isEscapingByref()); HasDeducedType = D->getType()->getContainedDeducedType(); @@ -1355,10 +1356,11 @@ void ASTDeclWriter::VisitVarDecl(VarDecl *D) { !D->hasExtInfo() && D->getFirstDecl() == D->getMostRecentDecl() && D->getKind() == Decl::Var && !D->isInline() && !D->isConstexpr() && !D->isInitCapture() && !D->isPreviousDeclInSameBlockScope() && - !D->isEscapingByref() && !HasDeducedType && - D->getStorageDuration() != SD_Static && !D->getDescribedVarTemplate() && - !D->getMemberSpecializationInfo() && !D->isObjCForDecl() && - !isa(D) && !D->isEscapingByref()) + !D->hasInitWithSideEffects() && !D->isEscapingByref() && + !HasDeducedType && D->getStorageDuration() != SD_Static && + !D->getDescribedVarTemplate() && !D->getMemberSpecializationInfo() && + !D->isObjCForDecl() && !isa(D) && + !D->isEscapingByref()) AbbrevToUse = Writer.getDeclVarAbbrev(); Code = serialization::DECL_VAR; @@ -2189,11 +2191,7 @@ void ASTDeclWriter::VisitDeclContext(DeclContext *DC) { static_assert(DeclContext::NumDeclContextBits == 13, "You need to update the serializer after you change the " "DeclContextBits"); - - uint64_t LexicalOffset = 0; - uint64_t VisibleOffset = 0; - uint64_t ModuleLocalOffset = 0; - uint64_t TULocalOffset = 0; + LookupBlockOffsets Offsets; if (Writer.isGeneratingReducedBMI() && isa(DC) && cast(DC)->isFromExplicitGlobalModule()) { @@ -2202,17 +2200,12 @@ void ASTDeclWriter::VisitDeclContext(DeclContext *DC) { // details. Writer.DelayedNamespace.push_back(cast(DC)); } else { - LexicalOffset = + Offsets.LexicalOffset = Writer.WriteDeclContextLexicalBlock(Record.getASTContext(), DC); - Writer.WriteDeclContextVisibleBlock(Record.getASTContext(), DC, - VisibleOffset, ModuleLocalOffset, - TULocalOffset); + Writer.WriteDeclContextVisibleBlock(Record.getASTContext(), DC, Offsets); } - Record.AddOffset(LexicalOffset); - Record.AddOffset(VisibleOffset); - Record.AddOffset(ModuleLocalOffset); - Record.AddOffset(TULocalOffset); + Record.AddLookupOffsets(Offsets); } const Decl *ASTWriter::getFirstLocalDecl(const Decl *D) { @@ -2740,12 +2733,12 @@ void ASTWriter::WriteDeclAbbrevs() { // VarDecl Abv->Add(BitCodeAbbrevOp( BitCodeAbbrevOp::Fixed, - 21)); // Packed Var Decl bits: Linkage, ModulesCodegen, + 22)); // Packed Var Decl bits: Linkage, ModulesCodegen, // SClass, TSCSpec, InitStyle, // isARCPseudoStrong, IsThisDeclarationADemotedDefinition, // isExceptionVariable, isNRVOVariable, isCXXForRangeDecl, // isInline, isInlineSpecified, isConstexpr, - // isInitCapture, isPrevDeclInSameScope, + // isInitCapture, isPrevDeclInSameScope, hasInitWithSideEffects, // EscapingByref, HasDeducedType, ImplicitParamKind, isObjCForDecl Abv->Add(BitCodeAbbrevOp(0)); // VarKind (local enum) // Type Source Info diff --git a/external/llvm-project/clang/lib/StaticAnalyzer/Checkers/DivZeroChecker.cpp b/external/llvm-project/clang/lib/StaticAnalyzer/Checkers/DivZeroChecker.cpp index 15d73fb9ca39..ab90615f6318 100644 --- a/external/llvm-project/clang/lib/StaticAnalyzer/Checkers/DivZeroChecker.cpp +++ b/external/llvm-project/clang/lib/StaticAnalyzer/Checkers/DivZeroChecker.cpp @@ -69,7 +69,7 @@ void DivZeroChecker::reportTaintBug( llvm::ArrayRef TaintedSyms) const { if (!TaintedDivChecker.isEnabled()) return; - if (ExplodedNode *N = C.generateNonFatalErrorNode(StateZero)) { + if (ExplodedNode *N = C.generateErrorNode(StateZero)) { auto R = std::make_unique(TaintedDivChecker, Msg, N); bugreporter::trackExpressionValue(N, getDenomExpr(N), *R); @@ -113,9 +113,9 @@ void DivZeroChecker::checkPreStmt(const BinaryOperator *B, if ((stateNotZero && stateZero)) { std::vector taintedSyms = getTaintedSymbols(C.getState(), *DV); if (!taintedSyms.empty()) { - reportTaintBug("Division by a tainted value, possibly zero", stateNotZero, - C, taintedSyms); - return; + reportTaintBug("Division by a tainted value, possibly zero", stateZero, C, + taintedSyms); + // Fallthrough to continue analysis in case of non-zero denominator. } } diff --git a/external/llvm-project/clang/lib/StaticAnalyzer/Checkers/DynamicTypePropagation.cpp b/external/llvm-project/clang/lib/StaticAnalyzer/Checkers/DynamicTypePropagation.cpp index 344be0b176c5..4982cd59b0a4 100644 --- a/external/llvm-project/clang/lib/StaticAnalyzer/Checkers/DynamicTypePropagation.cpp +++ b/external/llvm-project/clang/lib/StaticAnalyzer/Checkers/DynamicTypePropagation.cpp @@ -49,15 +49,19 @@ REGISTER_MAP_WITH_PROGRAMSTATE(MostSpecializedTypeArgsMap, SymbolRef, const ObjCObjectPointerType *) namespace { -class DynamicTypePropagation: - public Checker< check::PreCall, - check::PostCall, - check::DeadSymbols, - check::PostStmt, - check::PostStmt, - check::PreObjCMessage, - check::PostObjCMessage > { +class DynamicTypePropagation + : public CheckerFamily, + check::PostStmt, check::PreObjCMessage, + check::PostObjCMessage> { +public: + // This checker family implements only one frontend, but -- unlike a simple + // Checker -- its backend can be enabled (by the checker DynamicTypeChecker + // which depends on it) without enabling the frontend. + CheckerFrontendWithBugType ObjCGenericsChecker{ + "Generics", categories::CoreFoundationObjectiveC}; +private: /// Return a better dynamic type if one can be derived from the cast. const ObjCObjectPointerType *getBetterObjCType(const Expr *CastE, CheckerContext &C) const; @@ -66,13 +70,6 @@ class DynamicTypePropagation: ProgramStateRef &State, CheckerContext &C) const; - mutable std::unique_ptr ObjCGenericsBugType; - void initBugType() const { - if (!ObjCGenericsBugType) - ObjCGenericsBugType.reset(new BugType( - GenericCheckName, "Generics", categories::CoreFoundationObjectiveC)); - } - class GenericsBugVisitor : public BugReporterVisitor { public: GenericsBugVisitor(SymbolRef S) : Sym(S) {} @@ -106,9 +103,8 @@ class DynamicTypePropagation: void checkPreObjCMessage(const ObjCMethodCall &M, CheckerContext &C) const; void checkPostObjCMessage(const ObjCMethodCall &M, CheckerContext &C) const; - /// This value is set to true, when the Generics checker is turned on. - bool CheckGenerics = false; - CheckerNameRef GenericCheckName; + /// Identifies this checker family for debugging purposes. + StringRef getDebugTag() const override { return "DynamicTypePropagation"; } }; bool isObjCClassType(QualType Type) { @@ -1026,10 +1022,9 @@ void DynamicTypePropagation::reportGenericsBug( const ObjCObjectPointerType *From, const ObjCObjectPointerType *To, ExplodedNode *N, SymbolRef Sym, CheckerContext &C, const Stmt *ReportedNode) const { - if (!CheckGenerics) + if (!ObjCGenericsChecker.isEnabled()) return; - initBugType(); SmallString<192> Buf; llvm::raw_svector_ostream OS(Buf); OS << "Conversion from value of type '"; @@ -1037,7 +1032,7 @@ void DynamicTypePropagation::reportGenericsBug( OS << "' to incompatible type '"; QualType::print(To, Qualifiers(), OS, C.getLangOpts(), llvm::Twine()); OS << "'"; - auto R = std::make_unique(*ObjCGenericsBugType, + auto R = std::make_unique(ObjCGenericsChecker, OS.str(), N); R->markInteresting(Sym); R->addVisitor(std::make_unique(Sym)); @@ -1102,20 +1097,22 @@ PathDiagnosticPieceRef DynamicTypePropagation::GenericsBugVisitor::VisitNode( } /// Register checkers. -void ento::registerObjCGenericsChecker(CheckerManager &mgr) { - DynamicTypePropagation *checker = mgr.getChecker(); - checker->CheckGenerics = true; - checker->GenericCheckName = mgr.getCurrentCheckerName(); +void ento::registerObjCGenericsChecker(CheckerManager &Mgr) { + Mgr.getChecker()->ObjCGenericsChecker.enable(Mgr); } -bool ento::shouldRegisterObjCGenericsChecker(const CheckerManager &mgr) { +bool ento::shouldRegisterObjCGenericsChecker(const CheckerManager &) { return true; } -void ento::registerDynamicTypePropagation(CheckerManager &mgr) { - mgr.registerChecker(); +void ento::registerDynamicTypePropagation(CheckerManager &Mgr) { + // The checker 'core.DynamicTypeChecker' relies on the modeling implemented + // in the class 'DynamicTypePropagation', so this "modeling checker" can + // register the 'DynamicTypePropagation' backend for its callbacks without + // enabling its frontend. + Mgr.getChecker(); } -bool ento::shouldRegisterDynamicTypePropagation(const CheckerManager &mgr) { +bool ento::shouldRegisterDynamicTypePropagation(const CheckerManager &) { return true; } diff --git a/external/llvm-project/clang/lib/StaticAnalyzer/Checkers/MallocChecker.cpp b/external/llvm-project/clang/lib/StaticAnalyzer/Checkers/MallocChecker.cpp index fef33509c0b6..35e98a5e2719 100644 --- a/external/llvm-project/clang/lib/StaticAnalyzer/Checkers/MallocChecker.cpp +++ b/external/llvm-project/clang/lib/StaticAnalyzer/Checkers/MallocChecker.cpp @@ -1371,6 +1371,20 @@ void MallocChecker::checkIfFreeNameIndex(ProgramStateRef State, C.addTransition(State); } +const Expr *getPlacementNewBufferArg(const CallExpr *CE, + const FunctionDecl *FD) { + // Checking for signature: + // void* operator new ( std::size_t count, void* ptr ); + // void* operator new[]( std::size_t count, void* ptr ); + if (CE->getNumArgs() != 2 || (FD->getOverloadedOperator() != OO_New && + FD->getOverloadedOperator() != OO_Array_New)) + return nullptr; + auto BuffType = FD->getParamDecl(1)->getType(); + if (BuffType.isNull() || !BuffType->isVoidPointerType()) + return nullptr; + return CE->getArg(1); +} + void MallocChecker::checkCXXNewOrCXXDelete(ProgramStateRef State, const CallEvent &Call, CheckerContext &C) const { @@ -1386,6 +1400,14 @@ void MallocChecker::checkCXXNewOrCXXDelete(ProgramStateRef State, // processed by the checkPostStmt callbacks for CXXNewExpr and // CXXDeleteExpr. const FunctionDecl *FD = C.getCalleeDecl(CE); + if (const auto *BufArg = getPlacementNewBufferArg(CE, FD)) { + // Placement new does not allocate memory + auto RetVal = State->getSVal(BufArg, Call.getLocationContext()); + State = State->BindExpr(CE, C.getLocationContext(), RetVal); + C.addTransition(State); + return; + } + switch (FD->getOverloadedOperator()) { case OO_New: State = MallocMemAux(C, Call, CE->getArg(0), UndefinedVal(), State, diff --git a/external/llvm-project/clang/lib/StaticAnalyzer/Checkers/NullabilityChecker.cpp b/external/llvm-project/clang/lib/StaticAnalyzer/Checkers/NullabilityChecker.cpp index 461d01b452fd..9744d1abf779 100644 --- a/external/llvm-project/clang/lib/StaticAnalyzer/Checkers/NullabilityChecker.cpp +++ b/external/llvm-project/clang/lib/StaticAnalyzer/Checkers/NullabilityChecker.cpp @@ -81,11 +81,12 @@ enum class ErrorKind : int { }; class NullabilityChecker - : public Checker, - check::PostCall, check::PostStmt, - check::PostObjCMessage, check::DeadSymbols, eval::Assume, - check::Location, check::Event, - check::BeginFunction> { + : public CheckerFamily< + check::Bind, check::PreCall, check::PreStmt, + check::PostCall, check::PostStmt, + check::PostObjCMessage, check::DeadSymbols, eval::Assume, + check::Location, check::Event, + check::BeginFunction> { public: // If true, the checker will not diagnose nullabilility issues for calls @@ -113,25 +114,21 @@ class NullabilityChecker void printState(raw_ostream &Out, ProgramStateRef State, const char *NL, const char *Sep) const override; - enum CheckKind { - CK_NullPassedToNonnull, - CK_NullReturnedFromNonnull, - CK_NullableDereferenced, - CK_NullablePassedToNonnull, - CK_NullableReturnedFromNonnull, - CK_NumCheckKinds - }; - - bool ChecksEnabled[CK_NumCheckKinds] = {false}; - CheckerNameRef CheckNames[CK_NumCheckKinds]; - mutable std::unique_ptr BTs[CK_NumCheckKinds]; - - const std::unique_ptr &getBugType(CheckKind Kind) const { - if (!BTs[Kind]) - BTs[Kind].reset(new BugType(CheckNames[Kind], "Nullability", - categories::MemoryError)); - return BTs[Kind]; - } + StringRef getDebugTag() const override { return "NullabilityChecker"; } + + // FIXME: All bug types share the same Description ("Nullability") since the + // creation of this checker. We should write more descriptive descriptions... + // or just eliminate the Description field if it is meaningless? + CheckerFrontendWithBugType NullPassedToNonnull{"Nullability", + categories::MemoryError}; + CheckerFrontendWithBugType NullReturnedFromNonnull{"Nullability", + categories::MemoryError}; + CheckerFrontendWithBugType NullableDereferenced{"Nullability", + categories::MemoryError}; + CheckerFrontendWithBugType NullablePassedToNonnull{"Nullability", + categories::MemoryError}; + CheckerFrontendWithBugType NullableReturnedFromNonnull{ + "Nullability", categories::MemoryError}; // When set to false no nullability information will be tracked in // NullabilityMap. It is possible to catch errors like passing a null pointer @@ -164,17 +161,16 @@ class NullabilityChecker /// /// When \p SuppressPath is set to true, no more bugs will be reported on this /// path by this checker. - void reportBugIfInvariantHolds(StringRef Msg, ErrorKind Error, CheckKind CK, - ExplodedNode *N, const MemRegion *Region, - CheckerContext &C, + void reportBugIfInvariantHolds(StringRef Msg, ErrorKind Error, + const BugType &BT, ExplodedNode *N, + const MemRegion *Region, CheckerContext &C, const Stmt *ValueExpr = nullptr, bool SuppressPath = false) const; - void reportBug(StringRef Msg, ErrorKind Error, CheckKind CK, ExplodedNode *N, - const MemRegion *Region, BugReporter &BR, + void reportBug(StringRef Msg, ErrorKind Error, const BugType &BT, + ExplodedNode *N, const MemRegion *Region, BugReporter &BR, const Stmt *ValueExpr = nullptr) const { - const std::unique_ptr &BT = getBugType(CK); - auto R = std::make_unique(*BT, Msg, N); + auto R = std::make_unique(BT, Msg, N); if (Region) { R->markInteresting(Region); R->addVisitor(Region); @@ -480,7 +476,7 @@ static bool checkInvariantViolation(ProgramStateRef State, ExplodedNode *N, } void NullabilityChecker::reportBugIfInvariantHolds( - StringRef Msg, ErrorKind Error, CheckKind CK, ExplodedNode *N, + StringRef Msg, ErrorKind Error, const BugType &BT, ExplodedNode *N, const MemRegion *Region, CheckerContext &C, const Stmt *ValueExpr, bool SuppressPath) const { ProgramStateRef OriginalState = N->getState(); @@ -492,7 +488,7 @@ void NullabilityChecker::reportBugIfInvariantHolds( N = C.addTransition(OriginalState, N); } - reportBug(Msg, Error, CK, N, Region, C.getBugReporter(), ValueExpr); + reportBug(Msg, Error, BT, N, Region, C.getBugReporter(), ValueExpr); } /// Cleaning up the program state. @@ -546,19 +542,19 @@ void NullabilityChecker::checkEvent(ImplicitNullDerefEvent Event) const { if (!TrackedNullability) return; - if (ChecksEnabled[CK_NullableDereferenced] && + if (NullableDereferenced.isEnabled() && TrackedNullability->getValue() == Nullability::Nullable) { BugReporter &BR = *Event.BR; // Do not suppress errors on defensive code paths, because dereferencing // a nullable pointer is always an error. if (Event.IsDirectDereference) reportBug("Nullable pointer is dereferenced", - ErrorKind::NullableDereferenced, CK_NullableDereferenced, + ErrorKind::NullableDereferenced, NullableDereferenced, Event.SinkNode, Region, BR); else { reportBug("Nullable pointer is passed to a callee that requires a " "non-null", - ErrorKind::NullablePassedToNonnull, CK_NullableDereferenced, + ErrorKind::NullablePassedToNonnull, NullableDereferenced, Event.SinkNode, Region, BR); } } @@ -710,29 +706,28 @@ void NullabilityChecker::checkPreStmt(const ReturnStmt *S, Nullability RetExprTypeLevelNullability = getNullabilityAnnotation(lookThroughImplicitCasts(RetExpr)->getType()); - bool NullReturnedFromNonNull = (RequiredNullability == Nullability::Nonnull && - Nullness == NullConstraint::IsNull); - if (ChecksEnabled[CK_NullReturnedFromNonnull] && NullReturnedFromNonNull && - RetExprTypeLevelNullability != Nullability::Nonnull && - !InSuppressedMethodFamily) { - ExplodedNode *N = C.generateErrorNode(State); - if (!N) - return; + if (RequiredNullability == Nullability::Nonnull && + Nullness == NullConstraint::IsNull) { + if (NullReturnedFromNonnull.isEnabled() && + RetExprTypeLevelNullability != Nullability::Nonnull && + !InSuppressedMethodFamily) { + ExplodedNode *N = C.generateErrorNode(State); + if (!N) + return; - SmallString<256> SBuf; - llvm::raw_svector_ostream OS(SBuf); - OS << (RetExpr->getType()->isObjCObjectPointerType() ? "nil" : "Null"); - OS << " returned from a " << C.getDeclDescription(D) << - " that is expected to return a non-null value"; - reportBugIfInvariantHolds(OS.str(), ErrorKind::NilReturnedToNonnull, - CK_NullReturnedFromNonnull, N, nullptr, C, - RetExpr); - return; - } + SmallString<256> SBuf; + llvm::raw_svector_ostream OS(SBuf); + OS << (RetExpr->getType()->isObjCObjectPointerType() ? "nil" : "Null"); + OS << " returned from a " << C.getDeclDescription(D) + << " that is expected to return a non-null value"; + reportBugIfInvariantHolds(OS.str(), ErrorKind::NilReturnedToNonnull, + NullReturnedFromNonnull, N, nullptr, C, + RetExpr); + return; + } - // If null was returned from a non-null function, mark the nullability - // invariant as violated even if the diagnostic was suppressed. - if (NullReturnedFromNonNull) { + // If null was returned from a non-null function, mark the nullability + // invariant as violated even if the diagnostic was suppressed. State = State->set(true); C.addTransition(State); return; @@ -746,7 +741,7 @@ void NullabilityChecker::checkPreStmt(const ReturnStmt *S, State->get(Region); if (TrackedNullability) { Nullability TrackedNullabValue = TrackedNullability->getValue(); - if (ChecksEnabled[CK_NullableReturnedFromNonnull] && + if (NullableReturnedFromNonnull.isEnabled() && Nullness != NullConstraint::IsNotNull && TrackedNullabValue == Nullability::Nullable && RequiredNullability == Nullability::Nonnull) { @@ -758,7 +753,7 @@ void NullabilityChecker::checkPreStmt(const ReturnStmt *S, " that is expected to return a non-null value"; reportBugIfInvariantHolds(OS.str(), ErrorKind::NullableReturnedToNonnull, - CK_NullableReturnedFromNonnull, N, Region, C); + NullableReturnedFromNonnull, N, Region, C); } return; } @@ -809,8 +804,7 @@ void NullabilityChecker::checkPreCall(const CallEvent &Call, unsigned ParamIdx = Param->getFunctionScopeIndex() + 1; - if (ChecksEnabled[CK_NullPassedToNonnull] && - Nullness == NullConstraint::IsNull && + if (NullPassedToNonnull.isEnabled() && Nullness == NullConstraint::IsNull && ArgExprTypeLevelNullability != Nullability::Nonnull && RequiredNullability == Nullability::Nonnull && isDiagnosableCall(Call)) { @@ -824,7 +818,7 @@ void NullabilityChecker::checkPreCall(const CallEvent &Call, OS << " passed to a callee that requires a non-null " << ParamIdx << llvm::getOrdinalSuffix(ParamIdx) << " parameter"; reportBugIfInvariantHolds(OS.str(), ErrorKind::NilPassedToNonnull, - CK_NullPassedToNonnull, N, nullptr, C, ArgExpr, + NullPassedToNonnull, N, nullptr, C, ArgExpr, /*SuppressPath=*/false); return; } @@ -841,7 +835,7 @@ void NullabilityChecker::checkPreCall(const CallEvent &Call, TrackedNullability->getValue() != Nullability::Nullable) continue; - if (ChecksEnabled[CK_NullablePassedToNonnull] && + if (NullablePassedToNonnull.isEnabled() && RequiredNullability == Nullability::Nonnull && isDiagnosableCall(Call)) { ExplodedNode *N = C.addTransition(State); @@ -850,17 +844,16 @@ void NullabilityChecker::checkPreCall(const CallEvent &Call, OS << "Nullable pointer is passed to a callee that requires a non-null " << ParamIdx << llvm::getOrdinalSuffix(ParamIdx) << " parameter"; reportBugIfInvariantHolds(OS.str(), ErrorKind::NullablePassedToNonnull, - CK_NullablePassedToNonnull, N, Region, C, + NullablePassedToNonnull, N, Region, C, ArgExpr, /*SuppressPath=*/true); return; } - if (ChecksEnabled[CK_NullableDereferenced] && + if (NullableDereferenced.isEnabled() && Param->getType()->isReferenceType()) { ExplodedNode *N = C.addTransition(State); - reportBugIfInvariantHolds("Nullable pointer is dereferenced", - ErrorKind::NullableDereferenced, - CK_NullableDereferenced, N, Region, C, - ArgExpr, /*SuppressPath=*/true); + reportBugIfInvariantHolds( + "Nullable pointer is dereferenced", ErrorKind::NullableDereferenced, + NullableDereferenced, N, Region, C, ArgExpr, /*SuppressPath=*/true); return; } continue; @@ -1294,7 +1287,7 @@ void NullabilityChecker::checkBind(SVal L, SVal V, const Stmt *S, bool NullAssignedToNonNull = (LocNullability == Nullability::Nonnull && RhsNullness == NullConstraint::IsNull); - if (ChecksEnabled[CK_NullPassedToNonnull] && NullAssignedToNonNull && + if (NullPassedToNonnull.isEnabled() && NullAssignedToNonNull && ValNullability != Nullability::Nonnull && ValueExprTypeLevelNullability != Nullability::Nonnull && !isARCNilInitializedLocal(C, S)) { @@ -1312,7 +1305,7 @@ void NullabilityChecker::checkBind(SVal L, SVal V, const Stmt *S, OS << (LocType->isObjCObjectPointerType() ? "nil" : "Null"); OS << " assigned to a pointer which is expected to have non-null value"; reportBugIfInvariantHolds(OS.str(), ErrorKind::NilAssignedToNonnull, - CK_NullPassedToNonnull, N, nullptr, C, ValueStmt); + NullPassedToNonnull, N, nullptr, C, ValueStmt); return; } @@ -1338,13 +1331,13 @@ void NullabilityChecker::checkBind(SVal L, SVal V, const Stmt *S, if (RhsNullness == NullConstraint::IsNotNull || TrackedNullability->getValue() != Nullability::Nullable) return; - if (ChecksEnabled[CK_NullablePassedToNonnull] && + if (NullablePassedToNonnull.isEnabled() && LocNullability == Nullability::Nonnull) { ExplodedNode *N = C.addTransition(State, C.getPredecessor()); reportBugIfInvariantHolds("Nullable pointer is assigned to a pointer " "which is expected to have non-null value", ErrorKind::NullableAssignedToNonnull, - CK_NullablePassedToNonnull, N, ValueRegion, C); + NullablePassedToNonnull, N, ValueRegion, C); } return; } @@ -1391,28 +1384,26 @@ void NullabilityChecker::printState(raw_ostream &Out, ProgramStateRef State, } } -void ento::registerNullabilityBase(CheckerManager &mgr) { - mgr.registerChecker(); -} - -bool ento::shouldRegisterNullabilityBase(const CheckerManager &mgr) { - return true; -} - -#define REGISTER_CHECKER(name, trackingRequired) \ - void ento::register##name##Checker(CheckerManager &mgr) { \ - NullabilityChecker *checker = mgr.getChecker(); \ - checker->ChecksEnabled[NullabilityChecker::CK_##name] = true; \ - checker->CheckNames[NullabilityChecker::CK_##name] = \ - mgr.getCurrentCheckerName(); \ - checker->NeedTracking = checker->NeedTracking || trackingRequired; \ - checker->NoDiagnoseCallsToSystemHeaders = \ - checker->NoDiagnoseCallsToSystemHeaders || \ - mgr.getAnalyzerOptions().getCheckerBooleanOption( \ - checker, "NoDiagnoseCallsToSystemHeaders", true); \ +// The checker group "nullability" (which consists of the checkers that are +// implemented in this file) has a group-level configuration option which +// affects all the checkers in the group. As this is a completely unique +// remnant of old design (this is the only group option in the analyzer), there +// is no machinery to inject the group name from `Checkers.td`, so it is simply +// hardcoded here: +constexpr llvm::StringLiteral GroupName = "nullability"; +constexpr llvm::StringLiteral GroupOptName = "NoDiagnoseCallsToSystemHeaders"; + +#define REGISTER_CHECKER(NAME, TRACKING_REQUIRED) \ + void ento::register##NAME##Checker(CheckerManager &Mgr) { \ + NullabilityChecker *Chk = Mgr.getChecker(); \ + Chk->NAME.enable(Mgr); \ + Chk->NeedTracking = Chk->NeedTracking || TRACKING_REQUIRED; \ + Chk->NoDiagnoseCallsToSystemHeaders = \ + Mgr.getAnalyzerOptions().getCheckerBooleanOption(GroupName, \ + GroupOptName, true); \ } \ \ - bool ento::shouldRegister##name##Checker(const CheckerManager &mgr) { \ + bool ento::shouldRegister##NAME##Checker(const CheckerManager &) { \ return true; \ } diff --git a/external/llvm-project/clang/lib/StaticAnalyzer/Core/Z3CrosscheckVisitor.cpp b/external/llvm-project/clang/lib/StaticAnalyzer/Core/Z3CrosscheckVisitor.cpp index 836fc375809a..f965bfb590d8 100644 --- a/external/llvm-project/clang/lib/StaticAnalyzer/Core/Z3CrosscheckVisitor.cpp +++ b/external/llvm-project/clang/lib/StaticAnalyzer/Core/Z3CrosscheckVisitor.cpp @@ -92,7 +92,7 @@ void Z3CrosscheckVisitor::finalizeVisitor(BugReporterContext &BRC, }; auto AttemptOnce = [&](const llvm::SMTSolverRef &Solver) -> Z3Result { - constexpr auto getCurrentTime = llvm::TimeRecord::getCurrentTime; + auto getCurrentTime = llvm::TimeRecord::getCurrentTime; unsigned InitialRLimit = GetUsedRLimit(Solver); double Start = getCurrentTime(/*Start=*/true).getWallTime(); std::optional IsSAT = Solver->check(); diff --git a/external/llvm-project/clang/lib/Tooling/DependencyScanning/DependencyScanningFilesystem.cpp b/external/llvm-project/clang/lib/Tooling/DependencyScanning/DependencyScanningFilesystem.cpp index 140833050f4e..2868522f8001 100644 --- a/external/llvm-project/clang/lib/Tooling/DependencyScanning/DependencyScanningFilesystem.cpp +++ b/external/llvm-project/clang/lib/Tooling/DependencyScanning/DependencyScanningFilesystem.cpp @@ -7,6 +7,7 @@ //===----------------------------------------------------------------------===// #include "clang/Tooling/DependencyScanning/DependencyScanningFilesystem.h" +#include "clang/Tooling/DependencyScanning/DependencyScanningService.h" #include "llvm/Support/MemoryBuffer.h" #include "llvm/Support/Threading.h" #include @@ -232,19 +233,19 @@ bool DependencyScanningWorkerFilesystem::shouldBypass(StringRef Path) const { } DependencyScanningWorkerFilesystem::DependencyScanningWorkerFilesystem( - DependencyScanningFilesystemSharedCache &SharedCache, + DependencyScanningService &Service, IntrusiveRefCntPtr FS) : llvm::RTTIExtends(std::move(FS)), - SharedCache(SharedCache), - WorkingDirForCacheLookup(llvm::errc::invalid_argument) { + Service(Service), WorkingDirForCacheLookup(llvm::errc::invalid_argument) { updateWorkingDirForCacheLookup(); } const CachedFileSystemEntry & DependencyScanningWorkerFilesystem::getOrEmplaceSharedEntryForUID( TentativeEntry TEntry) { - auto &Shard = SharedCache.getShardForUID(TEntry.Status.getUniqueID()); + auto &Shard = + Service.getSharedCache().getShardForUID(TEntry.Status.getUniqueID()); return Shard.getOrEmplaceEntryForUID(TEntry.Status.getUniqueID(), std::move(TEntry.Status), std::move(TEntry.Contents)); @@ -255,18 +256,44 @@ DependencyScanningWorkerFilesystem::findEntryByFilenameWithWriteThrough( StringRef Filename) { if (const auto *Entry = LocalCache.findEntryByFilename(Filename)) return Entry; - auto &Shard = SharedCache.getShardForFilename(Filename); + auto &Shard = Service.getSharedCache().getShardForFilename(Filename); if (const auto *Entry = Shard.findEntryByFilename(Filename)) return &LocalCache.insertEntryForFilename(Filename, *Entry); return nullptr; } +const CachedFileSystemEntry * +DependencyScanningWorkerFilesystem::findSharedEntryByUID( + llvm::vfs::Status Stat) const { + return Service.getSharedCache() + .getShardForUID(Stat.getUniqueID()) + .findEntryByUID(Stat.getUniqueID()); +} + +const CachedFileSystemEntry & +DependencyScanningWorkerFilesystem::getOrEmplaceSharedEntryForFilename( + StringRef Filename, std::error_code EC) { + return Service.getSharedCache() + .getShardForFilename(Filename) + .getOrEmplaceEntryForFilename(Filename, EC); +} + +const CachedFileSystemEntry & +DependencyScanningWorkerFilesystem::getOrInsertSharedEntryForFilename( + StringRef Filename, const CachedFileSystemEntry &Entry) { + return Service.getSharedCache() + .getShardForFilename(Filename) + .getOrInsertEntryForFilename(Filename, Entry); +} + llvm::ErrorOr DependencyScanningWorkerFilesystem::computeAndStoreResult( StringRef OriginalFilename, StringRef FilenameForLookup) { llvm::ErrorOr Stat = getUnderlyingFS().status(OriginalFilename); if (!Stat) { + if (!Service.shouldCacheNegativeStats()) + return Stat.getError(); const auto &Entry = getOrEmplaceSharedEntryForFilename(FilenameForLookup, Stat.getError()); return insertLocalEntryForFilename(FilenameForLookup, Entry); @@ -420,7 +447,8 @@ DependencyScanningWorkerFilesystem::getRealPath(const Twine &Path, return HandleCachedRealPath(*RealPath); // If we have the result in the shared cache, cache it locally. - auto &Shard = SharedCache.getShardForFilename(*FilenameForLookup); + auto &Shard = + Service.getSharedCache().getShardForFilename(*FilenameForLookup); if (const auto *ShardRealPath = Shard.findRealPathByFilename(*FilenameForLookup)) { const auto &RealPath = LocalCache.insertRealPathForFilename( diff --git a/external/llvm-project/clang/lib/Tooling/DependencyScanning/DependencyScanningService.cpp b/external/llvm-project/clang/lib/Tooling/DependencyScanning/DependencyScanningService.cpp index 7f40c99f0728..c2f3cdbb02e3 100644 --- a/external/llvm-project/clang/lib/Tooling/DependencyScanning/DependencyScanningService.cpp +++ b/external/llvm-project/clang/lib/Tooling/DependencyScanning/DependencyScanningService.cpp @@ -15,7 +15,8 @@ using namespace dependencies; DependencyScanningService::DependencyScanningService( ScanningMode Mode, ScanningOutputFormat Format, ScanningOptimizations OptimizeArgs, bool EagerLoadModules, bool TraceVFS, - std::time_t BuildSessionTimestamp) + std::time_t BuildSessionTimestamp, bool CacheNegativeStats) : Mode(Mode), Format(Format), OptimizeArgs(OptimizeArgs), EagerLoadModules(EagerLoadModules), TraceVFS(TraceVFS), + CacheNegativeStats(CacheNegativeStats), BuildSessionTimestamp(BuildSessionTimestamp) {} diff --git a/external/llvm-project/clang/lib/Tooling/DependencyScanning/DependencyScanningWorker.cpp b/external/llvm-project/clang/lib/Tooling/DependencyScanning/DependencyScanningWorker.cpp index 9bd85479d981..d9820ca3c584 100644 --- a/external/llvm-project/clang/lib/Tooling/DependencyScanning/DependencyScanningWorker.cpp +++ b/external/llvm-project/clang/lib/Tooling/DependencyScanning/DependencyScanningWorker.cpp @@ -611,8 +611,7 @@ DependencyScanningWorker::DependencyScanningWorker( switch (Service.getMode()) { case ScanningMode::DependencyDirectivesScan: - DepFS = - new DependencyScanningWorkerFilesystem(Service.getSharedCache(), FS); + DepFS = new DependencyScanningWorkerFilesystem(Service, FS); BaseFS = DepFS; break; case ScanningMode::CanonicalPreprocessing: diff --git a/external/llvm-project/clang/test/AST/ByteCode/builtin-bit-cast-long-double.cpp b/external/llvm-project/clang/test/AST/ByteCode/builtin-bit-cast-long-double.cpp index 710612bef8fd..1013a771d13b 100644 --- a/external/llvm-project/clang/test/AST/ByteCode/builtin-bit-cast-long-double.cpp +++ b/external/llvm-project/clang/test/AST/ByteCode/builtin-bit-cast-long-double.cpp @@ -21,6 +21,9 @@ template constexpr To bit_cast(const From &from) { static_assert(sizeof(To) == sizeof(From)); return __builtin_bit_cast(To, from); +#if __x86_64 + // both-note@-2 {{indeterminate value can only initialize an object of type}} +#endif } template @@ -38,11 +41,8 @@ constexpr Init round_trip(const Init &init) { namespace test_long_double { #if __x86_64 -/// FIXME: We could enable this, but since it aborts, it causes the usual mempory leak. -#if 0 -constexpr __int128_t test_cast_to_int128 = bit_cast<__int128_t>((long double)0); // expected-error{{must be initialized by a constant expression}}\ - // expected-note{{in call}} -#endif +constexpr __int128_t test_cast_to_int128 = bit_cast<__int128_t>((long double)0); // both-error{{must be initialized by a constant expression}}\ + // both-note{{in call}} constexpr long double ld = 3.1425926539; struct bytes { diff --git a/external/llvm-project/clang/test/AST/ByteCode/builtin-functions.cpp b/external/llvm-project/clang/test/AST/ByteCode/builtin-functions.cpp index 21dca15a4577..3b95a8ea4859 100644 --- a/external/llvm-project/clang/test/AST/ByteCode/builtin-functions.cpp +++ b/external/llvm-project/clang/test/AST/ByteCode/builtin-functions.cpp @@ -208,7 +208,7 @@ namespace nan { constexpr double NaN3 = __builtin_nan("foo"); // both-error {{must be initialized by a constant expression}} constexpr float NaN4 = __builtin_nanf(""); - //constexpr long double NaN5 = __builtin_nanf128(""); + constexpr long double NaN5 = __builtin_nanf128(""); /// FIXME: This should be accepted by the current interpreter as well. constexpr char f[] = {'0', 'x', 'A', 'E', '\0'}; @@ -655,8 +655,6 @@ void test_noexcept(int *i) { } // end namespace test_launder -/// FIXME: The commented out tests here use a IntAP value and fail. -/// This currently means we will leak the IntAP value since nothing cleans it up. namespace clz { char clz1[__builtin_clz(1) == BITSIZE(int) - 1 ? 1 : -1]; char clz2[__builtin_clz(7) == BITSIZE(int) - 3 ? 1 : -1]; @@ -709,7 +707,7 @@ namespace clz { char clz48[__builtin_clzg(1ULL << (BITSIZE(long long) - 1)) == 0 ? 1 : -1]; char clz49[__builtin_clzg(1ULL << (BITSIZE(long long) - 1), 42) == 0 ? 1 : -1]; #ifdef __SIZEOF_INT128__ - // int clz50 = __builtin_clzg((unsigned __int128)0); + int clz50 = __builtin_clzg((unsigned __int128)0); char clz51[__builtin_clzg((unsigned __int128)0, 42) == 42 ? 1 : -1]; char clz52[__builtin_clzg((unsigned __int128)0x1) == BITSIZE(__int128) - 1 ? 1 : -1]; char clz53[__builtin_clzg((unsigned __int128)0x1, 42) == BITSIZE(__int128) - 1 ? 1 : -1]; @@ -717,7 +715,7 @@ namespace clz { char clz55[__builtin_clzg((unsigned __int128)0xf, 42) == BITSIZE(__int128) - 4 ? 1 : -1]; #endif #ifndef __AVR__ - // int clz58 = __builtin_clzg((unsigned _BitInt(128))0); + int clz58 = __builtin_clzg((unsigned _BitInt(128))0); char clz59[__builtin_clzg((unsigned _BitInt(128))0, 42) == 42 ? 1 : -1]; char clz60[__builtin_clzg((unsigned _BitInt(128))0x1) == BITSIZE(_BitInt(128)) - 1 ? 1 : -1]; char clz61[__builtin_clzg((unsigned _BitInt(128))0x1, 42) == BITSIZE(_BitInt(128)) - 1 ? 1 : -1]; @@ -775,7 +773,7 @@ namespace ctz { char ctz46[__builtin_ctzg(1ULL << (BITSIZE(long long) - 1)) == BITSIZE(long long) - 1 ? 1 : -1]; char ctz47[__builtin_ctzg(1ULL << (BITSIZE(long long) - 1), 42) == BITSIZE(long long) - 1 ? 1 : -1]; #ifdef __SIZEOF_INT128__ - // int ctz48 = __builtin_ctzg((unsigned __int128)0); + int ctz48 = __builtin_ctzg((unsigned __int128)0); char ctz49[__builtin_ctzg((unsigned __int128)0, 42) == 42 ? 1 : -1]; char ctz50[__builtin_ctzg((unsigned __int128)0x1) == 0 ? 1 : -1]; char ctz51[__builtin_ctzg((unsigned __int128)0x1, 42) == 0 ? 1 : -1]; @@ -785,7 +783,7 @@ namespace ctz { char ctz55[__builtin_ctzg((unsigned __int128)1 << (BITSIZE(__int128) - 1), 42) == BITSIZE(__int128) - 1 ? 1 : -1]; #endif #ifndef __AVR__ - // int ctz56 = __builtin_ctzg((unsigned _BitInt(128))0); + int ctz56 = __builtin_ctzg((unsigned _BitInt(128))0); char ctz57[__builtin_ctzg((unsigned _BitInt(128))0, 42) == 42 ? 1 : -1]; char ctz58[__builtin_ctzg((unsigned _BitInt(128))0x1) == 0 ? 1 : -1]; char ctz59[__builtin_ctzg((unsigned _BitInt(128))0x1, 42) == 0 ? 1 : -1]; @@ -1741,4 +1739,18 @@ namespace WithinLifetime { // both-warning {{expression result unused}} } } + +#ifdef __SIZEOF_INT128__ +namespace I128Mul { + constexpr int mul() { + __int128 A = 10; + __int128 B = 10; + __int128 R; + __builtin_mul_overflow(A, B, &R); + return 1; + } + static_assert(mul() == 1); +} +#endif + #endif diff --git a/external/llvm-project/clang/test/AST/ByteCode/intap.cpp b/external/llvm-project/clang/test/AST/ByteCode/intap.cpp index 3f952ddf626b..68883871ffd2 100644 --- a/external/llvm-project/clang/test/AST/ByteCode/intap.cpp +++ b/external/llvm-project/clang/test/AST/ByteCode/intap.cpp @@ -48,6 +48,14 @@ static_assert(DivA / DivB == 2, ""); constexpr _BitInt(4) DivC = DivA / 0; // both-error {{must be initialized by a constant expression}} \ // both-note {{division by zero}} +#ifdef __SIZEOF_INT128__ +constexpr __int128 isMinDiv() { + return __int128{0} / __int128{-1}; +} +static_assert(isMinDiv() == 0, ""); +#endif + + constexpr _BitInt(7) RemA = 47; constexpr _BitInt(6) RemB = 9; static_assert(RemA % RemB == 2, ""); @@ -273,4 +281,18 @@ namespace IncDec { #endif } +#if __cplusplus >= 201402L +const __int128_t a = ( (__int128_t)1 << 64 ); +const _BitInt(72) b = ( 1 << 72 ); // both-warning {{shift count >= width of type}} +constexpr int shifts() { // both-error {{never produces a constant expression}} + (void)(2 >> a); // both-warning {{shift count >= width of type}} \ + // both-note {{shift count 18446744073709551616 >= width of type 'int' (32 bits)}} + (void)(2 >> b); // ref-warning {{shift count is negative}} + (void)(2 << a); // both-warning {{shift count >= width of type}} + (void)(2 << b); // ref-warning {{shift count is negative}} + return 1; +} +#endif + + #endif diff --git a/external/llvm-project/clang/test/AST/HLSL/RootSignatures-AST.hlsl b/external/llvm-project/clang/test/AST/HLSL/RootSignatures-AST.hlsl index c700174da764..157d90aee7ee 100644 --- a/external/llvm-project/clang/test/AST/HLSL/RootSignatures-AST.hlsl +++ b/external/llvm-project/clang/test/AST/HLSL/RootSignatures-AST.hlsl @@ -5,29 +5,61 @@ // the Attr AST Node is created succesfully. If an invalid root signature was // passed in then we would exit out of Sema before the Attr is created. -#define SampleRS \ - "DescriptorTable( " \ - " CBV(b1), " \ - " SRV(t1, numDescriptors = 8, " \ - " flags = DESCRIPTORS_VOLATILE), " \ - " UAV(u1, numDescriptors = 0, " \ - " flags = DESCRIPTORS_VOLATILE) " \ - "), " \ - "DescriptorTable(Sampler(s0, numDescriptors = 4, space = 1))" +#define SampleRS "RootFlags( ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT | " \ + "DENY_VERTEX_SHADER_ROOT_ACCESS), " \ + "CBV(b0, space = 1, flags = DATA_STATIC), " \ + "SRV(t0), " \ + "UAV(u0), " \ + "DescriptorTable( CBV(b1), " \ + "SRV(t1, numDescriptors = 8, " \ + " flags = DESCRIPTORS_VOLATILE), " \ + "UAV(u1, numDescriptors = unbounded, " \ + " flags = DESCRIPTORS_VOLATILE)), " \ + "DescriptorTable(Sampler(s0, space=1, numDescriptors = 4)), " \ + "RootConstants(num32BitConstants=3, b10), " \ + "StaticSampler(s1)," \ + "StaticSampler(s2, " \ + "addressU = TEXTURE_ADDRESS_CLAMP, " \ + "filter = FILTER_MIN_MAG_MIP_LINEAR )" // CHECK: -HLSLRootSignatureDecl 0x{{.*}} {{.*}} implicit [[SAMPLE_RS_DECL:__hlsl_rootsig_decl_\d*]] // CHECK-SAME: RootElements{ -// CHECK-SAME: CBV(b1, numDescriptors = 1, space = 0, -// CHECK-SAME: offset = DescriptorTableOffsetAppend, flags = DataStaticWhileSetAtExecute), -// CHECK-SAME: SRV(t1, numDescriptors = 8, space = 0, -// CHECK-SAME: offset = DescriptorTableOffsetAppend, flags = DescriptorsVolatile), -// CHECK-SAME: UAV(u1, numDescriptors = 0, space = 0, -// CHECK-SAME: offset = DescriptorTableOffsetAppend, flags = DescriptorsVolatile), -// CHECK-SAME: DescriptorTable(numClauses = 3, visibility = All), -// CHECK-SAME: Sampler(s0, numDescriptors = 4, space = 1, -// CHECK-SAME: offset = DescriptorTableOffsetAppend, flags = None), -// CHECK-SAME: DescriptorTable(numClauses = 1, visibility = All) -// CHECK-SAME: } +// CHECK-SAME: RootFlags(AllowInputAssemblerInputLayout | DenyVertexShaderRootAccess), +// CHECK-SAME: RootCBV(b0, +// CHECK-SAME: space = 1, visibility = All, flags = DataStatic +// CHECK-SAME: ), +// CHECK-SAME: RootSRV(t0, +// CHECK-SAME: space = 0, visibility = All, flags = DataStaticWhileSetAtExecute +// CHECK-SAME: ), +// CHECK-SAME: RootUAV( +// CHECK-SAME: u0, space = 0, visibility = All, flags = DataVolatile +// CHECK-SAME: ), +// CHECK-SAME: CBV( +// CHECK-SAME: b1, numDescriptors = 1, space = 0, offset = DescriptorTableOffsetAppend, flags = DataStaticWhileSetAtExecute +// CHECK-SAME: ), +// CHECK-SAME: SRV( +// CHECK-SAME: t1, numDescriptors = 8, space = 0, offset = DescriptorTableOffsetAppend, flags = DescriptorsVolatile +// CHECK-SAME: ), +// CHECK-SAME: UAV( +// CHECK-SAME: u1, numDescriptors = unbounded, space = 0, offset = DescriptorTableOffsetAppend, flags = DescriptorsVolatile +// CHECK-SAME: ), +// CHECK-SAME: DescriptorTable( +// CHECK-SAME: numClauses = 3, visibility = All +// CHECK-SAME: ), +// CHECK-SAME: Sampler( +// CHECK-SAME: s0, numDescriptors = 4, space = 1, offset = DescriptorTableOffsetAppend, flags = None +// CHECK-SAME: ), +// CHECK-SAME: DescriptorTable( +// CHECK-SAME: numClauses = 1, visibility = All +// CHECK-SAME: ), +// CHECK-SAME: RootConstants( +// CHECK-SAME: num32BitConstants = 3, b10, space = 0, visibility = All +// CHECK-SAME: ), +// CHECK-SAME: StaticSampler( +// CHECK-SAME: s1, filter = Anisotropic, addressU = Wrap, addressV = Wrap, addressW = Wrap, +// CHECK-SAME: mipLODBias = 0.000000e+00, maxAnisotropy = 16, comparisonFunc = LessEqual, +// CHECK-SAME: borderColor = OpaqueWhite, minLOD = 0.000000e+00, maxLOD = 3.402823e+38, space = 0, visibility = All +// CHECK-SAME: )} // CHECK: -RootSignatureAttr 0x{{.*}} {{.*}} [[SAMPLE_RS_DECL]] [RootSignature(SampleRS)] @@ -44,14 +76,23 @@ void same_rs_main() {} // link to the same root signature declaration #define SampleSameRS \ - "DescriptorTable( " \ - " CBV(b1), " \ - " SRV(t1, numDescriptors = 8, " \ - " flags = DESCRIPTORS_VOLATILE), " \ - " UAV(u1, numDescriptors = 0, " \ - " flags = DESCRIPTORS_VOLATILE) " \ - "), " \ - "DescriptorTable(Sampler(s0, numDescriptors = 4, space = 1))" + "RootFlags( ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT | " \ + "DENY_VERTEX_SHADER_ROOT_ACCESS), " \ + "CBV(b0, space = 1, flags = DATA_STATIC), " \ + "SRV(t0), " \ + "UAV(u0), " \ + "DescriptorTable( CBV(b1), " \ + "SRV(t1, numDescriptors = 8, " \ + " flags = DESCRIPTORS_VOLATILE), " \ + "UAV(u1, numDescriptors = unbounded, " \ + " flags = DESCRIPTORS_VOLATILE)), " \ + "DescriptorTable(Sampler(s0, space=1, numDescriptors = 4)), " \ + "RootConstants(num32BitConstants=3, b10), " \ + "StaticSampler(s1)," \ + "StaticSampler(s2, " \ + "addressU = TEXTURE_ADDRESS_CLAMP, " \ + "filter = FILTER_MIN_MAG_MIP_LINEAR )" + // CHECK: -RootSignatureAttr 0x{{.*}} {{.*}} [[SAMPLE_RS_DECL]] [RootSignature(SampleSameRS)] diff --git a/external/llvm-project/clang/test/AST/HLSL/vk.spec-constant.usage.hlsl b/external/llvm-project/clang/test/AST/HLSL/vk.spec-constant.usage.hlsl new file mode 100644 index 000000000000..c0955c1ea7b4 --- /dev/null +++ b/external/llvm-project/clang/test/AST/HLSL/vk.spec-constant.usage.hlsl @@ -0,0 +1,130 @@ +// RUN: %clang_cc1 -finclude-default-header -triple spirv-unknown-vulkan-compute -x hlsl -ast-dump -o - %s | FileCheck %s + +// CHECK: VarDecl {{.*}} bool_const 'const hlsl_private bool' static cinit +// CHECK-NEXT: CallExpr {{.*}} 'bool' +// CHECK-NEXT: ImplicitCastExpr {{.*}} 'bool (*)(unsigned int, bool) noexcept' +// CHECK-NEXT: DeclRefExpr {{.*}} 'bool (unsigned int, bool) noexcept' lvalue Function {{.*}} '__builtin_get_spirv_spec_constant_bool' 'bool (unsigned int, bool) noexcept' +// CHECK-NEXT: ImplicitCastExpr {{.*}} 'unsigned int' +// CHECK-NEXT: IntegerLiteral {{.*}} 'int' 1 +// CHECK-NEXT: CXXBoolLiteralExpr {{.*}} 'bool' true +[[vk::constant_id(1)]] +const bool bool_const = true; + +// CHECK: VarDecl {{.*}} short_const 'const hlsl_private short' static cinit +// CHECK-NEXT: CallExpr {{.*}} 'short' +// CHECK-NEXT: ImplicitCastExpr {{.*}} 'short (*)(unsigned int, short) noexcept' +// CHECK-NEXT: DeclRefExpr {{.*}} 'short (unsigned int, short) noexcept' lvalue Function {{.*}} '__builtin_get_spirv_spec_constant_short' 'short (unsigned int, short) noexcept' +// CHECK-NEXT: ImplicitCastExpr {{.*}} 'unsigned int' +// CHECK-NEXT: IntegerLiteral {{.*}} 'int' 2 +// CHECK-NEXT: ImplicitCastExpr {{.*}} 'short' +// CHECK-NEXT: IntegerLiteral {{.*}} 'int' 4 +[[vk::constant_id(2)]] +const short short_const = 4; + +// CHECK: VarDecl {{.*}} int_const 'const hlsl_private int' static cinit +// CHECK-NEXT: CallExpr {{.*}} 'int' +// CHECK-NEXT: ImplicitCastExpr {{.*}} 'int (*)(unsigned int, int) noexcept' +// CHECK-NEXT: DeclRefExpr {{.*}} 'int (unsigned int, int) noexcept' lvalue Function {{.*}} '__builtin_get_spirv_spec_constant_int' 'int (unsigned int, int) noexcept' +// CHECK-NEXT: ImplicitCastExpr {{.*}} 'unsigned int' +// CHECK-NEXT: IntegerLiteral {{.*}} 'int' 3 +// CHECK-NEXT: IntegerLiteral {{.*}} 'int' 5 +[[vk::constant_id(3)]] +const int int_const = 5; + +// CHECK: VarDecl {{.*}} long_const 'const hlsl_private long long' static cinit +// CHECK-NEXT: CallExpr {{.*}} 'long long' +// CHECK-NEXT: ImplicitCastExpr {{.*}} 'long long (*)(unsigned int, long long) noexcept' +// CHECK-NEXT: DeclRefExpr {{.*}} 'long long (unsigned int, long long) noexcept' lvalue Function {{.*}} '__builtin_get_spirv_spec_constant_longlong' 'long long (unsigned int, long long) noexcept' +// CHECK-NEXT: ImplicitCastExpr {{.*}} 'unsigned int' +// CHECK-NEXT: IntegerLiteral {{.*}} 'int' 4 +// CHECK-NEXT: ImplicitCastExpr {{.*}} 'long long' +// CHECK-NEXT: IntegerLiteral {{.*}} 'int' 8 +[[vk::constant_id(4)]] +const long long long_const = 8; + +// CHECK: VarDecl {{.*}} ushort_const 'const hlsl_private unsigned short' static cinit +// CHECK-NEXT: CallExpr {{.*}} 'unsigned short' +// CHECK-NEXT: ImplicitCastExpr {{.*}} 'unsigned short (*)(unsigned int, unsigned short) noexcept' +// CHECK-NEXT: DeclRefExpr {{.*}} 'unsigned short (unsigned int, unsigned short) noexcept' lvalue Function {{.*}} '__builtin_get_spirv_spec_constant_ushort' 'unsigned short (unsigned int, unsigned short) noexcept' +// CHECK-NEXT: ImplicitCastExpr {{.*}} 'unsigned int' +// CHECK-NEXT: IntegerLiteral {{.*}} 'int' 5 +// CHECK-NEXT: ImplicitCastExpr {{.*}} 'unsigned short' +// CHECK-NEXT: IntegerLiteral {{.*}} 'int' 10 +[[vk::constant_id(5)]] +const unsigned short ushort_const = 10; + +// CHECK: VarDecl {{.*}} uint_const 'const hlsl_private unsigned int' static cinit +// CHECK-NEXT: CallExpr {{.*}} 'unsigned int' +// CHECK-NEXT: ImplicitCastExpr {{.*}} 'unsigned int (*)(unsigned int, unsigned int) noexcept' +// CHECK-NEXT: DeclRefExpr {{.*}} 'unsigned int (unsigned int, unsigned int) noexcept' lvalue Function {{.*}} '__builtin_get_spirv_spec_constant_uint' 'unsigned int (unsigned int, unsigned int) noexcept' +// CHECK-NEXT: ImplicitCastExpr {{.*}} 'unsigned int' +// CHECK-NEXT: IntegerLiteral {{.*}} 'int' 6 +// CHECK-NEXT: ImplicitCastExpr {{.*}} 'unsigned int' +// CHECK-NEXT: IntegerLiteral {{.*}} 'int' 12 +[[vk::constant_id(6)]] +const unsigned int uint_const = 12; + + +// CHECK: VarDecl {{.*}} ulong_const 'const hlsl_private unsigned long long' static cinit +// CHECK-NEXT: CallExpr {{.*}} 'unsigned long long' +// CHECK-NEXT: ImplicitCastExpr {{.*}} 'unsigned long long (*)(unsigned int, unsigned long long) noexcept' +// CHECK-NEXT: DeclRefExpr {{.*}} 'unsigned long long (unsigned int, unsigned long long) noexcept' lvalue Function {{.*}} '__builtin_get_spirv_spec_constant_ulonglong' 'unsigned long long (unsigned int, unsigned long long) noexcept' +// CHECK-NEXT: ImplicitCastExpr {{.*}} 'unsigned int' +// CHECK-NEXT: IntegerLiteral {{.*}} 'int' 7 +// CHECK-NEXT: ImplicitCastExpr {{.*}} 'unsigned long long' +// CHECK-NEXT: IntegerLiteral {{.*}} 'int' 25 +[[vk::constant_id(7)]] +const unsigned long long ulong_const = 25; + +// CHECK: VarDecl {{.*}} half_const 'const hlsl_private half' static cinit +// CHECK-NEXT: CallExpr {{.*}} 'half' +// CHECK-NEXT: ImplicitCastExpr {{.*}} 'half (*)(unsigned int, half) noexcept' +// CHECK-NEXT: DeclRefExpr {{.*}} 'half (unsigned int, half) noexcept' lvalue Function {{.*}} '__builtin_get_spirv_spec_constant_half' 'half (unsigned int, half) noexcept' +// CHECK-NEXT: ImplicitCastExpr {{.*}} 'unsigned int' +// CHECK-NEXT: IntegerLiteral {{.*}} 'int' 8 +// CHECK-NEXT: ImplicitCastExpr {{.*}} 'half' +// CHECK-NEXT: FloatingLiteral {{.*}} 'float' 4.040000e+01 +[[vk::constant_id(8)]] +const half half_const = 40.4; + +// CHECK: VarDecl {{.*}} float_const 'const hlsl_private float' static cinit +// CHECK-NEXT: CallExpr {{.*}} 'float' +// CHECK-NEXT: ImplicitCastExpr {{.*}} 'float (*)(unsigned int, float) noexcept' +// CHECK-NEXT: DeclRefExpr {{.*}} 'float (unsigned int, float) noexcept' lvalue Function {{.*}} '__builtin_get_spirv_spec_constant_float' 'float (unsigned int, float) noexcept' +// CHECK-NEXT: ImplicitCastExpr {{.*}} 'unsigned int' +// CHECK-NEXT: IntegerLiteral {{.*}} 'int' 8 +// CHECK-NEXT: ImplicitCastExpr {{.*}} 'float' +// CHECK-NEXT: IntegerLiteral {{.*}} 'int' 50 +[[vk::constant_id(8)]] +const float float_const = 50; + +// CHECK: VarDecl {{.*}} double_const 'const hlsl_private double' static cinit +// CHECK-NEXT: CallExpr {{.*}} 'double' +// CHECK-NEXT: ImplicitCastExpr {{.*}} 'double (*)(unsigned int, double) noexcept' +// CHECK-NEXT: DeclRefExpr {{.*}} 'double (unsigned int, double) noexcept' lvalue Function {{.*}} '__builtin_get_spirv_spec_constant_double' 'double (unsigned int, double) noexcept' +// CHECK-NEXT: ImplicitCastExpr {{.*}} 'unsigned int' +// CHECK-NEXT: IntegerLiteral {{.*}} 'int' 9 +// CHECK-NEXT: ImplicitCastExpr {{.*}} 'double' +// CHECK-NEXT: IntegerLiteral {{.*}} 'int' 100 +[[vk::constant_id(9)]] +const double double_const = 100; + +// CHECK: VarDecl {{.*}} enum_const 'const hlsl_private E' static cinit +// CHECK-NEXT: CStyleCastExpr {{.*}} 'E' +// CHECK-NEXT: CallExpr {{.*}} 'int' +// CHECK-NEXT: ImplicitCastExpr {{.*}} 'int (*)(unsigned int, int) noexcept' +// CHECK-NEXT: DeclRefExpr {{.*}} 'int (unsigned int, int) noexcept' lvalue Function {{.*}} '__builtin_get_spirv_spec_constant_int' 'int (unsigned int, int) noexcept' +// CHECK-NEXT: ImplicitCastExpr {{.*}} 'unsigned int' +// CHECK-NEXT: IntegerLiteral {{.*}} 'int' 10 +// CHECK-NEXT: ImplicitCastExpr {{.*}} 'int' +// CHECK-NEXT: DeclRefExpr {{.*}} 'E' EnumConstant {{.*}} 'e2' 'E' +enum E { + e0 = 10, + e1 = 20, + e2 = 30 +}; + +[[vk::constant_id(10)]] +const E enum_const = e2; + +// CHECK-NOT: CXXRecordDecl {{.*}} implicit struct __cblayout_$Globals definition diff --git a/external/llvm-project/clang/test/AST/ast-dump-ppc-types.c b/external/llvm-project/clang/test/AST/ast-dump-ppc-types.c index 26ae5441f20d..1c860c268e0e 100644 --- a/external/llvm-project/clang/test/AST/ast-dump-ppc-types.c +++ b/external/llvm-project/clang/test/AST/ast-dump-ppc-types.c @@ -1,9 +1,11 @@ +// RUN: %clang_cc1 -triple powerpc64le-unknown-unknown -target-cpu future \ +// RUN: -ast-dump %s | FileCheck %s // RUN: %clang_cc1 -triple powerpc64le-unknown-unknown -target-cpu pwr10 \ -// RUN: -ast-dump -ast-dump-filter __vector %s | FileCheck %s +// RUN: -ast-dump %s | FileCheck %s // RUN: %clang_cc1 -triple powerpc64le-unknown-unknown -target-cpu pwr9 \ -// RUN: -ast-dump -ast-dump-filter __vector %s | FileCheck %s +// RUN: -ast-dump %s | FileCheck %s // RUN: %clang_cc1 -triple powerpc64le-unknown-unknown -target-cpu pwr8 \ -// RUN: -ast-dump -ast-dump-filter __vector %s | FileCheck %s +// RUN: -ast-dump %s | FileCheck %s // RUN: %clang_cc1 -triple x86_64-unknown-unknown -ast-dump %s | FileCheck %s \ // RUN: --check-prefix=CHECK-X86_64 // RUN: %clang_cc1 -triple arm-unknown-unknown -ast-dump %s | FileCheck %s \ @@ -15,16 +17,21 @@ // are correctly defined. We also added checks on a couple of other targets to // ensure the types are target-dependent. +// CHECK: TypedefDecl {{.*}} implicit __dmr1024 '__dmr1024' +// CHECK: `-BuiltinType {{.*}} '__dmr1024' // CHECK: TypedefDecl {{.*}} implicit __vector_quad '__vector_quad' // CHECK-NEXT: -BuiltinType {{.*}} '__vector_quad' // CHECK: TypedefDecl {{.*}} implicit __vector_pair '__vector_pair' // CHECK-NEXT: -BuiltinType {{.*}} '__vector_pair' +// CHECK-X86_64-NOT: __dmr1024 // CHECK-X86_64-NOT: __vector_quad // CHECK-X86_64-NOT: __vector_pair +// CHECK-ARM-NOT: __dmr1024 // CHECK-ARM-NOT: __vector_quad // CHECK-ARM-NOT: __vector_pair +// CHECK-RISCV64-NOT: __dmr1024 // CHECK-RISCV64-NOT: __vector_quad // CHECK-RISCV64-NOT: __vector_pair diff --git a/external/llvm-project/clang/test/Analysis/NewDelete-checker-test.cpp b/external/llvm-project/clang/test/Analysis/NewDelete-checker-test.cpp index 06754f669b1e..da0eef7c52bd 100644 --- a/external/llvm-project/clang/test/Analysis/NewDelete-checker-test.cpp +++ b/external/llvm-project/clang/test/Analysis/NewDelete-checker-test.cpp @@ -26,9 +26,10 @@ // RUN: -analyzer-checker=cplusplus.NewDeleteLeaks // // RUN: %clang_analyze_cc1 -std=c++17 -fblocks -verify %s \ -// RUN: -verify=expected,leak \ +// RUN: -verify=expected,leak,inspection \ // RUN: -analyzer-checker=core \ -// RUN: -analyzer-checker=cplusplus.NewDeleteLeaks +// RUN: -analyzer-checker=cplusplus.NewDeleteLeaks \ +// RUN: -analyzer-checker=debug.ExprInspection #include "Inputs/system-header-simulator-cxx.h" @@ -63,6 +64,39 @@ void testGlobalNoThrowPlacementExprNewBeforeOverload() { int *p = new(std::nothrow) int; } // leak-warning{{Potential leak of memory pointed to by 'p'}} +//----- Standard pointer placement operators +void testGlobalPointerPlacementNew() { + int i; + void *p1 = operator new(0, &i); // no leak: placement new never allocates + void *p2 = operator new[](0, &i); // no leak + int *p3 = new(&i) int; // no leak + int *p4 = new(&i) int[0]; // no leak +} + +template +void clang_analyzer_dump(T x); + +void testPlacementNewBufValue() { + int i = 10; + int *p = new(&i) int; + clang_analyzer_dump(p); // inspection-warning{{&i}} + clang_analyzer_dump(*p); // inspection-warning{{10}} +} + +void testPlacementNewBufValueExplicitOp() { + int i = 10; + int *p = (int*)operator new(sizeof(int), &i); + clang_analyzer_dump(p); // inspection-warning{{&i}} + clang_analyzer_dump(*p); // inspection-warning{{10}} +} + +void testPlacementArrNewBufValueExplicitArrOp() { + int i = 10; + int *p = (int*)operator new[](sizeof(int), &i); + clang_analyzer_dump(p); // inspection-warning{{&i}} + clang_analyzer_dump(*p); // inspection-warning{{10}} +} + //----- Other cases void testNewMemoryIsInHeap() { int *p = new int; diff --git a/external/llvm-project/clang/test/Analysis/analyzer-enabled-checkers.c b/external/llvm-project/clang/test/Analysis/analyzer-enabled-checkers.c index 66b9be9795f1..78ee00deea18 100644 --- a/external/llvm-project/clang/test/Analysis/analyzer-enabled-checkers.c +++ b/external/llvm-project/clang/test/Analysis/analyzer-enabled-checkers.c @@ -34,7 +34,6 @@ // CHECK-NEXT: core.uninitialized.CapturedBlockVariable // CHECK-NEXT: core.uninitialized.UndefReturn // CHECK-NEXT: deadcode.DeadStores -// CHECK-NEXT: nullability.NullabilityBase // CHECK-NEXT: nullability.NullPassedToNonnull // CHECK-NEXT: nullability.NullReturnedFromNonnull // CHECK-NEXT: security.insecureAPI.SecuritySyntaxChecker diff --git a/external/llvm-project/clang/test/Analysis/bugfix-124477.m b/external/llvm-project/clang/test/Analysis/bugfix-124477.m index 80820f4c9344..8bb0196b2f9b 100644 --- a/external/llvm-project/clang/test/Analysis/bugfix-124477.m +++ b/external/llvm-project/clang/test/Analysis/bugfix-124477.m @@ -1,4 +1,4 @@ -// RUN: %clang_analyze_cc1 -analyzer-checker=core,apiModeling,nullability.NullableDereferenced,nullability.NullabilityBase -x objective-c %s +// RUN: %clang_analyze_cc1 -analyzer-checker=core,apiModeling,nullability.NullableDereferenced -x objective-c %s /* This test is reduced from a static analyzer crash. The bug causing the crash is explained in #124477. It can only be triggered in some diff --git a/external/llvm-project/clang/test/Analysis/std-c-library-functions-arg-enabled-checkers.c b/external/llvm-project/clang/test/Analysis/std-c-library-functions-arg-enabled-checkers.c index 8c6078a49c23..7f9c9ff4c9fd 100644 --- a/external/llvm-project/clang/test/Analysis/std-c-library-functions-arg-enabled-checkers.c +++ b/external/llvm-project/clang/test/Analysis/std-c-library-functions-arg-enabled-checkers.c @@ -42,7 +42,6 @@ // CHECK-NEXT: core.uninitialized.CapturedBlockVariable // CHECK-NEXT: core.uninitialized.UndefReturn // CHECK-NEXT: deadcode.DeadStores -// CHECK-NEXT: nullability.NullabilityBase // CHECK-NEXT: nullability.NullPassedToNonnull // CHECK-NEXT: nullability.NullReturnedFromNonnull // CHECK-NEXT: security.insecureAPI.SecuritySyntaxChecker diff --git a/external/llvm-project/clang/test/Analysis/taint-generic.c b/external/llvm-project/clang/test/Analysis/taint-generic.c index 3c520612c5d9..9d6d2942df4a 100644 --- a/external/llvm-project/clang/test/Analysis/taint-generic.c +++ b/external/llvm-project/clang/test/Analysis/taint-generic.c @@ -412,6 +412,19 @@ int testTaintedDivFP(void) { return 5/x; // x cannot be 0, so no tainted warning either } +void clang_analyzer_warnIfReached(); + +int testTaintDivZeroNonfatal() { + int x; + scanf("%d", &x); + int y = 5/x; // expected-warning {{Division by a tainted value, possibly zero}} + if (x == 0) + clang_analyzer_warnIfReached(); + else + clang_analyzer_warnIfReached(); // expected-warning {{REACHABLE}} + return y; +} + // Zero-sized VLAs. void testTaintedVLASize(void) { int x; diff --git a/external/llvm-project/clang/test/C/C23/n2975.c b/external/llvm-project/clang/test/C/C23/n2975.c index 6e7c936855e5..854afeff7a2b 100644 --- a/external/llvm-project/clang/test/C/C23/n2975.c +++ b/external/llvm-project/clang/test/C/C23/n2975.c @@ -51,3 +51,15 @@ void use(void) { // ...including conversion errors. fp other_local = diag; // expected-error {{incompatible function pointer types initializing 'fp' (aka 'void (*)(...)') with an expression of type 'void (int, int, ...)'}} } + +// int(...) not parsed as variadic function type. +// https://github.com/llvm/llvm-project/issues/145250 +int va_fn(...); // expected-warning {{'...' as the only parameter of a function is incompatible with C standards before C23}} + +// As typeof() argument +typeof(int(...))*fn_ptr = &va_fn; // expected-warning {{'...' as the only parameter of a function is incompatible with C standards before C23}} \ + // expected-warning {{'typeof' is incompatible with C standards before C23}} + +// As _Generic association type +int i = _Generic(typeof(va_fn), int(...):1); // expected-warning {{'...' as the only parameter of a function is incompatible with C standards before C23}} \ + // expected-warning {{'typeof' is incompatible with C standards before C23}} diff --git a/external/llvm-project/clang/test/CIR/CodeGen/bitfields.c b/external/llvm-project/clang/test/CIR/CodeGen/bitfields.c new file mode 100644 index 000000000000..ff5c6bc1787b --- /dev/null +++ b/external/llvm-project/clang/test/CIR/CodeGen/bitfields.c @@ -0,0 +1,78 @@ +// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir -emit-cir %s -o %t.cir +// RUN: FileCheck --input-file=%t.cir %s --check-prefix=CIR +// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir -emit-llvm %s -o %t-cir.ll +// RUN: FileCheck --input-file=%t-cir.ll %s --check-prefix=LLVM +// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -emit-llvm %s -o %t.ll +// RUN: FileCheck --input-file=%t.ll %s --check-prefix=OGCG + +typedef struct { + char a, b, c; + unsigned bits : 3; + unsigned more_bits : 4; + unsigned still_more_bits : 7; +} A; + +// CIR-DAG: !rec_A = !cir.record}> +// LLVM-DAG: %struct.A = type <{ i8, i8, i8, i16, [3 x i8] }> +// OGCG-DAG: %struct.A = type <{ i8, i8, i8, i16, [3 x i8] }> + +typedef struct { + int a : 4; + int b : 5; + int c; +} D; + +// CIR-DAG: !rec_D = !cir.record +// LLVM-DAG: %struct.D = type { i16, i32 } +// OGCG-DAG: %struct.D = type { i16, i32 } + +typedef struct { + int a : 4; + int b : 27; + int c : 17; + int d : 2; + int e : 15; + unsigned f; // type other than int above, not a bitfield +} S; +// CIR-DAG: !rec_S = !cir.record +// LLVM-DAG: %struct.S = type { i64, i16, i32 } +// OGCG-DAG: %struct.S = type { i64, i16, i32 } + +typedef struct { + int a : 3; // one bitfield with size < 8 + unsigned b; +} T; + +// CIR-DAG: !rec_T = !cir.record +// LLVM-DAG: %struct.T = type { i8, i32 } +// OGCG-DAG: %struct.T = type { i8, i32 } + +typedef struct { + char a; + char b; + char c; + + // startOffset 24 bits, new storage from here + int d: 2; + int e: 2; + int f: 4; + int g: 25; + int h: 3; + int i: 4; + int j: 3; + int k: 8; + + int l: 14; +} U; + +// CIR-DAG: !rec_U = !cir.record +// LLVM-DAG: %struct.U = type <{ i8, i8, i8, i8, i64 }> +// OGCG-DAG: %struct.U = type <{ i8, i8, i8, i8, i64 }> + +void def() { + A a; + D d; + S s; + T t; + U u; +} diff --git a/external/llvm-project/clang/test/CIR/CodeGen/bitfields.cpp b/external/llvm-project/clang/test/CIR/CodeGen/bitfields.cpp new file mode 100644 index 000000000000..762d24988474 --- /dev/null +++ b/external/llvm-project/clang/test/CIR/CodeGen/bitfields.cpp @@ -0,0 +1,32 @@ +// RUN: %clang_cc1 -std=c++17 -triple x86_64-unknown-linux-gnu -fclangir -emit-cir %s -o %t.cir +// RUN: FileCheck --input-file=%t.cir %s --check-prefix=CIR +// RUN: %clang_cc1 -std=c++17 -triple x86_64-unknown-linux-gnu -fclangir -emit-llvm %s -o %t-cir.ll +// RUN: FileCheck --input-file=%t-cir.ll %s --check-prefix=LLVM +// RUN: %clang_cc1 -std=c++17 -triple x86_64-unknown-linux-gnu -emit-llvm %s -o %t.ll +// RUN: FileCheck --input-file=%t.ll %s --check-prefix=OGCG + +typedef struct { + int a : 4; + int b : 27; + int c : 17; + int d : 2; + int e : 15; + unsigned f; // type other than int above, not a bitfield +} S; +// CIR-DAG: !rec_S = !cir.record +// LLVM-DAG: %struct.S = type { i64, i16, i32 } +// OGCG-DAG: %struct.S = type { i64, i16, i32 } + +typedef struct { + int a : 3; // one bitfield with size < 8 + unsigned b; +} T; + +// CIR-DAG: !rec_T = !cir.record +// LLVM-DAG: %struct.T = type { i8, i32 } +// OGCG-DAG: %struct.T = type { i8, i32 } + +void def() { + S s; + T t; +} diff --git a/external/llvm-project/clang/test/CIR/CodeGen/bitfields_be.c b/external/llvm-project/clang/test/CIR/CodeGen/bitfields_be.c new file mode 100644 index 000000000000..149e9c9ac33f --- /dev/null +++ b/external/llvm-project/clang/test/CIR/CodeGen/bitfields_be.c @@ -0,0 +1,17 @@ +// RUN: %clang_cc1 -triple aarch64_be-unknown-linux-gnu -fclangir -emit-cir %s -o %t.cir +// RUN: FileCheck --input-file=%t.cir %s --check-prefix=CIR +// RUN: %clang_cc1 -triple aarch64_be-unknown-linux-gnu -fclangir -emit-llvm %s -o %t-cir.ll +// RUN: FileCheck --input-file=%t-cir.ll %s --check-prefix=LLVM +// RUN: %clang_cc1 -triple aarch64_be-unknown-linux-gnu -emit-llvm %s -o %t.ll +// RUN: FileCheck --input-file=%t.ll %s --check-prefix=OGCG + +typedef struct { + int a : 4; + int b : 11; + int c : 17; +} S; +S s; + +// CIR: !rec_S = !cir.record +// LLVM: %struct.S = type { i32 } +// OGCG: %struct.S = type { i32 } diff --git a/external/llvm-project/clang/test/CIR/CodeGen/builtin_call.cpp b/external/llvm-project/clang/test/CIR/CodeGen/builtin_call.cpp index 2706ea7f8f85..0a2226a2cc59 100644 --- a/external/llvm-project/clang/test/CIR/CodeGen/builtin_call.cpp +++ b/external/llvm-project/clang/test/CIR/CodeGen/builtin_call.cpp @@ -76,3 +76,37 @@ float constant_fp_builtin_single() { // OGCG: define {{.*}}float @_Z26constant_fp_builtin_singlev() // OGCG: ret float 0x3FB99999A0000000 // OGCG: } + +void library_builtins() { + __builtin_printf(nullptr); + __builtin_abort(); +} + +// CIR: cir.func @_Z16library_builtinsv() { +// CIR: %[[NULL:.+]] = cir.const #cir.ptr : !cir.ptr +// CIR: cir.call @printf(%[[NULL]]) : (!cir.ptr) -> !s32i +// CIR: cir.call @abort() : () -> () + +// LLVM: define void @_Z16library_builtinsv() +// LLVM: call i32 (ptr, ...) @printf(ptr null) +// LLVM: call void @abort() + +// OGCG: define dso_local void @_Z16library_builtinsv() +// OGCG: call i32 (ptr, ...) @printf(ptr noundef null) +// OGCG: call void @abort() + +void assume(bool arg) { + __builtin_assume(arg); +} + +// CIR: cir.func @_Z6assumeb +// CIR: cir.assume %{{.+}} : !cir.bool +// CIR: } + +// LLVM: define void @_Z6assumeb +// LLVM: call void @llvm.assume(i1 %{{.+}}) +// LLVM: } + +// OGCG: define {{.*}}void @_Z6assumeb +// OGCG: call void @llvm.assume(i1 %{{.+}}) +// OGCG: } diff --git a/external/llvm-project/clang/test/CIR/CodeGen/builtin_printf.cpp b/external/llvm-project/clang/test/CIR/CodeGen/builtin_printf.cpp new file mode 100644 index 000000000000..366e474c2b09 --- /dev/null +++ b/external/llvm-project/clang/test/CIR/CodeGen/builtin_printf.cpp @@ -0,0 +1,65 @@ +// RUN: %clang_cc1 -std=c++11 -triple x86_64-unknown-linux-gnu -Wno-unused-value -fclangir -emit-cir %s -o %t.cir +// RUN: FileCheck --input-file=%t.cir %s -check-prefix=CIR +// RUN: %clang_cc1 -std=c++11 -triple x86_64-unknown-linux-gnu -Wno-unused-value -fclangir -emit-llvm %s -o %t-cir.ll +// RUN: FileCheck --input-file=%t-cir.ll %s -check-prefix=LLVM +// RUN: %clang_cc1 -std=c++11 -triple x86_64-unknown-linux-gnu -Wno-unused-value -emit-llvm %s -o %t.ll +// RUN: FileCheck --input-file=%t.ll %s -check-prefix=OGCG + +// CIR: cir.global "private" cir_private dsolocal @".str" = #cir.const_array<"%s\00" : !cir.array> : !cir.array +// CIR: cir.global "private" cir_private dsolocal @".str.1" = #cir.const_array<"%s %d\0A\00" : !cir.array> : !cir.array +// LLVM: @.str = private global [3 x i8] c"%s\00" +// LLVM: @.str.1 = private global [7 x i8] c"%s %d\0A\00" +// OGCG: @.str = private unnamed_addr constant [3 x i8] c"%s\00" +// OGCG: @.str.1 = private unnamed_addr constant [7 x i8] c"%s %d\0A\00" + +void func(char const * const str, int i) { + __builtin_printf(nullptr); + __builtin_printf("%s", str); + __builtin_printf("%s %d\n", str, i); +} + +// CIR: cir.func @printf(!cir.ptr, ...) -> !s32i + +// CIR: cir.func @_Z4funcPKci(%[[arg0:.+]]: !cir.ptr{{.*}}, %[[arg1:.+]]: !s32i{{.*}}) { +// CIR: %[[str_ptr:.+]] = cir.alloca !cir.ptr, !cir.ptr>, ["str", init, const] +// CIR: %[[i_ptr:.+]] = cir.alloca !s32i, !cir.ptr, ["i", init] +// CIR: cir.store %[[arg0]], %[[str_ptr]] : !cir.ptr, !cir.ptr> +// CIR: cir.store %[[arg1]], %[[i_ptr]] : !s32i, !cir.ptr +// CIR: %[[null_ptr:.+]] = cir.const #cir.ptr : !cir.ptr +// CIR: %[[printf_result1:.+]] = cir.call @printf(%[[null_ptr]]) : (!cir.ptr) -> !s32i +// CIR: %[[str_fmt_global:.+]] = cir.get_global @".str" : !cir.ptr> +// CIR: %[[str_fmt_ptr:.+]] = cir.cast(array_to_ptrdecay, %[[str_fmt_global]] : !cir.ptr>), !cir.ptr +// CIR: %[[str_val:.+]] = cir.load{{.*}} %[[str_ptr]] : !cir.ptr>, !cir.ptr +// CIR: %[[printf_result2:.+]] = cir.call @printf(%[[str_fmt_ptr]], %[[str_val]]) : (!cir.ptr, !cir.ptr) -> !s32i +// CIR: %[[full_fmt_global:.+]] = cir.get_global @".str.1" : !cir.ptr> +// CIR: %[[full_fmt_ptr:.+]] = cir.cast(array_to_ptrdecay, %[[full_fmt_global]] : !cir.ptr>), !cir.ptr +// CIR: %[[str_val2:.+]] = cir.load{{.*}} %[[str_ptr]] : !cir.ptr>, !cir.ptr +// CIR: %[[i_val:.+]] = cir.load{{.*}} %[[i_ptr]] : !cir.ptr, !s32i +// CIR: %[[printf_result3:.+]] = cir.call @printf(%[[full_fmt_ptr]], %[[str_val2]], %[[i_val]]) : (!cir.ptr, !cir.ptr, !s32i) -> !s32i +// CIR: cir.return + +// LLVM: define void @_Z4funcPKci(ptr %[[arg0:.+]], i32 %[[arg1:.+]]) +// LLVM: %[[str_ptr:.+]] = alloca ptr +// LLVM: %[[i_ptr:.+]] = alloca i32 +// LLVM: store ptr %[[arg0]], ptr %[[str_ptr]]{{.*}} +// LLVM: store i32 %[[arg1]], ptr %[[i_ptr]]{{.*}} +// LLVM: %[[printf_result1:.+]] = call i32 (ptr, ...) @printf(ptr null) +// LLVM: %[[str_val:.+]] = load ptr, ptr %[[str_ptr]]{{.*}} +// LLVM: %[[printf_result2:.+]] = call i32 (ptr, ...) @printf(ptr @.str, ptr %[[str_val]]) +// LLVM: %[[str_val2:.+]] = load ptr, ptr %[[str_ptr]]{{.*}} +// LLVM: %[[i_val:.+]] = load i32, ptr %[[i_ptr]]{{.*}} +// LLVM: %[[printf_result3:.+]] = call i32 (ptr, ...) @printf(ptr @.str.1, ptr %[[str_val2]], i32 %[[i_val]]) +// LLVM: ret void + +// OGCG: define dso_local void @_Z4funcPKci(ptr noundef %[[arg0:.+]], i32 noundef %[[arg1:.+]]) +// OGCG: %[[str_ptr:.+]] = alloca ptr +// OGCG: %[[i_ptr:.+]] = alloca i32 +// OGCG: store ptr %[[arg0]], ptr %[[str_ptr]]{{.*}} +// OGCG: store i32 %[[arg1]], ptr %[[i_ptr]]{{.*}} +// OGCG: %[[printf_result1:.+]] = call i32 (ptr, ...) @printf(ptr noundef null) +// OGCG: %[[str_val:.+]] = load ptr, ptr %[[str_ptr]]{{.*}} +// OGCG: %[[printf_result2:.+]] = call i32 (ptr, ...) @printf(ptr noundef @.str, ptr noundef %[[str_val]]) +// OGCG: %[[str_val2:.+]] = load ptr, ptr %[[str_ptr]]{{.*}} +// OGCG: %[[i_val:.+]] = load i32, ptr %[[i_ptr]]{{.*}} +// OGCG: %[[printf_result3:.+]] = call i32 (ptr, ...) @printf(ptr noundef @.str.1, ptr noundef %[[str_val2]], i32 noundef %[[i_val]]) +// OGCG: ret void diff --git a/external/llvm-project/clang/test/CIR/CodeGen/call.c b/external/llvm-project/clang/test/CIR/CodeGen/call.c index 13f3c5a21ceb..f6aa41df7439 100644 --- a/external/llvm-project/clang/test/CIR/CodeGen/call.c +++ b/external/llvm-project/clang/test/CIR/CodeGen/call.c @@ -109,3 +109,29 @@ void f9() { // OGCG-NEXT: store i64 %[[RET]], ptr %[[SLOT]], align 4 // OGCG-NEXT: %[[ARG:.+]] = load i64, ptr %[[SLOT]], align 4 // OGCG-NEXT: call void @f1(i64 %[[ARG]]) + +__attribute__((pure)) int f10(int); +__attribute__((const)) int f11(int); +int f12(void) { + return f10(1) + f11(2); +} + +// CIR-LABEL: cir.func @f12() -> !s32i +// CIR: %[[A:.+]] = cir.const #cir.int<1> : !s32i +// CIR-NEXT: %{{.+}} = cir.call @f10(%[[A]]) side_effect(pure) : (!s32i) -> !s32i +// CIR-NEXT: %[[B:.+]] = cir.const #cir.int<2> : !s32i +// CIR-NEXT: %{{.+}} = cir.call @f11(%[[B]]) side_effect(const) : (!s32i) -> !s32i + +// LLVM-LABEL: define i32 @f12() +// LLVM: %{{.+}} = call i32 @f10(i32 1) #[[ATTR0:.+]] +// LLVM-NEXT: %{{.+}} = call i32 @f11(i32 2) #[[ATTR1:.+]] + +// OGCG-LABEL: define dso_local i32 @f12() +// OGCG: %{{.+}} = call i32 @f10(i32 noundef 1) #[[ATTR0:.+]] +// OGCG-NEXT: %{{.+}} = call i32 @f11(i32 noundef 2) #[[ATTR1:.+]] + +// LLVM: attributes #[[ATTR0]] = { nounwind willreturn memory(read, errnomem: none) } +// LLVM: attributes #[[ATTR1]] = { nounwind willreturn memory(none) } + +// OGCG: attributes #[[ATTR0]] = { nounwind willreturn memory(read) } +// OGCG: attributes #[[ATTR1]] = { nounwind willreturn memory(none) } diff --git a/external/llvm-project/clang/test/CIR/CodeGen/complex.cpp b/external/llvm-project/clang/test/CIR/CodeGen/complex.cpp index d193b9f32efb..cfeed345b4f1 100644 --- a/external/llvm-project/clang/test/CIR/CodeGen/complex.cpp +++ b/external/llvm-project/clang/test/CIR/CodeGen/complex.cpp @@ -176,3 +176,83 @@ void foo7() { // OGCG: store float %[[TMP_A]], ptr %[[C_REAL_PTR]], align 4 // OGCG: store float 2.000000e+00, ptr %[[C_IMAG_PTR]], align 4 +void foo8() { + double _Complex c = 2.00i; +} + +// CIR: %[[COMPLEX:.*]] = cir.const #cir.const_complex<#cir.fp<0.000000e+00> : !cir.double, #cir.fp<2.000000e+00> : !cir.double> : !cir.complex + +// LLVM: %[[COMPLEX:.*]] = alloca { double, double }, i64 1, align 8 +// LLVM: store { double, double } { double 0.000000e+00, double 2.000000e+00 }, ptr %[[COMPLEX]], align 8 + +// OGCG: %[[COMPLEX:.*]] = alloca { double, double }, align 8 +// OGCG: %[[C_REAL_PTR:.*]] = getelementptr inbounds nuw { double, double }, ptr %[[COMPLEX]], i32 0, i32 0 +// OGCG: %[[C_IMAG_PTR:.*]] = getelementptr inbounds nuw { double, double }, ptr %[[COMPLEX]], i32 0, i32 1 +// OGCG: store double 0.000000e+00, ptr %[[C_REAL_PTR]], align 8 +// OGCG: store double 2.000000e+00, ptr %[[C_IMAG_PTR]], align 8 + +void foo9(double a, double b) { + double _Complex c = __builtin_complex(a, b); +} + +// CIR: %[[INIT:.*]] = cir.alloca !cir.complex, !cir.ptr>, ["c", init] +// CIR: %[[TMP_A:.*]] = cir.load{{.*}} {{.*}} : !cir.ptr, !cir.double +// CIR: %[[TMP_B:.*]] = cir.load{{.*}} {{.*}} : !cir.ptr, !cir.double +// CIR: %[[COMPLEX:.*]] = cir.complex.create %[[TMP_A]], %[[TMP_B]] : !cir.double -> !cir.complex +// CIR: cir.store{{.*}} %[[COMPLEX]], %[[INIT]] : !cir.complex, !cir.ptr> + +// LLVM: %[[COMPLEX:.*]] = alloca { double, double }, i64 1, align 8 +// LLVM: %[[TMP_A:.*]] = load double, ptr {{.*}}, align 8 +// LLVM: %[[TMP_B:.*]] = load double, ptr {{.*}}, align 8 +// LLVM: %[[TMP:.*]] = insertvalue { double, double } undef, double %[[TMP_A]], 0 +// LLVM: %[[TMP_2:.*]] = insertvalue { double, double } %[[TMP]], double %[[TMP_B]], 1 +// LLVM: store { double, double } %[[TMP_2]], ptr %[[COMPLEX]], align 8 + +// OGCG: %[[COMPLEX]] = alloca { double, double }, align 8 +// OGCG: %[[TMP_A:.*]] = load double, ptr {{.*}}, align 8 +// OGCG: %[[TMP_B:.*]] = load double, ptr {{.*}}, align 8 +// OGCG: %[[C_REAL_PTR:.*]] = getelementptr inbounds nuw { double, double }, ptr %[[COMPLEX]], i32 0, i32 0 +// OGCG: %[[C_IMAG_PTR:.*]] = getelementptr inbounds nuw { double, double }, ptr %[[COMPLEX]], i32 0, i32 1 +// OGCG: store double %[[TMP_A]], ptr %[[C_REAL_PTR]], align 8 +// OGCG: store double %[[TMP_B]], ptr %[[C_IMAG_PTR]], align 8 + +void foo14() { + int _Complex c = 2i; +} + +// CIR: %[[COMPLEX:.*]] = cir.const #cir.const_complex<#cir.int<0> : !s32i, #cir.int<2> : !s32i> : !cir.complex + +// LLVM: %[[COMPLEX:.*]] = alloca { i32, i32 }, i64 1, align 4 +// LLVM: store { i32, i32 } { i32 0, i32 2 }, ptr %[[COMPLEX]], align 4 + +// OGCG: %[[COMPLEX:.*]] = alloca { i32, i32 }, align 4 +// OGCG: %[[C_REAL_PTR:.*]] = getelementptr inbounds nuw { i32, i32 }, ptr %[[COMPLEX]], i32 0, i32 0 +// OGCG: %[[C_IMAG_PTR:.*]] = getelementptr inbounds nuw { i32, i32 }, ptr %[[COMPLEX]], i32 0, i32 1 +// OGCG: store i32 0, ptr %[[C_REAL_PTR]], align 4 +// OGCG: store i32 2, ptr %[[C_IMAG_PTR]], align 4 + +void foo15() { + int _Complex a; + int _Complex b = a; +} + +// CIR: %[[COMPLEX_A:.*]] = cir.alloca !cir.complex, !cir.ptr>, ["a"] +// CIR: %[[COMPLEX_B:.*]] = cir.alloca !cir.complex, !cir.ptr>, ["b", init] +// CIR: %[[TMP_A:.*]] = cir.load{{.*}} %[[COMPLEX_A]] : !cir.ptr>, !cir.complex +// CIR: cir.store{{.*}} %[[TMP_A]], %[[COMPLEX_B]] : !cir.complex, !cir.ptr> + +// LLVM: %[[COMPLEX_A:.*]] = alloca { i32, i32 }, i64 1, align 4 +// LLVM: %[[COMPLEX_B:.*]] = alloca { i32, i32 }, i64 1, align 4 +// LLVM: %[[TMP_A:.*]] = load { i32, i32 }, ptr %[[COMPLEX_A]], align 4 +// LLVM: store { i32, i32 } %[[TMP_A]], ptr %[[COMPLEX_B]], align 4 + +// OGCG: %[[COMPLEX_A:.*]] = alloca { i32, i32 }, align 4 +// OGCG: %[[COMPLEX_B:.*]] = alloca { i32, i32 }, align 4 +// OGCG: %[[A_REAL_PTR:.*]] = getelementptr inbounds nuw { i32, i32 }, ptr %[[COMPLEX_A]], i32 0, i32 0 +// OGCG: %[[A_REAL:.*]] = load i32, ptr %[[A_REAL_PTR]], align 4 +// OGCG: %[[A_IMAG_PTR:.*]] = getelementptr inbounds nuw { i32, i32 }, ptr %[[COMPLEX_A]], i32 0, i32 1 +// OGCG: %[[A_IMAG:.*]] = load i32, ptr %[[A_IMAG_PTR]], align 4 +// OGCG: %[[B_REAL_PTR:.*]] = getelementptr inbounds nuw { i32, i32 }, ptr %[[COMPLEX_B]], i32 0, i32 0 +// OGCG: %[[B_IMAG_PTR:.*]] = getelementptr inbounds nuw { i32, i32 }, ptr %[[COMPLEX_B]], i32 0, i32 1 +// OGCG: store i32 %[[A_REAL]], ptr %[[B_REAL_PTR]], align 4 +// OGCG: store i32 %[[A_IMAG]], ptr %[[B_IMAG_PTR]], align 4 diff --git a/external/llvm-project/clang/test/CIR/CodeGen/dumb-record.cpp b/external/llvm-project/clang/test/CIR/CodeGen/dumb-record.cpp new file mode 100644 index 000000000000..5e8c584ddddd --- /dev/null +++ b/external/llvm-project/clang/test/CIR/CodeGen/dumb-record.cpp @@ -0,0 +1,41 @@ +// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir -emit-cir -fdump-record-layouts %s -o - | FileCheck %s + +struct SimpleStruct { + int a; + float b; +} simple; +// CHECK: Layout: , !cir.float}> +// CHECK: NonVirtualBaseCIRType:!cir.record, !cir.float}> +// CHECK: IsZeroInitializable:1 +// CHECK: BitFields:[ +// CHECK: ]> + +struct Empty { +} empty; + +// CHECK: Layout: }> +// CHECK: NonVirtualBaseCIRType:!cir.record}> +// CHECK: IsZeroInitializable:1 +// CHECK: BitFields:[ +// CHECK: ]> + +struct BitfieldsInOrder { + char a; + unsigned bit: 8; + unsigned should : 20; + unsigned have: 3; + unsigned order: 1; +} bitfield_order; + +// CHECK: Layout: , !cir.int, !cir.int}> +// CHECK: NonVirtualBaseCIRType:!cir.record, !cir.int, !cir.int}> +// CHECK: IsZeroInitializable:1 +// CHECK: BitFields:[ +// CHECK-NEXT: +// CHECK-NEXT: +// CHECK-NEXT: +// CHECK-NEXT: +// CHECK:]> diff --git a/external/llvm-project/clang/test/CIR/CodeGen/string-literals.c b/external/llvm-project/clang/test/CIR/CodeGen/string-literals.c index 00f59b09400c..90ea21906f36 100644 --- a/external/llvm-project/clang/test/CIR/CodeGen/string-literals.c +++ b/external/llvm-project/clang/test/CIR/CodeGen/string-literals.c @@ -5,6 +5,18 @@ // RUN: %clang_cc1 -triple aarch64-none-linux-android21 -emit-llvm %s -o %t.ll // RUN: FileCheck --check-prefix=OGCG --input-file=%t.ll %s +char g_str[] = "1234"; + +// CIR: cir.global external @g_str = #cir.const_array<"1234\00" : !cir.array> : !cir.array + +char g_oversized[100] = "123"; + +// CIR: cir.global external @g_oversized = #cir.const_array<"123" : !cir.array, trailing_zeros> : !cir.array + +char g_exact[4] = "123"; + +// CIR: cir.global external @g_exact = #cir.const_array<"123\00" : !cir.array> : !cir.array + // CIR: cir.global "private" cir_private dsolocal @[[STR1_GLOBAL:.*]] = #cir.const_array<"1\00" : !cir.array> : !cir.array // CIR: cir.global "private" cir_private dsolocal @[[STR2_GLOBAL:.*]] = #cir.zero : !cir.array // CIR: cir.global "private" cir_private dsolocal @[[STR3_GLOBAL:.*]] = #cir.zero : !cir.array diff --git a/external/llvm-project/clang/test/CIR/CodeGen/string-literals.cpp b/external/llvm-project/clang/test/CIR/CodeGen/string-literals.cpp new file mode 100644 index 000000000000..c56eb7438732 --- /dev/null +++ b/external/llvm-project/clang/test/CIR/CodeGen/string-literals.cpp @@ -0,0 +1,23 @@ +// RUN: %clang_cc1 -triple aarch64-none-linux-android21 -fclangir -emit-cir %s -o %t.cir +// RUN: FileCheck --check-prefix=CIR --input-file=%t.cir %s +// RUN: %clang_cc1 -triple aarch64-none-linux-android21 -fclangir -emit-llvm %s -o %t-cir.ll +// RUN: FileCheck --check-prefix=LLVM --input-file=%t-cir.ll %s +// RUN: %clang_cc1 -triple aarch64-none-linux-android21 -emit-llvm %s -o %t.ll +// RUN: FileCheck --check-prefix=OGCG --input-file=%t.ll %s + +// CIR: cir.global "private" cir_private dsolocal @[[STR1_GLOBAL:.*]] = #cir.const_array<"abcd\00" : !cir.array> : !cir.array + +// LLVM: @[[STR1_GLOBAL:.*]] = private global [5 x i8] c"abcd\00" + +// OGCG: @[[STR1_GLOBAL:.*]] = private unnamed_addr constant [5 x i8] c"abcd\00" + +decltype(auto) returns_literal() { + return "abcd"; +} + +// CIR: cir.func{{.*}} @_Z15returns_literalv() -> !cir.ptr> +// CIR: %[[RET_ADDR:.*]] = cir.alloca !cir.ptr>, !cir.ptr>>, ["__retval"] +// CIR: %[[STR_ADDR:.*]] = cir.get_global @[[STR1_GLOBAL]] : !cir.ptr> +// CIR: cir.store{{.*}} %[[STR_ADDR]], %[[RET_ADDR]] +// CIR: %[[RET:.*]] = cir.load %[[RET_ADDR]] +// CIR: cir.return %[[RET]] diff --git a/external/llvm-project/clang/test/CIR/CodeGen/struct.c b/external/llvm-project/clang/test/CIR/CodeGen/struct.c index ed84edd97e5d..b722b64eeb58 100644 --- a/external/llvm-project/clang/test/CIR/CodeGen/struct.c +++ b/external/llvm-project/clang/test/CIR/CodeGen/struct.c @@ -19,6 +19,7 @@ // CIR-DAG: !rec_CycleEnd = !cir.record>}>>}>>}> // CIR-DAG: !rec_CycleMiddle = !cir.record}> // CIR-DAG: !rec_CycleStart = !cir.record}> +// CIR-DAG: !rec_IncompleteArray = !cir.record}> // LLVM-DAG: %struct.CompleteS = type { i32, i8 } // LLVM-DAG: %struct.OuterS = type { %struct.InnerS, i32 } // LLVM-DAG: %struct.InnerS = type { i32, i8 } @@ -30,6 +31,7 @@ // LLVM-DAG: %struct.CycleStart = type { ptr } // LLVM-DAG: %struct.CycleMiddle = type { ptr } // LLVM-DAG: %struct.CycleEnd = type { ptr } +// LLVM-DAG: %struct.IncompleteArray = type { [0 x i32] } // OGCG-DAG: %struct.CompleteS = type { i32, i8 } // OGCG-DAG: %struct.OuterS = type { %struct.InnerS, i32 } // OGCG-DAG: %struct.InnerS = type { i32, i8 } @@ -41,6 +43,7 @@ // OGCG-DAG: %struct.CycleStart = type { ptr } // OGCG-DAG: %struct.CycleMiddle = type { ptr } // OGCG-DAG: %struct.CycleEnd = type { ptr } +// OGCG-DAG: %struct.IncompleteArray = type { [0 x i32] } struct CompleteS { int a; @@ -149,6 +152,16 @@ struct CycleEnd { // LLVM-DAG: @end = global %struct.CycleEnd zeroinitializer // OGCG-DAG: @end = global %struct.CycleEnd zeroinitializer +struct IncompleteArray { + int array[]; +} incomplete; + +// CIR: cir.global external @incomplete = #cir.zero : !rec_IncompleteArray + +// LLVM-DAG: global %struct.IncompleteArray zeroinitializer + +// OGCG-DAG: global %struct.IncompleteArray zeroinitializer + void f(void) { struct IncompleteS *p; } @@ -313,3 +326,4 @@ void f6(struct CycleStart *start) { // OGCG: %[[MIDDLE:.*]] = getelementptr inbounds nuw %struct.CycleStart, ptr %{{.*}}, i32 0, i32 0 // OGCG: %[[END:.*]] = getelementptr inbounds nuw %struct.CycleMiddle, ptr %{{.*}}, i32 0, i32 0 // OGCG: %[[START2:.*]] = getelementptr inbounds nuw %struct.CycleEnd, ptr %{{.*}}, i32 0, i32 0 + diff --git a/external/llvm-project/clang/test/CIR/IR/call.cir b/external/llvm-project/clang/test/CIR/IR/call.cir index e35c201b6ed4..5f0916775479 100644 --- a/external/llvm-project/clang/test/CIR/IR/call.cir +++ b/external/llvm-project/clang/test/CIR/IR/call.cir @@ -8,11 +8,15 @@ cir.func @f1() cir.func @f2() { cir.call @f1() : () -> () + cir.call @f1() side_effect(pure) : () -> () + cir.call @f1() side_effect(const) : () -> () cir.return } // CHECK: cir.func @f2() { // CHECK-NEXT: cir.call @f1() : () -> () +// CHECK-NEXT: cir.call @f1() side_effect(pure) : () -> () +// CHECK-NEXT: cir.call @f1() side_effect(const) : () -> () // CHECK-NEXT: cir.return // CHECK-NEXT: } diff --git a/external/llvm-project/clang/test/CIR/Transforms/vector-cmp-fold.cir b/external/llvm-project/clang/test/CIR/Transforms/vector-cmp-fold.cir new file mode 100644 index 000000000000..b207fc08748e --- /dev/null +++ b/external/llvm-project/clang/test/CIR/Transforms/vector-cmp-fold.cir @@ -0,0 +1,227 @@ +// RUN: cir-opt %s -cir-canonicalize -o - -split-input-file | FileCheck %s + +!s32i = !cir.int + +module { + cir.func @fold_cmp_vector_op_test() -> !cir.vector<4 x !s32i> { + %vec_1 = cir.const #cir.const_vector<[#cir.int<1> : !s32i, #cir.int<3> : !s32i, #cir.int<5> : !s32i, #cir.int<7> : !s32i]> : !cir.vector<4 x !s32i> + %vec_2 = cir.const #cir.const_vector<[#cir.int<2> : !s32i, #cir.int<4> : !s32i, #cir.int<6> : !s32i, #cir.int<8> : !s32i]> : !cir.vector<4 x !s32i> + %new_vec = cir.vec.cmp(eq, %vec_1, %vec_2) : !cir.vector<4 x !s32i>, !cir.vector<4 x !s32i> + cir.return %new_vec : !cir.vector<4 x !s32i> + } + + // CHECK: cir.func @fold_cmp_vector_op_test() -> !cir.vector<4 x !s32i> { + // CHECK-NEXT: %[[RES:.*]] = cir.const #cir.const_vector<[#cir.int<0> : !s32i, #cir.int<0> : !s32i, + // CHECK-SAME: #cir.int<0> : !s32i, #cir.int<0> : !s32i]> : !cir.vector<4 x !s32i> + // CHECK-NEXT: cir.return %[[RES]] : !cir.vector<4 x !s32i> +} + +// ----- + +!s32i = !cir.int + +module { + cir.func @fold_cmp_vector_op_test() -> !cir.vector<4 x !s32i> { + %vec_1 = cir.const #cir.const_vector<[#cir.int<1> : !s32i, #cir.int<3> : !s32i, #cir.int<5> : !s32i, #cir.int<7> : !s32i]> : !cir.vector<4 x !s32i> + %vec_2 = cir.const #cir.const_vector<[#cir.int<2> : !s32i, #cir.int<4> : !s32i, #cir.int<6> : !s32i, #cir.int<8> : !s32i]> : !cir.vector<4 x !s32i> + %new_vec = cir.vec.cmp(ne, %vec_1, %vec_2) : !cir.vector<4 x !s32i>, !cir.vector<4 x !s32i> + cir.return %new_vec : !cir.vector<4 x !s32i> + } + + // CHECK: cir.func @fold_cmp_vector_op_test() -> !cir.vector<4 x !s32i> { + // CHECK-NEXT: %[[RES:.*]] = cir.const #cir.const_vector<[#cir.int<1> : !s32i, #cir.int<1> : !s32i, + // CHECK-SAME: #cir.int<1> : !s32i, #cir.int<1> : !s32i]> : !cir.vector<4 x !s32i> + // CHECK-NEXT: cir.return %[[RES]] : !cir.vector<4 x !s32i> +} + +// ----- + +!s32i = !cir.int + +module { + cir.func @fold_cmp_vector_op_test() -> !cir.vector<4 x !s32i> { + %vec_1 = cir.const #cir.const_vector<[#cir.int<1> : !s32i, #cir.int<3> : !s32i, #cir.int<5> : !s32i, #cir.int<7> : !s32i]> : !cir.vector<4 x !s32i> + %vec_2 = cir.const #cir.const_vector<[#cir.int<2> : !s32i, #cir.int<4> : !s32i, #cir.int<6> : !s32i, #cir.int<8> : !s32i]> : !cir.vector<4 x !s32i> + %new_vec = cir.vec.cmp(lt, %vec_1, %vec_2) : !cir.vector<4 x !s32i>, !cir.vector<4 x !s32i> + cir.return %new_vec : !cir.vector<4 x !s32i> + } + + // CHECK: cir.func @fold_cmp_vector_op_test() -> !cir.vector<4 x !s32i> { + // CHECK-NEXT: %[[RES:.*]] = cir.const #cir.const_vector<[#cir.int<1> : !s32i, #cir.int<1> : !s32i, + // CHECK-SAME: #cir.int<1> : !s32i, #cir.int<1> : !s32i]> : !cir.vector<4 x !s32i> + // CHECK-NEXT: cir.return %[[RES]] : !cir.vector<4 x !s32i> +} + +// ----- + +!s32i = !cir.int + +module { + cir.func @fold_cmp_vector_op_test() -> !cir.vector<4 x !s32i> { + %vec_1 = cir.const #cir.const_vector<[#cir.int<1> : !s32i, #cir.int<3> : !s32i, #cir.int<5> : !s32i, #cir.int<7> : !s32i]> : !cir.vector<4 x !s32i> + %vec_2 = cir.const #cir.const_vector<[#cir.int<2> : !s32i, #cir.int<4> : !s32i, #cir.int<6> : !s32i, #cir.int<8> : !s32i]> : !cir.vector<4 x !s32i> + %new_vec = cir.vec.cmp(le, %vec_1, %vec_2) : !cir.vector<4 x !s32i>, !cir.vector<4 x !s32i> + cir.return %new_vec : !cir.vector<4 x !s32i> + } + + // CHECK: cir.func @fold_cmp_vector_op_test() -> !cir.vector<4 x !s32i> { + // CHECK-NEXT: %[[RES:.*]] = cir.const #cir.const_vector<[#cir.int<1> : !s32i, #cir.int<1> : !s32i, + // CHECK-SAME: #cir.int<1> : !s32i, #cir.int<1> : !s32i]> : !cir.vector<4 x !s32i> + // CHECK-NEXT: cir.return %[[RES]] : !cir.vector<4 x !s32i> +} + +// ----- + +!s32i = !cir.int + +module { + cir.func @fold_cmp_vector_op_test() -> !cir.vector<4 x !s32i> { + %vec_1 = cir.const #cir.const_vector<[#cir.int<1> : !s32i, #cir.int<3> : !s32i, #cir.int<5> : !s32i, #cir.int<7> : !s32i]> : !cir.vector<4 x !s32i> + %vec_2 = cir.const #cir.const_vector<[#cir.int<2> : !s32i, #cir.int<4> : !s32i, #cir.int<6> : !s32i, #cir.int<8> : !s32i]> : !cir.vector<4 x !s32i> + %new_vec = cir.vec.cmp(gt, %vec_1, %vec_2) : !cir.vector<4 x !s32i>, !cir.vector<4 x !s32i> + cir.return %new_vec : !cir.vector<4 x !s32i> + } + + // CHECK: cir.func @fold_cmp_vector_op_test() -> !cir.vector<4 x !s32i> { + // CHECK-NEXT: %[[RES:.*]] = cir.const #cir.const_vector<[#cir.int<0> : !s32i, #cir.int<0> : !s32i, + // CHECK-SAME: #cir.int<0> : !s32i, #cir.int<0> : !s32i]> : !cir.vector<4 x !s32i> + // CHECK-NEXT: cir.return %[[RES]] : !cir.vector<4 x !s32i> +} + +// ----- + +!s32i = !cir.int + +module { + cir.func @fold_cmp_vector_op_test() -> !cir.vector<4 x !s32i> { + %vec_1 = cir.const #cir.const_vector<[#cir.int<1> : !s32i, #cir.int<3> : !s32i, #cir.int<5> : !s32i, #cir.int<7> : !s32i]> : !cir.vector<4 x !s32i> + %vec_2 = cir.const #cir.const_vector<[#cir.int<2> : !s32i, #cir.int<4> : !s32i, #cir.int<6> : !s32i, #cir.int<8> : !s32i]> : !cir.vector<4 x !s32i> + %new_vec = cir.vec.cmp(gt, %vec_1, %vec_2) : !cir.vector<4 x !s32i>, !cir.vector<4 x !s32i> + cir.return %new_vec : !cir.vector<4 x !s32i> + } + + // CHECK: cir.func @fold_cmp_vector_op_test() -> !cir.vector<4 x !s32i> { + // CHECK-NEXT: %[[RES:.*]] = cir.const #cir.const_vector<[#cir.int<0> : !s32i, #cir.int<0> : !s32i, + // CHECK-SAME: #cir.int<0> : !s32i, #cir.int<0> : !s32i]> : !cir.vector<4 x !s32i> + // CHECK-NEXT: cir.return %[[RES]] : !cir.vector<4 x !s32i> +} + +// ----- + +!s32i = !cir.int + +module { + cir.func @fold_cmp_vector_op_test() -> !cir.vector<4 x !s32i> { + %vec_1 = cir.const #cir.const_vector<[#cir.fp<1.000000e+00> : !cir.float, #cir.fp<2.000000e+00> + : !cir.float, #cir.fp<3.000000e+00> : !cir.float, #cir.fp<4.000000e+00> : !cir.float]> : !cir.vector<4 x !cir.float> + %vec_2 = cir.const #cir.const_vector<[#cir.fp<5.000000e+00> : !cir.float, #cir.fp<6.000000e+00> + : !cir.float, #cir.fp<7.000000e+00> : !cir.float, #cir.fp<8.000000e+00> : !cir.float]> : !cir.vector<4 x !cir.float> + %new_vec = cir.vec.cmp(eq, %vec_1, %vec_2) : !cir.vector<4 x !cir.float>, !cir.vector<4 x !s32i> + cir.return %new_vec : !cir.vector<4 x !s32i> + } + + // CHECK: cir.func @fold_cmp_vector_op_test() -> !cir.vector<4 x !s32i> { + // CHECK-NEXT: %[[RES:.*]] = cir.const #cir.const_vector<[#cir.int<0> : !s32i, #cir.int<0> : !s32i, + // CHECK-SAME: #cir.int<0> : !s32i, #cir.int<0> : !s32i]> : !cir.vector<4 x !s32i> + // CHECK-NEXT: cir.return %[[RES]] : !cir.vector<4 x !s32i> +} + +// ----- + +!s32i = !cir.int + +module { + cir.func @fold_cmp_vector_op_test() -> !cir.vector<4 x !s32i> { + %vec_1 = cir.const #cir.const_vector<[#cir.fp<1.000000e+00> : !cir.float, #cir.fp<2.000000e+00> + : !cir.float, #cir.fp<3.000000e+00> : !cir.float, #cir.fp<4.000000e+00> : !cir.float]> : !cir.vector<4 x !cir.float> + %vec_2 = cir.const #cir.const_vector<[#cir.fp<5.000000e+00> : !cir.float, #cir.fp<6.000000e+00> + : !cir.float, #cir.fp<7.000000e+00> : !cir.float, #cir.fp<8.000000e+00> : !cir.float]> : !cir.vector<4 x !cir.float> + %new_vec = cir.vec.cmp(ne, %vec_1, %vec_2) : !cir.vector<4 x !cir.float>, !cir.vector<4 x !s32i> + cir.return %new_vec : !cir.vector<4 x !s32i> + } + + // CHECK: cir.func @fold_cmp_vector_op_test() -> !cir.vector<4 x !s32i> { + // CHECK-NEXT: %[[RES:.*]] = cir.const #cir.const_vector<[#cir.int<1> : !s32i, #cir.int<1> : !s32i, + // CHECK-SAME: #cir.int<1> : !s32i, #cir.int<1> : !s32i]> : !cir.vector<4 x !s32i> + // CHECK-NEXT: cir.return %[[RES]] : !cir.vector<4 x !s32i> +} + +// ----- + +!s32i = !cir.int + +module { + cir.func @fold_cmp_vector_op_test() -> !cir.vector<4 x !s32i> { + %vec_1 = cir.const #cir.const_vector<[#cir.fp<1.000000e+00> : !cir.float, #cir.fp<2.000000e+00> + : !cir.float, #cir.fp<3.000000e+00> : !cir.float, #cir.fp<4.000000e+00> : !cir.float]> : !cir.vector<4 x !cir.float> + %vec_2 = cir.const #cir.const_vector<[#cir.fp<5.000000e+00> : !cir.float, #cir.fp<6.000000e+00> + : !cir.float, #cir.fp<7.000000e+00> : !cir.float, #cir.fp<8.000000e+00> : !cir.float]> : !cir.vector<4 x !cir.float> + %new_vec = cir.vec.cmp(lt, %vec_1, %vec_2) : !cir.vector<4 x !cir.float>, !cir.vector<4 x !s32i> + cir.return %new_vec : !cir.vector<4 x !s32i> + } + + // CHECK: cir.func @fold_cmp_vector_op_test() -> !cir.vector<4 x !s32i> { + // CHECK-NEXT: %[[RES:.*]] = cir.const #cir.const_vector<[#cir.int<1> : !s32i, #cir.int<1> : !s32i, + // CHECK-SAME: #cir.int<1> : !s32i, #cir.int<1> : !s32i]> : !cir.vector<4 x !s32i> + // CHECK-NEXT: cir.return %[[RES]] : !cir.vector<4 x !s32i> +} + +// ----- + +!s32i = !cir.int + +module { + cir.func @fold_cmp_vector_op_test() -> !cir.vector<4 x !s32i> { + %vec_1 = cir.const #cir.const_vector<[#cir.fp<1.000000e+00> : !cir.float, #cir.fp<2.000000e+00> + : !cir.float, #cir.fp<3.000000e+00> : !cir.float, #cir.fp<4.000000e+00> : !cir.float]> : !cir.vector<4 x !cir.float> + %vec_2 = cir.const #cir.const_vector<[#cir.fp<5.000000e+00> : !cir.float, #cir.fp<6.000000e+00> + : !cir.float, #cir.fp<7.000000e+00> : !cir.float, #cir.fp<8.000000e+00> : !cir.float]> : !cir.vector<4 x !cir.float> + %new_vec = cir.vec.cmp(le, %vec_1, %vec_2) : !cir.vector<4 x !cir.float>, !cir.vector<4 x !s32i> + cir.return %new_vec : !cir.vector<4 x !s32i> + } + + // CHECK: cir.func @fold_cmp_vector_op_test() -> !cir.vector<4 x !s32i> { + // CHECK-NEXT: %[[RES:.*]] = cir.const #cir.const_vector<[#cir.int<1> : !s32i, #cir.int<1> : !s32i, + // CHECK-SAME: #cir.int<1> : !s32i, #cir.int<1> : !s32i]> : !cir.vector<4 x !s32i> + // CHECK-NEXT: cir.return %[[RES]] : !cir.vector<4 x !s32i> +} + +// ----- + +!s32i = !cir.int + +module { + cir.func @fold_cmp_vector_op_test() -> !cir.vector<4 x !s32i> { + %vec_1 = cir.const #cir.const_vector<[#cir.fp<1.000000e+00> : !cir.float, #cir.fp<2.000000e+00> + : !cir.float, #cir.fp<3.000000e+00> : !cir.float, #cir.fp<4.000000e+00> : !cir.float]> : !cir.vector<4 x !cir.float> + %vec_2 = cir.const #cir.const_vector<[#cir.fp<5.000000e+00> : !cir.float, #cir.fp<6.000000e+00> + : !cir.float, #cir.fp<7.000000e+00> : !cir.float, #cir.fp<8.000000e+00> : !cir.float]> : !cir.vector<4 x !cir.float> + %new_vec = cir.vec.cmp(gt, %vec_1, %vec_2) : !cir.vector<4 x !cir.float>, !cir.vector<4 x !s32i> + cir.return %new_vec : !cir.vector<4 x !s32i> + } + + // CHECK: cir.func @fold_cmp_vector_op_test() -> !cir.vector<4 x !s32i> { + // CHECK-NEXT: %[[RES:.*]] = cir.const #cir.const_vector<[#cir.int<0> : !s32i, #cir.int<0> : !s32i, + // CHECK-SAME: #cir.int<0> : !s32i, #cir.int<0> : !s32i]> : !cir.vector<4 x !s32i> + // CHECK-NEXT: cir.return %[[RES]] : !cir.vector<4 x !s32i> +} + +// ----- + +!s32i = !cir.int + +module { + cir.func @fold_cmp_vector_op_test() -> !cir.vector<4 x !s32i> { + %vec_1 = cir.const #cir.const_vector<[#cir.fp<1.000000e+00> : !cir.float, #cir.fp<2.000000e+00> + : !cir.float, #cir.fp<3.000000e+00> : !cir.float, #cir.fp<4.000000e+00> : !cir.float]> : !cir.vector<4 x !cir.float> + %vec_2 = cir.const #cir.const_vector<[#cir.fp<5.000000e+00> : !cir.float, #cir.fp<6.000000e+00> + : !cir.float, #cir.fp<7.000000e+00> : !cir.float, #cir.fp<8.000000e+00> : !cir.float]> : !cir.vector<4 x !cir.float> + %new_vec = cir.vec.cmp(ge, %vec_1, %vec_2) : !cir.vector<4 x !cir.float>, !cir.vector<4 x !s32i> + cir.return %new_vec : !cir.vector<4 x !s32i> + } + + // CHECK: cir.func @fold_cmp_vector_op_test() -> !cir.vector<4 x !s32i> { + // CHECK-NEXT: %[[RES:.*]] = cir.const #cir.const_vector<[#cir.int<0> : !s32i, #cir.int<0> : !s32i, + // CHECK-SAME: #cir.int<0> : !s32i, #cir.int<0> : !s32i]> : !cir.vector<4 x !s32i> + // CHECK-NEXT: cir.return %[[RES]] : !cir.vector<4 x !s32i> +} diff --git a/external/llvm-project/clang/test/CIR/Transforms/vector-splat.cir b/external/llvm-project/clang/test/CIR/Transforms/vector-splat.cir new file mode 100644 index 000000000000..e2274b8627b1 --- /dev/null +++ b/external/llvm-project/clang/test/CIR/Transforms/vector-splat.cir @@ -0,0 +1,16 @@ +// RUN: cir-opt %s -cir-simplify -o - | FileCheck %s + +!s32i = !cir.int + +module { + cir.func @fold_shuffle_vector_op_test() -> !cir.vector<4 x !s32i> { + %v = cir.const #cir.int<3> : !s32i + %vec = cir.vec.splat %v : !s32i, !cir.vector<4 x !s32i> + cir.return %vec : !cir.vector<4 x !s32i> + } + + // CHECK: cir.func @fold_shuffle_vector_op_test() -> !cir.vector<4 x !s32i> { + // CHECK-NEXT: %0 = cir.const #cir.const_vector<[#cir.int<3> : !s32i, #cir.int<3> : !s32i, + // CHECK-SAME: #cir.int<3> : !s32i, #cir.int<3> : !s32i]> : !cir.vector<4 x !s32i> + // CHECK-NEXT: cir.return %0 : !cir.vector<4 x !s32i> +} diff --git a/external/llvm-project/clang/test/CXX/basic/basic.link/p1.cpp b/external/llvm-project/clang/test/CXX/basic/basic.link/p1.cpp index c6a119aa7f47..26a5f025f42f 100644 --- a/external/llvm-project/clang/test/CXX/basic/basic.link/p1.cpp +++ b/external/llvm-project/clang/test/CXX/basic/basic.link/p1.cpp @@ -1,57 +1,128 @@ -// RUN: %clang_cc1 -std=c++2a -verify %s -// RUN: %clang_cc1 -std=c++2a -verify -DNO_GLOBAL_FRAG %s -// RUN: %clang_cc1 -std=c++2a -verify -DNO_MODULE_DECL %s -// RUN: %clang_cc1 -std=c++2a -verify -DNO_PRIVATE_FRAG %s -// RUN: %clang_cc1 -std=c++2a -verify -DNO_MODULE_DECL -DNO_PRIVATE_FRAG %s -// RUN: %clang_cc1 -std=c++2a -verify -DNO_GLOBAL_FRAG -DNO_PRIVATE_FRAG %s -// RUN: %clang_cc1 -std=c++2a -verify -DNO_GLOBAL_FRAG -DNO_MODULE_DECL %s -// RUN: %clang_cc1 -std=c++2a -verify -DNO_GLOBAL_FRAG -DNO_MODULE_DECL -DNO_PRIVATE_FRAG %s -// RUN: %clang_cc1 -std=c++2a -verify -DEXPORT_FRAGS %s - -#ifndef NO_GLOBAL_FRAG -#ifdef EXPORT_FRAGS -export // expected-error {{global module fragment cannot be exported}} -#endif +// RUN: rm -rf %t +// RUN: split-file %s %t + +// RUN: %clang_cc1 -std=c++2a -verify %t/M.cppm +// RUN: %clang_cc1 -std=c++2a -verify %t/NoGlobalFrag.cppm +// RUN: %clang_cc1 -std=c++2a -verify %t/NoModuleDecl.cppm +// RUN: %clang_cc1 -std=c++2a -verify %t/NoPrivateFrag.cppm +// RUN: %clang_cc1 -std=c++2a -verify %t/NoModuleDeclAndNoPrivateFrag.cppm +// RUN: %clang_cc1 -std=c++2a -verify %t/NoGlobalFragAndNoPrivateFrag.cppm +// RUN: %clang_cc1 -std=c++2a -verify %t/NoGlobalFragAndNoModuleDecl.cppm +// RUN: %clang_cc1 -std=c++2a -verify %t/NoGlobalFragAndNoModuleDeclAndNoPrivateFrag.cppm +// RUN: %clang_cc1 -std=c++2a -verify %t/ExportFrags.cppm + +//--- M.cppm module; -#ifdef NO_MODULE_DECL -// expected-error@-2 {{missing 'module' declaration at end of global module fragment introduced here}} -#endif -#endif +extern int a; // #a1 +export module Foo; + +int a; // expected-error {{declaration of 'a' in module Foo follows declaration in the global module}} + // expected-note@#a1 {{previous decl}} +extern int b; + +module; // expected-error {{'module;' introducing a global module fragment can appear only at the start of the translation unit}} +module :private; // #priv-frag +int b; // ok +module :private; // expected-error {{private module fragment redefined}} + // expected-note@#priv-frag {{previous definition is here}} + +//--- NoGlobalFrag.cppm + +extern int a; // #a1 +export module Foo; // expected-error {{module declaration must occur at the start of the translation unit}} + // expected-note@-2 {{add 'module;' to the start of the file to introduce a global module fragment}} + +// expected-error@#a2 {{declaration of 'a' in module Foo follows declaration in the global module}} +// expected-note@#a1 {{previous decl}} + +int a; // #a2 +extern int b; +module; // expected-error {{'module;' introducing a global module fragment can appear only at the start of the translation unit}} +module :private; // #priv-frag +int b; // ok +module :private; // expected-error {{private module fragment redefined}} +// expected-note@#priv-frag {{previous definition is here}} +//--- NoModuleDecl.cppm +module; // expected-error {{missing 'module' declaration at end of global module fragment introduced here}} extern int a; // #a1 +int a; // #a2 +extern int b; +module; // expected-error {{'module;' introducing a global module fragment can appear only at the start of the translation unit}} +module :private; // expected-error {{private module fragment declaration with no preceding module declaration}} +int b; // ok -#ifndef NO_MODULE_DECL +//--- NoPrivateFrag.cppm +module; +extern int a; // #a1 export module Foo; -#ifdef NO_GLOBAL_FRAG -// expected-error@-2 {{module declaration must occur at the start of the translation unit}} + +// expected-error@#a2 {{declaration of 'a' in module Foo follows declaration in the global module}} +// expected-note@#a1 {{previous decl}} +int a; // #a2 +extern int b; + +module; // expected-error {{'module;' introducing a global module fragment can appear only at the start of the translation unit}} +int b; // ok + + +//--- NoModuleDeclAndNoPrivateFrag.cppm +module; // expected-error {{missing 'module' declaration at end of global module fragment introduced here}} +extern int a; // #a1 +int a; // #a2 +extern int b; + +module; // expected-error {{'module;' introducing a global module fragment can appear only at the start of the translation unit}} + +int b; // ok + +//--- NoGlobalFragAndNoPrivateFrag.cppm +extern int a; // #a1 +export module Foo; // expected-error {{module declaration must occur at the start of the translation unit}} // expected-note@1 {{add 'module;' to the start of the file to introduce a global module fragment}} -#endif // expected-error@#a2 {{declaration of 'a' in module Foo follows declaration in the global module}} // expected-note@#a1 {{previous decl}} -#endif int a; // #a2 extern int b; module; // expected-error {{'module;' introducing a global module fragment can appear only at the start of the translation unit}} -#ifndef NO_PRIVATE_FRAG -#ifdef EXPORT_FRAGS -export // expected-error {{private module fragment cannot be exported}} -#endif +int b; // ok + +//--- NoGlobalFragAndNoModuleDecl.cppm +extern int a; // #a1 +int a; // #a2 +extern int b; +module; // expected-error {{'module;' introducing a global module fragment can appear only at the start of the translation unit}} module :private; // #priv-frag -#ifdef NO_MODULE_DECL -// expected-error@-2 {{private module fragment declaration with no preceding module declaration}} -#endif -#endif +// expected-error@-1 {{private module fragment declaration with no preceding module declaration}} +int b; // ok + +//--- NoGlobalFragAndNoModuleDeclAndNoPrivateFrag.cppm +extern int a; // #a1 +int a; // #a2 +extern int b; + +module; // expected-error {{'module;' introducing a global module fragment can appear only at the start of the translation unit}} int b; // ok +//--- ExportFrags.cppm +export module; // expected-error {{global module fragment cannot be exported}} +extern int a; // #a1 +export module Foo; +// expected-error@#a2 {{declaration of 'a' in module Foo follows declaration in the global module}} +// expected-note@#a1 {{previous decl}} -#ifndef NO_PRIVATE_FRAG -#ifndef NO_MODULE_DECL +int a; // #a2 +extern int b; + +module; // expected-error {{'module;' introducing a global module fragment can appear only at the start of the translation unit}} + +module :private; // #priv-frag + +int b; // ok module :private; // expected-error {{private module fragment redefined}} -// expected-note@#priv-frag {{previous definition is here}} -#endif -#endif + // expected-note@#priv-frag {{previous definition is here}} diff --git a/external/llvm-project/clang/test/CXX/basic/basic.link/p2.cpp b/external/llvm-project/clang/test/CXX/basic/basic.link/p2.cpp index ccad42022ee8..94cbc62490b2 100644 --- a/external/llvm-project/clang/test/CXX/basic/basic.link/p2.cpp +++ b/external/llvm-project/clang/test/CXX/basic/basic.link/p2.cpp @@ -1,16 +1,16 @@ -// RUN: %clang_cc1 -std=c++2a -DEXPORT %s -verify -// RUN: %clang_cc1 -std=c++2a -DEXPORT %s -emit-module-interface -o %t.pcm -// RUN: %clang_cc1 -std=c++2a -UEXPORT %s -verify -fmodule-file=M=%t.pcm +// RUN: rm -rf %t +// RUN: split-file %s %t + +// RUN: %clang_cc1 -std=c++2a %t/pmf_in_interface.cpp -verify +// RUN: %clang_cc1 -std=c++2a %t/pmf_in_interface.cpp -emit-module-interface -o %t.pcm +// RUN: %clang_cc1 -std=c++2a %t/pmf_in_implementation.cpp -verify -fmodule-file=M=%t.pcm -#ifdef EXPORT -// expected-no-diagnostics -export -#else -// expected-note@+2 {{add 'export' here}} -#endif -module M; -#ifndef EXPORT -// expected-error@+2 {{private module fragment in module implementation unit}} -#endif +//--- pmf_in_interface.cpp +// expected-no-diagnostics +export module M; module :private; + +//--- pmf_in_implementation.cpp +module M; // expected-note {{add 'export' here}} +module :private; // expected-error {{private module fragment in module implementation unit}} diff --git a/external/llvm-project/clang/test/CXX/basic/basic.scope/basic.scope.namespace/p2.cpp b/external/llvm-project/clang/test/CXX/basic/basic.scope/basic.scope.namespace/p2.cpp index d70eb7de22c6..fd0038b3f774 100644 --- a/external/llvm-project/clang/test/CXX/basic/basic.scope/basic.scope.namespace/p2.cpp +++ b/external/llvm-project/clang/test/CXX/basic/basic.scope/basic.scope.namespace/p2.cpp @@ -1,14 +1,16 @@ // RUN: rm -rf %t -// RUN: mkdir -p %t -// RUN: echo '#ifndef FOO_H' > %t/foo.h -// RUN: echo '#define FOO_H' >> %t/foo.h -// RUN: echo 'extern int in_header;' >> %t/foo.h -// RUN: echo '#endif' >> %t/foo.h -// RUN: %clang_cc1 -std=c++2a -I%t -emit-module-interface -DINTERFACE %s -o %t.pcm -// RUN: %clang_cc1 -std=c++2a -I%t -fmodule-file=A=%t.pcm -DIMPLEMENTATION %s -verify -fno-modules-error-recovery -// RUN: %clang_cc1 -std=c++2a -I%t -fmodule-file=A=%t.pcm %s -verify -fno-modules-error-recovery - -#ifdef INTERFACE +// RUN: split-file %s %t +// RUN: %clang_cc1 -std=c++2a -I%t -emit-module-interface %t/interface.cppm -o %t.pcm +// RUN: %clang_cc1 -std=c++2a -I%t -fmodule-file=A=%t.pcm %t/implA.cppm -verify -fno-modules-error-recovery +// RUN: %clang_cc1 -std=c++2a -I%t -fmodule-file=A=%t.pcm %t/implB.cppm -verify -fno-modules-error-recovery + +//--- foo.h +#ifndef FOO_H +#define FOO_H +extern int in_header; +#endif + +//--- interface.cppm module; #include "foo.h" // FIXME: The following need to be moved to a header file. The global module @@ -22,11 +24,9 @@ static int internal; module :private; int not_exported_private; static int internal_private; -#else -#ifdef IMPLEMENTATION +//--- implA.cppm module; -#endif void test_early() { in_header = 1; // expected-error {{use of undeclared identifier 'in_header'}} @@ -46,11 +46,7 @@ void test_early() { internal_private = 1; // expected-error {{undeclared identifier}} } -#ifdef IMPLEMENTATION module A; -#else -import A; -#endif void test_late() { in_header = 1; // expected-error {{missing '#include "foo.h"'; 'in_header' must be declared before it is used}} @@ -61,20 +57,54 @@ void test_late() { exported = 1; not_exported = 1; -#ifndef IMPLEMENTATION - // expected-error@-2 {{use of undeclared identifier 'not_exported'; did you mean 'exported'?}} - // expected-note@p2.cpp:18 {{'exported' declared here}} -#endif internal = 1; // expected-error {{use of undeclared identifier 'internal'}} not_exported_private = 1; -#ifndef IMPLEMENTATION - // FIXME: should not be visible here - // expected-error@-3 {{undeclared identifier}} -#endif internal_private = 1; // expected-error {{use of undeclared identifier 'internal_private'}} } -#endif +//--- implB.cppm +module; + +void test_early() { + in_header = 1; // expected-error {{use of undeclared identifier 'in_header'}} + // expected-note@* {{not visible}} + + global_module_fragment = 1; // expected-error {{use of undeclared identifier 'global_module_fragment'}} + + exported = 1; // expected-error {{use of undeclared identifier 'exported'}} + + not_exported = 1; // expected-error {{use of undeclared identifier 'not_exported'}} + + // FIXME: We need better diagnostic message for static variable. + internal = 1; // expected-error {{use of undeclared identifier 'internal'}} + + not_exported_private = 1; // expected-error {{undeclared identifier}} + + internal_private = 1; // expected-error {{undeclared identifier}} +} + +export module B; +import A; + +void test_late() { + in_header = 1; // expected-error {{missing '#include "foo.h"'; 'in_header' must be declared before it is used}} + // expected-note@* {{not visible}} + + global_module_fragment = 1; // expected-error {{missing '#include'; 'global_module_fragment' must be declared before it is used}} + + exported = 1; + + not_exported = 1; // expected-error {{use of undeclared identifier 'not_exported'; did you mean 'exported'?}} + // expected-note@* {{'exported' declared here}} + + internal = 1; // expected-error {{use of undeclared identifier 'internal'}} + + not_exported_private = 1; + // FIXME: should not be visible here + // expected-error@-2 {{undeclared identifier}} + + internal_private = 1; // expected-error {{use of undeclared identifier 'internal_private'}} +} \ No newline at end of file diff --git a/external/llvm-project/clang/test/CXX/module/basic/basic.def.odr/p6.cppm b/external/llvm-project/clang/test/CXX/module/basic/basic.def.odr/p6.cppm index 8e7917dc63ea..c532e7ad40a1 100644 --- a/external/llvm-project/clang/test/CXX/module/basic/basic.def.odr/p6.cppm +++ b/external/llvm-project/clang/test/CXX/module/basic/basic.def.odr/p6.cppm @@ -3,29 +3,28 @@ // RUN: split-file %s %t // // RUN: %clang_cc1 -std=c++20 -verify %t/global-vs-module.cppm -// RUN: %clang_cc1 -std=c++20 -verify %t/global-vs-module.cppm -DEXPORT -// RUN: %clang_cc1 -std=c++20 -verify %t/global-vs-module.cppm -DUSING +// RUN: %clang_cc1 -std=c++20 -verify %t/global-vs-module-export.cppm +// RUN: %clang_cc1 -std=c++20 -verify %t/global-vs-module-using.cppm // -// RUN: %clang_cc1 -std=c++20 -emit-module-interface %t/global-vs-module.cppm -o %t/M.pcm -DNO_GLOBAL -DEXPORT +// RUN: %clang_cc1 -std=c++20 -emit-module-interface %t/M.cppm -o %t/M.pcm // RUN: %clang_cc1 -std=c++20 -verify %t/module-vs-global.cpp -fmodule-file=M=%t/M.pcm // // Some of the following tests intentionally have no -verify in their RUN // lines; we are testing that those cases do not produce errors. // -// RUN: %clang_cc1 -std=c++20 %t/module-vs-module.cpp -fmodule-file=M=%t/M.pcm -DMODULE_INTERFACE -verify -// RUN: %clang_cc1 -std=c++20 %t/module-vs-module.cpp -fmodule-file=M=%t/M.pcm -DMODULE_INTERFACE -DNO_IMPORT +// RUN: %clang_cc1 -std=c++20 %t/module-vs-module-interface.cpp -fmodule-file=M=%t/M.pcm -verify +// RUN: %clang_cc1 -std=c++20 %t/module-vs-module-interface.cpp -fmodule-file=M=%t/M.pcm -DNO_IMPORT // -// RUN: %clang_cc1 -std=c++20 %t/module-vs-module.cpp -fmodule-file=M=%t/M.pcm -emit-module-interface -o %t/N.pcm -DMODULE_INTERFACE -DNO_ERRORS -// RUN: %clang_cc1 -std=c++20 %t/module-vs-module.cpp -fmodule-file=M=%t/M.pcm -fmodule-file=N=%t/N.pcm -verify +// RUN: %clang_cc1 -std=c++20 %t/module-vs-module-interface.cpp -fmodule-file=M=%t/M.pcm -emit-module-interface -o %t/N.pcm -DNO_ERRORS +// RUN: %clang_cc1 -std=c++20 %t/module-vs-module-impl.cpp -fmodule-file=M=%t/M.pcm -fmodule-file=N=%t/N.pcm -verify // -// RUN: %clang_cc1 -std=c++20 %t/module-vs-module.cpp -fmodule-file=M=%t/M.pcm -fmodule-file=N=%t/N.pcm -DNO_IMPORT -verify +// RUN: %clang_cc1 -std=c++20 %t/module-vs-module-impl.cpp -fmodule-file=M=%t/M.pcm -fmodule-file=N=%t/N.pcm -DNO_IMPORT -verify // -// RUN: %clang_cc1 -std=c++20 %t/module-vs-module.cpp -fmodule-file=M=%t/M.pcm -emit-module-interface -o %t/N-no-M.pcm -DMODULE_INTERFACE -DNO_ERRORS -DNO_IMPORT -// RUN: %clang_cc1 -std=c++20 %t/module-vs-module.cpp -fmodule-file=M=%t/M.pcm -fmodule-file=N=%t/N-no-M.pcm -verify -// RUN: %clang_cc1 -std=c++20 %t/module-vs-module.cpp -fmodule-file=N=%t/N-no-M.pcm -DNO_IMPORT +// RUN: %clang_cc1 -std=c++20 %t/module-vs-module-interface.cpp -fmodule-file=M=%t/M.pcm -emit-module-interface -o %t/N-no-M.pcm -DNO_ERRORS -DNO_IMPORT +// RUN: %clang_cc1 -std=c++20 %t/module-vs-module-impl.cpp -fmodule-file=M=%t/M.pcm -fmodule-file=N=%t/N-no-M.pcm -verify +// RUN: %clang_cc1 -std=c++20 %t/module-vs-module-impl.cpp -fmodule-file=N=%t/N-no-M.pcm -DNO_IMPORT //--- global-vs-module.cppm -#ifndef NO_GLOBAL module; extern int var; // expected-note {{previous declaration is here}} int func(); // expected-note {{previous declaration is here}} @@ -40,11 +39,75 @@ template using type_tpl = int; // expected-note {{previous declaration typedef int type; namespace ns { using ::func; } namespace ns_alias = ns; -#endif export module M; -#ifdef USING +extern int var; // expected-error {{declaration of 'var' in module M follows declaration in the global module}} +int func(); // expected-error {{declaration of 'func' in module M follows declaration in the global module}} +struct str; // expected-error {{declaration of 'str' in module M follows declaration in the global module}} +using type = int; + +template extern int var_tpl; // expected-error {{declaration of 'var_tpl' in module M follows declaration in the global module}} +template int func_tpl(); // expected-error {{declaration of 'func_tpl' in module M follows declaration in the global module}} +template struct str_tpl; // expected-error {{declaration of 'str_tpl' in module M follows declaration in the global module}} +template using type_tpl = int; // expected-error {{declaration of 'type_tpl' in module M follows declaration in the global module}} + +typedef int type; +namespace ns { using ::func; } +namespace ns_alias = ns; + +//--- global-vs-module-export.cppm +module; +extern int var; // expected-note {{previous declaration is here}} +int func(); // expected-note {{previous declaration is here}} +struct str; // expected-note {{previous declaration is here}} +using type = int; + +template extern int var_tpl; // expected-note {{previous declaration is here}} +template int func_tpl(); // expected-note {{previous declaration is here}} +template struct str_tpl; // expected-note {{previous declaration is here}} +template using type_tpl = int; // expected-note {{previous declaration is here}} + +typedef int type; +namespace ns { using ::func; } +namespace ns_alias = ns; + +export module M; + +export { +extern int var; // expected-error {{declaration of 'var' in module M follows declaration in the global module}} +int func(); // expected-error {{declaration of 'func' in module M follows declaration in the global module}} +struct str; // expected-error {{declaration of 'str' in module M follows declaration in the global module}} +using type = int; + +template extern int var_tpl; // expected-error {{declaration of 'var_tpl' in module M follows declaration in the global module}} +template int func_tpl(); // expected-error {{declaration of 'func_tpl' in module M follows declaration in the global module}} +template struct str_tpl; // expected-error {{declaration of 'str_tpl' in module M follows declaration in the global module}} +template using type_tpl = int; // expected-error {{declaration of 'type_tpl' in module M follows declaration in the global module}} + +typedef int type; +namespace ns { using ::func; } +namespace ns_alias = ns; +} + +//--- global-vs-module-using.cppm +module; +extern int var; // expected-note {{previous declaration is here}} +int func(); // expected-note {{previous declaration is here}} +struct str; // expected-note {{previous declaration is here}} +using type = int; + +template extern int var_tpl; // expected-note {{previous declaration is here}} +template int func_tpl(); // expected-note {{previous declaration is here}} +template struct str_tpl; // expected-note {{previous declaration is here}} +template using type_tpl = int; // expected-note {{previous declaration is here}} + +typedef int type; +namespace ns { using ::func; } +namespace ns_alias = ns; + +export module M; + using ::var; using ::func; using ::str; @@ -53,11 +116,6 @@ using ::var_tpl; using ::func_tpl; using ::str_tpl; using ::type_tpl; -#endif - -#ifdef EXPORT -export { -#endif extern int var; // expected-error {{declaration of 'var' in module M follows declaration in the global module}} int func(); // expected-error {{declaration of 'func' in module M follows declaration in the global module}} @@ -73,51 +131,87 @@ typedef int type; namespace ns { using ::func; } namespace ns_alias = ns; -#ifdef EXPORT +//--- M.cppm +export module M; + +export { +extern int var; // expected-error {{declaration of 'var' in module M follows declaration in the global module}} +int func(); // expected-error {{declaration of 'func' in module M follows declaration in the global module}} +struct str; // expected-error {{declaration of 'str' in module M follows declaration in the global module}} +using type = int; + +template extern int var_tpl; // expected-error {{declaration of 'var_tpl' in module M follows declaration in the global module}} +template int func_tpl(); // expected-error {{declaration of 'func_tpl' in module M follows declaration in the global module}} +template struct str_tpl; // expected-error {{declaration of 'str_tpl' in module M follows declaration in the global module}} +template using type_tpl = int; // expected-error {{declaration of 'type_tpl' in module M follows declaration in the global module}} + +typedef int type; +namespace ns { using ::func; } +namespace ns_alias = ns; } -#endif //--- module-vs-global.cpp +module; import M; -extern int var; // expected-error {{declaration of 'var' in the global module follows declaration in module M}} expected-note@global-vs-module.cppm:35 {{previous}} -int func(); // expected-error {{declaration of 'func' in the global module follows declaration in module M}} expected-note@global-vs-module.cppm:36 {{previous}} -struct str; // expected-error {{declaration of 'str' in the global module follows declaration in module M}} expected-note@global-vs-module.cppm:37 {{previous}} +extern int var; // expected-error {{declaration of 'var' in the global module follows declaration in module M}} expected-note@M.cppm:4 {{previous}} +int func(); // expected-error {{declaration of 'func' in the global module follows declaration in module M}} expected-note@M.cppm:5 {{previous}} +struct str; // expected-error {{declaration of 'str' in the global module follows declaration in module M}} expected-note@M.cppm:6 {{previous}} using type = int; -template extern int var_tpl; // expected-error {{declaration of 'var_tpl' in the global module follows declaration in module M}} expected-note@global-vs-module.cppm:40 {{previous}} -template int func_tpl(); // expected-error {{declaration of 'func_tpl' in the global module follows declaration in module M}} expected-note@global-vs-module.cppm:41 {{previous}} -template struct str_tpl; // expected-error {{declaration of 'str_tpl' in the global module follows declaration in module M}} expected-note@global-vs-module.cppm:42 {{previous}} -template using type_tpl = int; // expected-error {{declaration of 'type_tpl' in the global module follows declaration in module M}} expected-note@global-vs-module.cppm:43 {{previous}} +template extern int var_tpl; // expected-error {{declaration of 'var_tpl' in the global module follows declaration in module M}} expected-note@M.cppm:9 {{previous}} +template int func_tpl(); // expected-error {{declaration of 'func_tpl' in the global module follows declaration in module M}} expected-note@M.cppm:10 {{previous}} +template struct str_tpl; // expected-error {{declaration of 'str_tpl' in the global module follows declaration in module M}} expected-note@M.cppm:11 {{previous}} +template using type_tpl = int; // expected-error {{declaration of 'type_tpl' in the global module follows declaration in module M}} expected-note@M.cppm:12 {{previous}} typedef int type; namespace ns { using ::func; } namespace ns_alias = ns; -//--- module-vs-module.cpp -#ifdef MODULE_INTERFACE export module N; -#else -module N; -#endif + +//--- module-vs-module-interface.cpp +export module N; #ifndef NO_IMPORT import M; #endif #ifndef NO_ERRORS -extern int var; // expected-error {{declaration of 'var' in module N follows declaration in module M}} expected-note@global-vs-module.cppm:35 {{previous}} -int func(); // expected-error {{declaration of 'func' in module N follows declaration in module M}} expected-note@global-vs-module.cppm:36 {{previous}} -struct str; // expected-error {{declaration of 'str' in module N follows declaration in module M}} expected-note@global-vs-module.cppm:37 {{previous}} +extern int var; // expected-error {{declaration of 'var' in module N follows declaration in module M}} expected-note@M.cppm:4 {{previous}} +int func(); // expected-error {{declaration of 'func' in module N follows declaration in module M}} expected-note@M.cppm:5 {{previous}} +struct str; // expected-error {{declaration of 'str' in module N follows declaration in module M}} expected-note@M.cppm:6 {{previous}} using type = int; -template extern int var_tpl; // expected-error {{declaration of 'var_tpl' in module N follows declaration in module M}} expected-note@global-vs-module.cppm:40 {{previous}} -template int func_tpl(); // expected-error {{declaration of 'func_tpl' in module N follows declaration in module M}} expected-note@global-vs-module.cppm:41 {{previous}} -template struct str_tpl; // expected-error {{declaration of 'str_tpl' in module N follows declaration in module M}} expected-note@global-vs-module.cppm:42 {{previous}} -template using type_tpl = int; // expected-error {{declaration of 'type_tpl' in module N follows declaration in module M}} expected-note@global-vs-module.cppm:43 {{previous}} +template extern int var_tpl; // expected-error {{declaration of 'var_tpl' in module N follows declaration in module M}} expected-note@M.cppm:9 {{previous}} +template int func_tpl(); // expected-error {{declaration of 'func_tpl' in module N follows declaration in module M}} expected-note@M.cppm:10 {{previous}} +template struct str_tpl; // expected-error {{declaration of 'str_tpl' in module N follows declaration in module M}} expected-note@M.cppm:11 {{previous}} +template using type_tpl = int; // expected-error {{declaration of 'type_tpl' in module N follows declaration in module M}} expected-note@M.cppm:12 {{previous}} typedef int type; namespace ns { using ::func; } namespace ns_alias = ns; #endif +//--- module-vs-module-impl.cpp +module N; + +#ifndef NO_IMPORT +import M; +#endif + +#ifndef NO_ERRORS +extern int var; // expected-error {{declaration of 'var' in module N follows declaration in module M}} expected-note@M.cppm:4 {{previous}} +int func(); // expected-error {{declaration of 'func' in module N follows declaration in module M}} expected-note@M.cppm:5 {{previous}} +struct str; // expected-error {{declaration of 'str' in module N follows declaration in module M}} expected-note@M.cppm:6 {{previous}} +using type = int; + +template extern int var_tpl; // expected-error {{declaration of 'var_tpl' in module N follows declaration in module M}} expected-note@M.cppm:9 {{previous}} +template int func_tpl(); // expected-error {{declaration of 'func_tpl' in module N follows declaration in module M}} expected-note@M.cppm:10 {{previous}} +template struct str_tpl; // expected-error {{declaration of 'str_tpl' in module N follows declaration in module M}} expected-note@M.cppm:11 {{previous}} +template using type_tpl = int; // expected-error {{declaration of 'type_tpl' in module N follows declaration in module M}} expected-note@M.cppm:12 {{previous}} + +typedef int type; +namespace ns { using ::func; } +namespace ns_alias = ns; +#endif diff --git a/external/llvm-project/clang/test/CXX/module/basic/basic.link/module-declaration.cpp b/external/llvm-project/clang/test/CXX/module/basic/basic.link/module-declaration.cpp index d71358cc7a57..4bdcc9e5f278 100644 --- a/external/llvm-project/clang/test/CXX/module/basic/basic.link/module-declaration.cpp +++ b/external/llvm-project/clang/test/CXX/module/basic/basic.link/module-declaration.cpp @@ -8,27 +8,19 @@ // RUN: %clang_cc1 -std=c++20 -emit-module-interface -fmodule-file=x=%t/x.pcm %t/x.y.cppm -o %t/x.y.pcm // // Module implementation for unknown and known module. (The former is ill-formed.) -// RUN: %clang_cc1 -std=c++20 -I%t -fmodule-file=x.y=%t/x.y.pcm -verify -x c++ %t/M.cpp \ -// RUN: -DTEST=1 -DEXPORT= -DMODULE_NAME=z -// RUN: %clang_cc1 -std=c++20 -I%t -fmodule-file=x=%t/x.pcm -fmodule-file=x.y=%t/x.y.pcm -verify -x c++ %t/M.cpp \ -// RUN: -DTEST=2 -DEXPORT= -DMODULE_NAME=x +// RUN: %clang_cc1 -std=c++20 -I%t -fmodule-file=x.y=%t/x.y.pcm -verify -x c++ %t/z_impl.cppm +// RUN: %clang_cc1 -std=c++20 -I%t -fmodule-file=x=%t/x.pcm -fmodule-file=x.y=%t/x.y.pcm -verify -x c++ %t/x_impl.cppm // // Module interface for unknown and known module. (The latter is ill-formed due to // redefinition.) -// RUN: %clang_cc1 -std=c++20 -I%t -fmodule-file=x.y=%t/x.y.pcm -verify %t/M.cpp \ -// RUN: -DTEST=3 -DEXPORT=export -DMODULE_NAME=z -// RUN: %clang_cc1 -std=c++20 -I%t -fmodule-file=x.y=%t/x.y.pcm -verify %t/M.cpp \ -// RUN: -DTEST=4 -DEXPORT=export -DMODULE_NAME=x +// RUN: %clang_cc1 -std=c++20 -I%t -fmodule-file=x.y=%t/x.y.pcm -verify %t/z_interface.cppm +// RUN: %clang_cc1 -std=c++20 -I%t -fmodule-file=x.y=%t/x.y.pcm -verify %t/x_interface.cppm // // Miscellaneous syntax. -// RUN: %clang_cc1 -std=c++20 -I%t -fmodule-file=x.y=%t/x.y.pcm -verify %t/M.cpp \ -// RUN: -DTEST=7 -DEXPORT=export -DMODULE_NAME='z elderberry' -// RUN: %clang_cc1 -std=c++20 -I%t -fmodule-file=x.y=%t/x.y.pcm -verify %t/M.cpp \ -// RUN: -DTEST=8 -DEXPORT=export -DMODULE_NAME='z [[]]' -// RUN: %clang_cc1 -std=c++20 -I%t -fmodule-file=x.y=%t/x.y.pcm -verify %t/M.cpp \ -// RUN: -DTEST=9 -DEXPORT=export -DMODULE_NAME='z [[fancy]]' -// RUN: %clang_cc1 -std=c++20 -I%t -fmodule-file=x.y=%t/x.y.pcm -verify %t/M.cpp \ -// RUN: -DTEST=10 -DEXPORT=export -DMODULE_NAME='z [[maybe_unused]]' +// RUN: %clang_cc1 -std=c++20 -I%t -fmodule-file=x.y=%t/x.y.pcm -verify %t/invalid_module_name.cppm +// RUN: %clang_cc1 -std=c++20 -I%t -fmodule-file=x.y=%t/x.y.pcm -verify %t/empty_attribute.cppm +// RUN: %clang_cc1 -std=c++20 -I%t -fmodule-file=x.y=%t/x.y.pcm -verify %t/fancy_attribute.cppm +// RUN: %clang_cc1 -std=c++20 -I%t -fmodule-file=x.y=%t/x.y.pcm -verify %t/maybe_unused_attribute.cppm //--- x.cppm export module x; @@ -38,17 +30,31 @@ int a, b; export module x.y; int c; -//--- M.cpp - -EXPORT module MODULE_NAME; -#if TEST == 7 -// expected-error@-2 {{expected ';'}} expected-error@-2 {{a type specifier is required}} -#elif TEST == 9 -// expected-warning@-4 {{unknown attribute 'fancy' ignored}} -#elif TEST == 10 -// expected-error-re@-6 {{'maybe_unused' attribute cannot be applied to a module{{$}}}} -#elif TEST == 1 -// expected-error@-8 {{module 'z' not found}} -#else +//--- z_impl.cppm +module z; // expected-error {{module 'z' not found}} + +//--- x_impl.cppm +// expected-no-diagnostics +module x; + +//--- z_interface.cppm // expected-no-diagnostics -#endif +export module z; + +//--- x_interface.cppm +// expected-no-diagnostics +export module x; + +//--- invalid_module_name.cppm +export module z elderberry; // expected-error {{expected ';'}} \ + // expected-error {{a type specifier is required}} + +//--- empty_attribute.cppm +// expected-no-diagnostics +export module z [[]]; + +//--- fancy_attribute.cppm +export module z [[fancy]]; // expected-warning {{unknown attribute 'fancy' ignored}} + +//--- maybe_unused_attribute.cppm +export module z [[maybe_unused]]; // expected-error-re {{'maybe_unused' attribute cannot be applied to a module{{$}}}} diff --git a/external/llvm-project/clang/test/CXX/module/cpp.pre/module_decl.cpp b/external/llvm-project/clang/test/CXX/module/cpp.pre/module_decl.cpp new file mode 100644 index 000000000000..6238347c167a --- /dev/null +++ b/external/llvm-project/clang/test/CXX/module/cpp.pre/module_decl.cpp @@ -0,0 +1,8 @@ +// RUN: rm -rf %t +// RUN: mkdir -p %t +// RUN: %clang_cc1 -std=c++20 -emit-module-interface %s -verify -o %t/M.pcm + +// This is a comment +#define I32 int // expected-note {{add 'module;' to the start of the file to introduce a global module fragment}} +export module M; // expected-error {{module declaration must occur at the start of the translation unit}} +export I32 i32; diff --git a/external/llvm-project/clang/test/CXX/module/dcl.dcl/dcl.module/dcl.module.import/p1.cppm b/external/llvm-project/clang/test/CXX/module/dcl.dcl/dcl.module/dcl.module.import/p1.cppm index 3670f9430ed4..f65f050a3c7b 100644 --- a/external/llvm-project/clang/test/CXX/module/dcl.dcl/dcl.module/dcl.module.import/p1.cppm +++ b/external/llvm-project/clang/test/CXX/module/dcl.dcl/dcl.module/dcl.module.import/p1.cppm @@ -6,10 +6,10 @@ // RUN: %clang_cc1 -std=c++20 -emit-module-interface -fmodule-file=x=%t/x.pcm %t/x.y.cppm -o %t/x.y.pcm // RUN: %clang_cc1 -std=c++20 -emit-module-interface %t/a.b.cppm -o %t/a.b.pcm // -// RUN: %clang_cc1 -std=c++20 -I%t -fmodule-file=x.y=%t/x.y.pcm -fmodule-file=x=%t/x.pcm -verify %t/test.cpp \ -// RUN: -DMODULE_NAME=z -DINTERFACE // RUN: %clang_cc1 -std=c++20 -I%t -fmodule-file=x.y=%t/x.y.pcm -fmodule-file=x=%t/x.pcm \ -// RUN: -fmodule-file=a.b=%t/a.b.pcm -verify %t/test.cpp -DMODULE_NAME=a.b +// RUN: -verify %t/test.interface.cpp +// RUN: %clang_cc1 -std=c++20 -I%t -fmodule-file=x.y=%t/x.y.pcm -fmodule-file=x=%t/x.pcm \ +// RUN: -fmodule-file=a.b=%t/a.b.pcm -verify %t/test.implementation.cpp // RUN: %clang_cc1 -std=c++20 -I%t -fmodule-file=x.y=%t/x.y.pcm -fmodule-file=x=%t/x.pcm -verify %t/test.x.cpp //--- x.cppm @@ -33,19 +33,33 @@ int use_2 = b; // ok // There is no relation between module x and module x.y. int use_3 = c; // expected-error {{use of undeclared identifier 'c'}} -//--- test.cpp -#ifdef INTERFACE -export module MODULE_NAME; -#else -module MODULE_NAME; -#endif +//--- test.interface.cpp +export module z; + +import x; + +import x [[]]; +import x [[foo]]; // expected-warning {{unknown attribute 'foo' ignored}} +import x [[noreturn]]; // expected-error {{'noreturn' attribute cannot be applied to a module import}} +import x [[blarg::noreturn]]; // expected-warning-re {{unknown attribute 'blarg::noreturn' ignored{{.*}}}} + +import x.y; +import x.; // expected-error {{expected a module name after 'import'}} +import .x; // expected-error {{expected a module name after 'import'}} + +import blarg; // expected-error {{module 'blarg' not found}} + +int use_4 = c; // ok + +//--- test.implementation.cpp +module a.b; import x; import x [[]]; import x [[foo]]; // expected-warning {{unknown attribute 'foo' ignored}} import x [[noreturn]]; // expected-error {{'noreturn' attribute cannot be applied to a module import}} -import x [[blarg::noreturn]]; // expected-warning {{unknown attribute 'blarg::noreturn' ignored}} +import x [[blarg::noreturn]]; // expected-warning-re {{unknown attribute 'blarg::noreturn' ignored{{.*}}}} import x.y; import x.; // expected-error {{expected a module name after 'import'}} diff --git a/external/llvm-project/clang/test/CXX/module/dcl.dcl/dcl.module/dcl.module.interface/p1.cppm b/external/llvm-project/clang/test/CXX/module/dcl.dcl/dcl.module/dcl.module.interface/p1.cppm index 84ef85126c36..2158d7fa84b8 100644 --- a/external/llvm-project/clang/test/CXX/module/dcl.dcl/dcl.module/dcl.module.interface/p1.cppm +++ b/external/llvm-project/clang/test/CXX/module/dcl.dcl/dcl.module/dcl.module.interface/p1.cppm @@ -1,29 +1,26 @@ -// RUN: %clang_cc1 -std=c++20 %s -verify -emit-module-interface -o /dev/null -// RUN: %clang_cc1 -std=c++20 %s -DINTERFACE -verify -emit-module-interface -o %t -// RUN: %clang_cc1 -std=c++20 %s -DIMPLEMENTATION -verify -fmodule-file=A=%t -o /dev/null +// RUN: rm -rf %t +// RUN: split-file %s %t + +// RUN: %clang_cc1 -std=c++20 %t/ExportDeclNotInModulePurview.cppm -verify -emit-module-interface -o /dev/null +// RUN: %clang_cc1 -std=c++20 %t/A.cppm -verify -emit-module-interface -o %t/A.pcm +// RUN: %clang_cc1 -std=c++20 %t/AddExport.cppm -verify -fmodule-file=A=%t/A.pcm -o /dev/null // -// RUN: %clang_cc1 -std=c++20 %s -DBUILT_AS_INTERFACE -emit-module-interface -verify -o /dev/null -// RUN: %clang_cc1 -std=c++20 %s -DINTERFACE -DBUILT_AS_INTERFACE -emit-module-interface -verify -o /dev/null -// RUN: %clang_cc1 -std=c++20 %s -DIMPLEMENTATION -DBUILT_AS_INTERFACE -emit-module-interface -verify -o /dev/null +// RUN: %clang_cc1 -std=c++20 %t/AddExport2.cppm -emit-module-interface -verify -o /dev/null -#if INTERFACE +//--- ExportDeclNotInModulePurview.cppm +// expected-error@* {{missing 'export module' declaration in module interface unit}} +export int b; // expected-error {{export declaration can only be used within a module purview}} + +//--- A.cppm // expected-no-diagnostics export module A; -#elif IMPLEMENTATION -module A; // #module-decl - #ifdef BUILT_AS_INTERFACE - // expected-error@-2 {{missing 'export' specifier in module declaration while building module interface}} - #define INTERFACE - #endif -#else // Not in a module -// expected-error@* {{missing 'export module' declaration in module interface unit}} -#endif +export int a; -#ifndef INTERFACE +//--- AddExport.cppm +module A; // #module-decl export int b; // expected-error {{export declaration can only be used within a module purview}} -#ifdef IMPLEMENTATION // expected-note@#module-decl {{add 'export' here}} -#endif -#else + +//--- AddExport2.cppm +module A; // expected-error {{missing 'export' specifier in module declaration while building module interface}} export int a; -#endif diff --git a/external/llvm-project/clang/test/CXX/module/dcl.dcl/dcl.module/p1.cpp b/external/llvm-project/clang/test/CXX/module/dcl.dcl/dcl.module/p1.cpp index db86b5dd34c3..95d087e0f6c7 100644 --- a/external/llvm-project/clang/test/CXX/module/dcl.dcl/dcl.module/p1.cpp +++ b/external/llvm-project/clang/test/CXX/module/dcl.dcl/dcl.module/p1.cpp @@ -1,14 +1,30 @@ -// RUN: %clang_cc1 -std=c++20 -verify %s -DFOO=export -DBAR=export -// RUN: %clang_cc1 -std=c++20 -verify %s -DFOO=export -DBAR= -// RUN: %clang_cc1 -std=c++20 %s -DFOO=export -emit-module-interface -o %t -// RUN: %clang_cc1 -std=c++20 %s -fmodule-file=foo=%t -DFOO= -// RUN: %clang_cc1 -std=c++20 %s -fmodule-file=foo=%t -DBAR=export -// RUN: %clang_cc1 -std=c++20 -verify %s -fmodule-file=foo=%t -DFOO= -DBAR=export - -#ifdef FOO -FOO module foo; // expected-note {{previous module declaration is here}} -#endif - -#ifdef BAR -BAR module bar; // expected-error {{translation unit contains multiple module declarations}} -#endif +// RUN: rm -rf %t +// RUN: split-file %s %t + +// RUN: %clang_cc1 -std=c++20 -verify %t/A.cppm +// RUN: %clang_cc1 -std=c++20 -verify %t/B.cppm +// RUN: %clang_cc1 -std=c++20 %t/C.cppm -emit-module-interface -o %t/C.pcm +// RUN: %clang_cc1 -std=c++20 %t/D.cppm -fmodule-file=foo=%t/C.pcm +// RUN: %clang_cc1 -std=c++20 %t/E.cppm -fmodule-file=foo=%t/C.pcm +// RUN: %clang_cc1 -std=c++20 -verify %t/F.cppm -fmodule-file=foo=%t/C.pcm + +//--- A.cppm +export module foo; // expected-note {{previous module declaration is here}} +export module bar; // expected-error {{translation unit contains multiple module declarations}} + +//--- B.cppm +export module foo; // expected-note {{previous module declaration is here}} +module bar; // expected-error {{translation unit contains multiple module declarations}} + +//--- C.cppm +export module foo; + +//--- D.cppm +module foo; + +//--- E.cppm +export module bar; + +//--- F.cppm +module foo; // expected-note {{previous module declaration is here}} +export module bar; // expected-error {{translation unit contains multiple module declarations}} diff --git a/external/llvm-project/clang/test/CXX/module/dcl.dcl/dcl.module/p5.cpp b/external/llvm-project/clang/test/CXX/module/dcl.dcl/dcl.module/p5.cpp index ca100443a4c6..a0d30233809f 100644 --- a/external/llvm-project/clang/test/CXX/module/dcl.dcl/dcl.module/p5.cpp +++ b/external/llvm-project/clang/test/CXX/module/dcl.dcl/dcl.module/p5.cpp @@ -1,22 +1,47 @@ // RUN: rm -rf %t -// RUN: %clang_cc1 -std=c++20 -emit-module-interface %s -o %t -DINTERFACE -// RUN: %clang_cc1 -std=c++20 -fmodule-file=Foo=%t %s -verify -DIMPLEMENTATION -// RUN: %clang_cc1 -std=c++20 -fmodule-file=Foo=%t %s -verify -DEARLY_IMPLEMENTATION -// RUN: %clang_cc1 -std=c++20 -fmodule-file=Foo=%t %s -verify -DUSER +// RUN: split-file %s %t +// RUN: %clang_cc1 -std=c++20 -emit-module-interface %t/interface.cppm -o %t/interface.pcm +// RUN: %clang_cc1 -std=c++20 -fmodule-file=Foo=%t/interface.pcm %t/implementation.cppm -verify -DIMPLEMENTATION +// RUN: %clang_cc1 -std=c++20 -fmodule-file=Foo=%t/interface.pcm %t/early_impl.cppm -verify -DEARLY_IMPLEMENTATION +// RUN: %clang_cc1 -std=c++20 -fmodule-file=Foo=%t/interface.pcm %t/user.cppm -verify -DUSER + +//--- interface.cppm // expected-no-diagnostics +module; -#if defined(INTERFACE) || defined(EARLY_IMPLEMENTATION) || defined(IMPLEMENTATION) +template struct type_template { + typedef T type; + void f(type); +}; + +template void type_template::f(type) {} + +template class = type_template> +struct default_template_args {}; + +export module Foo; + +//--- implementation.cppm +// expected-no-diagnostics module; -#endif -#ifdef USER -import Foo; -#endif +template struct type_template { + typedef T type; + void f(type); +}; + +template void type_template::f(type) {} + +template class = type_template> +struct default_template_args {}; -#ifdef EARLY_IMPLEMENTATION module Foo; -#endif + +//--- early_impl.cppm +// expected-no-diagnostics +module; +module Foo; template struct type_template { typedef T type; @@ -28,10 +53,16 @@ template void type_template::f(type) {} template class = type_template> struct default_template_args {}; -#ifdef INTERFACE -export module Foo; -#endif +//--- user.cppm +// expected-no-diagnostics +import Foo; -#ifdef IMPLEMENTATION -module Foo; -#endif +template struct type_template { + typedef T type; + void f(type); +}; + +template void type_template::f(type) {} + +template class = type_template> +struct default_template_args {}; diff --git a/external/llvm-project/clang/test/CXX/module/module.interface/p2.cpp b/external/llvm-project/clang/test/CXX/module/module.interface/p2.cpp index 4f06b9f38686..8221c400ecd6 100644 --- a/external/llvm-project/clang/test/CXX/module/module.interface/p2.cpp +++ b/external/llvm-project/clang/test/CXX/module/module.interface/p2.cpp @@ -1,24 +1,26 @@ // RUN: rm -rf %t // RUN: mkdir -p %t +// RUN: split-file %s %t +// // RUN: %clang_cc1 -std=c++20 -x c++-header %S/Inputs/header.h -emit-header-unit -o %t/h.pcm -// RUN: %clang_cc1 -std=c++20 %s -DX_INTERFACE -emit-module-interface -o %t/x.pcm -// RUN: %clang_cc1 -std=c++20 %s -DY_INTERFACE -emit-module-interface -o %t/y.pcm -// RUN: %clang_cc1 -std=c++20 %s -DINTERFACE -fmodule-file=X=%t/x.pcm -fmodule-file=Y=%t/y.pcm -emit-module-interface -o %t/m.pcm -// RUN: %clang_cc1 -std=c++20 %s -DIMPLEMENTATION -I%S/Inputs -fmodule-file=%t/h.pcm \ +// RUN: %clang_cc1 -std=c++20 %t/x.cppm -emit-module-interface -o %t/x.pcm +// RUN: %clang_cc1 -std=c++20 %t/y.cppm -emit-module-interface -o %t/y.pcm +// RUN: %clang_cc1 -std=c++20 %t/interface.cppm -fmodule-file=X=%t/x.pcm -fmodule-file=Y=%t/y.pcm -emit-module-interface -o %t/m.pcm +// RUN: %clang_cc1 -std=c++20 %t/impl.cppm -I%S/Inputs -fmodule-file=%t/h.pcm \ // RUN: -fmodule-file=X=%t/x.pcm -fmodule-file=Y=%t/y.pcm -fmodule-file=p2=%t/m.pcm -verify \ // RUN: -Wno-experimental-header-units -// RUN: %clang_cc1 -std=c++20 %s -DUSER -I%S/Inputs -fmodule-file=%t/h.pcm -fmodule-file=p2=%t/m.pcm \ +// RUN: %clang_cc1 -std=c++20 %t/user.cppm -I%S/Inputs -fmodule-file=%t/h.pcm -fmodule-file=p2=%t/m.pcm \ // RUN: -fmodule-file=X=%t/x.pcm -fmodule-file=Y=%t/y.pcm -Wno-experimental-header-units -verify -#if defined(X_INTERFACE) +//--- x.cppm export module X; export int x; -#elif defined(Y_INTERFACE) +//--- y.cppm export module Y; export int y; -#elif defined(INTERFACE) +//--- interface.cppm export module p2; export import X; import Y; // not exported @@ -39,7 +41,7 @@ namespace C {} namespace D { int f(); } export namespace D {} -#elif defined(IMPLEMENTATION) +//--- impl.cppm module p2; import "header.h"; @@ -66,7 +68,7 @@ void use() { int use_header() { return foo + bar::baz(); } -#elif defined(USER) +//--- user.cppm import p2; import "header.h"; @@ -96,7 +98,3 @@ void use() { } int use_header() { return foo + bar::baz(); } - -#else -#error unknown mode -#endif diff --git a/external/llvm-project/clang/test/CXX/module/module.unit/p8.cpp b/external/llvm-project/clang/test/CXX/module/module.unit/p8.cpp index a5c01c493558..fb190257d3a2 100644 --- a/external/llvm-project/clang/test/CXX/module/module.unit/p8.cpp +++ b/external/llvm-project/clang/test/CXX/module/module.unit/p8.cpp @@ -1,37 +1,45 @@ -// RUN: echo 'export module foo; export int n;' > %t.cppm +// RUN: rm -rf %t +// RUN: mkdir %t +// RUN: split-file %s %t +// RUN: echo 'export module foo;' > %t.cppm +// RUN: echo 'export int n;' >> %t.cppm // RUN: %clang_cc1 -std=c++2a %t.cppm -emit-module-interface -o %t.pcm -// RUN: %clang_cc1 -std=c++2a -fmodule-file=foo=%t.pcm -verify -DMODE=0 %s -// RUN: %clang_cc1 -std=c++2a -fmodule-file=foo=%t.pcm -verify -DMODE=1 %s -// RUN: %clang_cc1 -std=c++2a -fmodule-file=foo=%t.pcm -verify -DMODE=2 %s -// RUN: %clang_cc1 -std=c++2a -fmodule-file=foo=%t.pcm -verify -DMODE=3 %s -// RUN: %clang_cc1 -std=c++2a -fmodule-file=foo=%t.pcm -verify -DMODE=4 %s -// RUN: %clang_cc1 -std=c++2a -fmodule-file=foo=%t.pcm -verify -DMODE=5 %s - -#if MODE == 0 +// RUN: %clang_cc1 -std=c++2a -fmodule-file=foo=%t.pcm -verify -DMODE=0 %t/A.cppm +// RUN: %clang_cc1 -std=c++2a -fmodule-file=foo=%t.pcm -verify -DMODE=1 %t/B.cppm +// RUN: %clang_cc1 -std=c++2a -fmodule-file=foo=%t.pcm -verify -DMODE=2 %t/C.cppm +// RUN: %clang_cc1 -std=c++2a -fmodule-file=foo=%t.pcm -verify -DMODE=3 %t/D.cppm +// RUN: %clang_cc1 -std=c++2a -fmodule-file=foo=%t.pcm -verify -DMODE=4 %t/E.cppm +// RUN: %clang_cc1 -std=c++2a -fmodule-file=foo=%t.pcm -verify -DMODE=5 %t/F.cppm + +//--- A.cppm // no module declaration +// expected-no-diagnostics -#elif MODE == 1 +//--- B.cppm // expected-no-diagnostics module foo; // Implementation, implicitly imports foo. #define IMPORTED -#elif MODE == 2 +int k = n; + +//--- C.cppm export module foo; -#elif MODE == 3 +int k = n; // expected-error {{use of undeclared identifier 'n'}} + +//--- D.cppm export module bar; // A different module -#elif MODE == 4 +int k = n; // expected-error {{use of undeclared identifier 'n'}} + +//--- E.cppm module foo:bar; // Partition implementation //#define IMPORTED (we don't import foo here) -#elif MODE == 5 +int k = n; // expected-error {{use of undeclared identifier 'n'}} + +//--- F.cppm export module foo:bar; // Partition interface //#define IMPORTED (we don't import foo here) -#endif - -int k = n; -#ifndef IMPORTED -// expected-error@-2 {{use of undeclared identifier 'n'}} -#endif +int k = n; // expected-error {{use of undeclared identifier 'n'}} diff --git a/external/llvm-project/clang/test/CodeGen/PowerPC/builtins-ppc-dmf.c b/external/llvm-project/clang/test/CodeGen/PowerPC/builtins-ppc-dmf.c new file mode 100644 index 000000000000..41f13155847b --- /dev/null +++ b/external/llvm-project/clang/test/CodeGen/PowerPC/builtins-ppc-dmf.c @@ -0,0 +1,94 @@ +// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py +// RUN: %clang_cc1 -O3 -triple powerpc64le-unknown-unknown -target-cpu future \ +// RUN: -emit-llvm %s -o - | FileCheck %s +// RUN: %clang_cc1 -O3 -triple powerpc64-ibm-aix -target-cpu future \ +// RUN: -emit-llvm %s -o - | FileCheck %s + + +// CHECK-LABEL: @test_dmxvi8gerx4( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = load <256 x i1>, ptr [[VPP:%.*]], align 32, !tbaa [[TBAA2:![0-9]+]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <1024 x i1> @llvm.ppc.mma.dmxvi8gerx4(<256 x i1> [[TMP0]], <16 x i8> [[VC:%.*]]) +// CHECK-NEXT: store <1024 x i1> [[TMP1]], ptr [[RESP:%.*]], align 128, !tbaa [[TBAA6:![0-9]+]] +// CHECK-NEXT: ret void +// +void test_dmxvi8gerx4(unsigned char *vdmrp, unsigned char *vpp, vector unsigned char vc, unsigned char *resp) { + __dmr1024 vdmr = *((__dmr1024 *)vdmrp); + __vector_pair vp = *((__vector_pair *)vpp); + __builtin_mma_dmxvi8gerx4(&vdmr, vp, vc); + *((__dmr1024 *)resp) = vdmr; +} + +// CHECK-LABEL: @test_pmdmxvi8gerx4( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = load <256 x i1>, ptr [[VPP:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call <1024 x i1> @llvm.ppc.mma.pmdmxvi8gerx4(<256 x i1> [[TMP0]], <16 x i8> [[VC:%.*]], i32 0, i32 0, i32 0) +// CHECK-NEXT: store <1024 x i1> [[TMP1]], ptr [[RESP:%.*]], align 128, !tbaa [[TBAA6]] +// CHECK-NEXT: ret void +// +void test_pmdmxvi8gerx4(unsigned char *vdmrp, unsigned char *vpp, vector unsigned char vc, unsigned char *resp) { + __dmr1024 vdmr = *((__dmr1024 *)vdmrp); + __vector_pair vp = *((__vector_pair *)vpp); + __builtin_mma_pmdmxvi8gerx4(&vdmr, vp, vc, 0, 0, 0); + *((__dmr1024 *)resp) = vdmr; +} + +// CHECK-LABEL: @test_dmxvi8gerx4pp( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = load <1024 x i1>, ptr [[VDMRP:%.*]], align 128, !tbaa [[TBAA6]] +// CHECK-NEXT: [[TMP1:%.*]] = load <256 x i1>, ptr [[VPP:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <1024 x i1> @llvm.ppc.mma.dmxvi8gerx4pp(<1024 x i1> [[TMP0]], <256 x i1> [[TMP1]], <16 x i8> [[VC:%.*]]) +// CHECK-NEXT: store <1024 x i1> [[TMP2]], ptr [[RESP:%.*]], align 128, !tbaa [[TBAA6]] +// CHECK-NEXT: ret void +// +void test_dmxvi8gerx4pp(unsigned char *vdmrp, unsigned char *vpp, vector unsigned char vc, unsigned char *resp) { + __dmr1024 vdmr = *((__dmr1024 *)vdmrp); + __vector_pair vp = *((__vector_pair *)vpp); + __builtin_mma_dmxvi8gerx4pp(&vdmr, vp, vc); + *((__dmr1024 *)resp) = vdmr; +} + +// CHECK-LABEL: @test_pmdmxvi8gerx4pp( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = load <1024 x i1>, ptr [[VDMRP:%.*]], align 128, !tbaa [[TBAA6]] +// CHECK-NEXT: [[TMP1:%.*]] = load <256 x i1>, ptr [[VPP:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <1024 x i1> @llvm.ppc.mma.pmdmxvi8gerx4pp(<1024 x i1> [[TMP0]], <256 x i1> [[TMP1]], <16 x i8> [[VC:%.*]], i32 0, i32 0, i32 0) +// CHECK-NEXT: store <1024 x i1> [[TMP2]], ptr [[RESP:%.*]], align 128, !tbaa [[TBAA6]] +// CHECK-NEXT: ret void +// +void test_pmdmxvi8gerx4pp(unsigned char *vdmrp, unsigned char *vpp, vector unsigned char vc, unsigned char *resp) { + __dmr1024 vdmr = *((__dmr1024 *)vdmrp); + __vector_pair vp = *((__vector_pair *)vpp); + __builtin_mma_pmdmxvi8gerx4pp(&vdmr, vp, vc, 0, 0, 0); + *((__dmr1024 *)resp) = vdmr; +} + +// CHECK-LABEL: @test_dmxvi8gerx4spp( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = load <1024 x i1>, ptr [[VDMRP:%.*]], align 128, !tbaa [[TBAA6]] +// CHECK-NEXT: [[TMP1:%.*]] = load <256 x i1>, ptr [[VPP:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <1024 x i1> @llvm.ppc.mma.dmxvi8gerx4spp(<1024 x i1> [[TMP0]], <256 x i1> [[TMP1]], <16 x i8> [[VC:%.*]]) +// CHECK-NEXT: store <1024 x i1> [[TMP2]], ptr [[RESP:%.*]], align 128, !tbaa [[TBAA6]] +// CHECK-NEXT: ret void +// +void test_dmxvi8gerx4spp(unsigned char *vdmrp, unsigned char *vpp, vector unsigned char vc, unsigned char *resp) { + __dmr1024 vdmr = *((__dmr1024 *)vdmrp); + __vector_pair vp = *((__vector_pair *)vpp); + __builtin_mma_dmxvi8gerx4spp(&vdmr, vp, vc); + *((__dmr1024 *)resp) = vdmr; +} + +// CHECK-LABEL: @test_pmdmxvi8gerx4spp( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = load <1024 x i1>, ptr [[VDMRP:%.*]], align 128, !tbaa [[TBAA6]] +// CHECK-NEXT: [[TMP1:%.*]] = load <256 x i1>, ptr [[VPP:%.*]], align 32, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call <1024 x i1> @llvm.ppc.mma.pmdmxvi8gerx4spp(<1024 x i1> [[TMP0]], <256 x i1> [[TMP1]], <16 x i8> [[VC:%.*]], i32 0, i32 0, i32 0) +// CHECK-NEXT: store <1024 x i1> [[TMP2]], ptr [[RESP:%.*]], align 128, !tbaa [[TBAA6]] +// CHECK-NEXT: ret void +// +void test_pmdmxvi8gerx4spp(unsigned char *vdmrp, unsigned char *vpp, vector unsigned char vc, unsigned char *resp) { + __dmr1024 vdmr = *((__dmr1024 *)vdmrp); + __vector_pair vp = *((__vector_pair *)vpp); + __builtin_mma_pmdmxvi8gerx4spp(&vdmr, vp, vc, 0, 0, 0); + *((__dmr1024 *)resp) = vdmr; +} diff --git a/external/llvm-project/clang/test/CodeGen/PowerPC/ppc-dmf-paired-vec-memops-builtin-err.c b/external/llvm-project/clang/test/CodeGen/PowerPC/ppc-dmf-paired-vec-memops-builtin-err.c new file mode 100644 index 000000000000..eef1abca2241 --- /dev/null +++ b/external/llvm-project/clang/test/CodeGen/PowerPC/ppc-dmf-paired-vec-memops-builtin-err.c @@ -0,0 +1,20 @@ +// RUN: not %clang_cc1 -triple powerpc64le-unknown-linux-gnu -target-cpu future \ +// RUN: %s -emit-llvm-only 2>&1 | FileCheck %s + +__attribute__((target("no-paired-vector-memops"))) +void test_pair(unsigned char *vdmr, unsigned char *vpp, vector unsigned char vc) { + __vector_pair vp = *((__vector_pair *)vpp); + __builtin_mma_dmxvi8gerx4((__dmr1024 *)vdmr, vp, vc); + __builtin_mma_pmdmxvi8gerx4((__dmr1024 *)vdmr, vp, vc, 0, 0, 0); + __builtin_mma_dmxvi8gerx4pp((__dmr1024 *)vdmr, vp, vc); + __builtin_mma_pmdmxvi8gerx4pp((__dmr1024 *)vdmr, vp, vc, 0, 0, 0); + __builtin_mma_dmxvi8gerx4spp((__dmr1024 *)vdmr, vp, vc); + __builtin_mma_pmdmxvi8gerx4spp((__dmr1024 *)vdmr, vp, vc, 0, 0, 0); + +// CHECK: error: '__builtin_mma_dmxvi8gerx4' needs target feature mma,paired-vector-memops +// CHECK: error: '__builtin_mma_pmdmxvi8gerx4' needs target feature mma,paired-vector-memops +// CHECK: error: '__builtin_mma_dmxvi8gerx4pp' needs target feature mma,paired-vector-memops +// CHECK: error: '__builtin_mma_pmdmxvi8gerx4pp' needs target feature mma,paired-vector-memops +// CHECK: error: '__builtin_mma_dmxvi8gerx4spp' needs target feature mma,paired-vector-memops +// CHECK: error: '__builtin_mma_pmdmxvi8gerx4spp' needs target feature mma,paired-vector-memops +} diff --git a/external/llvm-project/clang/test/CodeGen/PowerPC/ppc-dmf-types.c b/external/llvm-project/clang/test/CodeGen/PowerPC/ppc-dmf-types.c new file mode 100644 index 000000000000..9dff289370eb --- /dev/null +++ b/external/llvm-project/clang/test/CodeGen/PowerPC/ppc-dmf-types.c @@ -0,0 +1,177 @@ +// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py +// RUN: %clang_cc1 -triple powerpc64le-linux-unknown -target-cpu future \ +// RUN: -emit-llvm -o - %s | FileCheck %s + + +// CHECK-LABEL: @test_dmr_copy( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[PTR1_ADDR:%.*]] = alloca ptr, align 8 +// CHECK-NEXT: [[PTR2_ADDR:%.*]] = alloca ptr, align 8 +// CHECK-NEXT: store ptr [[PTR1:%.*]], ptr [[PTR1_ADDR]], align 8 +// CHECK-NEXT: store ptr [[PTR2:%.*]], ptr [[PTR2_ADDR]], align 8 +// CHECK-NEXT: [[TMP0:%.*]] = load ptr, ptr [[PTR1_ADDR]], align 8 +// CHECK-NEXT: [[ADD_PTR:%.*]] = getelementptr inbounds <1024 x i1>, ptr [[TMP0]], i64 2 +// CHECK-NEXT: [[TMP1:%.*]] = load <1024 x i1>, ptr [[ADD_PTR]], align 128 +// CHECK-NEXT: [[TMP2:%.*]] = load ptr, ptr [[PTR2_ADDR]], align 8 +// CHECK-NEXT: [[ADD_PTR1:%.*]] = getelementptr inbounds <1024 x i1>, ptr [[TMP2]], i64 1 +// CHECK-NEXT: store <1024 x i1> [[TMP1]], ptr [[ADD_PTR1]], align 128 +// CHECK-NEXT: ret void +// +void test_dmr_copy(__dmr1024 *ptr1, __dmr1024 *ptr2) { + *(ptr2 + 1) = *(ptr1 + 2); +} + +// CHECK-LABEL: @test_dmr_typedef( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[INP_ADDR:%.*]] = alloca ptr, align 8 +// CHECK-NEXT: [[OUTP_ADDR:%.*]] = alloca ptr, align 8 +// CHECK-NEXT: [[VDMRIN:%.*]] = alloca ptr, align 8 +// CHECK-NEXT: [[VDMROUT:%.*]] = alloca ptr, align 8 +// CHECK-NEXT: store ptr [[INP:%.*]], ptr [[INP_ADDR]], align 8 +// CHECK-NEXT: store ptr [[OUTP:%.*]], ptr [[OUTP_ADDR]], align 8 +// CHECK-NEXT: [[TMP0:%.*]] = load ptr, ptr [[INP_ADDR]], align 8 +// CHECK-NEXT: store ptr [[TMP0]], ptr [[VDMRIN]], align 8 +// CHECK-NEXT: [[TMP1:%.*]] = load ptr, ptr [[OUTP_ADDR]], align 8 +// CHECK-NEXT: store ptr [[TMP1]], ptr [[VDMROUT]], align 8 +// CHECK-NEXT: [[TMP2:%.*]] = load ptr, ptr [[VDMRIN]], align 8 +// CHECK-NEXT: [[TMP3:%.*]] = load <1024 x i1>, ptr [[TMP2]], align 128 +// CHECK-NEXT: [[TMP4:%.*]] = load ptr, ptr [[VDMROUT]], align 8 +// CHECK-NEXT: store <1024 x i1> [[TMP3]], ptr [[TMP4]], align 128 +// CHECK-NEXT: ret void +// +void test_dmr_typedef(int *inp, int *outp) { + __dmr1024 *vdmrin = (__dmr1024 *)inp; + __dmr1024 *vdmrout = (__dmr1024 *)outp; + *vdmrout = *vdmrin; +} + +// CHECK-LABEL: @test_dmr_arg( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[VDMR_ADDR:%.*]] = alloca ptr, align 8 +// CHECK-NEXT: [[PTR_ADDR:%.*]] = alloca ptr, align 8 +// CHECK-NEXT: [[VDMRP:%.*]] = alloca ptr, align 8 +// CHECK-NEXT: store ptr [[VDMR:%.*]], ptr [[VDMR_ADDR]], align 8 +// CHECK-NEXT: store ptr [[PTR:%.*]], ptr [[PTR_ADDR]], align 8 +// CHECK-NEXT: [[TMP0:%.*]] = load ptr, ptr [[PTR_ADDR]], align 8 +// CHECK-NEXT: store ptr [[TMP0]], ptr [[VDMRP]], align 8 +// CHECK-NEXT: [[TMP1:%.*]] = load ptr, ptr [[VDMR_ADDR]], align 8 +// CHECK-NEXT: [[TMP2:%.*]] = load <1024 x i1>, ptr [[TMP1]], align 128 +// CHECK-NEXT: [[TMP3:%.*]] = load ptr, ptr [[VDMRP]], align 8 +// CHECK-NEXT: store <1024 x i1> [[TMP2]], ptr [[TMP3]], align 128 +// CHECK-NEXT: ret void +// +void test_dmr_arg(__dmr1024 *vdmr, int *ptr) { + __dmr1024 *vdmrp = (__dmr1024 *)ptr; + *vdmrp = *vdmr; +} + +// CHECK-LABEL: @test_dmr_const_arg( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[VDMR_ADDR:%.*]] = alloca ptr, align 8 +// CHECK-NEXT: [[PTR_ADDR:%.*]] = alloca ptr, align 8 +// CHECK-NEXT: [[VDMRP:%.*]] = alloca ptr, align 8 +// CHECK-NEXT: store ptr [[VDMR:%.*]], ptr [[VDMR_ADDR]], align 8 +// CHECK-NEXT: store ptr [[PTR:%.*]], ptr [[PTR_ADDR]], align 8 +// CHECK-NEXT: [[TMP0:%.*]] = load ptr, ptr [[PTR_ADDR]], align 8 +// CHECK-NEXT: store ptr [[TMP0]], ptr [[VDMRP]], align 8 +// CHECK-NEXT: [[TMP1:%.*]] = load ptr, ptr [[VDMR_ADDR]], align 8 +// CHECK-NEXT: [[TMP2:%.*]] = load <1024 x i1>, ptr [[TMP1]], align 128 +// CHECK-NEXT: [[TMP3:%.*]] = load ptr, ptr [[VDMRP]], align 8 +// CHECK-NEXT: store <1024 x i1> [[TMP2]], ptr [[TMP3]], align 128 +// CHECK-NEXT: ret void +// +void test_dmr_const_arg(const __dmr1024 *const vdmr, int *ptr) { + __dmr1024 *vdmrp = (__dmr1024 *)ptr; + *vdmrp = *vdmr; +} + +// CHECK-LABEL: @test_dmr_array_arg( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[VDMRA_ADDR:%.*]] = alloca ptr, align 8 +// CHECK-NEXT: [[PTR_ADDR:%.*]] = alloca ptr, align 8 +// CHECK-NEXT: [[VDMRP:%.*]] = alloca ptr, align 8 +// CHECK-NEXT: store ptr [[VDMRA:%.*]], ptr [[VDMRA_ADDR]], align 8 +// CHECK-NEXT: store ptr [[PTR:%.*]], ptr [[PTR_ADDR]], align 8 +// CHECK-NEXT: [[TMP0:%.*]] = load ptr, ptr [[PTR_ADDR]], align 8 +// CHECK-NEXT: store ptr [[TMP0]], ptr [[VDMRP]], align 8 +// CHECK-NEXT: [[TMP1:%.*]] = load ptr, ptr [[VDMRA_ADDR]], align 8 +// CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds <1024 x i1>, ptr [[TMP1]], i64 0 +// CHECK-NEXT: [[TMP2:%.*]] = load <1024 x i1>, ptr [[ARRAYIDX]], align 128 +// CHECK-NEXT: [[TMP3:%.*]] = load ptr, ptr [[VDMRP]], align 8 +// CHECK-NEXT: store <1024 x i1> [[TMP2]], ptr [[TMP3]], align 128 +// CHECK-NEXT: ret void +// +void test_dmr_array_arg(__dmr1024 vdmra[], int *ptr) { + __dmr1024 *vdmrp = (__dmr1024 *)ptr; + *vdmrp = vdmra[0]; +} + +// CHECK-LABEL: @test_dmr_ret( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[PTR_ADDR:%.*]] = alloca ptr, align 8 +// CHECK-NEXT: [[VDMRP:%.*]] = alloca ptr, align 8 +// CHECK-NEXT: store ptr [[PTR:%.*]], ptr [[PTR_ADDR]], align 8 +// CHECK-NEXT: [[TMP0:%.*]] = load ptr, ptr [[PTR_ADDR]], align 8 +// CHECK-NEXT: store ptr [[TMP0]], ptr [[VDMRP]], align 8 +// CHECK-NEXT: [[TMP1:%.*]] = load ptr, ptr [[VDMRP]], align 8 +// CHECK-NEXT: [[ADD_PTR:%.*]] = getelementptr inbounds <1024 x i1>, ptr [[TMP1]], i64 2 +// CHECK-NEXT: ret ptr [[ADD_PTR]] +// +__dmr1024 *test_dmr_ret(int *ptr) { + __dmr1024 *vdmrp = (__dmr1024 *)ptr; + return vdmrp + 2; +} + +// CHECK-LABEL: @test_dmr_ret_const( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[PTR_ADDR:%.*]] = alloca ptr, align 8 +// CHECK-NEXT: [[VDMRP:%.*]] = alloca ptr, align 8 +// CHECK-NEXT: store ptr [[PTR:%.*]], ptr [[PTR_ADDR]], align 8 +// CHECK-NEXT: [[TMP0:%.*]] = load ptr, ptr [[PTR_ADDR]], align 8 +// CHECK-NEXT: store ptr [[TMP0]], ptr [[VDMRP]], align 8 +// CHECK-NEXT: [[TMP1:%.*]] = load ptr, ptr [[VDMRP]], align 8 +// CHECK-NEXT: [[ADD_PTR:%.*]] = getelementptr inbounds <1024 x i1>, ptr [[TMP1]], i64 2 +// CHECK-NEXT: ret ptr [[ADD_PTR]] +// +const __dmr1024 *test_dmr_ret_const(int *ptr) { + __dmr1024 *vdmrp = (__dmr1024 *)ptr; + return vdmrp + 2; +} + +// CHECK-LABEL: @test_dmr_sizeof_alignof( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[PTR_ADDR:%.*]] = alloca ptr, align 8 +// CHECK-NEXT: [[VDMRP:%.*]] = alloca ptr, align 8 +// CHECK-NEXT: [[VDMR:%.*]] = alloca <1024 x i1>, align 128 +// CHECK-NEXT: [[SIZET:%.*]] = alloca i32, align 4 +// CHECK-NEXT: [[ALIGNT:%.*]] = alloca i32, align 4 +// CHECK-NEXT: [[SIZEV:%.*]] = alloca i32, align 4 +// CHECK-NEXT: [[ALIGNV:%.*]] = alloca i32, align 4 +// CHECK-NEXT: store ptr [[PTR:%.*]], ptr [[PTR_ADDR]], align 8 +// CHECK-NEXT: [[TMP0:%.*]] = load ptr, ptr [[PTR_ADDR]], align 8 +// CHECK-NEXT: store ptr [[TMP0]], ptr [[VDMRP]], align 8 +// CHECK-NEXT: [[TMP1:%.*]] = load ptr, ptr [[VDMRP]], align 8 +// CHECK-NEXT: [[TMP2:%.*]] = load <1024 x i1>, ptr [[TMP1]], align 128 +// CHECK-NEXT: store <1024 x i1> [[TMP2]], ptr [[VDMR]], align 128 +// CHECK-NEXT: store i32 128, ptr [[SIZET]], align 4 +// CHECK-NEXT: store i32 128, ptr [[ALIGNT]], align 4 +// CHECK-NEXT: store i32 128, ptr [[SIZEV]], align 4 +// CHECK-NEXT: store i32 128, ptr [[ALIGNV]], align 4 +// CHECK-NEXT: [[TMP3:%.*]] = load i32, ptr [[SIZET]], align 4 +// CHECK-NEXT: [[TMP4:%.*]] = load i32, ptr [[ALIGNT]], align 4 +// CHECK-NEXT: [[ADD:%.*]] = add i32 [[TMP3]], [[TMP4]] +// CHECK-NEXT: [[TMP5:%.*]] = load i32, ptr [[SIZEV]], align 4 +// CHECK-NEXT: [[ADD1:%.*]] = add i32 [[ADD]], [[TMP5]] +// CHECK-NEXT: [[TMP6:%.*]] = load i32, ptr [[ALIGNV]], align 4 +// CHECK-NEXT: [[ADD2:%.*]] = add i32 [[ADD1]], [[TMP6]] +// CHECK-NEXT: ret i32 [[ADD2]] +// +int test_dmr_sizeof_alignof(int *ptr) { + __dmr1024 *vdmrp = (__dmr1024 *)ptr; + __dmr1024 vdmr = *vdmrp; + unsigned sizet = sizeof(__dmr1024); + unsigned alignt = __alignof__(__dmr1024); + unsigned sizev = sizeof(vdmr); + unsigned alignv = __alignof__(vdmr); + return sizet + alignt + sizev + alignv; +} diff --git a/external/llvm-project/clang/test/CodeGen/PowerPC/ppc-future-mma-builtin-err.c b/external/llvm-project/clang/test/CodeGen/PowerPC/ppc-future-mma-builtin-err.c new file mode 100644 index 000000000000..1b8d345ac7ec --- /dev/null +++ b/external/llvm-project/clang/test/CodeGen/PowerPC/ppc-future-mma-builtin-err.c @@ -0,0 +1,21 @@ +// RUN: not %clang_cc1 -triple powerpc64le-unknown-linux-gnu -target-cpu future \ +// RUN: %s -emit-llvm-only 2>&1 | FileCheck %s + +__attribute__((target("no-mma"))) +void test_mma(unsigned char *vdmrp, unsigned char *vpp, vector unsigned char vc) { + __dmr1024 vdmr = *((__dmr1024 *)vdmrp); + __vector_pair vp = *((__vector_pair *)vpp); + __builtin_mma_dmxvi8gerx4(&vdmr, vp, vc); + __builtin_mma_pmdmxvi8gerx4(&vdmr, vp, vc, 0, 0, 0); + __builtin_mma_dmxvi8gerx4pp(&vdmr, vp, vc); + __builtin_mma_pmdmxvi8gerx4pp(&vdmr, vp, vc, 0, 0, 0); + __builtin_mma_dmxvi8gerx4spp(&vdmr, vp, vc); + __builtin_mma_pmdmxvi8gerx4spp(&vdmr, vp, vc, 0, 0, 0); + +// CHECK: error: '__builtin_mma_dmxvi8gerx4' needs target feature mma,paired-vector-memops +// CHECK: error: '__builtin_mma_pmdmxvi8gerx4' needs target feature mma,paired-vector-memops +// CHECK: error: '__builtin_mma_dmxvi8gerx4pp' needs target feature mma,paired-vector-memops +// CHECK: error: '__builtin_mma_pmdmxvi8gerx4pp' needs target feature mma,paired-vector-memops +// CHECK: error: '__builtin_mma_dmxvi8gerx4spp' needs target feature mma,paired-vector-memops +// CHECK: error: '__builtin_mma_pmdmxvi8gerx4spp' needs target feature mma,paired-vector-memops +} diff --git a/external/llvm-project/clang/test/CodeGen/aarch64-always-inline-feature-bug.c b/external/llvm-project/clang/test/CodeGen/aarch64-always-inline-feature-bug.c new file mode 100644 index 000000000000..27c3983c66d2 --- /dev/null +++ b/external/llvm-project/clang/test/CodeGen/aarch64-always-inline-feature-bug.c @@ -0,0 +1,8 @@ +// RUN: %clang_cc1 -triple aarch64-- -target-feature +neon -target-feature +sve\ +// RUN: -target-feature -sve -emit-llvm %s -o - | FileCheck %s + +// Reproducer for bug where clang would reject always_inline for unrelated +// target features if they were disable with `-feature` on the command line. +// CHECK: @bar +__attribute__((always_inline)) __attribute__((target("neon"))) void foo() {} +void bar() { foo(); } diff --git a/external/llvm-project/clang/test/CodeGen/builtin_vectorelements.c b/external/llvm-project/clang/test/CodeGen/builtin_vectorelements.c index b0ff6f83b1e4..45f7a3c34562 100644 --- a/external/llvm-project/clang/test/CodeGen/builtin_vectorelements.c +++ b/external/llvm-project/clang/test/CodeGen/builtin_vectorelements.c @@ -85,7 +85,7 @@ int test_builtin_vectorelements_neon64x1() { long test_builtin_vectorelements_sve32() { // SVE: i64 @test_builtin_vectorelements_sve32( // SVE: [[VSCALE:%.+]] = call i64 @llvm.vscale.i64() - // SVE: [[RES:%.+]] = mul i64 [[VSCALE]], 4 + // SVE: [[RES:%.+]] = mul nuw i64 [[VSCALE]], 4 // SVE: ret i64 [[RES]] return __builtin_vectorelements(svuint32_t); } @@ -93,7 +93,7 @@ long test_builtin_vectorelements_sve32() { long test_builtin_vectorelements_sve8() { // SVE: i64 @test_builtin_vectorelements_sve8( // SVE: [[VSCALE:%.+]] = call i64 @llvm.vscale.i64() - // SVE: [[RES:%.+]] = mul i64 [[VSCALE]], 16 + // SVE: [[RES:%.+]] = mul nuw i64 [[VSCALE]], 16 // SVE: ret i64 [[RES]] return __builtin_vectorelements(svuint8_t); } @@ -105,7 +105,7 @@ long test_builtin_vectorelements_sve8() { long test_builtin_vectorelements_riscv8() { // RISCV: i64 @test_builtin_vectorelements_riscv8( // RISCV: [[VSCALE:%.+]] = call i64 @llvm.vscale.i64() - // RISCV: [[RES:%.+]] = mul i64 [[VSCALE]], 8 + // RISCV: [[RES:%.+]] = mul nuw i64 [[VSCALE]], 8 // RISCV: ret i64 [[RES]] return __builtin_vectorelements(vuint8m1_t); } @@ -120,7 +120,7 @@ long test_builtin_vectorelements_riscv64() { long test_builtin_vectorelements_riscv32m2() { // RISCV: i64 @test_builtin_vectorelements_riscv32m2( // RISCV: [[VSCALE:%.+]] = call i64 @llvm.vscale.i64() - // RISCV: [[RES:%.+]] = mul i64 [[VSCALE]], 4 + // RISCV: [[RES:%.+]] = mul nuw i64 [[VSCALE]], 4 // RISCV: ret i64 [[RES]] return __builtin_vectorelements(vuint32m2_t); } diff --git a/external/llvm-project/clang/test/CodeGen/epilog-unwind.c b/external/llvm-project/clang/test/CodeGen/epilog-unwind.c index 991ff09fb37c..b2f7497b455b 100644 --- a/external/llvm-project/clang/test/CodeGen/epilog-unwind.c +++ b/external/llvm-project/clang/test/CodeGen/epilog-unwind.c @@ -1,9 +1,11 @@ // RUN: %clang_cc1 -emit-llvm %s -o - | FileCheck %s -check-prefix=DISABLED -// RUN: %clang_cc1 -fwinx64-eh-unwindv2 -emit-llvm %s -o - | FileCheck %s -check-prefix=ENABLED -// RUN: %clang -fwinx64-eh-unwindv2 -S -emit-llvm %s -o - | FileCheck %s -check-prefix=ENABLED -// RUN: %clang -fno-winx64-eh-unwindv2 -S -emit-llvm %s -o - | FileCheck %s -check-prefix=DISABLED +// RUN: %clang_cc1 -fwinx64-eh-unwindv2=disabled -emit-llvm %s -o - | FileCheck %s -check-prefix=DISABLED +// RUN: %clang_cc1 -fwinx64-eh-unwindv2=best-effort -emit-llvm %s -o - | FileCheck %s -check-prefix=BESTEFFORT +// RUN: %clang_cc1 -fwinx64-eh-unwindv2=required -emit-llvm %s -o - | FileCheck %s -check-prefix=REQUIRED +// RUN: %clang -fwinx64-eh-unwindv2=best-effort -S -emit-llvm %s -o - | FileCheck %s -check-prefix=BESTEFFORT void f(void) {} -// ENABLED: !"winx64-eh-unwindv2", i32 1} +// BESTEFFORT: !"winx64-eh-unwindv2", i32 1} +// REQUIRED: !"winx64-eh-unwindv2", i32 2} // DISABLED-NOT: "winx64-eh-unwindv2" diff --git a/external/llvm-project/clang/test/CodeGenCXX/cxx11-thread-local-reference.cpp b/external/llvm-project/clang/test/CodeGenCXX/cxx11-thread-local-reference.cpp index cd5a18f39060..a0e76e8a9a0b 100644 --- a/external/llvm-project/clang/test/CodeGenCXX/cxx11-thread-local-reference.cpp +++ b/external/llvm-project/clang/test/CodeGenCXX/cxx11-thread-local-reference.cpp @@ -35,5 +35,5 @@ int &g() { return r; } // DARWIN-LABEL: define internal cxx_fast_tlscc void @__tls_init() // CHECK: call void @[[R_INIT]]() -// LINUX_AIX: attributes [[ATTR0]] = { {{.*}}"target-features"{{.*}} } +// LINUX_AIX: attributes [[ATTR0]] = { {{.*}} } // DARWIN: attributes [[ATTR1]] = { {{.*}}nounwind{{.*}}"target-features"{{.*}} } diff --git a/external/llvm-project/clang/test/CodeGenCXX/ppc-mangle-mma-types.cpp b/external/llvm-project/clang/test/CodeGenCXX/ppc-mangle-mma-types.cpp index 74e50ceea386..1e213e7f7512 100644 --- a/external/llvm-project/clang/test/CodeGenCXX/ppc-mangle-mma-types.cpp +++ b/external/llvm-project/clang/test/CodeGenCXX/ppc-mangle-mma-types.cpp @@ -1,3 +1,5 @@ +// RUN: %clang_cc1 -triple powerpc64le-linux-unknown -target-cpu future %s \ +// RUN: -emit-llvm -o - | FileCheck %s // RUN: %clang_cc1 -triple powerpc64le-linux-unknown -target-cpu pwr10 %s \ // RUN: -emit-llvm -o - | FileCheck %s // RUN: %clang_cc1 -triple powerpc64le-linux-unknown -target-cpu pwr9 %s \ @@ -5,6 +7,9 @@ // RUN: %clang_cc1 -triple powerpc64le-linux-unknown -target-cpu pwr8 %s \ // RUN: -emit-llvm -o - | FileCheck %s +// CHECK: _Z2f0Pu9__dmr1024 +void f0(__dmr1024 *vdmr) {} + // CHECK: _Z2f1Pu13__vector_quad void f1(__vector_quad *vq) {} diff --git a/external/llvm-project/clang/test/CodeGenHLSL/ArrayAssignable.hlsl b/external/llvm-project/clang/test/CodeGenHLSL/ArrayAssignable.hlsl index c3204570d6ef..aaa486eff10b 100644 --- a/external/llvm-project/clang/test/CodeGenHLSL/ArrayAssignable.hlsl +++ b/external/llvm-project/clang/test/CodeGenHLSL/ArrayAssignable.hlsl @@ -7,10 +7,10 @@ struct S { // CHECK: [[CBLayout:%.*]] = type <{ [2 x float], [2 x <4 x i32>], [2 x [2 x i32]], [1 x target("dx.Layout", %S, 8, 0, 4)] }> // CHECK: @CBArrays.cb = global target("dx.CBuffer", target("dx.Layout", [[CBLayout]], 136, 0, 32, 64, 128)) -// CHECK: @c1 = external addrspace(2) global [2 x float], align 4 -// CHECK: @c2 = external addrspace(2) global [2 x <4 x i32>], align 16 -// CHECK: @c3 = external addrspace(2) global [2 x [2 x i32]], align 4 -// CHECK: @c4 = external addrspace(2) global [1 x target("dx.Layout", %S, 8, 0, 4)], align 1 +// CHECK: @c1 = external hidden addrspace(2) global [2 x float], align 4 +// CHECK: @c2 = external hidden addrspace(2) global [2 x <4 x i32>], align 16 +// CHECK: @c3 = external hidden addrspace(2) global [2 x [2 x i32]], align 4 +// CHECK: @c4 = external hidden addrspace(2) global [1 x target("dx.Layout", %S, 8, 0, 4)], align 1 cbuffer CBArrays : register(b0) { float c1[2]; @@ -19,7 +19,7 @@ cbuffer CBArrays : register(b0) { S c4[1]; } -// CHECK-LABEL: define void {{.*}}arr_assign1 +// CHECK-LABEL: define hidden void {{.*}}arr_assign1 // CHECK: [[Arr:%.*]] = alloca [2 x i32], align 4 // CHECK-NEXT: [[Arr2:%.*]] = alloca [2 x i32], align 4 // CHECK-NOT: alloca @@ -33,7 +33,7 @@ void arr_assign1() { Arr = Arr2; } -// CHECK-LABEL: define void {{.*}}arr_assign2 +// CHECK-LABEL: define hidden void {{.*}}arr_assign2 // CHECK: [[Arr:%.*]] = alloca [2 x i32], align 4 // CHECK-NEXT: [[Arr2:%.*]] = alloca [2 x i32], align 4 // CHECK-NEXT: [[Arr3:%.*]] = alloca [2 x i32], align 4 @@ -51,7 +51,7 @@ void arr_assign2() { Arr = Arr2 = Arr3; } -// CHECK-LABEL: define void {{.*}}arr_assign3 +// CHECK-LABEL: define hidden void {{.*}}arr_assign3 // CHECK: [[Arr3:%.*]] = alloca [2 x [2 x i32]], align 4 // CHECK-NEXT: [[Arr4:%.*]] = alloca [2 x [2 x i32]], align 4 // CHECK-NOT: alloca @@ -65,7 +65,7 @@ void arr_assign3() { Arr2 = Arr3; } -// CHECK-LABEL: define void {{.*}}arr_assign4 +// CHECK-LABEL: define hidden void {{.*}}arr_assign4 // CHECK: [[Arr:%.*]] = alloca [2 x i32], align 4 // CHECK-NEXT: [[Arr2:%.*]] = alloca [2 x i32], align 4 // CHECK-NOT: alloca @@ -81,7 +81,7 @@ void arr_assign4() { (Arr = Arr2)[0] = 6; } -// CHECK-LABEL: define void {{.*}}arr_assign5 +// CHECK-LABEL: define hidden void {{.*}}arr_assign5 // CHECK: [[Arr:%.*]] = alloca [2 x i32], align 4 // CHECK-NEXT: [[Arr2:%.*]] = alloca [2 x i32], align 4 // CHECK-NEXT: [[Arr3:%.*]] = alloca [2 x i32], align 4 @@ -101,7 +101,7 @@ void arr_assign5() { (Arr = Arr2 = Arr3)[0] = 6; } -// CHECK-LABEL: define void {{.*}}arr_assign6 +// CHECK-LABEL: define hidden void {{.*}}arr_assign6 // CHECK: [[Arr3:%.*]] = alloca [2 x [2 x i32]], align 4 // CHECK-NEXT: [[Arr4:%.*]] = alloca [2 x [2 x i32]], align 4 // CHECK-NOT: alloca @@ -118,7 +118,7 @@ void arr_assign6() { (Arr = Arr2)[0][0] = 6; } -// CHECK-LABEL: define void {{.*}}arr_assign7 +// CHECK-LABEL: define hidden void {{.*}}arr_assign7 // CHECK: [[Arr:%.*]] = alloca [2 x [2 x i32]], align 4 // CHECK-NEXT: [[Arr2:%.*]] = alloca [2 x [2 x i32]], align 4 // CHECK-NOT: alloca @@ -138,7 +138,7 @@ void arr_assign7() { // Verify you can assign from a cbuffer array -// CHECK-LABEL: define void {{.*}}arr_assign8 +// CHECK-LABEL: define hidden void {{.*}}arr_assign8 // CHECK: [[C:%.*]] = alloca [2 x float], align 4 // CHECK-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 4 [[C]], ptr align 4 {{.*}}, i32 8, i1 false) // CHECK-NEXT: call void @llvm.memcpy.p0.p2.i32(ptr align 4 [[C]], ptr addrspace(2) align 4 @c1, i32 8, i1 false) @@ -148,7 +148,7 @@ void arr_assign8() { C = c1; } -// CHECK-LABEL: define void {{.*}}arr_assign9 +// CHECK-LABEL: define hidden void {{.*}}arr_assign9 // CHECK: [[C:%.*]] = alloca [2 x <4 x i32>], align 16 // CHECK-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 16 [[C]], ptr align 16 {{.*}}, i32 32, i1 false) // CHECK-NEXT: call void @llvm.memcpy.p0.p2.i32(ptr align 16 [[C]], ptr addrspace(2) align 16 @c2, i32 32, i1 false) @@ -158,7 +158,7 @@ void arr_assign9() { C = c2; } -// CHECK-LABEL: define void {{.*}}arr_assign10 +// CHECK-LABEL: define hidden void {{.*}}arr_assign10 // CHECK: [[C:%.*]] = alloca [2 x [2 x i32]], align 4 // CHECK-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 4 [[C]], ptr align 4 {{.*}}, i32 16, i1 false) // CHECK-NEXT: call void @llvm.memcpy.p0.p2.i32(ptr align 4 [[C]], ptr addrspace(2) align 4 @c3, i32 16, i1 false) @@ -168,7 +168,7 @@ void arr_assign10() { C = c3; } -// CHECK-LABEL: define void {{.*}}arr_assign11 +// CHECK-LABEL: define hidden void {{.*}}arr_assign11 // CHECK: [[C:%.*]] = alloca [1 x %struct.S], align 1 // CHECK: call void @llvm.memcpy.p0.p2.i32(ptr align 1 [[C]], ptr addrspace(2) align 1 @c4, i32 8, i1 false) // CHECK-NEXT: ret void diff --git a/external/llvm-project/clang/test/CodeGenHLSL/ArrayTemporary.hlsl b/external/llvm-project/clang/test/CodeGenHLSL/ArrayTemporary.hlsl index 29ea896045bb..42a469ae8795 100644 --- a/external/llvm-project/clang/test/CodeGenHLSL/ArrayTemporary.hlsl +++ b/external/llvm-project/clang/test/CodeGenHLSL/ArrayTemporary.hlsl @@ -3,7 +3,7 @@ void fn(float x[2]) { } -// CHECK-LABEL: define void {{.*}}call{{.*}} +// CHECK-LABEL: define hidden void {{.*}}call{{.*}} // CHECK: [[Arr:%.*]] = alloca [2 x float] // CHECK: [[Tmp:%.*]] = alloca [2 x float] // CHECK: call void @llvm.memset.p0.i32(ptr align 4 [[Arr]], i8 0, i32 8, i1 false) @@ -21,7 +21,7 @@ struct Obj { void fn2(Obj O[4]) { } -// CHECK-LABEL: define void {{.*}}call2{{.*}} +// CHECK-LABEL: define hidden void {{.*}}call2{{.*}} // CHECK: [[Arr:%.*]] = alloca [4 x %struct.Obj] // CHECK: [[Tmp:%.*]] = alloca [4 x %struct.Obj] // CHECK: call void @llvm.memset.p0.i32(ptr align 1 [[Arr]], i8 0, i32 32, i1 false) @@ -35,7 +35,7 @@ void call2() { void fn3(float x[2][2]) { } -// CHECK-LABEL: define void {{.*}}call3{{.*}} +// CHECK-LABEL: define hidden void {{.*}}call3{{.*}} // CHECK: [[Arr:%.*]] = alloca [2 x [2 x float]] // CHECK: [[Tmp:%.*]] = alloca [2 x [2 x float]] // CHECK: call void @llvm.memcpy.p0.p0.i32(ptr align 4 [[Arr]], ptr align 4 {{.*}}, i32 16, i1 false) @@ -46,7 +46,7 @@ void call3() { fn3(Arr); } -// CHECK-LABEL: define void {{.*}}call4{{.*}}(ptr +// CHECK-LABEL: define hidden void {{.*}}call4{{.*}}(ptr // CHECK-SAME: noundef byval([2 x [2 x float]]) align 4 [[Arr:%.*]]) // CHECK: [[Tmp:%.*]] = alloca [2 x [2 x float]] // CHECK: call void @llvm.memcpy.p0.p0.i32(ptr align 4 [[Tmp]], ptr align 4 [[Arr]], i32 16, i1 false) @@ -59,7 +59,7 @@ void call4(float Arr[2][2]) { // Verify that each template instantiation codegens to a unique and correctly // mangled function name. -// CHECK-LABEL: define void {{.*}}template_call{{.*}}(ptr +// CHECK-LABEL: define hidden void {{.*}}template_call{{.*}}(ptr // CHECK-SAME: noundef byval([2 x float]) align 4 [[FA2:%[0-9A-Z]+]], // CHECK-SAME: ptr noundef byval([4 x float]) align 4 [[FA4:%[0-9A-Z]+]], @@ -86,7 +86,7 @@ void template_call(float FA2[2], float FA4[4], int IA3[3]) { // Verify that Array parameter element access correctly codegens. -// CHECK-LABEL: define void {{.*}}element_access{{.*}}(ptr +// CHECK-LABEL: define hidden void {{.*}}element_access{{.*}}(ptr // CHECK-SAME: noundef byval([2 x float]) align 4 [[FA2:%[0-9A-Z]+]] // CHECK: [[Addr:%.*]] = getelementptr inbounds [2 x float], ptr [[FA2]], i32 0, i32 0 diff --git a/external/llvm-project/clang/test/CodeGenHLSL/BasicFeatures/ArrayOutputArguments.hlsl b/external/llvm-project/clang/test/CodeGenHLSL/BasicFeatures/ArrayOutputArguments.hlsl index eb7d755bca61..bccfaf597f0e 100644 --- a/external/llvm-project/clang/test/CodeGenHLSL/BasicFeatures/ArrayOutputArguments.hlsl +++ b/external/llvm-project/clang/test/CodeGenHLSL/BasicFeatures/ArrayOutputArguments.hlsl @@ -11,7 +11,7 @@ void increment(inout int Arr[2]) { // CHECK-NEXT: [[Tmp:%.*]] = alloca [2 x i32], align 4 // CHECK-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 4 [[A]], ptr align 4 @{{.*}}, i32 8, i1 false) // CHECK-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 4 [[Tmp]], ptr align 4 [[A]], i32 8, i1 false) -// CHECK-NEXT: call void @{{.*}}increment{{.*}}(ptr noalias noundef byval([2 x i32]) align 4 [[Tmp]]) #3 +// CHECK-NEXT: call void @{{.*}}increment{{.*}}(ptr noalias noundef byval([2 x i32]) align 4 [[Tmp]]) // CHECK-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 4 [[A]], ptr align 4 [[Tmp]], i32 8, i1 false) // CHECK-NEXT: [[Idx:%.*]] = getelementptr inbounds [2 x i32], ptr [[A]], i32 0, i32 0 // CHECK-NEXT: [[B:%.*]] = load i32, ptr [[Idx]], align 4 @@ -32,7 +32,7 @@ void fn2(out int Arr[2]) { // CHECK: [[A:%.*]] = alloca [2 x i32], align 4 // CHECK-NEXT: [[Tmp:%.*]] = alloca [2 x i32], align 4 // CHECK-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 4 [[A]], ptr align 4 @{{.*}}, i32 8, i1 false) -// CHECK-NEXT: call void @{{.*}}fn2{{.*}}(ptr noalias noundef byval([2 x i32]) align 4 [[Tmp]]) #3 +// CHECK-NEXT: call void @{{.*}}fn2{{.*}}(ptr noalias noundef byval([2 x i32]) align 4 [[Tmp]]) // CHECK-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 4 [[A]], ptr align 4 [[Tmp]], i32 8, i1 false) // CHECK-NEXT: [[Idx:%.*]] = getelementptr inbounds [2 x i32], ptr [[A]], i32 0, i32 0 // CHECK-NEXT: [[B:%.*]] = load i32, ptr [[Idx]], align 4 @@ -56,7 +56,7 @@ void nestedCall(inout int Arr[2], uint index) { // CHECK-NEXT: [[Tmp:%.*]] = alloca [2 x i32], align 4 // CHECK-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 4 [[A]], ptr align 4 @{{.*}}, i32 8, i1 false) // CHECK-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 4 [[Tmp]], ptr align 4 [[A]], i32 8, i1 false) -// CHECK-NEXT: call void @{{.*}}nestedCall{{.*}}(ptr noalias noundef byval([2 x i32]) align 4 [[Tmp]], i32 noundef 0) #3 +// CHECK-NEXT: call void @{{.*}}nestedCall{{.*}}(ptr noalias noundef byval([2 x i32]) align 4 [[Tmp]], i32 noundef 0) // CHECK-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 4 [[A]], ptr align 4 [[Tmp]], i32 8, i1 false) // CHECK-NEXT: [[Idx:%.*]] = getelementptr inbounds [2 x i32], ptr [[A]], i32 0, i32 1 // CHECK-NEXT: [[B:%.*]] = load i32, ptr [[Idx]], align 4 @@ -70,7 +70,7 @@ export int arrayCall3() { // CHECK-LABEL: outerCall // CHECK: [[Tmp:%.*]] = alloca [2 x i32], align 4 // CHECK-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 4 [[Tmp]], ptr align 4 %{{.*}}, i32 8, i1 false) -// CHECK-NEXT: call void {{.*}}increment{{.*}}(ptr noalias noundef byval([2 x i32]) align 4 [[Tmp]]) #3 +// CHECK-NEXT: call void {{.*}}increment{{.*}}(ptr noalias noundef byval([2 x i32]) align 4 [[Tmp]]) // CHECK-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 4 {{.*}}, ptr align 4 [[Tmp]], i32 8, i1 false) // CHECK-NEXT: ret void void outerCall(inout int Arr[2]) { @@ -82,7 +82,7 @@ void outerCall(inout int Arr[2]) { // CHECK-NEXT: [[Tmp:%.*]] = alloca [2 x i32], align 4 // CHECK-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 4 [[A]], ptr align 4 @{{.*}}, i32 8, i1 false) // CHECK-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 4 [[Tmp]], ptr align 4 [[A]], i32 8, i1 false) -// CHECK-NEXT: call void @{{.*}}outerCall{{.*}}(ptr noalias noundef byval([2 x i32]) align 4 [[Tmp]]) #3 +// CHECK-NEXT: call void @{{.*}}outerCall{{.*}}(ptr noalias noundef byval([2 x i32]) align 4 [[Tmp]]) // CHECK-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 4 [[A]], ptr align 4 [[Tmp]], i32 8, i1 false) // CHECK-NEXT: [[Idx:%.*]] = getelementptr inbounds [2 x i32], ptr [[A]], i32 0, i32 0 // CHECK-NEXT: [[B:%.*]] = load i32, ptr [[Idx]], align 4 @@ -99,7 +99,7 @@ void fn3(int Arr[2]) {} // CHECK-LABEL: outerCall2 // CHECK: [[Tmp:%.*]] = alloca [2 x i32], align 4 // CHECK-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 4 [[Tmp]], ptr align 4 {{.*}}, i32 8, i1 false) -// CHECK-NEXT: call void {{.*}}fn3{{.*}}(ptr noundef byval([2 x i32]) align 4 [[Tmp]]) #3 +// CHECK-NEXT: call void {{.*}}fn3{{.*}}(ptr noundef byval([2 x i32]) align 4 [[Tmp]]) // CHECK-NEXT: ret void void outerCall2(inout int Arr[2]) { fn3(Arr); @@ -110,7 +110,7 @@ void outerCall2(inout int Arr[2]) { // CHECK-NEXT: [[Tmp:%.*]] = alloca [2 x i32], align 4 // CHECK-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 4 [[A]], ptr align 4 @{{.*}}, i32 8, i1 false) // CHECK-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 4 [[Tmp]], ptr align 4 [[A]], i32 8, i1 false) -// CHECK-NEXT: call void @{{.*}}outerCall2{{.*}}(ptr noalias noundef byval([2 x i32]) align 4 [[Tmp]]) #3 +// CHECK-NEXT: call void @{{.*}}outerCall2{{.*}}(ptr noalias noundef byval([2 x i32]) align 4 [[Tmp]]) // CHECK-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 4 [[A]], ptr align 4 [[Tmp]], i32 8, i1 false) // CHECK-NEXT: [[Idx:%.*]] = getelementptr inbounds [2 x i32], ptr [[A]], i32 0, i32 0 // CHECK-NEXT: [[B:%.*]] = load i32, ptr [[Idx]], align 4 diff --git a/external/llvm-project/clang/test/CodeGenHLSL/BasicFeatures/InitLists.hlsl b/external/llvm-project/clang/test/CodeGenHLSL/BasicFeatures/InitLists.hlsl index 371f31c9e4af..c30c640519cd 100644 --- a/external/llvm-project/clang/test/CodeGenHLSL/BasicFeatures/InitLists.hlsl +++ b/external/llvm-project/clang/test/CodeGenHLSL/BasicFeatures/InitLists.hlsl @@ -46,7 +46,7 @@ struct SlicyBits { }; // Case 1: Extraneous braces get ignored in literal instantiation. -// CHECK-LABEL: define void @_Z5case1v( +// CHECK-LABEL: define hidden void @_Z5case1v( // CHECK-SAME: ptr dead_on_unwind noalias writable sret([[STRUCT_TWOFLOATS:%.*]]) align 1 [[AGG_RESULT:%.*]]) #[[ATTR0:[0-9]+]] { // CHECK-NEXT: [[ENTRY:.*:]] // CHECK-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 1 [[AGG_RESULT]], ptr align 1 @__const._Z5case1v.TF1, i32 8, i1 false) @@ -58,7 +58,7 @@ TwoFloats case1() { } // Case 2: Valid C/C++ initializer is handled appropriately. -// CHECK-LABEL: define void @_Z5case2v( +// CHECK-LABEL: define hidden void @_Z5case2v( // CHECK-SAME: ptr dead_on_unwind noalias writable sret([[STRUCT_TWOFLOATS:%.*]]) align 1 [[AGG_RESULT:%.*]]) #[[ATTR0]] { // CHECK-NEXT: [[ENTRY:.*:]] // CHECK-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 1 [[AGG_RESULT]], ptr align 1 @__const._Z5case2v.TF2, i32 8, i1 false) @@ -70,7 +70,7 @@ TwoFloats case2() { } // Case 3: Simple initialization with conversion of an argument. -// CHECK-LABEL: define void @_Z5case3i( +// CHECK-LABEL: define hidden void @_Z5case3i( // CHECK-SAME: ptr dead_on_unwind noalias writable sret([[STRUCT_TWOFLOATS:%.*]]) align 1 [[AGG_RESULT:%.*]], i32 noundef [[VAL:%.*]]) #[[ATTR0]] { // CHECK-NEXT: [[ENTRY:.*:]] // CHECK-NEXT: [[VAL_ADDR:%.*]] = alloca i32, align 4 @@ -90,7 +90,7 @@ TwoFloats case3(int Val) { // Case 4: Initialization from a scalarized vector into a structure with element // conversions. -// CHECK-LABEL: define void @_Z5case4Dv2_i( +// CHECK-LABEL: define hidden void @_Z5case4Dv2_i( // CHECK-SAME: ptr dead_on_unwind noalias writable sret([[STRUCT_TWOFLOATS:%.*]]) align 1 [[AGG_RESULT:%.*]], <2 x i32> noundef [[TWOVALS:%.*]]) #[[ATTR0]] { // CHECK-NEXT: [[ENTRY:.*:]] // CHECK-NEXT: [[TWOVALS_ADDR:%.*]] = alloca <2 x i32>, align 8 @@ -113,7 +113,7 @@ TwoFloats case4(int2 TwoVals) { } // Case 5: Initialization from a scalarized vector of matching type. -// CHECK-LABEL: define void @_Z5case5Dv2_i( +// CHECK-LABEL: define hidden void @_Z5case5Dv2_i( // CHECK-SAME: ptr dead_on_unwind noalias writable sret([[STRUCT_TWOINTS:%.*]]) align 1 [[AGG_RESULT:%.*]], <2 x i32> noundef [[TWOVALS:%.*]]) #[[ATTR0]] { // CHECK-NEXT: [[ENTRY:.*:]] // CHECK-NEXT: [[TWOVALS_ADDR:%.*]] = alloca <2 x i32>, align 8 @@ -135,7 +135,7 @@ TwoInts case5(int2 TwoVals) { // Case 6: Initialization from a scalarized structure of different type with // different element types. -// CHECK-LABEL: define void @_Z5case69TwoFloats( +// CHECK-LABEL: define hidden void @_Z5case69TwoFloats( // CHECK-SAME: ptr dead_on_unwind noalias writable sret([[STRUCT_TWOINTS:%.*]]) align 1 [[AGG_RESULT:%.*]], ptr noundef byval([[STRUCT_TWOFLOATS:%.*]]) align 1 [[TF4:%.*]]) #[[ATTR0]] { // CHECK-NEXT: [[ENTRY:.*:]] // CHECK-NEXT: [[Z:%.*]] = getelementptr inbounds nuw [[STRUCT_TWOINTS]], ptr [[AGG_RESULT]], i32 0, i32 0 @@ -157,7 +157,7 @@ TwoInts case6(TwoFloats TF4) { // Case 7: Initialization of a complex structure, with bogus braces and element // conversions from a collection of scalar values, and structures. -// CHECK-LABEL: define void @_Z5case77TwoIntsS_i9TwoFloatsS0_S0_S0_( +// CHECK-LABEL: define hidden void @_Z5case77TwoIntsS_i9TwoFloatsS0_S0_S0_( // CHECK-SAME: ptr dead_on_unwind noalias writable sret([[STRUCT_DOGGO:%.*]]) align 1 [[AGG_RESULT:%.*]], ptr noundef byval([[STRUCT_TWOINTS:%.*]]) align 1 [[TI1:%.*]], ptr noundef byval([[STRUCT_TWOINTS]]) align 1 [[TI2:%.*]], i32 noundef [[VAL:%.*]], ptr noundef byval([[STRUCT_TWOFLOATS:%.*]]) align 1 [[TF1:%.*]], ptr noundef byval([[STRUCT_TWOFLOATS]]) align 1 [[TF2:%.*]], ptr noundef byval([[STRUCT_TWOFLOATS]]) align 1 [[TF3:%.*]], ptr noundef byval([[STRUCT_TWOFLOATS]]) align 1 [[TF4:%.*]]) #[[ATTR0]] { // CHECK-NEXT: [[ENTRY:.*:]] // CHECK-NEXT: [[VAL_ADDR:%.*]] = alloca i32, align 4 @@ -221,7 +221,7 @@ Doggo case7(TwoInts TI1, TwoInts TI2, int Val, TwoFloats TF1, TwoFloats TF2, // Case 8: Initialization of a structure from a different structure with // significantly different element types and grouping. -// CHECK-LABEL: define void @_Z5case85Doggo( +// CHECK-LABEL: define hidden void @_Z5case85Doggo( // CHECK-SAME: ptr dead_on_unwind noalias writable sret([[STRUCT_ANIMALBITS:%.*]]) align 1 [[AGG_RESULT:%.*]], ptr noundef byval([[STRUCT_DOGGO:%.*]]) align 1 [[D1:%.*]]) #[[ATTR0]] { // CHECK-NEXT: [[ENTRY:.*:]] // CHECK-NEXT: [[LEGS:%.*]] = getelementptr inbounds nuw [[STRUCT_ANIMALBITS]], ptr [[AGG_RESULT]], i32 0, i32 0 @@ -307,7 +307,7 @@ AnimalBits case8(Doggo D1) { // Case 9: Everything everywhere all at once... Initializing mismatched // structures from different layouts, different component groupings, with no // top-level bracing separation. -// CHECK-LABEL: define void @_Z5case95Doggo10AnimalBits( +// CHECK-LABEL: define hidden void @_Z5case95Doggo10AnimalBits( // CHECK-SAME: ptr dead_on_unwind noalias writable sret([[STRUCT_ZOO:%.*]]) align 1 [[AGG_RESULT:%.*]], ptr noundef byval([[STRUCT_DOGGO:%.*]]) align 1 [[D1:%.*]], ptr noundef byval([[STRUCT_ANIMALBITS:%.*]]) align 1 [[A1:%.*]]) #[[ATTR0]] { // CHECK-NEXT: [[ENTRY:.*:]] // CHECK-NEXT: [[DOGS:%.*]] = getelementptr inbounds nuw [[STRUCT_ZOO]], ptr [[AGG_RESULT]], i32 0, i32 0 @@ -723,7 +723,7 @@ Zoo case9(Doggo D1, AnimalBits A1) { } // Case 10: Initialize an object with a base class from two objects. -// CHECK-LABEL: define void @_Z6case109TwoFloatsS_( +// CHECK-LABEL: define hidden void @_Z6case109TwoFloatsS_( // CHECK-SAME: ptr dead_on_unwind noalias writable sret([[STRUCT_FOURFLOATS:%.*]]) align 1 [[AGG_RESULT:%.*]], ptr noundef byval([[STRUCT_TWOFLOATS:%.*]]) align 1 [[TF1:%.*]], ptr noundef byval([[STRUCT_TWOFLOATS]]) align 1 [[TF2:%.*]]) #[[ATTR0]] { // CHECK-NEXT: [[ENTRY:.*:]] // CHECK-NEXT: [[X:%.*]] = getelementptr inbounds nuw [[STRUCT_TWOFLOATS]], ptr [[AGG_RESULT]], i32 0, i32 0 @@ -750,7 +750,7 @@ FourFloats case10(TwoFloats TF1, TwoFloats TF2) { } // Case 11: Initialize an object with a base class from a vector splat. -// CHECK-LABEL: define void @_Z6case11f( +// CHECK-LABEL: define hidden void @_Z6case11f( // CHECK-SAME: ptr dead_on_unwind noalias writable sret([[STRUCT_FOURFLOATS:%.*]]) align 1 [[AGG_RESULT:%.*]], float noundef nofpclass(nan inf) [[F:%.*]]) #[[ATTR0]] { // CHECK-NEXT: [[ENTRY:.*:]] // CHECK-NEXT: [[F_ADDR:%.*]] = alloca float, align 4 @@ -799,7 +799,7 @@ FourFloats case11(float F) { } // Case 12: Initialize bitfield from two integers. -// CHECK-LABEL: define void @_Z6case12ii( +// CHECK-LABEL: define hidden void @_Z6case12ii( // CHECK-SAME: ptr dead_on_unwind noalias writable sret([[STRUCT_SLICYBITS:%.*]]) align 1 [[AGG_RESULT:%.*]], i32 noundef [[I:%.*]], i32 noundef [[J:%.*]]) #[[ATTR0]] { // CHECK-NEXT: [[ENTRY:.*:]] // CHECK-NEXT: [[I_ADDR:%.*]] = alloca i32, align 4 @@ -821,7 +821,7 @@ SlicyBits case12(int I, int J) { } // Case 13: Initialize bitfield from a struct of two ints. -// CHECK-LABEL: define void @_Z6case137TwoInts( +// CHECK-LABEL: define hidden void @_Z6case137TwoInts( // CHECK-SAME: ptr dead_on_unwind noalias writable sret([[STRUCT_SLICYBITS:%.*]]) align 1 [[AGG_RESULT:%.*]], ptr noundef byval([[STRUCT_TWOINTS:%.*]]) align 1 [[TI:%.*]]) #[[ATTR0]] { // CHECK-NEXT: [[ENTRY:.*:]] // CHECK-NEXT: [[Z:%.*]] = getelementptr inbounds nuw [[STRUCT_TWOINTS]], ptr [[TI]], i32 0, i32 0 @@ -841,7 +841,7 @@ SlicyBits case13(TwoInts TI) { } // Case 14: Initialize struct of ints from struct with bitfields. -// CHECK-LABEL: define void @_Z6case149SlicyBits( +// CHECK-LABEL: define hidden void @_Z6case149SlicyBits( // CHECK-SAME: ptr dead_on_unwind noalias writable sret([[STRUCT_TWOINTS:%.*]]) align 1 [[AGG_RESULT:%.*]], ptr noundef byval([[STRUCT_SLICYBITS:%.*]]) align 1 [[SB:%.*]]) #[[ATTR0]] { // CHECK-NEXT: [[ENTRY:.*:]] // CHECK-NEXT: [[Z:%.*]] = getelementptr inbounds nuw [[STRUCT_TWOINTS]], ptr [[AGG_RESULT]], i32 0, i32 0 @@ -861,7 +861,7 @@ TwoInts case14(SlicyBits SB) { } // Case 15: Initialize struct of floats from struct with bitfields. -// CHECK-LABEL: define void @_Z6case159SlicyBits( +// CHECK-LABEL: define hidden void @_Z6case159SlicyBits( // CHECK-SAME: ptr dead_on_unwind noalias writable sret([[STRUCT_TWOFLOATS:%.*]]) align 1 [[AGG_RESULT:%.*]], ptr noundef byval([[STRUCT_SLICYBITS:%.*]]) align 1 [[SB:%.*]]) #[[ATTR0]] { // CHECK-NEXT: [[ENTRY:.*:]] // CHECK-NEXT: [[X:%.*]] = getelementptr inbounds nuw [[STRUCT_TWOFLOATS]], ptr [[AGG_RESULT]], i32 0, i32 0 @@ -884,7 +884,7 @@ TwoFloats case15(SlicyBits SB) { // Case 16: Side-effecting initialization list arguments. The important thing // here is that case16 only has _one_ call to makeTwo. -// CHECK-LABEL: define void @_Z7makeTwoRf( +// CHECK-LABEL: define hidden void @_Z7makeTwoRf( // CHECK-SAME: ptr dead_on_unwind noalias writable sret([[STRUCT_TWOFLOATS:%.*]]) align 1 [[AGG_RESULT:%.*]], ptr noalias noundef nonnull align 4 dereferenceable(4) [[X:%.*]]) #[[ATTR0]] { // CHECK-NEXT: [[ENTRY:.*:]] // CHECK-NEXT: [[X_ADDR:%.*]] = alloca ptr, align 4 @@ -910,7 +910,7 @@ TwoFloats makeTwo(inout float X) { return TF; } -// CHECK-LABEL: define void @_Z6case16v( +// CHECK-LABEL: define hidden void @_Z6case16v( // CHECK-SAME: ptr dead_on_unwind noalias writable sret([[STRUCT_FOURFLOATS:%.*]]) align 1 [[AGG_RESULT:%.*]]) #[[ATTR0]] { // CHECK-NEXT: [[ENTRY:.*:]] // CHECK-NEXT: [[X:%.*]] = alloca float, align 4 @@ -948,7 +948,7 @@ int case17Helper(int x) { } // InitList with OpaqueValueExpr -// CHECK-LABEL: define void {{.*}}case17 +// CHECK-LABEL: define hidden void {{.*}}case17 // CHECK: [[X:%.*]] = alloca <2 x i32>, align 8 // CHECK-NEXT: [[C:%.*]] = call noundef i32 {{.*}}case17Helper{{.*}}(i32 noundef 0) // CHECK-NEXT: [[C1:%.*]] = call noundef i32 {{.*}}case17Helper{{.*}}(i32 noundef 1) diff --git a/external/llvm-project/clang/test/CodeGenHLSL/BasicFeatures/OutputArguments.hlsl b/external/llvm-project/clang/test/CodeGenHLSL/BasicFeatures/OutputArguments.hlsl index 1f45a7f9b46d..d0ba8f447b73 100644 --- a/external/llvm-project/clang/test/CodeGenHLSL/BasicFeatures/OutputArguments.hlsl +++ b/external/llvm-project/clang/test/CodeGenHLSL/BasicFeatures/OutputArguments.hlsl @@ -6,7 +6,7 @@ // integer. It is converted to an integer on call and converted back after the // function. -// CHECK: define void {{.*}}trunc_Param{{.*}}(ptr noalias noundef nonnull align 4 dereferenceable(4) {{%.*}}) +// CHECK: define hidden void {{.*}}trunc_Param{{.*}}(ptr noalias noundef nonnull align 4 dereferenceable(4) {{%.*}}) void trunc_Param(inout int X) {} // ALL-LABEL: define noundef nofpclass(nan inf) float {{.*}}case1 @@ -32,7 +32,7 @@ export float case1(float F) { // uninitialized in the function. If they are not initialized before the // function returns the value is undefined. -// CHECK: define void {{.*}}undef{{.*}}(ptr noalias noundef nonnull align 4 dereferenceable(4) {{%.*}}) +// CHECK: define hidden void {{.*}}undef{{.*}}(ptr noalias noundef nonnull align 4 dereferenceable(4) {{%.*}}) void undef(out int Z) { } // ALL-LABEL: define noundef i32 {{.*}}case2 @@ -54,7 +54,7 @@ export int case2() { // This test should verify that an out parameter value is written to as // expected. -// CHECK: define void {{.*}}zero{{.*}}(ptr noalias noundef nonnull align 4 dereferenceable(4) {{%.*}}) +// CHECK: define hidden void {{.*}}zero{{.*}}(ptr noalias noundef nonnull align 4 dereferenceable(4) {{%.*}}) void zero(out int Z) { Z = 0; } // ALL-LABEL: define noundef i32 {{.*}}case3 @@ -76,7 +76,7 @@ export int case3() { // Vector swizzles in HLSL produce lvalues, so they can be used as arguments to // inout parameters and the swizzle is reversed on writeback. -// CHECK: define void {{.*}}funky{{.*}}(ptr noalias noundef nonnull align 16 dereferenceable(16) {{%.*}}) +// CHECK: define hidden void {{.*}}funky{{.*}}(ptr noalias noundef nonnull align 16 dereferenceable(16) {{%.*}}) void funky(inout int3 X) { X.x += 1; X.y += 2; @@ -116,7 +116,7 @@ export int3 case4() { // Case 5: Straightforward inout of a scalar value. -// CHECK: define void {{.*}}increment{{.*}}(ptr noalias noundef nonnull align 4 dereferenceable(4) {{%.*}}) +// CHECK: define hidden void {{.*}}increment{{.*}}(ptr noalias noundef nonnull align 4 dereferenceable(4) {{%.*}}) void increment(inout int I) { I += 1; } @@ -144,7 +144,7 @@ struct S { float Y; }; -// CHECK: define void {{.*}}init{{.*}}(ptr noalias noundef nonnull align 1 dereferenceable(8) {{%.*}}) +// CHECK: define hidden void {{.*}}init{{.*}}(ptr noalias noundef nonnull align 1 dereferenceable(8) {{%.*}}) void init(out S s) { s.X = 3; s.Y = 4; @@ -170,7 +170,7 @@ struct R { float Y; }; -// CHECK: define void {{.*}}init{{.*}}(ptr noalias noundef nonnull align 1 dereferenceable(8) {{%.*}}) +// CHECK: define hidden void {{.*}}init{{.*}}(ptr noalias noundef nonnull align 1 dereferenceable(8) {{%.*}}) void init(inout R s) { s.X = 3; s.Y = 4; @@ -194,7 +194,7 @@ export int case7() { // Case 8: Non-scalars with a cast expression. -// CHECK: define void {{.*}}trunc_vec{{.*}}(ptr noalias noundef nonnull align 16 dereferenceable(16) {{%.*}}) +// CHECK: define hidden void {{.*}}trunc_vec{{.*}}(ptr noalias noundef nonnull align 16 dereferenceable(16) {{%.*}}) void trunc_vec(inout int3 V) {} // ALL-LABEL: define noundef nofpclass(nan inf) <3 x float> {{.*}}case8 diff --git a/external/llvm-project/clang/test/CodeGenHLSL/Bool.hlsl b/external/llvm-project/clang/test/CodeGenHLSL/Bool.hlsl index fb0f32b11241..21328c1f9d4d 100644 --- a/external/llvm-project/clang/test/CodeGenHLSL/Bool.hlsl +++ b/external/llvm-project/clang/test/CodeGenHLSL/Bool.hlsl @@ -1,6 +1,6 @@ // RUN: %clang_cc1 -finclude-default-header -triple dxil-pc-shadermodel6.3-library -emit-llvm -disable-llvm-passes -o - %s | FileCheck %s -// CHECK-LABEL: define noundef i1 {{.*}}fn{{.*}}(i1 noundef %x) +// CHECK-LABEL: define hidden noundef i1 {{.*}}fn{{.*}}(i1 noundef %x) // CHECK: [[X:%.*]] = alloca i32, align 4 // CHECK-NEXT: [[Y:%.*]] = zext i1 {{%.*}} to i32 // CHECK-NEXT: store i32 [[Y]], ptr [[X]], align 4 diff --git a/external/llvm-project/clang/test/CodeGenHLSL/BoolVector.hlsl b/external/llvm-project/clang/test/CodeGenHLSL/BoolVector.hlsl index 35d8b9dac801..d5054a5a92b5 100644 --- a/external/llvm-project/clang/test/CodeGenHLSL/BoolVector.hlsl +++ b/external/llvm-project/clang/test/CodeGenHLSL/BoolVector.hlsl @@ -9,7 +9,7 @@ struct S { float f; }; -// CHECK-LABEL: define noundef i1 {{.*}}fn1{{.*}} +// CHECK-LABEL: define hidden noundef i1 {{.*}}fn1{{.*}} // CHECK: [[B:%.*]] = alloca <2 x i32>, align 8 // CHECK-NEXT: store <2 x i32> splat (i32 1), ptr [[B]], align 8 // CHECK-NEXT: [[BoolVec:%.*]] = load <2 x i32>, ptr [[B]], align 8 @@ -21,7 +21,7 @@ bool fn1() { return B[0]; } -// CHECK-LABEL: define noundef <2 x i1> {{.*}}fn2{{.*}} +// CHECK-LABEL: define hidden noundef <2 x i1> {{.*}}fn2{{.*}} // CHECK: [[VAddr:%.*]] = alloca i32, align 4 // CHECK-NEXT: [[A:%.*]] = alloca <2 x i32>, align 8 // CHECK-NEXT: [[StoreV:%.*]] = zext i1 {{.*}} to i32 @@ -40,7 +40,7 @@ bool2 fn2(bool V) { return A; } -// CHECK-LABEL: define noundef i1 {{.*}}fn3{{.*}} +// CHECK-LABEL: define hidden noundef i1 {{.*}}fn3{{.*}} // CHECK: [[s:%.*]] = alloca %struct.S, align 1 // CHECK-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 1 [[s]], ptr align 1 [[ConstS]], i32 12, i1 false) // CHECK-NEXT: [[BV:%.*]] = getelementptr inbounds nuw %struct.S, ptr [[s]], i32 0, i32 0 @@ -53,7 +53,7 @@ bool fn3() { return s.bv[0]; } -// CHECK-LABEL: define noundef i1 {{.*}}fn4{{.*}} +// CHECK-LABEL: define hidden noundef i1 {{.*}}fn4{{.*}} // CHECK: [[Arr:%.*]] = alloca [2 x <2 x i32>], align 8 // CHECK-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 8 [[Arr]], ptr align 8 [[ConstArr]], i32 16, i1 false) // CHECK-NEXT: [[Idx:%.*]] = getelementptr inbounds [2 x <2 x i32>], ptr [[Arr]], i32 0, i32 0 @@ -66,7 +66,7 @@ bool fn4() { return Arr[0][1]; } -// CHECK-LABEL: define void {{.*}}fn5{{.*}} +// CHECK-LABEL: define hidden void {{.*}}fn5{{.*}} // CHECK: [[Arr:%.*]] = alloca <2 x i32>, align 8 // CHECK-NEXT: store <2 x i32> splat (i32 1), ptr [[Arr]], align 8 // CHECK-NEXT: [[L:%.*]] = load <2 x i32>, ptr [[Arr]], align 8 @@ -78,7 +78,7 @@ void fn5() { Arr[1] = false; } -// CHECK-LABEL: define void {{.*}}fn6{{.*}} +// CHECK-LABEL: define hidden void {{.*}}fn6{{.*}} // CHECK: [[V:%.*]] = alloca i32, align 4 // CHECK-NEXT: [[S:%.*]] = alloca %struct.S, align 1 // CHECK-NEXT: store i32 0, ptr [[V]], align 4 @@ -97,7 +97,7 @@ void fn6() { s.bv[1] = V; } -// CHECK-LABEL: define void {{.*}}fn7{{.*}} +// CHECK-LABEL: define hidden void {{.*}}fn7{{.*}} // CHECK: [[Arr:%.*]] = alloca [2 x <2 x i32>], align 8 // CHECK-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 8 [[Arr]], ptr align 8 {{.*}}, i32 16, i1 false) // CHECK-NEXT: [[Idx:%.*]] = getelementptr inbounds [2 x <2 x i32>], ptr [[Arr]], i32 0, i32 0 diff --git a/external/llvm-project/clang/test/CodeGenHLSL/GlobalConstructorLib.hlsl b/external/llvm-project/clang/test/CodeGenHLSL/GlobalConstructorLib.hlsl index 9090e9e85ed9..afda714106fa 100644 --- a/external/llvm-project/clang/test/CodeGenHLSL/GlobalConstructorLib.hlsl +++ b/external/llvm-project/clang/test/CodeGenHLSL/GlobalConstructorLib.hlsl @@ -33,7 +33,7 @@ void SecondEntry() {} // Verify the constructor is alwaysinline // NOINLINE: ; Function Attrs: {{.*}}alwaysinline -// NOINLINE-NEXT: define linkonce_odr void @_ZN4hlsl8RWBufferIfEC2EjijjPKc({{.*}} [[CtorAttr:\#[0-9]+]] +// NOINLINE-NEXT: define linkonce_odr hidden void @_ZN4hlsl8RWBufferIfEC2EjijjPKc({{.*}} [[CtorAttr:\#[0-9]+]] // NOINLINE: ; Function Attrs: {{.*}}alwaysinline // NOINLINE-NEXT: define internal void @_GLOBAL__sub_I_GlobalConstructorLib.hlsl() [[InitAttr:\#[0-9]+]] diff --git a/external/llvm-project/clang/test/CodeGenHLSL/RootSignature.hlsl b/external/llvm-project/clang/test/CodeGenHLSL/RootSignature.hlsl index ca843ffbb1ce..6618ca741aa9 100644 --- a/external/llvm-project/clang/test/CodeGenHLSL/RootSignature.hlsl +++ b/external/llvm-project/clang/test/CodeGenHLSL/RootSignature.hlsl @@ -3,14 +3,14 @@ // CHECK: !dx.rootsignatures = !{![[#EMPTY_ENTRY:]], ![[#DT_ENTRY:]], // CHECK-SAME: ![[#RF_ENTRY:]], ![[#RC_ENTRY:]], ![[#RD_ENTRY:]], ![[#SS_ENTRY:]]} -// CHECK: ![[#EMPTY_ENTRY]] = !{ptr @EmptyEntry, ![[#EMPTY:]]} +// CHECK: ![[#EMPTY_ENTRY]] = !{ptr @EmptyEntry, ![[#EMPTY:]], i32 2} // CHECK: ![[#EMPTY]] = !{} [shader("compute"), RootSignature("")] [numthreads(1,1,1)] void EmptyEntry() {} -// CHECK: ![[#DT_ENTRY]] = !{ptr @DescriptorTableEntry, ![[#DT_RS:]]} +// CHECK: ![[#DT_ENTRY]] = !{ptr @DescriptorTableEntry, ![[#DT_RS:]], i32 2} // CHECK: ![[#DT_RS]] = !{![[#TABLE:]]} // CHECK: ![[#TABLE]] = !{!"DescriptorTable", i32 0, ![[#CBV:]], ![[#SRV:]]} // CHECK: ![[#CBV]] = !{!"CBV", i32 1, i32 0, i32 0, i32 -1, i32 4} @@ -25,7 +25,7 @@ void EmptyEntry() {} [numthreads(1,1,1)] void DescriptorTableEntry() {} -// CHECK: ![[#RF_ENTRY]] = !{ptr @RootFlagsEntry, ![[#RF_RS:]]} +// CHECK: ![[#RF_ENTRY]] = !{ptr @RootFlagsEntry, ![[#RF_RS:]], i32 2} // CHECK: ![[#RF_RS]] = !{![[#ROOT_FLAGS:]]} // CHECK: ![[#ROOT_FLAGS]] = !{!"RootFlags", i32 2114} @@ -38,7 +38,7 @@ void DescriptorTableEntry() {} [numthreads(1,1,1)] void RootFlagsEntry() {} -// CHECK: ![[#RC_ENTRY]] = !{ptr @RootConstantsEntry, ![[#RC_RS:]]} +// CHECK: ![[#RC_ENTRY]] = !{ptr @RootConstantsEntry, ![[#RC_RS:]], i32 2} // CHECK: ![[#RC_RS]] = !{![[#ROOT_CONSTANTS:]]} // CHECK: ![[#ROOT_CONSTANTS]] = !{!"RootConstants", i32 5, i32 1, i32 2, i32 1} @@ -52,7 +52,7 @@ void RootFlagsEntry() {} [numthreads(1,1,1)] void RootConstantsEntry() {} -// CHECK: ![[#RD_ENTRY]] = !{ptr @RootDescriptorsEntry, ![[#RD_RS:]]} +// CHECK: ![[#RD_ENTRY]] = !{ptr @RootDescriptorsEntry, ![[#RD_RS:]], i32 2} // CHECK: ![[#RD_RS]] = !{![[#ROOT_CBV:]], ![[#ROOT_UAV:]], ![[#ROOT_SRV:]]} // CHECK: ![[#ROOT_CBV]] = !{!"RootCBV", i32 0, i32 0, i32 0, i32 4} // CHECK: ![[#ROOT_UAV]] = !{!"RootUAV", i32 0, i32 42, i32 3, i32 2} @@ -66,7 +66,7 @@ void RootConstantsEntry() {} [numthreads(1,1,1)] void RootDescriptorsEntry() {} -// CHECK: ![[#SS_ENTRY]] = !{ptr @StaticSamplerEntry, ![[#SS_RS:]]} +// CHECK: ![[#SS_ENTRY]] = !{ptr @StaticSamplerEntry, ![[#SS_RS:]], i32 2} // CHECK: ![[#SS_RS]] = !{![[#STATIC_SAMPLER:]]} // checking filter = 0x4 diff --git a/external/llvm-project/clang/test/CodeGenHLSL/basic_types.hlsl b/external/llvm-project/clang/test/CodeGenHLSL/basic_types.hlsl index 362042654ea8..37fb5195e976 100644 --- a/external/llvm-project/clang/test/CodeGenHLSL/basic_types.hlsl +++ b/external/llvm-project/clang/test/CodeGenHLSL/basic_types.hlsl @@ -6,38 +6,38 @@ // RUN: -emit-llvm -disable-llvm-passes -o - -DNAMESPACED| FileCheck %s -// CHECK: @uint16_t_Val = external addrspace(2) global i16, align 2 -// CHECK: @int16_t_Val = external addrspace(2) global i16, align 2 -// CHECK: @uint_Val = external addrspace(2) global i32, align 4 -// CHECK: @uint64_t_Val = external addrspace(2) global i64, align 8 -// CHECK: @int64_t_Val = external addrspace(2) global i64, align 8 -// CHECK: @int16_t2_Val = external addrspace(2) global <2 x i16>, align 4 -// CHECK: @int16_t3_Val = external addrspace(2) global <3 x i16>, align 8 -// CHECK: @int16_t4_Val = external addrspace(2) global <4 x i16>, align 8 -// CHECK: @uint16_t2_Val = external addrspace(2) global <2 x i16>, align 4 -// CHECK: @uint16_t3_Val = external addrspace(2) global <3 x i16>, align 8 -// CHECK: @uint16_t4_Val = external addrspace(2) global <4 x i16>, align 8 -// CHECK: @int2_Val = external addrspace(2) global <2 x i32>, align 8 -// CHECK: @int3_Val = external addrspace(2) global <3 x i32>, align 16 -// CHECK: @int4_Val = external addrspace(2) global <4 x i32>, align 16 -// CHECK: @uint2_Val = external addrspace(2) global <2 x i32>, align 8 -// CHECK: @uint3_Val = external addrspace(2) global <3 x i32>, align 16 -// CHECK: @uint4_Val = external addrspace(2) global <4 x i32>, align 16 -// CHECK: @int64_t2_Val = external addrspace(2) global <2 x i64>, align 16 -// CHECK: @int64_t3_Val = external addrspace(2) global <3 x i64>, align 32 -// CHECK: @int64_t4_Val = external addrspace(2) global <4 x i64>, align 32 -// CHECK: @uint64_t2_Val = external addrspace(2) global <2 x i64>, align 16 -// CHECK: @uint64_t3_Val = external addrspace(2) global <3 x i64>, align 32 -// CHECK: @uint64_t4_Val = external addrspace(2) global <4 x i64>, align 32 -// CHECK: @half2_Val = external addrspace(2) global <2 x half>, align 4 -// CHECK: @half3_Val = external addrspace(2) global <3 x half>, align 8 -// CHECK: @half4_Val = external addrspace(2) global <4 x half>, align 8 -// CHECK: @float2_Val = external addrspace(2) global <2 x float>, align 8 -// CHECK: @float3_Val = external addrspace(2) global <3 x float>, align 16 -// CHECK: @float4_Val = external addrspace(2) global <4 x float>, align 16 -// CHECK: @double2_Val = external addrspace(2) global <2 x double>, align 16 -// CHECK: @double3_Val = external addrspace(2) global <3 x double>, align 32 -// CHECK: @double4_Val = external addrspace(2) global <4 x double>, align 32 +// CHECK: @uint16_t_Val = external hidden addrspace(2) global i16, align 2 +// CHECK: @int16_t_Val = external hidden addrspace(2) global i16, align 2 +// CHECK: @uint_Val = external hidden addrspace(2) global i32, align 4 +// CHECK: @uint64_t_Val = external hidden addrspace(2) global i64, align 8 +// CHECK: @int64_t_Val = external hidden addrspace(2) global i64, align 8 +// CHECK: @int16_t2_Val = external hidden addrspace(2) global <2 x i16>, align 4 +// CHECK: @int16_t3_Val = external hidden addrspace(2) global <3 x i16>, align 8 +// CHECK: @int16_t4_Val = external hidden addrspace(2) global <4 x i16>, align 8 +// CHECK: @uint16_t2_Val = external hidden addrspace(2) global <2 x i16>, align 4 +// CHECK: @uint16_t3_Val = external hidden addrspace(2) global <3 x i16>, align 8 +// CHECK: @uint16_t4_Val = external hidden addrspace(2) global <4 x i16>, align 8 +// CHECK: @int2_Val = external hidden addrspace(2) global <2 x i32>, align 8 +// CHECK: @int3_Val = external hidden addrspace(2) global <3 x i32>, align 16 +// CHECK: @int4_Val = external hidden addrspace(2) global <4 x i32>, align 16 +// CHECK: @uint2_Val = external hidden addrspace(2) global <2 x i32>, align 8 +// CHECK: @uint3_Val = external hidden addrspace(2) global <3 x i32>, align 16 +// CHECK: @uint4_Val = external hidden addrspace(2) global <4 x i32>, align 16 +// CHECK: @int64_t2_Val = external hidden addrspace(2) global <2 x i64>, align 16 +// CHECK: @int64_t3_Val = external hidden addrspace(2) global <3 x i64>, align 32 +// CHECK: @int64_t4_Val = external hidden addrspace(2) global <4 x i64>, align 32 +// CHECK: @uint64_t2_Val = external hidden addrspace(2) global <2 x i64>, align 16 +// CHECK: @uint64_t3_Val = external hidden addrspace(2) global <3 x i64>, align 32 +// CHECK: @uint64_t4_Val = external hidden addrspace(2) global <4 x i64>, align 32 +// CHECK: @half2_Val = external hidden addrspace(2) global <2 x half>, align 4 +// CHECK: @half3_Val = external hidden addrspace(2) global <3 x half>, align 8 +// CHECK: @half4_Val = external hidden addrspace(2) global <4 x half>, align 8 +// CHECK: @float2_Val = external hidden addrspace(2) global <2 x float>, align 8 +// CHECK: @float3_Val = external hidden addrspace(2) global <3 x float>, align 16 +// CHECK: @float4_Val = external hidden addrspace(2) global <4 x float>, align 16 +// CHECK: @double2_Val = external hidden addrspace(2) global <2 x double>, align 16 +// CHECK: @double3_Val = external hidden addrspace(2) global <3 x double>, align 32 +// CHECK: @double4_Val = external hidden addrspace(2) global <4 x double>, align 32 #ifdef NAMESPACED #define TYPE_DECL(T) hlsl::T T##_Val diff --git a/external/llvm-project/clang/test/CodeGenHLSL/builtins/AddUint64.hlsl b/external/llvm-project/clang/test/CodeGenHLSL/builtins/AddUint64.hlsl index e1832bdbbf33..8457ad6da293 100644 --- a/external/llvm-project/clang/test/CodeGenHLSL/builtins/AddUint64.hlsl +++ b/external/llvm-project/clang/test/CodeGenHLSL/builtins/AddUint64.hlsl @@ -4,7 +4,7 @@ // RUN: FileCheck %s --check-prefixes=CHECK -// CHECK-LABEL: define noundef <2 x i32> @_Z20test_AddUint64_uint2Dv2_jS_( +// CHECK-LABEL: define hidden noundef <2 x i32> @_Z20test_AddUint64_uint2Dv2_jS_( // CHECK-SAME: <2 x i32> noundef [[A:%.*]], <2 x i32> noundef [[B:%.*]]) #[[ATTR0:[0-9]+]] { // CHECK-NEXT: [[ENTRY:.*:]] // CHECK-NEXT: [[A_ADDR:%.*]] = alloca <2 x i32>, align 8 @@ -31,7 +31,7 @@ uint2 test_AddUint64_uint2(uint2 a, uint2 b) { return AddUint64(a, b); } -// CHECK-LABEL: define noundef <4 x i32> @_Z20test_AddUint64_uint4Dv4_jS_( +// CHECK-LABEL: define hidden noundef <4 x i32> @_Z20test_AddUint64_uint4Dv4_jS_( // CHECK-SAME: <4 x i32> noundef [[A:%.*]], <4 x i32> noundef [[B:%.*]]) #[[ATTR0]] { // CHECK-NEXT: [[ENTRY:.*:]] // CHECK-NEXT: [[A_ADDR:%.*]] = alloca <4 x i32>, align 16 diff --git a/external/llvm-project/clang/test/CodeGenHLSL/builtins/ByteAddressBuffers-constructors.hlsl b/external/llvm-project/clang/test/CodeGenHLSL/builtins/ByteAddressBuffers-constructors.hlsl index 403d473ce968..3a8d2c03e173 100644 --- a/external/llvm-project/clang/test/CodeGenHLSL/builtins/ByteAddressBuffers-constructors.hlsl +++ b/external/llvm-project/clang/test/CodeGenHLSL/builtins/ByteAddressBuffers-constructors.hlsl @@ -35,7 +35,7 @@ export void foo() { // CHECK-SAME: i32 noundef 1, i32 noundef 2, i32 noundef 1, i32 noundef 0, ptr noundef @[[Buf1Str]]) // Buf1 initialization part 2 - body of ByteAddressBuffer C1 constructor with explicit binding that calls the C2 constructor -// CHECK: define linkonce_odr void @_ZN4hlsl17ByteAddressBufferC1EjjijPKc(ptr noundef nonnull align 4 dereferenceable(4) %this, +// CHECK: define linkonce_odr hidden void @_ZN4hlsl17ByteAddressBufferC1EjjijPKc(ptr noundef nonnull align 4 dereferenceable(4) %this, // CHECK-SAME: i32 noundef %registerNo, i32 noundef %spaceNo, i32 noundef %range, i32 noundef %index, ptr noundef %name) // CHECK: call void @_ZN4hlsl17ByteAddressBufferC2EjjijPKc(ptr noundef nonnull align 4 dereferenceable(4) // CHECK-SAME: %{{.*}}, i32 noundef %{{.*}}, i32 noundef %{{.*}}, i32 noundef %{{.*}}, i32 noundef %{{.*}}, ptr noundef %{{.*}}) @@ -47,27 +47,27 @@ export void foo() { // CHECK-SAME: i32 noundef 0, i32 noundef 1, i32 noundef 0, i32 noundef 0, ptr noundef @[[Buf2Str]]) // Buf2 initialization part 2 - body of RWByteAddressBuffer C1 constructor with implicit binding that calls the C2 constructor -// CHECK: define linkonce_odr void @_ZN4hlsl19RWByteAddressBufferC1EjijjPKc(ptr noundef nonnull align 4 dereferenceable(4) %this, +// CHECK: define linkonce_odr hidden void @_ZN4hlsl19RWByteAddressBufferC1EjijjPKc(ptr noundef nonnull align 4 dereferenceable(4) %this, // CHECK-SAME: i32 noundef %spaceNo, i32 noundef %range, i32 noundef %index, i32 noundef %orderId, ptr noundef %name) // CHECK: call void @_ZN4hlsl19RWByteAddressBufferC2EjijjPKc(ptr noundef nonnull align 4 dereferenceable(4) %this1, // CHECK-SAME: i32 noundef %{{.*}}, i32 noundef %{{.*}}, i32 noundef %{{.*}}, i32 noundef %{{.*}}, ptr noundef %{{.*}}) // Buf3 initialization part 1 - local variable declared in function foo() is initialized by // RasterizerOrderedByteAddressBuffer C1 default constructor -// CHECK: define void @_Z3foov() #2 { +// CHECK: define void @_Z3foov() // CHECK-NEXT: entry: // CHECK-NEXT: %Buf3 = alloca %"class.hlsl::RasterizerOrderedByteAddressBuffer", align 4 // CHECK-NEXT: call void @_ZN4hlsl34RasterizerOrderedByteAddressBufferC1Ev(ptr noundef nonnull align 4 dereferenceable(4) %Buf3) // Buf3 initialization part 2 - body of RasterizerOrderedByteAddressBuffer default C1 constructor that // calls the default C2 constructor -// CHECK: define linkonce_odr void @_ZN4hlsl34RasterizerOrderedByteAddressBufferC1Ev(ptr noundef nonnull align 4 dereferenceable(4) %this) +// CHECK: define linkonce_odr hidden void @_ZN4hlsl34RasterizerOrderedByteAddressBufferC1Ev(ptr noundef nonnull align 4 dereferenceable(4) %this) // CHECK: call void @_ZN4hlsl34RasterizerOrderedByteAddressBufferC2Ev(ptr noundef nonnull align 4 dereferenceable(4) %{{.*}}) // CHECK-NEXT: ret void // Buf1 initialization part 3 - ByteAddressBuffer C2 constructor with explicit binding that initializes // handle with @llvm.dx.resource.handlefrombinding -// CHECK: define linkonce_odr void @_ZN4hlsl17ByteAddressBufferC2EjjijPKc(ptr noundef nonnull align 4 dereferenceable(4) %this, +// CHECK: define linkonce_odr hidden void @_ZN4hlsl17ByteAddressBufferC2EjjijPKc(ptr noundef nonnull align 4 dereferenceable(4) %this, // CHECK-SAME: i32 noundef %registerNo, i32 noundef %spaceNo, i32 noundef %range, i32 noundef %index, ptr noundef %name) // CHECK-DXIL: %[[HANDLE:.*]] = call target("dx.RawBuffer", i8, 0, 0) @llvm.dx.resource.handlefrombinding.tdx.RawBuffer_i8_0_0t( // CHECK-DXIL-SAME: i32 %{{.*}}, i32 %{{.*}}, i32 %{{.*}}, i32 %{{.*}}, i1 false, ptr %{{.*}}) @@ -76,7 +76,7 @@ export void foo() { // Buf2 initialization part 3 - body of RWByteAddressBuffer C2 constructor with implicit binding that initializes // handle with @llvm.dx.resource.handlefromimplicitbinding -// CHECK: define linkonce_odr void @_ZN4hlsl19RWByteAddressBufferC2EjijjPKc(ptr noundef nonnull align 4 dereferenceable(4) %this, +// CHECK: define linkonce_odr hidden void @_ZN4hlsl19RWByteAddressBufferC2EjijjPKc(ptr noundef nonnull align 4 dereferenceable(4) %this, // CHECK-SAME: i32 noundef %spaceNo, i32 noundef %range, i32 noundef %index, i32 noundef %orderId, ptr noundef %name) // CHECK: %[[HANDLE:.*]] = call target("dx.RawBuffer", i8, 1, 0) @llvm.dx.resource.handlefromimplicitbinding.tdx.RawBuffer_i8_1_0t // CHECK-SAME: (i32 %{{.*}}, i32 %{{.*}}, i32 %{{.*}}, i32 %{{.*}}, i1 false, ptr %{{.*}}) @@ -85,7 +85,7 @@ export void foo() { // Buf3 initialization part 3 - body of RasterizerOrderedByteAddressBuffer default C2 constructor that // initializes handle to poison -// CHECK: define linkonce_odr void @_ZN4hlsl34RasterizerOrderedByteAddressBufferC2Ev(ptr noundef nonnull align 4 dereferenceable(4) %this) +// CHECK: define linkonce_odr hidden void @_ZN4hlsl34RasterizerOrderedByteAddressBufferC2Ev(ptr noundef nonnull align 4 dereferenceable(4) %this) // CHECK: %__handle = getelementptr inbounds nuw %"class.hlsl::RasterizerOrderedByteAddressBuffer", ptr %{{.*}}, i32 0, i32 0 // CHECK: store target("dx.RawBuffer", i8, 1, 1) poison, ptr %__handle, align 4 diff --git a/external/llvm-project/clang/test/CodeGenHLSL/builtins/GroupMemoryBarrierWithGroupSync.hlsl b/external/llvm-project/clang/test/CodeGenHLSL/builtins/GroupMemoryBarrierWithGroupSync.hlsl index 9d95d54852c0..114230d38ba5 100644 --- a/external/llvm-project/clang/test/CodeGenHLSL/builtins/GroupMemoryBarrierWithGroupSync.hlsl +++ b/external/llvm-project/clang/test/CodeGenHLSL/builtins/GroupMemoryBarrierWithGroupSync.hlsl @@ -1,14 +1,14 @@ // RUN: %clang_cc1 -finclude-default-header -x hlsl -triple \ // RUN: dxil-pc-shadermodel6.3-library %s \ // RUN: -emit-llvm -disable-llvm-passes -o - | FileCheck %s \ -// RUN: -DTARGET=dx -DFNATTRS=noundef -check-prefixes=CHECK,CHECK-DXIL +// RUN: -DTARGET=dx -check-prefixes=CHECK,CHECK-DXIL // RUN: %clang_cc1 -finclude-default-header -x hlsl -triple \ // RUN: spirv-unknown-vulkan-compute %s \ // RUN: -emit-llvm -disable-llvm-passes -o - | FileCheck %s \ -// RUN: -DTARGET=spv -DFNATTRS="spir_func noundef" -check-prefixes=CHECK,CHECK-SPIRV +// RUN: -DTARGET=spv -check-prefixes=CHECK,CHECK-SPIRV -// CHECK-DXIL: define void @ -// CHECK-SPIRV: define spir_func void @ +// CHECK-DXIL: define hidden void @ +// CHECK-SPIRV: define hidden spir_func void @ void test_GroupMemoryBarrierWithGroupSync() { // CHECK-DXIL: call void @llvm.[[TARGET]].group.memory.barrier.with.group.sync() // CHECK-SPIRV: call spir_func void @llvm.[[TARGET]].group.memory.barrier.with.group.sync() diff --git a/external/llvm-project/clang/test/CodeGenHLSL/builtins/RWBuffer-constructor.hlsl b/external/llvm-project/clang/test/CodeGenHLSL/builtins/RWBuffer-constructor.hlsl index e74a7ed270b0..114468914e2e 100644 --- a/external/llvm-project/clang/test/CodeGenHLSL/builtins/RWBuffer-constructor.hlsl +++ b/external/llvm-project/clang/test/CodeGenHLSL/builtins/RWBuffer-constructor.hlsl @@ -35,7 +35,7 @@ export void foo() { // CHECK-SAME: i32 noundef 5, i32 noundef 3, i32 noundef 1, i32 noundef 0, ptr noundef @[[Buf1Str]]) // Buf1 initialization part 2 - body of RWBuffer C1 constructor with explicit binding that calls the C2 constructor -// CHECK: define linkonce_odr void @_ZN4hlsl8RWBufferIfEC1EjjijPKc(ptr noundef nonnull align 4 dereferenceable(4) %this, +// CHECK: define linkonce_odr hidden void @_ZN4hlsl8RWBufferIfEC1EjjijPKc(ptr noundef nonnull align 4 dereferenceable(4) %this, // CHECK-SAME: i32 noundef %registerNo, i32 noundef %spaceNo, i32 noundef %range, i32 noundef %index, ptr noundef %name) // CHECK: call void @_ZN4hlsl8RWBufferIfEC2EjjijPKc(ptr noundef nonnull align 4 dereferenceable(4) // CHECK-SAME: %{{.*}}, i32 noundef %{{.*}}, i32 noundef %{{.*}}, i32 noundef %{{.*}}, i32 noundef %{{.*}}, ptr noundef %{{.*}}) @@ -47,7 +47,7 @@ export void foo() { // CHECK-SAME: i32 noundef 0, i32 noundef 1, i32 noundef 0, i32 noundef 0, ptr noundef @[[Buf2Str]]) // Buf2 initialization part 2 - body of RWBuffer C1 constructor with implicit binding that calls the C2 constructor -// CHECK: define linkonce_odr void @_ZN4hlsl8RWBufferIdEC1EjijjPKc(ptr noundef nonnull align 4 dereferenceable(4) %this, +// CHECK: define linkonce_odr hidden void @_ZN4hlsl8RWBufferIdEC1EjijjPKc(ptr noundef nonnull align 4 dereferenceable(4) %this, // CHECK-SAME: i32 noundef %spaceNo, i32 noundef %range, i32 noundef %index, i32 noundef %orderId, ptr noundef %name) // CHECK: call void @_ZN4hlsl8RWBufferIdEC2EjijjPKc(ptr noundef nonnull align 4 dereferenceable(4) // CHECK-SAME: %{{.*}}, i32 noundef %{{.*}}, i32 noundef %{{.*}}, i32 noundef %{{.*}}, i32 noundef %{{.*}}, ptr noundef %{{.*}}) @@ -59,12 +59,12 @@ export void foo() { // CHECK-NEXT: call void @_ZN4hlsl8RWBufferIiEC1Ev(ptr noundef nonnull align 4 dereferenceable(4) %Buf3) // Buf3 initialization part 2 - body of RWBuffer default C1 constructor that calls the default C2 constructor -// CHECK: define linkonce_odr void @_ZN4hlsl8RWBufferIiEC1Ev(ptr noundef nonnull align 4 dereferenceable(4) %this) +// CHECK: define linkonce_odr hidden void @_ZN4hlsl8RWBufferIiEC1Ev(ptr noundef nonnull align 4 dereferenceable(4) %this) // CHECK: call void @_ZN4hlsl8RWBufferIiEC2Ev(ptr noundef nonnull align 4 dereferenceable(4) %{{.*}}) // Buf1 initialization part 3 - body of RWBuffer C2 constructor with explicit binding that initializes // handle with @llvm.dx.resource.handlefrombinding -// CHECK: define linkonce_odr void @_ZN4hlsl8RWBufferIfEC2EjjijPKc(ptr noundef nonnull align 4 dereferenceable(4) %this, +// CHECK: define linkonce_odr hidden void @_ZN4hlsl8RWBufferIfEC2EjjijPKc(ptr noundef nonnull align 4 dereferenceable(4) %this, // CHECK-SAME: i32 noundef %registerNo, i32 noundef %spaceNo, i32 noundef %range, i32 noundef %index, ptr noundef %name) // CHECK-DXIL: %[[HANDLE:.*]] = call target("dx.TypedBuffer", float, 1, 0, 0) @llvm.dx.resource.handlefrombinding.tdx.TypedBuffer_f32_1_0_0t( // CHECK-DXIL-SAME: i32 %{{.*}}, i32 %{{.*}}, i32 %{{.*}}, i32 %{{.*}}, i1 false, ptr %{{.*}}) @@ -73,7 +73,7 @@ export void foo() { // Buf2 initialization part 3 - body of RWBuffer C2 constructor with implicit binding that initializes // handle with @llvm.dx.resource.handlefromimplicitbinding -// CHECK: define linkonce_odr void @_ZN4hlsl8RWBufferIdEC2EjijjPKc(ptr noundef nonnull align 4 dereferenceable(4) %this, +// CHECK: define linkonce_odr hidden void @_ZN4hlsl8RWBufferIdEC2EjijjPKc(ptr noundef nonnull align 4 dereferenceable(4) %this, // CHECK-SAME: i32 noundef %spaceNo, i32 noundef %range, i32 noundef %index, i32 noundef %orderId, ptr noundef %name) // CHECK: %[[HANDLE:.*]] = call target("dx.TypedBuffer", double, 1, 0, 0) @llvm.dx.resource.handlefromimplicitbinding.tdx.TypedBuffer_f64_1_0_0t // CHECK-SAME: (i32 %{{.*}}, i32 %{{.*}}, i32 %{{.*}}, i32 %{{.*}}, i1 false, ptr %{{.*}}) @@ -81,7 +81,7 @@ export void foo() { // CHECK-NEXT: store target("dx.TypedBuffer", double, 1, 0, 0) %[[HANDLE]], ptr %__handle, align 4 // Buf3 initialization part 3 - body of RWBuffer default C2 constructor that initializes handle to poison -// CHECK: define linkonce_odr void @_ZN4hlsl8RWBufferIiEC2Ev(ptr noundef nonnull align 4 dereferenceable(4) %this) +// CHECK: define linkonce_odr hidden void @_ZN4hlsl8RWBufferIiEC2Ev(ptr noundef nonnull align 4 dereferenceable(4) %this) // CHECK: %__handle = getelementptr inbounds nuw %"class.hlsl::RWBuffer.1", ptr %{{.*}}, i32 0, i32 0 // CHECK-NEXT: store target("dx.TypedBuffer", i32, 1, 0, 1) poison, ptr %__handle, align 4 diff --git a/external/llvm-project/clang/test/CodeGenHLSL/builtins/ScalarSwizzles.hlsl b/external/llvm-project/clang/test/CodeGenHLSL/builtins/ScalarSwizzles.hlsl index 8a3958ad8fd0..7804239edcca 100644 --- a/external/llvm-project/clang/test/CodeGenHLSL/builtins/ScalarSwizzles.hlsl +++ b/external/llvm-project/clang/test/CodeGenHLSL/builtins/ScalarSwizzles.hlsl @@ -304,7 +304,7 @@ bool2 AccessBools() { return X.zw; } -// CHECK-LABEL: define void {{.*}}BoolSizeMismatch{{.*}} +// CHECK-LABEL: define hidden void {{.*}}BoolSizeMismatch{{.*}} // CHECK: [[B:%.*]] = alloca <4 x i32>, align 16 // CHECK-NEXT: [[Tmp:%.*]] = alloca <1 x i32>, align 4 // CHECK-NEXT: store <4 x i32> splat (i32 1), ptr [[B]], align 16 diff --git a/external/llvm-project/clang/test/CodeGenHLSL/builtins/StructuredBuffers-constructors.hlsl b/external/llvm-project/clang/test/CodeGenHLSL/builtins/StructuredBuffers-constructors.hlsl index fc7b6be5c900..28841732df99 100644 --- a/external/llvm-project/clang/test/CodeGenHLSL/builtins/StructuredBuffers-constructors.hlsl +++ b/external/llvm-project/clang/test/CodeGenHLSL/builtins/StructuredBuffers-constructors.hlsl @@ -36,7 +36,7 @@ export void foo() { // Buf1 initialization part 2 - body of StructuredBuffer C1 constructor with explicit binding // that calls the C2 constructor -// CHECK: define linkonce_odr void @_ZN4hlsl16StructuredBufferIfEC1EjjijPKc(ptr noundef nonnull align 4 dereferenceable(4) %this, +// CHECK: define linkonce_odr hidden void @_ZN4hlsl16StructuredBufferIfEC1EjjijPKc(ptr noundef nonnull align 4 dereferenceable(4) %this, // CHECK-SAME: i32 noundef %registerNo, i32 noundef %spaceNo, i32 noundef %range, i32 noundef %index, ptr noundef %name) // CHECK: call void @_ZN4hlsl16StructuredBufferIfEC2EjjijPKc(ptr noundef nonnull align 4 dereferenceable(4) // CHECK-SAME: %{{.*}}, i32 noundef %{{.*}}, i32 noundef %{{.*}}, i32 noundef %{{.*}}, i32 noundef %{{.*}}, ptr noundef %{{.*}}) @@ -49,7 +49,7 @@ export void foo() { // CHECK-SAME: i32 noundef 0, i32 noundef 1, i32 noundef 0, i32 noundef 0, ptr noundef @[[Buf2Str]]) // Buf2 initialization part 2 - body of RWStructuredBuffer C1 constructor with implicit binding that calls the C2 constructor -// CHECK: define linkonce_odr void @_ZN4hlsl18RWStructuredBufferIfEC1EjijjPKc(ptr noundef nonnull align 4 dereferenceable(4) %this, +// CHECK: define linkonce_odr hidden void @_ZN4hlsl18RWStructuredBufferIfEC1EjijjPKc(ptr noundef nonnull align 4 dereferenceable(4) %this, // CHECK-SAME: i32 noundef %spaceNo, i32 noundef %range, i32 noundef %index, i32 noundef %orderId, ptr noundef %name) // CHECK: call void @_ZN4hlsl18RWStructuredBufferIfEC2EjijjPKc(ptr noundef nonnull align 4 dereferenceable(4) // CHECK-SAME: %{{.*}}, i32 noundef %{{.*}}, i32 noundef %{{.*}}, i32 noundef %{{.*}}, i32 noundef %{{.*}}, ptr noundef %{{.*}}) @@ -63,12 +63,12 @@ export void foo() { // Buf3 initialization part 2 - body of AppendStructuredBuffer default C1 constructor that calls // the default C2 constructor -// CHECK: define linkonce_odr void @_ZN4hlsl22AppendStructuredBufferIfEC1Ev(ptr noundef nonnull align 4 dereferenceable(4) %this) +// CHECK: define linkonce_odr hidden void @_ZN4hlsl22AppendStructuredBufferIfEC1Ev(ptr noundef nonnull align 4 dereferenceable(4) %this) // CHECK: call void @_ZN4hlsl22AppendStructuredBufferIfEC2Ev(ptr noundef nonnull align 4 dereferenceable(4) %{{.*}}) // Buf1 initialization part 3 - body of AppendStructuredBuffer C2 constructor with explicit binding // that initializes handle with @llvm.dx.resource.handlefrombinding -// CHECK: define linkonce_odr void @_ZN4hlsl16StructuredBufferIfEC2EjjijPKc(ptr noundef nonnull align 4 dereferenceable(4) %this, +// CHECK: define linkonce_odr hidden void @_ZN4hlsl16StructuredBufferIfEC2EjjijPKc(ptr noundef nonnull align 4 dereferenceable(4) %this, // CHECK-SAME: i32 noundef %registerNo, i32 noundef %spaceNo, i32 noundef %range, i32 noundef %index, ptr noundef %name) // CHECK-DXIL: %[[HANDLE:.*]] = call target("dx.RawBuffer", float, 0, 0) @llvm.dx.resource.handlefrombinding.tdx.RawBuffer_f32_0_0t( // CHECK-SAME: i32 %{{.*}}, i32 %{{.*}}, i32 %{{.*}}, i32 %{{.*}}, i1 false, ptr %{{.*}}) @@ -77,7 +77,7 @@ export void foo() { // Buf2 initialization part 3 - body of RWStructuredBuffer C2 constructor with implicit binding that initializes // handle with @llvm.dx.resource.handlefromimplicitbinding -// CHECK: define linkonce_odr void @_ZN4hlsl18RWStructuredBufferIfEC2EjijjPKc(ptr noundef nonnull align 4 dereferenceable(4) %this, +// CHECK: define linkonce_odr hidden void @_ZN4hlsl18RWStructuredBufferIfEC2EjijjPKc(ptr noundef nonnull align 4 dereferenceable(4) %this, // CHECK-SAME: i32 noundef %spaceNo, i32 noundef %range, i32 noundef %index, i32 noundef %orderId, ptr noundef %name) // CHECK: %[[HANDLE:.*]] = call target("dx.RawBuffer", float, 1, 0) @llvm.dx.resource.handlefromimplicitbinding.tdx.RawBuffer_f32_1_0t // CHECK-SAME: (i32 %{{.*}}, i32 %{{.*}}, i32 %{{.*}}, i32 %{{.*}}, i1 false, ptr %{{.*}}) @@ -86,7 +86,7 @@ export void foo() { // Buf3 initialization part 3 - body of AppendStructuredBuffer default C2 constructor that // initializes handle to poison -// CHECK: define linkonce_odr void @_ZN4hlsl22AppendStructuredBufferIfEC2Ev(ptr noundef nonnull align 4 dereferenceable(4) %this) +// CHECK: define linkonce_odr hidden void @_ZN4hlsl22AppendStructuredBufferIfEC2Ev(ptr noundef nonnull align 4 dereferenceable(4) %this) // CHECK: %__handle = getelementptr inbounds nuw %"class.hlsl::AppendStructuredBuffer", ptr %{{.*}}, i32 0, i32 0 // CHECK: store target("dx.RawBuffer", float, 1, 0) poison, ptr %__handle, align 4 diff --git a/external/llvm-project/clang/test/CodeGenHLSL/builtins/WaveActiveMax.hlsl b/external/llvm-project/clang/test/CodeGenHLSL/builtins/WaveActiveMax.hlsl index 7891cfc1989a..be05a17cc369 100644 --- a/external/llvm-project/clang/test/CodeGenHLSL/builtins/WaveActiveMax.hlsl +++ b/external/llvm-project/clang/test/CodeGenHLSL/builtins/WaveActiveMax.hlsl @@ -16,7 +16,7 @@ int test_int(int expr) { } // CHECK-DXIL: declare [[TY]] @llvm.dx.wave.reduce.max.i32([[TY]]) #[[#attr:]] -// CHECK-SPIRV: declare spir_func [[TY]] @llvm.spv.wave.reduce.max.i32([[TY]]) #[[#attr:]] +// CHECK-SPIRV: declare [[TY]] @llvm.spv.wave.reduce.max.i32([[TY]]) #[[#attr:]] // CHECK-LABEL: test_uint64_t uint64_t test_uint64_t(uint64_t expr) { @@ -27,7 +27,7 @@ uint64_t test_uint64_t(uint64_t expr) { } // CHECK-DXIL: declare [[TY]] @llvm.dx.wave.reduce.umax.i64([[TY]]) #[[#attr:]] -// CHECK-SPIRV: declare spir_func [[TY]] @llvm.spv.wave.reduce.umax.i64([[TY]]) #[[#attr:]] +// CHECK-SPIRV: declare [[TY]] @llvm.spv.wave.reduce.umax.i64([[TY]]) #[[#attr:]] // Test basic lowering to runtime function call with array and float value. @@ -40,7 +40,7 @@ float4 test_floatv4(float4 expr) { } // CHECK-DXIL: declare [[TY1]] @llvm.dx.wave.reduce.max.v4f32([[TY1]]) #[[#attr]] -// CHECK-SPIRV: declare spir_func [[TY1]] @llvm.spv.wave.reduce.max.v4f32([[TY1]]) #[[#attr]] +// CHECK-SPIRV: declare [[TY1]] @llvm.spv.wave.reduce.max.v4f32([[TY1]]) #[[#attr]] // CHECK: attributes #[[#attr]] = {{{.*}} convergent {{.*}}} diff --git a/external/llvm-project/clang/test/CodeGenHLSL/builtins/WaveActiveSum.hlsl b/external/llvm-project/clang/test/CodeGenHLSL/builtins/WaveActiveSum.hlsl index 4bf423ccc1b8..1fc93c62c8db 100644 --- a/external/llvm-project/clang/test/CodeGenHLSL/builtins/WaveActiveSum.hlsl +++ b/external/llvm-project/clang/test/CodeGenHLSL/builtins/WaveActiveSum.hlsl @@ -16,7 +16,7 @@ int test_int(int expr) { } // CHECK-DXIL: declare [[TY]] @llvm.dx.wave.reduce.sum.i32([[TY]]) #[[#attr:]] -// CHECK-SPIRV: declare spir_func [[TY]] @llvm.spv.wave.reduce.sum.i32([[TY]]) #[[#attr:]] +// CHECK-SPIRV: declare [[TY]] @llvm.spv.wave.reduce.sum.i32([[TY]]) #[[#attr:]] // CHECK-LABEL: test_uint64_t uint64_t test_uint64_t(uint64_t expr) { @@ -27,7 +27,7 @@ uint64_t test_uint64_t(uint64_t expr) { } // CHECK-DXIL: declare [[TY]] @llvm.dx.wave.reduce.usum.i64([[TY]]) #[[#attr:]] -// CHECK-SPIRV: declare spir_func [[TY]] @llvm.spv.wave.reduce.sum.i64([[TY]]) #[[#attr:]] +// CHECK-SPIRV: declare [[TY]] @llvm.spv.wave.reduce.sum.i64([[TY]]) #[[#attr:]] // Test basic lowering to runtime function call with array and float value. @@ -40,6 +40,6 @@ float4 test_floatv4(float4 expr) { } // CHECK-DXIL: declare [[TY1]] @llvm.dx.wave.reduce.sum.v4f32([[TY1]]) #[[#attr]] -// CHECK-SPIRV: declare spir_func [[TY1]] @llvm.spv.wave.reduce.sum.v4f32([[TY1]]) #[[#attr]] +// CHECK-SPIRV: declare [[TY1]] @llvm.spv.wave.reduce.sum.v4f32([[TY1]]) #[[#attr]] // CHECK: attributes #[[#attr]] = {{{.*}} convergent {{.*}}} diff --git a/external/llvm-project/clang/test/CodeGenHLSL/builtins/WaveReadLaneAt.hlsl b/external/llvm-project/clang/test/CodeGenHLSL/builtins/WaveReadLaneAt.hlsl index c94ef8a67735..8c787a42618a 100644 --- a/external/llvm-project/clang/test/CodeGenHLSL/builtins/WaveReadLaneAt.hlsl +++ b/external/llvm-project/clang/test/CodeGenHLSL/builtins/WaveReadLaneAt.hlsl @@ -17,7 +17,7 @@ int test_int(int expr, uint idx) { } // CHECK-DXIL: declare [[TY]] @llvm.dx.wave.readlane.i32([[TY]], i32) #[[#attr:]] -// CHECK-SPIRV: declare spir_func [[TY]] @llvm.spv.wave.readlane.i32([[TY]], i32) #[[#attr:]] +// CHECK-SPIRV: declare [[TY]] @llvm.spv.wave.readlane.i32([[TY]], i32) #[[#attr:]] // CHECK-LABEL: test_uint uint test_uint(uint expr, uint idx) { @@ -38,7 +38,7 @@ int64_t test_int64_t(int64_t expr, uint idx) { } // CHECK-DXIL: declare [[TY]] @llvm.dx.wave.readlane.i64([[TY]], i32) #[[#attr:]] -// CHECK-SPIRV: declare spir_func [[TY]] @llvm.spv.wave.readlane.i64([[TY]], i32) #[[#attr:]] +// CHECK-SPIRV: declare [[TY]] @llvm.spv.wave.readlane.i64([[TY]], i32) #[[#attr:]] // CHECK-LABEL: test_uint64_t uint64_t test_uint64_t(uint64_t expr, uint idx) { @@ -60,7 +60,7 @@ int16_t test_int16(int16_t expr, uint idx) { } // CHECK-DXIL: declare [[TY]] @llvm.dx.wave.readlane.i16([[TY]], i32) #[[#attr:]] -// CHECK-SPIRV: declare spir_func [[TY]] @llvm.spv.wave.readlane.i16([[TY]], i32) #[[#attr:]] +// CHECK-SPIRV: declare [[TY]] @llvm.spv.wave.readlane.i16([[TY]], i32) #[[#attr:]] // CHECK-LABEL: test_uint16 uint16_t test_uint16(uint16_t expr, uint idx) { @@ -84,7 +84,7 @@ half test_half(half expr, uint idx) { } // CHECK-DXIL: declare [[TY]] @llvm.dx.wave.readlane.f16([[TY]], i32) #[[#attr:]] -// CHECK-SPIRV: declare spir_func [[TY]] @llvm.spv.wave.readlane.f16([[TY]], i32) #[[#attr:]] +// CHECK-SPIRV: declare [[TY]] @llvm.spv.wave.readlane.f16([[TY]], i32) #[[#attr:]] // CHECK-LABEL: test_double double test_double(double expr, uint idx) { @@ -96,7 +96,7 @@ double test_double(double expr, uint idx) { } // CHECK-DXIL: declare [[TY]] @llvm.dx.wave.readlane.f64([[TY]], i32) #[[#attr:]] -// CHECK-SPIRV: declare spir_func [[TY]] @llvm.spv.wave.readlane.f64([[TY]], i32) #[[#attr:]] +// CHECK-SPIRV: declare [[TY]] @llvm.spv.wave.readlane.f64([[TY]], i32) #[[#attr:]] // CHECK-LABEL: test_floatv4 float4 test_floatv4(float4 expr, uint idx) { @@ -108,6 +108,6 @@ float4 test_floatv4(float4 expr, uint idx) { } // CHECK-DXIL: declare [[TY1]] @llvm.dx.wave.readlane.v4f32([[TY1]], i32) #[[#attr]] -// CHECK-SPIRV: declare spir_func [[TY1]] @llvm.spv.wave.readlane.v4f32([[TY1]], i32) #[[#attr]] +// CHECK-SPIRV: declare [[TY1]] @llvm.spv.wave.readlane.v4f32([[TY1]], i32) #[[#attr]] // CHECK: attributes #[[#attr]] = {{{.*}} convergent {{.*}}} diff --git a/external/llvm-project/clang/test/CodeGenHLSL/builtins/abs.hlsl b/external/llvm-project/clang/test/CodeGenHLSL/builtins/abs.hlsl index e8a6ee044957..6abe2f816c84 100644 --- a/external/llvm-project/clang/test/CodeGenHLSL/builtins/abs.hlsl +++ b/external/llvm-project/clang/test/CodeGenHLSL/builtins/abs.hlsl @@ -8,16 +8,16 @@ using hlsl::abs; #ifdef __HLSL_ENABLE_16_BIT -// NATIVE_HALF-LABEL: define noundef i16 @_Z16test_abs_int16_t +// NATIVE_HALF-LABEL: define hidden noundef i16 @_Z16test_abs_int16_t // NATIVE_HALF: call i16 @llvm.abs.i16( int16_t test_abs_int16_t(int16_t p0) { return abs(p0); } -// NATIVE_HALF-LABEL: define noundef <2 x i16> @_Z17test_abs_int16_t2 +// NATIVE_HALF-LABEL: define hidden noundef <2 x i16> @_Z17test_abs_int16_t2 // NATIVE_HALF: call <2 x i16> @llvm.abs.v2i16( int16_t2 test_abs_int16_t2(int16_t2 p0) { return abs(p0); } -// NATIVE_HALF-LABEL: define noundef <3 x i16> @_Z17test_abs_int16_t3 +// NATIVE_HALF-LABEL: define hidden noundef <3 x i16> @_Z17test_abs_int16_t3 // NATIVE_HALF: call <3 x i16> @llvm.abs.v3i16( int16_t3 test_abs_int16_t3(int16_t3 p0) { return abs(p0); } -// NATIVE_HALF-LABEL: define noundef <4 x i16> @_Z17test_abs_int16_t4 +// NATIVE_HALF-LABEL: define hidden noundef <4 x i16> @_Z17test_abs_int16_t4 // NATIVE_HALF: call <4 x i16> @llvm.abs.v4i16( int16_t4 test_abs_int16_t4(int16_t4 p0) { return abs(p0); } @@ -50,76 +50,76 @@ uint16_t3 test_abs_uint64_t3(uint16_t3 p0) { return abs(p0); } uint16_t4 test_abs_uint64_t4(uint16_t4 p0) { return abs(p0); } #endif // __HLSL_ENABLE_16_BIT -// NATIVE_HALF-LABEL: define noundef nofpclass(nan inf) half @_Z13test_abs_half +// NATIVE_HALF-LABEL: define hidden noundef nofpclass(nan inf) half @_Z13test_abs_half // NATIVE_HALF: call reassoc nnan ninf nsz arcp afn half @llvm.fabs.f16( -// NO_HALF-LABEL: define noundef nofpclass(nan inf) float @_Z13test_abs_half +// NO_HALF-LABEL: define hidden noundef nofpclass(nan inf) float @_Z13test_abs_half // NO_HALF: call reassoc nnan ninf nsz arcp afn float @llvm.fabs.f32(float %0) half test_abs_half(half p0) { return abs(p0); } -// NATIVE_HALF-LABEL: define noundef nofpclass(nan inf) <2 x half> @_Z14test_abs_half2 +// NATIVE_HALF-LABEL: define hidden noundef nofpclass(nan inf) <2 x half> @_Z14test_abs_half2 // NATIVE_HALF: call reassoc nnan ninf nsz arcp afn <2 x half> @llvm.fabs.v2f16( -// NO_HALF-LABEL: define noundef nofpclass(nan inf) <2 x float> @_Z14test_abs_half2 +// NO_HALF-LABEL: define hidden noundef nofpclass(nan inf) <2 x float> @_Z14test_abs_half2 // NO_HALF: call reassoc nnan ninf nsz arcp afn <2 x float> @llvm.fabs.v2f32( half2 test_abs_half2(half2 p0) { return abs(p0); } -// NATIVE_HALF-LABEL: define noundef nofpclass(nan inf) <3 x half> @_Z14test_abs_half3 +// NATIVE_HALF-LABEL: define hidden noundef nofpclass(nan inf) <3 x half> @_Z14test_abs_half3 // NATIVE_HALF: call reassoc nnan ninf nsz arcp afn <3 x half> @llvm.fabs.v3f16( -// NO_HALF-LABEL: define noundef nofpclass(nan inf) <3 x float> @_Z14test_abs_half3 +// NO_HALF-LABEL: define hidden noundef nofpclass(nan inf) <3 x float> @_Z14test_abs_half3 // NO_HALF: call reassoc nnan ninf nsz arcp afn <3 x float> @llvm.fabs.v3f32( half3 test_abs_half3(half3 p0) { return abs(p0); } -// NATIVE_HALF-LABEL: define noundef nofpclass(nan inf) <4 x half> @_Z14test_abs_half4 +// NATIVE_HALF-LABEL: define hidden noundef nofpclass(nan inf) <4 x half> @_Z14test_abs_half4 // NATIVE_HALF: call reassoc nnan ninf nsz arcp afn <4 x half> @llvm.fabs.v4f16( -// NO_HALF-LABEL: define noundef nofpclass(nan inf) <4 x float> @_Z14test_abs_half4 +// NO_HALF-LABEL: define hidden noundef nofpclass(nan inf) <4 x float> @_Z14test_abs_half4 // NO_HALF: call reassoc nnan ninf nsz arcp afn <4 x float> @llvm.fabs.v4f32( half4 test_abs_half4(half4 p0) { return abs(p0); } -// CHECK-LABEL: define noundef i32 @_Z12test_abs_int +// CHECK-LABEL: define hidden noundef i32 @_Z12test_abs_int // CHECK: call i32 @llvm.abs.i32( int test_abs_int(int p0) { return abs(p0); } -// CHECK-LABEL: define noundef <2 x i32> @_Z13test_abs_int2 +// CHECK-LABEL: define hidden noundef <2 x i32> @_Z13test_abs_int2 // CHECK: call <2 x i32> @llvm.abs.v2i32( int2 test_abs_int2(int2 p0) { return abs(p0); } -// CHECK-LABEL: define noundef <3 x i32> @_Z13test_abs_int3 +// CHECK-LABEL: define hidden noundef <3 x i32> @_Z13test_abs_int3 // CHECK: call <3 x i32> @llvm.abs.v3i32( int3 test_abs_int3(int3 p0) { return abs(p0); } -// CHECK-LABEL: define noundef <4 x i32> @_Z13test_abs_int4 +// CHECK-LABEL: define hidden noundef <4 x i32> @_Z13test_abs_int4 // CHECK: call <4 x i32> @llvm.abs.v4i32( int4 test_abs_int4(int4 p0) { return abs(p0); } -// CHECK-LABEL: define noundef nofpclass(nan inf) float @_Z14test_abs_float +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) float @_Z14test_abs_float // CHECK: call reassoc nnan ninf nsz arcp afn float @llvm.fabs.f32( float test_abs_float(float p0) { return abs(p0); } -// CHECK-LABEL: define noundef nofpclass(nan inf) <2 x float> @_Z15test_abs_float2 +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) <2 x float> @_Z15test_abs_float2 // CHECK: call reassoc nnan ninf nsz arcp afn <2 x float> @llvm.fabs.v2f32( float2 test_abs_float2(float2 p0) { return abs(p0); } -// CHECK-LABEL: define noundef nofpclass(nan inf) <3 x float> @_Z15test_abs_float3 +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) <3 x float> @_Z15test_abs_float3 // CHECK: call reassoc nnan ninf nsz arcp afn <3 x float> @llvm.fabs.v3f32( float3 test_abs_float3(float3 p0) { return abs(p0); } -// CHECK-LABEL: define noundef nofpclass(nan inf) <4 x float> @_Z15test_abs_float4 +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) <4 x float> @_Z15test_abs_float4 // CHECK: call reassoc nnan ninf nsz arcp afn <4 x float> @llvm.fabs.v4f32( float4 test_abs_float4(float4 p0) { return abs(p0); } -// CHECK-LABEL: define noundef i64 @_Z16test_abs_int64_t +// CHECK-LABEL: define hidden noundef i64 @_Z16test_abs_int64_t // CHECK: call i64 @llvm.abs.i64( int64_t test_abs_int64_t(int64_t p0) { return abs(p0); } -// CHECK-LABEL: define noundef <2 x i64> @_Z17test_abs_int64_t2 +// CHECK-LABEL: define hidden noundef <2 x i64> @_Z17test_abs_int64_t2 // CHECK: call <2 x i64> @llvm.abs.v2i64( int64_t2 test_abs_int64_t2(int64_t2 p0) { return abs(p0); } -// CHECK-LABEL: define noundef <3 x i64> @_Z17test_abs_int64_t3 +// CHECK-LABEL: define hidden noundef <3 x i64> @_Z17test_abs_int64_t3 // CHECK: call <3 x i64> @llvm.abs.v3i64( int64_t3 test_abs_int64_t3(int64_t3 p0) { return abs(p0); } -// CHECK-LABEL: define noundef <4 x i64> @_Z17test_abs_int64_t4 +// CHECK-LABEL: define hidden noundef <4 x i64> @_Z17test_abs_int64_t4 // CHECK: call <4 x i64> @llvm.abs.v4i64( int64_t4 test_abs_int64_t4(int64_t4 p0) { return abs(p0); } -// CHECK-LABEL: define noundef nofpclass(nan inf) double @_Z15test_abs_double +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) double @_Z15test_abs_double // CHECK: call reassoc nnan ninf nsz arcp afn double @llvm.fabs.f64( double test_abs_double(double p0) { return abs(p0); } -// CHECK-LABEL: define noundef nofpclass(nan inf) <2 x double> @_Z16test_abs_double2 +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) <2 x double> @_Z16test_abs_double2 // CHECK: call reassoc nnan ninf nsz arcp afn <2 x double> @llvm.fabs.v2f64( double2 test_abs_double2(double2 p0) { return abs(p0); } -// CHECK-LABEL: define noundef nofpclass(nan inf) <3 x double> @_Z16test_abs_double3 +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) <3 x double> @_Z16test_abs_double3 // CHECK: call reassoc nnan ninf nsz arcp afn <3 x double> @llvm.fabs.v3f64( double3 test_abs_double3(double3 p0) { return abs(p0); } -// CHECK-LABEL: define noundef nofpclass(nan inf) <4 x double> @_Z16test_abs_double4 +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) <4 x double> @_Z16test_abs_double4 // CHECK: call reassoc nnan ninf nsz arcp afn <4 x double> @llvm.fabs.v4f64( double4 test_abs_double4(double4 p0) { return abs(p0); } diff --git a/external/llvm-project/clang/test/CodeGenHLSL/builtins/all.hlsl b/external/llvm-project/clang/test/CodeGenHLSL/builtins/all.hlsl index 39f364c5953d..391fad0ef33f 100644 --- a/external/llvm-project/clang/test/CodeGenHLSL/builtins/all.hlsl +++ b/external/llvm-project/clang/test/CodeGenHLSL/builtins/all.hlsl @@ -2,20 +2,20 @@ // RUN: spirv-unknown-vulkan-compute %s -fnative-half-type \ // RUN: -emit-llvm -disable-llvm-passes -o - | FileCheck %s \ // RUN: --check-prefixes=CHECK,NATIVE_HALF \ -// RUN: -DFNATTRS="spir_func noundef" -DTARGET=spv +// RUN: -DFNATTRS="hidden spir_func noundef" -DTARGET=spv // RUN: %clang_cc1 -finclude-default-header -x hlsl -triple \ // RUN: spirv-unknown-vulkan-compute %s -emit-llvm -disable-llvm-passes \ // RUN: -o - | FileCheck %s --check-prefixes=CHECK \ -// RUN: -DFNATTRS="spir_func noundef" -DTARGET=spv +// RUN: -DFNATTRS="hidden spir_func noundef" -DTARGET=spv // RUN: %clang_cc1 -finclude-default-header -x hlsl -triple \ // RUN: dxil-pc-shadermodel6.3-library %s -fnative-half-type \ // RUN: -emit-llvm -disable-llvm-passes -o - | FileCheck %s \ // RUN: --check-prefixes=CHECK,NATIVE_HALF \ -// RUN: -DFNATTRS=noundef -DTARGET=dx +// RUN: -DFNATTRS="hidden noundef" -DTARGET=dx // RUN: %clang_cc1 -finclude-default-header -x hlsl -triple \ // RUN: dxil-pc-shadermodel6.3-library %s -emit-llvm -disable-llvm-passes \ // RUN: -o - | FileCheck %s --check-prefixes=CHECK \ -// RUN: -DFNATTRS=noundef -DTARGET=dx +// RUN: -DFNATTRS="hidden noundef" -DTARGET=dx #ifdef __HLSL_ENABLE_16_BIT // NATIVE_HALF: define [[FNATTRS]] i1 @ diff --git a/external/llvm-project/clang/test/CodeGenHLSL/builtins/and.hlsl b/external/llvm-project/clang/test/CodeGenHLSL/builtins/and.hlsl index b77889cd9ae7..d2ca7cf4163e 100644 --- a/external/llvm-project/clang/test/CodeGenHLSL/builtins/and.hlsl +++ b/external/llvm-project/clang/test/CodeGenHLSL/builtins/and.hlsl @@ -3,7 +3,7 @@ // RUN: dxil-pc-shadermodel6.3-library %s \ // RUN: -emit-llvm -O1 -o - | FileCheck %s -// CHECK-LABEL: define noundef i1 @_Z15test_and_scalarbb( +// CHECK-LABEL: define hidden noundef i1 @_Z15test_and_scalarbb( // CHECK-SAME: i1 noundef [[X:%.*]], i1 noundef [[Y:%.*]]) local_unnamed_addr #[[ATTR0:[0-9]+]] { // CHECK-NEXT: [[ENTRY:.*:]] // CHECK-NEXT: [[HLSL_AND:%.*]] = and i1 [[X]], [[Y]] @@ -13,7 +13,7 @@ bool test_and_scalar(bool x, bool y) { return and(x, y); } -// CHECK-LABEL: define noundef <2 x i1> @_Z14test_and_bool2Dv2_bS_( +// CHECK-LABEL: define hidden noundef <2 x i1> @_Z14test_and_bool2Dv2_bS_( // CHECK-SAME: <2 x i1> noundef [[X:%.*]], <2 x i1> noundef [[Y:%.*]]) local_unnamed_addr #[[ATTR0]] { // CHECK-NEXT: [[ENTRY:.*:]] // CHECK-NEXT: [[HLSL_AND:%.*]] = and <2 x i1> [[X]], [[Y]] @@ -23,7 +23,7 @@ bool2 test_and_bool2(bool2 x, bool2 y) { return and(x, y); } -// CHECK-LABEL: define noundef <3 x i1> @_Z14test_and_bool3Dv3_bS_( +// CHECK-LABEL: define hidden noundef <3 x i1> @_Z14test_and_bool3Dv3_bS_( // CHECK-SAME: <3 x i1> noundef [[X:%.*]], <3 x i1> noundef [[Y:%.*]]) local_unnamed_addr #[[ATTR0]] { // CHECK-NEXT: [[ENTRY:.*:]] // CHECK-NEXT: [[HLSL_AND:%.*]] = and <3 x i1> [[X]], [[Y]] @@ -33,7 +33,7 @@ bool3 test_and_bool3(bool3 x, bool3 y) { return and(x, y); } -// CHECK-LABEL: define noundef <4 x i1> @_Z14test_and_bool4Dv4_bS_( +// CHECK-LABEL: define hidden noundef <4 x i1> @_Z14test_and_bool4Dv4_bS_( // CHECK-SAME: <4 x i1> noundef [[X:%.*]], <4 x i1> noundef [[Y:%.*]]) local_unnamed_addr #[[ATTR0]] { // CHECK-NEXT: [[ENTRY:.*:]] // CHECK-NEXT: [[HLSL_AND:%.*]] = and <4 x i1> [[X]], [[Y]] @@ -43,7 +43,7 @@ bool4 test_and_bool4(bool4 x, bool4 y) { return and(x, y); } -// CHECK-LABEL: define noundef <4 x i1> @_Z13test_and_int4Dv4_iS_( +// CHECK-LABEL: define hidden noundef <4 x i1> @_Z13test_and_int4Dv4_iS_( // CHECK-SAME: <4 x i32> noundef [[X:%.*]], <4 x i32> noundef [[Y:%.*]]) local_unnamed_addr #[[ATTR0]] { // CHECK-NEXT: [[ENTRY:.*:]] // CHECK-NEXT: [[TOBOOL:%.*]] = icmp ne <4 x i32> [[X]], zeroinitializer @@ -55,7 +55,7 @@ bool4 test_and_int4(int4 x, int4 y) { return and(x, y); } -// CHECK-LABEL: define noundef <4 x i1> @_Z15test_and_float4Dv4_fS_( +// CHECK-LABEL: define hidden noundef <4 x i1> @_Z15test_and_float4Dv4_fS_( // CHECK-SAME: <4 x float> noundef nofpclass(nan inf) [[X:%.*]], <4 x float> noundef nofpclass(nan inf) [[Y:%.*]]) local_unnamed_addr #[[ATTR0]] { // CHECK-NEXT: [[ENTRY:.*:]] // CHECK-NEXT: [[TOBOOL:%.*]] = fcmp reassoc nnan ninf nsz arcp afn une <4 x float> [[X]], zeroinitializer diff --git a/external/llvm-project/clang/test/CodeGenHLSL/builtins/any.hlsl b/external/llvm-project/clang/test/CodeGenHLSL/builtins/any.hlsl index 3d9d8e9e689e..e4837876e269 100644 --- a/external/llvm-project/clang/test/CodeGenHLSL/builtins/any.hlsl +++ b/external/llvm-project/clang/test/CodeGenHLSL/builtins/any.hlsl @@ -2,20 +2,20 @@ // RUN: spirv-unknown-vulkan-compute %s -fnative-half-type \ // RUN: -emit-llvm -disable-llvm-passes -o - | FileCheck %s \ // RUN: --check-prefixes=CHECK,NATIVE_HALF \ -// RUN: -DFNATTRS="spir_func noundef" -DTARGET=spv +// RUN: -DFNATTRS="hidden spir_func noundef" -DTARGET=spv // RUN: %clang_cc1 -finclude-default-header -x hlsl -triple \ // RUN: spirv-unknown-vulkan-compute %s -emit-llvm -disable-llvm-passes \ // RUN: -o - | FileCheck %s --check-prefixes=CHECK \ -// RUN: -DFNATTRS="spir_func noundef" -DTARGET=spv +// RUN: -DFNATTRS="hidden spir_func noundef" -DTARGET=spv // RUN: %clang_cc1 -finclude-default-header -x hlsl -triple \ // RUN: dxil-pc-shadermodel6.3-library %s -fnative-half-type \ // RUN: -emit-llvm -disable-llvm-passes -o - | FileCheck %s \ // RUN: --check-prefixes=CHECK,NATIVE_HALF \ -// RUN: -DFNATTRS=noundef -DTARGET=dx +// RUN: -DFNATTRS="hidden noundef" -DTARGET=dx // RUN: %clang_cc1 -finclude-default-header -x hlsl -triple \ // RUN: dxil-pc-shadermodel6.3-library %s -emit-llvm -disable-llvm-passes \ // RUN: -o - | FileCheck %s --check-prefixes=CHECK \ -// RUN: -DFNATTRS=noundef -DTARGET=dx +// RUN: -DFNATTRS="hidden noundef" -DTARGET=dx #ifdef __HLSL_ENABLE_16_BIT // NATIVE_HALF: define [[FNATTRS]] i1 @ diff --git a/external/llvm-project/clang/test/CodeGenHLSL/builtins/ceil-overloads.hlsl b/external/llvm-project/clang/test/CodeGenHLSL/builtins/ceil-overloads.hlsl index b313c99e89a5..bdefe46b802e 100644 --- a/external/llvm-project/clang/test/CodeGenHLSL/builtins/ceil-overloads.hlsl +++ b/external/llvm-project/clang/test/CodeGenHLSL/builtins/ceil-overloads.hlsl @@ -4,67 +4,67 @@ using hlsl::ceil; -// CHECK-LABEL: define noundef nofpclass(nan inf) float {{.*}}test_ceil_double +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) float {{.*}}test_ceil_double // CHECK: call reassoc nnan ninf nsz arcp afn float @llvm.ceil.f32( float test_ceil_double(double p0) { return ceil(p0); } -// CHECK-LABEL: define noundef nofpclass(nan inf) <2 x float> {{.*}}test_ceil_double2 +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) <2 x float> {{.*}}test_ceil_double2 // CHECK: call reassoc nnan ninf nsz arcp afn <2 x float> @llvm.ceil.v2f32( float2 test_ceil_double2(double2 p0) { return ceil(p0); } -// CHECK-LABEL: define noundef nofpclass(nan inf) <3 x float> {{.*}}test_ceil_double3 +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) <3 x float> {{.*}}test_ceil_double3 // CHECK: call reassoc nnan ninf nsz arcp afn <3 x float> @llvm.ceil.v3f32( float3 test_ceil_double3(double3 p0) { return ceil(p0); } -// CHECK-LABEL: define noundef nofpclass(nan inf) <4 x float> {{.*}}test_ceil_double4 +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) <4 x float> {{.*}}test_ceil_double4 // CHECK: call reassoc nnan ninf nsz arcp afn <4 x float> @llvm.ceil.v4f32( float4 test_ceil_double4(double4 p0) { return ceil(p0); } -// CHECK-LABEL: define noundef nofpclass(nan inf) float {{.*}}test_ceil_int +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) float {{.*}}test_ceil_int // CHECK: call reassoc nnan ninf nsz arcp afn float @llvm.ceil.f32( float test_ceil_int(int p0) { return ceil(p0); } -// CHECK-LABEL: define noundef nofpclass(nan inf) <2 x float> {{.*}}test_ceil_int2 +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) <2 x float> {{.*}}test_ceil_int2 // CHECK: call reassoc nnan ninf nsz arcp afn <2 x float> @llvm.ceil.v2f32( float2 test_ceil_int2(int2 p0) { return ceil(p0); } -// CHECK-LABEL: define noundef nofpclass(nan inf) <3 x float> {{.*}}test_ceil_int3 +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) <3 x float> {{.*}}test_ceil_int3 // CHECK: call reassoc nnan ninf nsz arcp afn <3 x float> @llvm.ceil.v3f32( float3 test_ceil_int3(int3 p0) { return ceil(p0); } -// CHECK-LABEL: define noundef nofpclass(nan inf) <4 x float> {{.*}}test_ceil_int4 +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) <4 x float> {{.*}}test_ceil_int4 // CHECK: call reassoc nnan ninf nsz arcp afn <4 x float> @llvm.ceil.v4f32( float4 test_ceil_int4(int4 p0) { return ceil(p0); } -// CHECK-LABEL: define noundef nofpclass(nan inf) float {{.*}}test_ceil_uint +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) float {{.*}}test_ceil_uint // CHECK: call reassoc nnan ninf nsz arcp afn float @llvm.ceil.f32( float test_ceil_uint(uint p0) { return ceil(p0); } -// CHECK-LABEL: define noundef nofpclass(nan inf) <2 x float> {{.*}}test_ceil_uint2 +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) <2 x float> {{.*}}test_ceil_uint2 // CHECK: call reassoc nnan ninf nsz arcp afn <2 x float> @llvm.ceil.v2f32( float2 test_ceil_uint2(uint2 p0) { return ceil(p0); } -// CHECK-LABEL: define noundef nofpclass(nan inf) <3 x float> {{.*}}test_ceil_uint3 +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) <3 x float> {{.*}}test_ceil_uint3 // CHECK: call reassoc nnan ninf nsz arcp afn <3 x float> @llvm.ceil.v3f32( float3 test_ceil_uint3(uint3 p0) { return ceil(p0); } -// CHECK-LABEL: define noundef nofpclass(nan inf) <4 x float> {{.*}}test_ceil_uint4 +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) <4 x float> {{.*}}test_ceil_uint4 // CHECK: call reassoc nnan ninf nsz arcp afn <4 x float> @llvm.ceil.v4f32( float4 test_ceil_uint4(uint4 p0) { return ceil(p0); } -// CHECK-LABEL: define noundef nofpclass(nan inf) float {{.*}}test_ceil_int64_t +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) float {{.*}}test_ceil_int64_t // CHECK: call reassoc nnan ninf nsz arcp afn float @llvm.ceil.f32( float test_ceil_int64_t(int64_t p0) { return ceil(p0); } -// CHECK-LABEL: define noundef nofpclass(nan inf) <2 x float> {{.*}}test_ceil_int64_t2 +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) <2 x float> {{.*}}test_ceil_int64_t2 // CHECK: call reassoc nnan ninf nsz arcp afn <2 x float> @llvm.ceil.v2f32( float2 test_ceil_int64_t2(int64_t2 p0) { return ceil(p0); } -// CHECK-LABEL: define noundef nofpclass(nan inf) <3 x float> {{.*}}test_ceil_int64_t3 +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) <3 x float> {{.*}}test_ceil_int64_t3 // CHECK: call reassoc nnan ninf nsz arcp afn <3 x float> @llvm.ceil.v3f32( float3 test_ceil_int64_t3(int64_t3 p0) { return ceil(p0); } -// CHECK-LABEL: define noundef nofpclass(nan inf) <4 x float> {{.*}}test_ceil_int64_t4 +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) <4 x float> {{.*}}test_ceil_int64_t4 // CHECK: call reassoc nnan ninf nsz arcp afn <4 x float> @llvm.ceil.v4f32( float4 test_ceil_int64_t4(int64_t4 p0) { return ceil(p0); } -// CHECK-LABEL: define noundef nofpclass(nan inf) float {{.*}}test_ceil_uint64_t +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) float {{.*}}test_ceil_uint64_t // CHECK: call reassoc nnan ninf nsz arcp afn float @llvm.ceil.f32( float test_ceil_uint64_t(uint64_t p0) { return ceil(p0); } -// CHECK-LABEL: define noundef nofpclass(nan inf) <2 x float> {{.*}}test_ceil_uint64_t2 +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) <2 x float> {{.*}}test_ceil_uint64_t2 // CHECK: call reassoc nnan ninf nsz arcp afn <2 x float> @llvm.ceil.v2f32( float2 test_ceil_uint64_t2(uint64_t2 p0) { return ceil(p0); } -// CHECK-LABEL: define noundef nofpclass(nan inf) <3 x float> {{.*}}test_ceil_uint64_t3 +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) <3 x float> {{.*}}test_ceil_uint64_t3 // CHECK: call reassoc nnan ninf nsz arcp afn <3 x float> @llvm.ceil.v3f32( float3 test_ceil_uint64_t3(uint64_t3 p0) { return ceil(p0); } -// CHECK-LABEL: define noundef nofpclass(nan inf) <4 x float> {{.*}}test_ceil_uint64_t4 +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) <4 x float> {{.*}}test_ceil_uint64_t4 // CHECK: call reassoc nnan ninf nsz arcp afn <4 x float> @llvm.ceil.v4f32( float4 test_ceil_uint64_t4(uint64_t4 p0) { return ceil(p0); } diff --git a/external/llvm-project/clang/test/CodeGenHLSL/builtins/ceil.hlsl b/external/llvm-project/clang/test/CodeGenHLSL/builtins/ceil.hlsl index fe0b8f898383..1a9c630b60e5 100644 --- a/external/llvm-project/clang/test/CodeGenHLSL/builtins/ceil.hlsl +++ b/external/llvm-project/clang/test/CodeGenHLSL/builtins/ceil.hlsl @@ -7,36 +7,36 @@ using hlsl::ceil; -// NATIVE_HALF-LABEL: define noundef nofpclass(nan inf) half @_Z14test_ceil_half +// NATIVE_HALF-LABEL: define hidden noundef nofpclass(nan inf) half @_Z14test_ceil_half // NATIVE_HALF: call reassoc nnan ninf nsz arcp afn half @llvm.ceil.f16( -// NO_HALF-LABEL: define noundef nofpclass(nan inf) float @_Z14test_ceil_half +// NO_HALF-LABEL: define hidden noundef nofpclass(nan inf) float @_Z14test_ceil_half // NO_HALF: call reassoc nnan ninf nsz arcp afn float @llvm.ceil.f32(float %0) half test_ceil_half(half p0) { return ceil(p0); } -// NATIVE_HALF-LABEL: define noundef nofpclass(nan inf) <2 x half> @_Z15test_ceil_half2 +// NATIVE_HALF-LABEL: define hidden noundef nofpclass(nan inf) <2 x half> @_Z15test_ceil_half2 // NATIVE_HALF: call reassoc nnan ninf nsz arcp afn <2 x half> @llvm.ceil.v2f16( -// NO_HALF-LABEL: define noundef nofpclass(nan inf) <2 x float> @_Z15test_ceil_half2 +// NO_HALF-LABEL: define hidden noundef nofpclass(nan inf) <2 x float> @_Z15test_ceil_half2 // NO_HALF: call reassoc nnan ninf nsz arcp afn <2 x float> @llvm.ceil.v2f32( half2 test_ceil_half2(half2 p0) { return ceil(p0); } -// NATIVE_HALF-LABEL: define noundef nofpclass(nan inf) <3 x half> @_Z15test_ceil_half3 +// NATIVE_HALF-LABEL: define hidden noundef nofpclass(nan inf) <3 x half> @_Z15test_ceil_half3 // NATIVE_HALF: call reassoc nnan ninf nsz arcp afn <3 x half> @llvm.ceil.v3f16( -// NO_HALF-LABEL: define noundef nofpclass(nan inf) <3 x float> @_Z15test_ceil_half3 +// NO_HALF-LABEL: define hidden noundef nofpclass(nan inf) <3 x float> @_Z15test_ceil_half3 // NO_HALF: call reassoc nnan ninf nsz arcp afn <3 x float> @llvm.ceil.v3f32( half3 test_ceil_half3(half3 p0) { return ceil(p0); } -// NATIVE_HALF-LABEL: define noundef nofpclass(nan inf) <4 x half> @_Z15test_ceil_half4 +// NATIVE_HALF-LABEL: define hidden noundef nofpclass(nan inf) <4 x half> @_Z15test_ceil_half4 // NATIVE_HALF: call reassoc nnan ninf nsz arcp afn <4 x half> @llvm.ceil.v4f16( -// NO_HALF-LABEL: define noundef nofpclass(nan inf) <4 x float> @_Z15test_ceil_half4 +// NO_HALF-LABEL: define hidden noundef nofpclass(nan inf) <4 x float> @_Z15test_ceil_half4 // NO_HALF: call reassoc nnan ninf nsz arcp afn <4 x float> @llvm.ceil.v4f32( half4 test_ceil_half4(half4 p0) { return ceil(p0); } -// CHECK-LABEL: define noundef nofpclass(nan inf) float @_Z15test_ceil_float +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) float @_Z15test_ceil_float // CHECK: call reassoc nnan ninf nsz arcp afn float @llvm.ceil.f32( float test_ceil_float(float p0) { return ceil(p0); } -// CHECK-LABEL: define noundef nofpclass(nan inf) <2 x float> @_Z16test_ceil_float2 +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) <2 x float> @_Z16test_ceil_float2 // CHECK: call reassoc nnan ninf nsz arcp afn <2 x float> @llvm.ceil.v2f32( float2 test_ceil_float2(float2 p0) { return ceil(p0); } -// CHECK-LABEL: define noundef nofpclass(nan inf) <3 x float> @_Z16test_ceil_float3 +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) <3 x float> @_Z16test_ceil_float3 // CHECK: call reassoc nnan ninf nsz arcp afn <3 x float> @llvm.ceil.v3f32( float3 test_ceil_float3(float3 p0) { return ceil(p0); } -// CHECK-LABEL: define noundef nofpclass(nan inf) <4 x float> @_Z16test_ceil_float4 +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) <4 x float> @_Z16test_ceil_float4 // CHECK: call reassoc nnan ninf nsz arcp afn <4 x float> @llvm.ceil.v4f32( float4 test_ceil_float4(float4 p0) { return ceil(p0); } diff --git a/external/llvm-project/clang/test/CodeGenHLSL/builtins/clamp-overloads.hlsl b/external/llvm-project/clang/test/CodeGenHLSL/builtins/clamp-overloads.hlsl index c0e1e914831a..eaedfb419c19 100644 --- a/external/llvm-project/clang/test/CodeGenHLSL/builtins/clamp-overloads.hlsl +++ b/external/llvm-project/clang/test/CodeGenHLSL/builtins/clamp-overloads.hlsl @@ -1,18 +1,18 @@ // RUN: %clang_cc1 -std=hlsl202x -finclude-default-header -triple dxil-pc-shadermodel6.3-library %s \ // RUN: -fnative-half-type -emit-llvm -o - | FileCheck %s --check-prefixes=CHECK,NATIVE_HALF \ -// RUN: -DTARGET=dx -DFNATTRS=noundef -DFFNATTRS="nofpclass(nan inf)" +// RUN: -DTARGET=dx -DFNATTRS="hidden noundef" -DFFNATTRS="nofpclass(nan inf)" // RUN: %clang_cc1 -std=hlsl202x -finclude-default-header -triple dxil-pc-shadermodel6.3-library %s \ // RUN: -emit-llvm -o - | FileCheck %s --check-prefixes=CHECK,NO_HALF \ -// RUN: -DTARGET=dx -DFNATTRS=noundef -DFFNATTRS="nofpclass(nan inf)" +// RUN: -DTARGET=dx -DFNATTRS="hidden noundef" -DFFNATTRS="nofpclass(nan inf)" // RUN: %clang_cc1 -std=hlsl202x -finclude-default-header -triple spirv-unknown-vulkan-compute %s \ // RUN: -fnative-half-type -emit-llvm -o - | FileCheck %s --check-prefixes=CHECK,NATIVE_HALF \ -// RUN: -DTARGET=spv -DFNATTRS="spir_func noundef" -DFFNATTRS="nofpclass(nan inf)" +// RUN: -DTARGET=spv -DFNATTRS="hidden spir_func noundef" -DFFNATTRS="nofpclass(nan inf)" // RUN: %clang_cc1 -std=hlsl202x -finclude-default-header -triple spirv-unknown-vulkan-compute %s \ // RUN: -emit-llvm -o - | FileCheck %s --check-prefixes=CHECK,NO_HALF \ -// RUN: -DTARGET=spv -DFNATTRS="spir_func noundef" -DFFNATTRS="nofpclass(nan inf)" +// RUN: -DTARGET=spv -DFNATTRS="hidden spir_func noundef" -DFFNATTRS="nofpclass(nan inf)" #ifdef __HLSL_ENABLE_16_BIT // NATIVE_HALF: define [[FNATTRS]] <4 x i16> {{.*}}test_clamp_short4_mismatch diff --git a/external/llvm-project/clang/test/CodeGenHLSL/builtins/clamp.hlsl b/external/llvm-project/clang/test/CodeGenHLSL/builtins/clamp.hlsl index d01c2a45c43c..58db4423799b 100644 --- a/external/llvm-project/clang/test/CodeGenHLSL/builtins/clamp.hlsl +++ b/external/llvm-project/clang/test/CodeGenHLSL/builtins/clamp.hlsl @@ -1,19 +1,19 @@ // RUN: %clang_cc1 -finclude-default-header -triple dxil-pc-shadermodel6.3-library %s \ // RUN: -fnative-half-type -emit-llvm -disable-llvm-passes -o - | \ // RUN: FileCheck %s --check-prefixes=CHECK,NATIVE_HALF \ -// RUN: -DTARGET=dx -DFNATTRS=noundef -DFFNATTRS="nofpclass(nan inf)" +// RUN: -DTARGET=dx -DFNATTRS="hidden noundef" -DFFNATTRS="nofpclass(nan inf)" // RUN: %clang_cc1 -finclude-default-header -triple dxil-pc-shadermodel6.3-library %s \ // RUN: -emit-llvm -disable-llvm-passes -o - | \ // RUN: FileCheck %s --check-prefixes=CHECK,NO_HALF \ -// RUN: -DTARGET=dx -DFNATTRS=noundef -DFFNATTRS="nofpclass(nan inf)" +// RUN: -DTARGET=dx -DFNATTRS="hidden noundef" -DFFNATTRS="nofpclass(nan inf)" // RUN: %clang_cc1 -finclude-default-header -triple spirv-unknown-vulkan-compute %s \ // RUN: -fnative-half-type -emit-llvm -disable-llvm-passes -o - | \ // RUN: FileCheck %s --check-prefixes=CHECK,NATIVE_HALF \ -// RUN: -DTARGET=spv -DFNATTRS="spir_func noundef" -DFFNATTRS="nofpclass(nan inf)" +// RUN: -DTARGET=spv -DFNATTRS="hidden spir_func noundef" -DFFNATTRS="nofpclass(nan inf)" // RUN: %clang_cc1 -finclude-default-header -triple spirv-unknown-vulkan-compute %s \ // RUN: -emit-llvm -disable-llvm-passes -o - | \ // RUN: FileCheck %s --check-prefixes=CHECK,NO_HALF \ -// RUN: -DTARGET=spv -DFNATTRS="spir_func noundef" -DFFNATTRS="nofpclass(nan inf)" +// RUN: -DTARGET=spv -DFNATTRS="hidden spir_func noundef" -DFFNATTRS="nofpclass(nan inf)" #ifdef __HLSL_ENABLE_16_BIT // NATIVE_HALF: define [[FNATTRS]] i16 @_Z16test_clamp_short diff --git a/external/llvm-project/clang/test/CodeGenHLSL/builtins/clip-builtin.hlsl b/external/llvm-project/clang/test/CodeGenHLSL/builtins/clip-builtin.hlsl index c864f93af472..aaeb2f026449 100644 --- a/external/llvm-project/clang/test/CodeGenHLSL/builtins/clip-builtin.hlsl +++ b/external/llvm-project/clang/test/CodeGenHLSL/builtins/clip-builtin.hlsl @@ -1,6 +1,6 @@ // RUN: %clang_cc1 -finclude-default-header -x hlsl -triple dxil-pc-shadermodel6.3-library %s -fnative-half-type -emit-llvm -disable-llvm-passes -o - | FileCheck %s -// CHECK: define void @{{.*}}builtin_clip_float{{.*}}(float {{.*}} [[P0:%.*]]) +// CHECK: define hidden void @{{.*}}builtin_clip_float{{.*}}(float {{.*}} [[P0:%.*]]) // CHECK: [[LOAD:%.*]] = load float, ptr [[P0]].addr, align 4 // CHECK-NEXT: [[FCMP:%.*]] = fcmp reassoc nnan ninf nsz arcp afn olt float [[LOAD]], 0.000000e+00 // CHECK-NO: call i1 @llvm.dx.any diff --git a/external/llvm-project/clang/test/CodeGenHLSL/builtins/clip.hlsl b/external/llvm-project/clang/test/CodeGenHLSL/builtins/clip.hlsl index 5a1753766a8a..e067828c38bf 100644 --- a/external/llvm-project/clang/test/CodeGenHLSL/builtins/clip.hlsl +++ b/external/llvm-project/clang/test/CodeGenHLSL/builtins/clip.hlsl @@ -3,13 +3,13 @@ void test_scalar(float Buf) { - // CHECK: define void @{{.*}}test_scalar{{.*}}(float {{.*}} [[VALP:%.*]]) + // CHECK: define hidden void @{{.*}}test_scalar{{.*}}(float {{.*}} [[VALP:%.*]]) // CHECK: [[LOAD:%.*]] = load float, ptr [[VALP]].addr, align 4 // CHECK-NEXT: [[FCMP:%.*]] = fcmp reassoc nnan ninf nsz arcp afn olt float [[LOAD]], 0.000000e+00 // CHECK-NO: call i1 @llvm.dx.any // CHECK-NEXT: call void @llvm.dx.discard(i1 [[FCMP]]) // - // SPIRV: define spir_func void @{{.*}}test_scalar{{.*}}(float {{.*}} [[VALP:%.*]]) + // SPIRV: define hidden spir_func void @{{.*}}test_scalar{{.*}}(float {{.*}} [[VALP:%.*]]) // SPIRV: [[LOAD:%.*]] = load float, ptr [[VALP]].addr, align 4 // SPIRV-NEXT: [[FCMP:%.*]] = fcmp reassoc nnan ninf nsz arcp afn olt float [[LOAD]], 0.000000e+00 // SPIRV-NO: call i1 @llvm.spv.any @@ -21,13 +21,13 @@ void test_scalar(float Buf) { } void test_vector4(float4 Buf) { - // CHECK: define void @{{.*}}test_vector{{.*}}(<4 x float> {{.*}} [[VALP:%.*]]) + // CHECK: define hidden void @{{.*}}test_vector{{.*}}(<4 x float> {{.*}} [[VALP:%.*]]) // CHECK: [[LOAD:%.*]] = load <4 x float>, ptr [[VALP]].addr, align 16 // CHECK-NEXT: [[FCMP:%.*]] = fcmp reassoc nnan ninf nsz arcp afn olt <4 x float> [[LOAD]], zeroinitializer // CHECK-NEXT: [[ANYC:%.*]] = call i1 @llvm.dx.any.v4i1(<4 x i1> [[FCMP]]) // CHECK-NEXT: call void @llvm.dx.discard(i1 [[ANYC]]) // - // SPIRV: define spir_func void @{{.*}}test_vector{{.*}}(<4 x float> {{.*}} [[VALP:%.*]]) + // SPIRV: define hidden spir_func void @{{.*}}test_vector{{.*}}(<4 x float> {{.*}} [[VALP:%.*]]) // SPIRV: [[LOAD:%.*]] = load <4 x float>, ptr [[VALP]].addr, align 16 // SPIRV-NEXT: [[FCMP:%.*]] = fcmp reassoc nnan ninf nsz arcp afn olt <4 x float> [[LOAD]], zeroinitializer // SPIRV-NEXT: [[ANYC:%.*]] = call i1 @llvm.spv.any.v4i1(<4 x i1> [[FCMP]]) diff --git a/external/llvm-project/clang/test/CodeGenHLSL/builtins/cos-overloads.hlsl b/external/llvm-project/clang/test/CodeGenHLSL/builtins/cos-overloads.hlsl index b7b11b1c3bd6..70926cc8ba74 100644 --- a/external/llvm-project/clang/test/CodeGenHLSL/builtins/cos-overloads.hlsl +++ b/external/llvm-project/clang/test/CodeGenHLSL/builtins/cos-overloads.hlsl @@ -2,67 +2,67 @@ // RUN: -emit-llvm -disable-llvm-passes -o - | \ // RUN: FileCheck %s --check-prefixes=CHECK -// CHECK-LABEL: define noundef nofpclass(nan inf) float {{.*}}test_cos_double +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) float {{.*}}test_cos_double // CHECK: call reassoc nnan ninf nsz arcp afn float @llvm.cos.f32( float test_cos_double(double p0) { return cos(p0); } -// CHECK-LABEL: define noundef nofpclass(nan inf) <2 x float> {{.*}}test_cos_double2 +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) <2 x float> {{.*}}test_cos_double2 // CHECK: call reassoc nnan ninf nsz arcp afn <2 x float> @llvm.cos.v2f32 float2 test_cos_double2(double2 p0) { return cos(p0); } -// CHECK-LABEL: define noundef nofpclass(nan inf) <3 x float> {{.*}}test_cos_double3 +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) <3 x float> {{.*}}test_cos_double3 // CHECK: call reassoc nnan ninf nsz arcp afn <3 x float> @llvm.cos.v3f32 float3 test_cos_double3(double3 p0) { return cos(p0); } -// CHECK-LABEL: define noundef nofpclass(nan inf) <4 x float> {{.*}}test_cos_double4 +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) <4 x float> {{.*}}test_cos_double4 // CHECK: call reassoc nnan ninf nsz arcp afn <4 x float> @llvm.cos.v4f32 float4 test_cos_double4(double4 p0) { return cos(p0); } -// CHECK-LABEL: define noundef nofpclass(nan inf) float {{.*}}test_cos_int +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) float {{.*}}test_cos_int // CHECK: call reassoc nnan ninf nsz arcp afn float @llvm.cos.f32( float test_cos_int(int p0) { return cos(p0); } -// CHECK-LABEL: define noundef nofpclass(nan inf) <2 x float> {{.*}}test_cos_int2 +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) <2 x float> {{.*}}test_cos_int2 // CHECK: call reassoc nnan ninf nsz arcp afn <2 x float> @llvm.cos.v2f32 float2 test_cos_int2(int2 p0) { return cos(p0); } -// CHECK-LABEL: define noundef nofpclass(nan inf) <3 x float> {{.*}}test_cos_int3 +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) <3 x float> {{.*}}test_cos_int3 // CHECK: call reassoc nnan ninf nsz arcp afn <3 x float> @llvm.cos.v3f32 float3 test_cos_int3(int3 p0) { return cos(p0); } -// CHECK-LABEL: define noundef nofpclass(nan inf) <4 x float> {{.*}}test_cos_int4 +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) <4 x float> {{.*}}test_cos_int4 // CHECK: call reassoc nnan ninf nsz arcp afn <4 x float> @llvm.cos.v4f32 float4 test_cos_int4(int4 p0) { return cos(p0); } -// CHECK-LABEL: define noundef nofpclass(nan inf) float {{.*}}test_cos_uint +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) float {{.*}}test_cos_uint // CHECK: call reassoc nnan ninf nsz arcp afn float @llvm.cos.f32( float test_cos_uint(uint p0) { return cos(p0); } -// CHECK-LABEL: define noundef nofpclass(nan inf) <2 x float> {{.*}}test_cos_uint2 +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) <2 x float> {{.*}}test_cos_uint2 // CHECK: call reassoc nnan ninf nsz arcp afn <2 x float> @llvm.cos.v2f32 float2 test_cos_uint2(uint2 p0) { return cos(p0); } -// CHECK-LABEL: define noundef nofpclass(nan inf) <3 x float> {{.*}}test_cos_uint3 +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) <3 x float> {{.*}}test_cos_uint3 // CHECK: call reassoc nnan ninf nsz arcp afn <3 x float> @llvm.cos.v3f32 float3 test_cos_uint3(uint3 p0) { return cos(p0); } -// CHECK-LABEL: define noundef nofpclass(nan inf) <4 x float> {{.*}}test_cos_uint4 +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) <4 x float> {{.*}}test_cos_uint4 // CHECK: call reassoc nnan ninf nsz arcp afn <4 x float> @llvm.cos.v4f32 float4 test_cos_uint4(uint4 p0) { return cos(p0); } -// CHECK-LABEL: define noundef nofpclass(nan inf) float {{.*}}test_cos_int64_t +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) float {{.*}}test_cos_int64_t // CHECK: call reassoc nnan ninf nsz arcp afn float @llvm.cos.f32( float test_cos_int64_t(int64_t p0) { return cos(p0); } -// CHECK-LABEL: define noundef nofpclass(nan inf) <2 x float> {{.*}}test_cos_int64_t2 +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) <2 x float> {{.*}}test_cos_int64_t2 // CHECK: call reassoc nnan ninf nsz arcp afn <2 x float> @llvm.cos.v2f32 float2 test_cos_int64_t2(int64_t2 p0) { return cos(p0); } -// CHECK-LABEL: define noundef nofpclass(nan inf) <3 x float> {{.*}}test_cos_int64_t3 +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) <3 x float> {{.*}}test_cos_int64_t3 // CHECK: call reassoc nnan ninf nsz arcp afn <3 x float> @llvm.cos.v3f32 float3 test_cos_int64_t3(int64_t3 p0) { return cos(p0); } -// CHECK-LABEL: define noundef nofpclass(nan inf) <4 x float> {{.*}}test_cos_int64_t4 +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) <4 x float> {{.*}}test_cos_int64_t4 // CHECK: call reassoc nnan ninf nsz arcp afn <4 x float> @llvm.cos.v4f32 float4 test_cos_int64_t4(int64_t4 p0) { return cos(p0); } -// CHECK-LABEL: define noundef nofpclass(nan inf) float {{.*}}test_cos_uint64_t +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) float {{.*}}test_cos_uint64_t // CHECK: call reassoc nnan ninf nsz arcp afn float @llvm.cos.f32( float test_cos_uint64_t(uint64_t p0) { return cos(p0); } -// CHECK-LABEL: define noundef nofpclass(nan inf) <2 x float> {{.*}}test_cos_uint64_t2 +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) <2 x float> {{.*}}test_cos_uint64_t2 // CHECK: call reassoc nnan ninf nsz arcp afn <2 x float> @llvm.cos.v2f32 float2 test_cos_uint64_t2(uint64_t2 p0) { return cos(p0); } -// CHECK-LABEL: define noundef nofpclass(nan inf) <3 x float> {{.*}}test_cos_uint64_t3 +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) <3 x float> {{.*}}test_cos_uint64_t3 // CHECK: call reassoc nnan ninf nsz arcp afn <3 x float> @llvm.cos.v3f32 float3 test_cos_uint64_t3(uint64_t3 p0) { return cos(p0); } -// CHECK-LABEL: define noundef nofpclass(nan inf) <4 x float> {{.*}}test_cos_uint64_t4 +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) <4 x float> {{.*}}test_cos_uint64_t4 // CHECK: call reassoc nnan ninf nsz arcp afn <4 x float> @llvm.cos.v4f32 float4 test_cos_uint64_t4(uint64_t4 p0) { return cos(p0); } diff --git a/external/llvm-project/clang/test/CodeGenHLSL/builtins/cos.hlsl b/external/llvm-project/clang/test/CodeGenHLSL/builtins/cos.hlsl index 5f993d50498b..79f9e1e6fbec 100644 --- a/external/llvm-project/clang/test/CodeGenHLSL/builtins/cos.hlsl +++ b/external/llvm-project/clang/test/CodeGenHLSL/builtins/cos.hlsl @@ -5,36 +5,36 @@ // RUN: -emit-llvm -disable-llvm-passes -o - | \ // RUN: FileCheck %s --check-prefixes=CHECK,NO_HALF -// NATIVE_HALF-LABEL: define noundef nofpclass(nan inf) half @_Z13test_cos_half +// NATIVE_HALF-LABEL: define hidden noundef nofpclass(nan inf) half @_Z13test_cos_half // NATIVE_HALF: call reassoc nnan ninf nsz arcp afn half @llvm.cos.f16( -// NO_HALF-LABEL: define noundef nofpclass(nan inf) float @_Z13test_cos_half +// NO_HALF-LABEL: define hidden noundef nofpclass(nan inf) float @_Z13test_cos_half // NO_HALF: call reassoc nnan ninf nsz arcp afn float @llvm.cos.f32( half test_cos_half(half p0) { return cos(p0); } -// NATIVE_HALF-LABEL: define noundef nofpclass(nan inf) <2 x half> @_Z14test_cos_half2 +// NATIVE_HALF-LABEL: define hidden noundef nofpclass(nan inf) <2 x half> @_Z14test_cos_half2 // NATIVE_HALF: call reassoc nnan ninf nsz arcp afn <2 x half> @llvm.cos.v2f16 -// NO_HALF-LABEL: define noundef nofpclass(nan inf) <2 x float> @_Z14test_cos_half2 +// NO_HALF-LABEL: define hidden noundef nofpclass(nan inf) <2 x float> @_Z14test_cos_half2 // NO_HALF: call reassoc nnan ninf nsz arcp afn <2 x float> @llvm.cos.v2f32( half2 test_cos_half2(half2 p0) { return cos(p0); } -// NATIVE_HALF-LABEL: define noundef nofpclass(nan inf) <3 x half> @_Z14test_cos_half3 +// NATIVE_HALF-LABEL: define hidden noundef nofpclass(nan inf) <3 x half> @_Z14test_cos_half3 // NATIVE_HALF: call reassoc nnan ninf nsz arcp afn <3 x half> @llvm.cos.v3f16 -// NO_HALF-LABEL: define noundef nofpclass(nan inf) <3 x float> @_Z14test_cos_half3 +// NO_HALF-LABEL: define hidden noundef nofpclass(nan inf) <3 x float> @_Z14test_cos_half3 // NO_HALF: call reassoc nnan ninf nsz arcp afn <3 x float> @llvm.cos.v3f32( half3 test_cos_half3(half3 p0) { return cos(p0); } -// NATIVE_HALF-LABEL: define noundef nofpclass(nan inf) <4 x half> @_Z14test_cos_half4 +// NATIVE_HALF-LABEL: define hidden noundef nofpclass(nan inf) <4 x half> @_Z14test_cos_half4 // NATIVE_HALF: call reassoc nnan ninf nsz arcp afn <4 x half> @llvm.cos.v4f16 -// NO_HALF-LABEL: define noundef nofpclass(nan inf) <4 x float> @_Z14test_cos_half4 +// NO_HALF-LABEL: define hidden noundef nofpclass(nan inf) <4 x float> @_Z14test_cos_half4 // NO_HALF: call reassoc nnan ninf nsz arcp afn <4 x float> @llvm.cos.v4f32( half4 test_cos_half4(half4 p0) { return cos(p0); } -// CHECK-LABEL: define noundef nofpclass(nan inf) float @_Z14test_cos_float +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) float @_Z14test_cos_float // CHECK: call reassoc nnan ninf nsz arcp afn float @llvm.cos.f32( float test_cos_float(float p0) { return cos(p0); } -// CHECK-LABEL: define noundef nofpclass(nan inf) <2 x float> @_Z15test_cos_float2 +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) <2 x float> @_Z15test_cos_float2 // CHECK: call reassoc nnan ninf nsz arcp afn <2 x float> @llvm.cos.v2f32 float2 test_cos_float2(float2 p0) { return cos(p0); } -// CHECK-LABEL: define noundef nofpclass(nan inf) <3 x float> @_Z15test_cos_float3 +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) <3 x float> @_Z15test_cos_float3 // CHECK: call reassoc nnan ninf nsz arcp afn <3 x float> @llvm.cos.v3f32 float3 test_cos_float3(float3 p0) { return cos(p0); } -// CHECK-LABEL: define noundef nofpclass(nan inf) <4 x float> @_Z15test_cos_float4 +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) <4 x float> @_Z15test_cos_float4 // CHECK: call reassoc nnan ninf nsz arcp afn <4 x float> @llvm.cos.v4f32 float4 test_cos_float4(float4 p0) { return cos(p0); } diff --git a/external/llvm-project/clang/test/CodeGenHLSL/builtins/cross.hlsl b/external/llvm-project/clang/test/CodeGenHLSL/builtins/cross.hlsl index b2a1d6316787..89ac383e2517 100644 --- a/external/llvm-project/clang/test/CodeGenHLSL/builtins/cross.hlsl +++ b/external/llvm-project/clang/test/CodeGenHLSL/builtins/cross.hlsl @@ -2,20 +2,20 @@ // RUN: dxil-pc-shadermodel6.3-library %s -fnative-half-type \ // RUN: -emit-llvm -disable-llvm-passes -o - | FileCheck %s \ // RUN: --check-prefixes=CHECK,NATIVE_HALF \ -// RUN: -DFNATTRS="noundef nofpclass(nan inf)" -DTARGET=dx +// RUN: -DFNATTRS="hidden noundef nofpclass(nan inf)" -DTARGET=dx // RUN: %clang_cc1 -finclude-default-header -x hlsl -triple \ // RUN: dxil-pc-shadermodel6.3-library %s -emit-llvm -disable-llvm-passes \ // RUN: -o - | FileCheck %s --check-prefixes=CHECK,NO_HALF \ -// RUN: -DFNATTRS="noundef nofpclass(nan inf)" -DTARGET=dx +// RUN: -DFNATTRS="hidden noundef nofpclass(nan inf)" -DTARGET=dx // RUN: %clang_cc1 -finclude-default-header -x hlsl -triple \ // RUN: spirv-unknown-vulkan-compute %s -fnative-half-type \ // RUN: -emit-llvm -disable-llvm-passes -o - | FileCheck %s \ // RUN: --check-prefixes=CHECK,NATIVE_HALF \ -// RUN: -DFNATTRS="spir_func noundef nofpclass(nan inf)" -DTARGET=spv +// RUN: -DFNATTRS="hidden spir_func noundef nofpclass(nan inf)" -DTARGET=spv // RUN: %clang_cc1 -finclude-default-header -x hlsl -triple \ // RUN: spirv-unknown-vulkan-compute %s -emit-llvm -disable-llvm-passes \ // RUN: -o - | FileCheck %s --check-prefixes=CHECK,NO_HALF \ -// RUN: -DFNATTRS="spir_func noundef nofpclass(nan inf)" -DTARGET=spv +// RUN: -DFNATTRS="hidden spir_func noundef nofpclass(nan inf)" -DTARGET=spv // NATIVE_HALF: define [[FNATTRS]] <3 x half> @ // NATIVE_HALF: call reassoc nnan ninf nsz arcp afn <3 x half> @llvm.[[TARGET]].cross.v3f16(<3 x half> diff --git a/external/llvm-project/clang/test/CodeGenHLSL/builtins/degrees-overloads.hlsl b/external/llvm-project/clang/test/CodeGenHLSL/builtins/degrees-overloads.hlsl index bafd2368c996..a1abf435ea10 100644 --- a/external/llvm-project/clang/test/CodeGenHLSL/builtins/degrees-overloads.hlsl +++ b/external/llvm-project/clang/test/CodeGenHLSL/builtins/degrees-overloads.hlsl @@ -1,11 +1,11 @@ // RUN: %clang_cc1 -std=hlsl202x -finclude-default-header -triple \ // RUN: dxil-pc-shadermodel6.3-library %s -emit-llvm -disable-llvm-passes \ // RUN: -o - | FileCheck %s --check-prefixes=CHECK \ -// RUN: -DFNATTRS="noundef nofpclass(nan inf)" -DTARGET=dx +// RUN: -DFNATTRS="hidden noundef nofpclass(nan inf)" -DTARGET=dx // RUN: %clang_cc1 -std=hlsl202x -finclude-default-header -triple \ // RUN: spirv-unknown-vulkan-compute %s -emit-llvm -disable-llvm-passes \ // RUN: -o - | FileCheck %s --check-prefixes=CHECK \ -// RUN: -DFNATTRS="spir_func noundef nofpclass(nan inf)" -DTARGET=spv +// RUN: -DFNATTRS="hidden spir_func noundef nofpclass(nan inf)" -DTARGET=spv // CHECK: define [[FNATTRS]] float @ // CHECK: %hlsl.degrees = call reassoc nnan ninf nsz arcp afn float @llvm.[[TARGET]].degrees.f32( diff --git a/external/llvm-project/clang/test/CodeGenHLSL/builtins/degrees.hlsl b/external/llvm-project/clang/test/CodeGenHLSL/builtins/degrees.hlsl index 64531dd2785e..f0fb12855e5f 100644 --- a/external/llvm-project/clang/test/CodeGenHLSL/builtins/degrees.hlsl +++ b/external/llvm-project/clang/test/CodeGenHLSL/builtins/degrees.hlsl @@ -2,20 +2,20 @@ // RUN: dxil-pc-shadermodel6.3-library %s -fnative-half-type \ // RUN: -emit-llvm -disable-llvm-passes -o - | FileCheck %s \ // RUN: --check-prefixes=CHECK,NATIVE_HALF \ -// RUN: -DFNATTRS="noundef nofpclass(nan inf)" -DTARGET=dx +// RUN: -DFNATTRS="hidden noundef nofpclass(nan inf)" -DTARGET=dx // RUN: %clang_cc1 -finclude-default-header -triple \ // RUN: dxil-pc-shadermodel6.3-library %s -emit-llvm -disable-llvm-passes \ // RUN: -o - | FileCheck %s --check-prefixes=CHECK,NO_HALF \ -// RUN: -DFNATTRS="noundef nofpclass(nan inf)" -DTARGET=dx +// RUN: -DFNATTRS="hidden noundef nofpclass(nan inf)" -DTARGET=dx // RUN: %clang_cc1 -finclude-default-header -triple \ // RUN: spirv-unknown-vulkan-compute %s -fnative-half-type \ // RUN: -emit-llvm -disable-llvm-passes -o - | FileCheck %s \ // RUN: --check-prefixes=CHECK,NATIVE_HALF \ -// RUN: -DFNATTRS="spir_func noundef nofpclass(nan inf)" -DTARGET=spv +// RUN: -DFNATTRS="hidden spir_func noundef nofpclass(nan inf)" -DTARGET=spv // RUN: %clang_cc1 -finclude-default-header -triple \ // RUN: spirv-unknown-vulkan-compute %s -emit-llvm -disable-llvm-passes \ // RUN: -o - | FileCheck %s --check-prefixes=CHECK,NO_HALF \ -// RUN: -DFNATTRS="spir_func noundef nofpclass(nan inf)" -DTARGET=spv +// RUN: -DFNATTRS="hidden spir_func noundef nofpclass(nan inf)" -DTARGET=spv // NATIVE_HALF: define [[FNATTRS]] half @ // NATIVE_HALF: %hlsl.degrees = call reassoc nnan ninf nsz arcp afn half @llvm.[[TARGET]].degrees.f16( diff --git a/external/llvm-project/clang/test/CodeGenHLSL/builtins/distance.hlsl b/external/llvm-project/clang/test/CodeGenHLSL/builtins/distance.hlsl index ac38cf185379..0c24fbb9f185 100644 --- a/external/llvm-project/clang/test/CodeGenHLSL/builtins/distance.hlsl +++ b/external/llvm-project/clang/test/CodeGenHLSL/builtins/distance.hlsl @@ -6,14 +6,14 @@ // RUN: spirv-unknown-vulkan-compute %s -fnative-half-type \ // RUN: -emit-llvm -O1 -o - | FileCheck %s --check-prefix=SPVCHECK -// CHECK-LABEL: define noundef nofpclass(nan inf) half @_Z18test_distance_halfDhDh( +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) half @_Z18test_distance_halfDhDh( // CHECK-SAME: half noundef nofpclass(nan inf) [[X:%.*]], half noundef nofpclass(nan inf) [[Y:%.*]]) local_unnamed_addr #[[ATTR0:[0-9]+]] { // CHECK-NEXT: [[ENTRY:.*:]] // CHECK-NEXT: [[SUB_I:%.*]] = fsub reassoc nnan ninf nsz arcp afn half [[X]], [[Y]] // CHECK-NEXT: [[ELT_ABS_I:%.*]] = tail call reassoc nnan ninf nsz arcp afn noundef half @llvm.fabs.f16(half nofpclass(nan inf) [[SUB_I]]) // CHECK-NEXT: ret half [[ELT_ABS_I]] // -// SPVCHECK-LABEL: define spir_func noundef nofpclass(nan inf) half @_Z18test_distance_halfDhDh( +// SPVCHECK-LABEL: define hidden spir_func noundef nofpclass(nan inf) half @_Z18test_distance_halfDhDh( // SPVCHECK-SAME: half noundef nofpclass(nan inf) [[X:%.*]], half noundef nofpclass(nan inf) [[Y:%.*]]) local_unnamed_addr #[[ATTR0:[0-9]+]] { // SPVCHECK-NEXT: [[ENTRY:.*:]] // SPVCHECK-NEXT: [[SUB_I:%.*]] = fsub reassoc nnan ninf nsz arcp afn half [[X]], [[Y]] @@ -22,7 +22,7 @@ // half test_distance_half(half X, half Y) { return distance(X, Y); } -// CHECK-LABEL: define noundef nofpclass(nan inf) half @_Z19test_distance_half2Dv2_DhS_( +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) half @_Z19test_distance_half2Dv2_DhS_( // CHECK-SAME: <2 x half> noundef nofpclass(nan inf) [[X:%.*]], <2 x half> noundef nofpclass(nan inf) [[Y:%.*]]) local_unnamed_addr #[[ATTR0]] { // CHECK-NEXT: [[ENTRY:.*:]] // CHECK-NEXT: [[SUB_I:%.*]] = fsub reassoc nnan ninf nsz arcp afn <2 x half> [[X]], [[Y]] @@ -30,7 +30,7 @@ half test_distance_half(half X, half Y) { return distance(X, Y); } // CHECK-NEXT: [[TMP0:%.*]] = tail call reassoc nnan ninf nsz arcp afn noundef half @llvm.sqrt.f16(half [[HLSL_DOT_I]]) // CHECK-NEXT: ret half [[TMP0]] // -// SPVCHECK-LABEL: define spir_func noundef nofpclass(nan inf) half @_Z19test_distance_half2Dv2_DhS_( +// SPVCHECK-LABEL: define hidden spir_func noundef nofpclass(nan inf) half @_Z19test_distance_half2Dv2_DhS_( // SPVCHECK-SAME: <2 x half> noundef nofpclass(nan inf) [[X:%.*]], <2 x half> noundef nofpclass(nan inf) [[Y:%.*]]) local_unnamed_addr #[[ATTR0]] { // SPVCHECK-NEXT: [[ENTRY:.*:]] // SPVCHECK-NEXT: [[SUB_I:%.*]] = fsub reassoc nnan ninf nsz arcp afn <2 x half> [[X]], [[Y]] @@ -39,7 +39,7 @@ half test_distance_half(half X, half Y) { return distance(X, Y); } // half test_distance_half2(half2 X, half2 Y) { return distance(X, Y); } -// CHECK-LABEL: define noundef nofpclass(nan inf) half @_Z19test_distance_half3Dv3_DhS_( +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) half @_Z19test_distance_half3Dv3_DhS_( // CHECK-SAME: <3 x half> noundef nofpclass(nan inf) [[X:%.*]], <3 x half> noundef nofpclass(nan inf) [[Y:%.*]]) local_unnamed_addr #[[ATTR0]] { // CHECK-NEXT: [[ENTRY:.*:]] // CHECK-NEXT: [[SUB_I:%.*]] = fsub reassoc nnan ninf nsz arcp afn <3 x half> [[X]], [[Y]] @@ -47,7 +47,7 @@ half test_distance_half2(half2 X, half2 Y) { return distance(X, Y); } // CHECK-NEXT: [[TMP0:%.*]] = tail call reassoc nnan ninf nsz arcp afn noundef half @llvm.sqrt.f16(half [[HLSL_DOT_I]]) // CHECK-NEXT: ret half [[TMP0]] // -// SPVCHECK-LABEL: define spir_func noundef nofpclass(nan inf) half @_Z19test_distance_half3Dv3_DhS_( +// SPVCHECK-LABEL: define hidden spir_func noundef nofpclass(nan inf) half @_Z19test_distance_half3Dv3_DhS_( // SPVCHECK-SAME: <3 x half> noundef nofpclass(nan inf) [[X:%.*]], <3 x half> noundef nofpclass(nan inf) [[Y:%.*]]) local_unnamed_addr #[[ATTR0]] { // SPVCHECK-NEXT: [[ENTRY:.*:]] // SPVCHECK-NEXT: [[SUB_I:%.*]] = fsub reassoc nnan ninf nsz arcp afn <3 x half> [[X]], [[Y]] @@ -56,7 +56,7 @@ half test_distance_half2(half2 X, half2 Y) { return distance(X, Y); } // half test_distance_half3(half3 X, half3 Y) { return distance(X, Y); } -// CHECK-LABEL: define noundef nofpclass(nan inf) half @_Z19test_distance_half4Dv4_DhS_( +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) half @_Z19test_distance_half4Dv4_DhS_( // CHECK-SAME: <4 x half> noundef nofpclass(nan inf) [[X:%.*]], <4 x half> noundef nofpclass(nan inf) [[Y:%.*]]) local_unnamed_addr #[[ATTR0]] { // CHECK-NEXT: [[ENTRY:.*:]] // CHECK-NEXT: [[SUB_I:%.*]] = fsub reassoc nnan ninf nsz arcp afn <4 x half> [[X]], [[Y]] @@ -64,7 +64,7 @@ half test_distance_half3(half3 X, half3 Y) { return distance(X, Y); } // CHECK-NEXT: [[TMP0:%.*]] = tail call reassoc nnan ninf nsz arcp afn noundef half @llvm.sqrt.f16(half [[HLSL_DOT_I]]) // CHECK-NEXT: ret half [[TMP0]] // -// SPVCHECK-LABEL: define spir_func noundef nofpclass(nan inf) half @_Z19test_distance_half4Dv4_DhS_( +// SPVCHECK-LABEL: define hidden spir_func noundef nofpclass(nan inf) half @_Z19test_distance_half4Dv4_DhS_( // SPVCHECK-SAME: <4 x half> noundef nofpclass(nan inf) [[X:%.*]], <4 x half> noundef nofpclass(nan inf) [[Y:%.*]]) local_unnamed_addr #[[ATTR0]] { // SPVCHECK-NEXT: [[ENTRY:.*:]] // SPVCHECK-NEXT: [[SUB_I:%.*]] = fsub reassoc nnan ninf nsz arcp afn <4 x half> [[X]], [[Y]] @@ -73,14 +73,14 @@ half test_distance_half3(half3 X, half3 Y) { return distance(X, Y); } // half test_distance_half4(half4 X, half4 Y) { return distance(X, Y); } -// CHECK-LABEL: define noundef nofpclass(nan inf) float @_Z19test_distance_floatff( +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) float @_Z19test_distance_floatff( // CHECK-SAME: float noundef nofpclass(nan inf) [[X:%.*]], float noundef nofpclass(nan inf) [[Y:%.*]]) local_unnamed_addr #[[ATTR0]] { // CHECK-NEXT: [[ENTRY:.*:]] // CHECK-NEXT: [[SUB_I:%.*]] = fsub reassoc nnan ninf nsz arcp afn float [[X]], [[Y]] // CHECK-NEXT: [[ELT_ABS_I:%.*]] = tail call reassoc nnan ninf nsz arcp afn noundef float @llvm.fabs.f32(float nofpclass(nan inf) [[SUB_I]]) // CHECK-NEXT: ret float [[ELT_ABS_I]] // -// SPVCHECK-LABEL: define spir_func noundef nofpclass(nan inf) float @_Z19test_distance_floatff( +// SPVCHECK-LABEL: define hidden spir_func noundef nofpclass(nan inf) float @_Z19test_distance_floatff( // SPVCHECK-SAME: float noundef nofpclass(nan inf) [[X:%.*]], float noundef nofpclass(nan inf) [[Y:%.*]]) local_unnamed_addr #[[ATTR0]] { // SPVCHECK-NEXT: [[ENTRY:.*:]] // SPVCHECK-NEXT: [[SUB_I:%.*]] = fsub reassoc nnan ninf nsz arcp afn float [[X]], [[Y]] @@ -89,7 +89,7 @@ half test_distance_half4(half4 X, half4 Y) { return distance(X, Y); } // float test_distance_float(float X, float Y) { return distance(X, Y); } -// CHECK-LABEL: define noundef nofpclass(nan inf) float @_Z20test_distance_float2Dv2_fS_( +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) float @_Z20test_distance_float2Dv2_fS_( // CHECK-SAME: <2 x float> noundef nofpclass(nan inf) [[X:%.*]], <2 x float> noundef nofpclass(nan inf) [[Y:%.*]]) local_unnamed_addr #[[ATTR0]] { // CHECK-NEXT: [[ENTRY:.*:]] // CHECK-NEXT: [[SUB_I:%.*]] = fsub reassoc nnan ninf nsz arcp afn <2 x float> [[X]], [[Y]] @@ -97,7 +97,7 @@ float test_distance_float(float X, float Y) { return distance(X, Y); } // CHECK-NEXT: [[TMP0:%.*]] = tail call reassoc nnan ninf nsz arcp afn noundef float @llvm.sqrt.f32(float [[HLSL_DOT_I]]) // CHECK-NEXT: ret float [[TMP0]] // -// SPVCHECK-LABEL: define spir_func noundef nofpclass(nan inf) float @_Z20test_distance_float2Dv2_fS_( +// SPVCHECK-LABEL: define hidden spir_func noundef nofpclass(nan inf) float @_Z20test_distance_float2Dv2_fS_( // SPVCHECK-SAME: <2 x float> noundef nofpclass(nan inf) [[X:%.*]], <2 x float> noundef nofpclass(nan inf) [[Y:%.*]]) local_unnamed_addr #[[ATTR0]] { // SPVCHECK-NEXT: [[ENTRY:.*:]] // SPVCHECK-NEXT: [[SUB_I:%.*]] = fsub reassoc nnan ninf nsz arcp afn <2 x float> [[X]], [[Y]] @@ -106,7 +106,7 @@ float test_distance_float(float X, float Y) { return distance(X, Y); } // float test_distance_float2(float2 X, float2 Y) { return distance(X, Y); } -// CHECK-LABEL: define noundef nofpclass(nan inf) float @_Z20test_distance_float3Dv3_fS_( +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) float @_Z20test_distance_float3Dv3_fS_( // CHECK-SAME: <3 x float> noundef nofpclass(nan inf) [[X:%.*]], <3 x float> noundef nofpclass(nan inf) [[Y:%.*]]) local_unnamed_addr #[[ATTR0]] { // CHECK-NEXT: [[ENTRY:.*:]] // CHECK-NEXT: [[SUB_I:%.*]] = fsub reassoc nnan ninf nsz arcp afn <3 x float> [[X]], [[Y]] @@ -114,7 +114,7 @@ float test_distance_float2(float2 X, float2 Y) { return distance(X, Y); } // CHECK-NEXT: [[TMP0:%.*]] = tail call reassoc nnan ninf nsz arcp afn noundef float @llvm.sqrt.f32(float [[HLSL_DOT_I]]) // CHECK-NEXT: ret float [[TMP0]] // -// SPVCHECK-LABEL: define spir_func noundef nofpclass(nan inf) float @_Z20test_distance_float3Dv3_fS_( +// SPVCHECK-LABEL: define hidden spir_func noundef nofpclass(nan inf) float @_Z20test_distance_float3Dv3_fS_( // SPVCHECK-SAME: <3 x float> noundef nofpclass(nan inf) [[X:%.*]], <3 x float> noundef nofpclass(nan inf) [[Y:%.*]]) local_unnamed_addr #[[ATTR0]] { // SPVCHECK-NEXT: [[ENTRY:.*:]] // SPVCHECK-NEXT: [[SUB_I:%.*]] = fsub reassoc nnan ninf nsz arcp afn <3 x float> [[X]], [[Y]] @@ -123,7 +123,7 @@ float test_distance_float2(float2 X, float2 Y) { return distance(X, Y); } // float test_distance_float3(float3 X, float3 Y) { return distance(X, Y); } -// CHECK-LABEL: define noundef nofpclass(nan inf) float @_Z20test_distance_float4Dv4_fS_( +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) float @_Z20test_distance_float4Dv4_fS_( // CHECK-SAME: <4 x float> noundef nofpclass(nan inf) [[X:%.*]], <4 x float> noundef nofpclass(nan inf) [[Y:%.*]]) local_unnamed_addr #[[ATTR0]] { // CHECK-NEXT: [[ENTRY:.*:]] // CHECK-NEXT: [[SUB_I:%.*]] = fsub reassoc nnan ninf nsz arcp afn <4 x float> [[X]], [[Y]] @@ -131,7 +131,7 @@ float test_distance_float3(float3 X, float3 Y) { return distance(X, Y); } // CHECK-NEXT: [[TMP0:%.*]] = tail call reassoc nnan ninf nsz arcp afn noundef float @llvm.sqrt.f32(float [[HLSL_DOT_I]]) // CHECK-NEXT: ret float [[TMP0]] // -// SPVCHECK-LABEL: define spir_func noundef nofpclass(nan inf) float @_Z20test_distance_float4Dv4_fS_( +// SPVCHECK-LABEL: define hidden spir_func noundef nofpclass(nan inf) float @_Z20test_distance_float4Dv4_fS_( // SPVCHECK-SAME: <4 x float> noundef nofpclass(nan inf) [[X:%.*]], <4 x float> noundef nofpclass(nan inf) [[Y:%.*]]) local_unnamed_addr #[[ATTR0]] { // SPVCHECK-NEXT: [[ENTRY:.*:]] // SPVCHECK-NEXT: [[SUB_I:%.*]] = fsub reassoc nnan ninf nsz arcp afn <4 x float> [[X]], [[Y]] diff --git a/external/llvm-project/clang/test/CodeGenHLSL/builtins/exp-overloads.hlsl b/external/llvm-project/clang/test/CodeGenHLSL/builtins/exp-overloads.hlsl index 858a1210169d..df34beeba7a8 100644 --- a/external/llvm-project/clang/test/CodeGenHLSL/builtins/exp-overloads.hlsl +++ b/external/llvm-project/clang/test/CodeGenHLSL/builtins/exp-overloads.hlsl @@ -2,87 +2,87 @@ // RUN: -emit-llvm -disable-llvm-passes -o - | \ // RUN: FileCheck %s --check-prefixes=CHECK -// CHECK-LABEL: define noundef nofpclass(nan inf) float {{.*}}test_exp_double +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) float {{.*}}test_exp_double // CHECK: %elt.exp = call reassoc nnan ninf nsz arcp afn float @llvm.exp.f32( // CHECK: ret float %elt.exp float test_exp_double(double p0) { return exp(p0); } -// CHECK-LABEL: define noundef nofpclass(nan inf) <2 x float> {{.*}}test_exp_double2 +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) <2 x float> {{.*}}test_exp_double2 // CHECK: %elt.exp = call reassoc nnan ninf nsz arcp afn <2 x float> @llvm.exp.v2f32 // CHECK: ret <2 x float> %elt.exp float2 test_exp_double2(double2 p0) { return exp(p0); } -// CHECK-LABEL: define noundef nofpclass(nan inf) <3 x float> {{.*}}test_exp_double3 +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) <3 x float> {{.*}}test_exp_double3 // CHECK: %elt.exp = call reassoc nnan ninf nsz arcp afn <3 x float> @llvm.exp.v3f32 // CHECK: ret <3 x float> %elt.exp float3 test_exp_double3(double3 p0) { return exp(p0); } -// CHECK-LABEL: define noundef nofpclass(nan inf) <4 x float> {{.*}}test_exp_double4 +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) <4 x float> {{.*}}test_exp_double4 // CHECK: %elt.exp = call reassoc nnan ninf nsz arcp afn <4 x float> @llvm.exp.v4f32 // CHECK: ret <4 x float> %elt.exp float4 test_exp_double4(double4 p0) { return exp(p0); } -// CHECK-LABEL: define noundef nofpclass(nan inf) float {{.*}}test_exp_int +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) float {{.*}}test_exp_int // CHECK: %elt.exp = call reassoc nnan ninf nsz arcp afn float @llvm.exp.f32( // CHECK: ret float %elt.exp float test_exp_int(int p0) { return exp(p0); } -// CHECK-LABEL: define noundef nofpclass(nan inf) <2 x float> {{.*}}test_exp_int2 +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) <2 x float> {{.*}}test_exp_int2 // CHECK: %elt.exp = call reassoc nnan ninf nsz arcp afn <2 x float> @llvm.exp.v2f32 // CHECK: ret <2 x float> %elt.exp float2 test_exp_int2(int2 p0) { return exp(p0); } -// CHECK-LABEL: define noundef nofpclass(nan inf) <3 x float> {{.*}}test_exp_int3 +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) <3 x float> {{.*}}test_exp_int3 // CHECK: %elt.exp = call reassoc nnan ninf nsz arcp afn <3 x float> @llvm.exp.v3f32 // CHECK: ret <3 x float> %elt.exp float3 test_exp_int3(int3 p0) { return exp(p0); } -// CHECK-LABEL: define noundef nofpclass(nan inf) <4 x float> {{.*}}test_exp_int4 +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) <4 x float> {{.*}}test_exp_int4 // CHECK: %elt.exp = call reassoc nnan ninf nsz arcp afn <4 x float> @llvm.exp.v4f32 // CHECK: ret <4 x float> %elt.exp float4 test_exp_int4(int4 p0) { return exp(p0); } -// CHECK-LABEL: define noundef nofpclass(nan inf) float {{.*}}test_exp_uint +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) float {{.*}}test_exp_uint // CHECK: %elt.exp = call reassoc nnan ninf nsz arcp afn float @llvm.exp.f32( // CHECK: ret float %elt.exp float test_exp_uint(uint p0) { return exp(p0); } -// CHECK-LABEL: define noundef nofpclass(nan inf) <2 x float> {{.*}}test_exp_uint2 +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) <2 x float> {{.*}}test_exp_uint2 // CHECK: %elt.exp = call reassoc nnan ninf nsz arcp afn <2 x float> @llvm.exp.v2f32 // CHECK: ret <2 x float> %elt.exp float2 test_exp_uint2(uint2 p0) { return exp(p0); } -// CHECK-LABEL: define noundef nofpclass(nan inf) <3 x float> {{.*}}test_exp_uint3 +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) <3 x float> {{.*}}test_exp_uint3 // CHECK: %elt.exp = call reassoc nnan ninf nsz arcp afn <3 x float> @llvm.exp.v3f32 // CHECK: ret <3 x float> %elt.exp float3 test_exp_uint3(uint3 p0) { return exp(p0); } -// CHECK-LABEL: define noundef nofpclass(nan inf) <4 x float> {{.*}}test_exp_uint4 +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) <4 x float> {{.*}}test_exp_uint4 // CHECK: %elt.exp = call reassoc nnan ninf nsz arcp afn <4 x float> @llvm.exp.v4f32 // CHECK: ret <4 x float> %elt.exp float4 test_exp_uint4(uint4 p0) { return exp(p0); } -// CHECK-LABEL: define noundef nofpclass(nan inf) float {{.*}}test_exp_int64_t +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) float {{.*}}test_exp_int64_t // CHECK: %elt.exp = call reassoc nnan ninf nsz arcp afn float @llvm.exp.f32( // CHECK: ret float %elt.exp float test_exp_int64_t(int64_t p0) { return exp(p0); } -// CHECK-LABEL: define noundef nofpclass(nan inf) <2 x float> {{.*}}test_exp_int64_t2 +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) <2 x float> {{.*}}test_exp_int64_t2 // CHECK: %elt.exp = call reassoc nnan ninf nsz arcp afn <2 x float> @llvm.exp.v2f32 // CHECK: ret <2 x float> %elt.exp float2 test_exp_int64_t2(int64_t2 p0) { return exp(p0); } -// CHECK-LABEL: define noundef nofpclass(nan inf) <3 x float> {{.*}}test_exp_int64_t3 +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) <3 x float> {{.*}}test_exp_int64_t3 // CHECK: %elt.exp = call reassoc nnan ninf nsz arcp afn <3 x float> @llvm.exp.v3f32 // CHECK: ret <3 x float> %elt.exp float3 test_exp_int64_t3(int64_t3 p0) { return exp(p0); } -// CHECK-LABEL: define noundef nofpclass(nan inf) <4 x float> {{.*}}test_exp_int64_t4 +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) <4 x float> {{.*}}test_exp_int64_t4 // CHECK: %elt.exp = call reassoc nnan ninf nsz arcp afn <4 x float> @llvm.exp.v4f32 // CHECK: ret <4 x float> %elt.exp float4 test_exp_int64_t4(int64_t4 p0) { return exp(p0); } -// CHECK-LABEL: define noundef nofpclass(nan inf) float {{.*}}test_exp_uint64_t +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) float {{.*}}test_exp_uint64_t // CHECK: %elt.exp = call reassoc nnan ninf nsz arcp afn float @llvm.exp.f32( // CHECK: ret float %elt.exp float test_exp_uint64_t(uint64_t p0) { return exp(p0); } -// CHECK-LABEL: define noundef nofpclass(nan inf) <2 x float> {{.*}}test_exp_uint64_t2 +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) <2 x float> {{.*}}test_exp_uint64_t2 // CHECK: %elt.exp = call reassoc nnan ninf nsz arcp afn <2 x float> @llvm.exp.v2f32 // CHECK: ret <2 x float> %elt.exp float2 test_exp_uint64_t2(uint64_t2 p0) { return exp(p0); } -// CHECK-LABEL: define noundef nofpclass(nan inf) <3 x float> {{.*}}test_exp_uint64_t3 +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) <3 x float> {{.*}}test_exp_uint64_t3 // CHECK: %elt.exp = call reassoc nnan ninf nsz arcp afn <3 x float> @llvm.exp.v3f32 // CHECK: ret <3 x float> %elt.exp float3 test_exp_uint64_t3(uint64_t3 p0) { return exp(p0); } -// CHECK-LABEL: define noundef nofpclass(nan inf) <4 x float> {{.*}}test_exp_uint64_t4 +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) <4 x float> {{.*}}test_exp_uint64_t4 // CHECK: %elt.exp = call reassoc nnan ninf nsz arcp afn <4 x float> @llvm.exp.v4f32 // CHECK: ret <4 x float> %elt.exp float4 test_exp_uint64_t4(uint64_t4 p0) { return exp(p0); } diff --git a/external/llvm-project/clang/test/CodeGenHLSL/builtins/exp.hlsl b/external/llvm-project/clang/test/CodeGenHLSL/builtins/exp.hlsl index 6ed40ed8f433..5a8f60528a84 100644 --- a/external/llvm-project/clang/test/CodeGenHLSL/builtins/exp.hlsl +++ b/external/llvm-project/clang/test/CodeGenHLSL/builtins/exp.hlsl @@ -5,48 +5,48 @@ // RUN: -emit-llvm -disable-llvm-passes -o - | \ // RUN: FileCheck %s --check-prefixes=CHECK,NO_HALF -// NATIVE_HALF-LABEL: define noundef nofpclass(nan inf) half @_Z13test_exp_half +// NATIVE_HALF-LABEL: define hidden noundef nofpclass(nan inf) half @_Z13test_exp_half // NATIVE_HALF: %elt.exp = call reassoc nnan ninf nsz arcp afn half @llvm.exp.f16( // NATIVE_HALF: ret half %elt.exp -// NO_HALF-LABEL: define noundef nofpclass(nan inf) float @_Z13test_exp_half +// NO_HALF-LABEL: define hidden noundef nofpclass(nan inf) float @_Z13test_exp_half // NO_HALF: %elt.exp = call reassoc nnan ninf nsz arcp afn float @llvm.exp.f32( // NO_HALF: ret float %elt.exp half test_exp_half(half p0) { return exp(p0); } -// NATIVE_HALF-LABEL: define noundef nofpclass(nan inf) <2 x half> @_Z14test_exp_half2 +// NATIVE_HALF-LABEL: define hidden noundef nofpclass(nan inf) <2 x half> @_Z14test_exp_half2 // NATIVE_HALF: %elt.exp = call reassoc nnan ninf nsz arcp afn <2 x half> @llvm.exp.v2f16 // NATIVE_HALF: ret <2 x half> %elt.exp -// NO_HALF-LABEL: define noundef nofpclass(nan inf) <2 x float> @_Z14test_exp_half2 +// NO_HALF-LABEL: define hidden noundef nofpclass(nan inf) <2 x float> @_Z14test_exp_half2 // NO_HALF: %elt.exp = call reassoc nnan ninf nsz arcp afn <2 x float> @llvm.exp.v2f32( // NO_HALF: ret <2 x float> %elt.exp half2 test_exp_half2(half2 p0) { return exp(p0); } -// NATIVE_HALF-LABEL: define noundef nofpclass(nan inf) <3 x half> @_Z14test_exp_half3 +// NATIVE_HALF-LABEL: define hidden noundef nofpclass(nan inf) <3 x half> @_Z14test_exp_half3 // NATIVE_HALF: %elt.exp = call reassoc nnan ninf nsz arcp afn <3 x half> @llvm.exp.v3f16 // NATIVE_HALF: ret <3 x half> %elt.exp -// NO_HALF-LABEL: define noundef nofpclass(nan inf) <3 x float> @_Z14test_exp_half3 +// NO_HALF-LABEL: define hidden noundef nofpclass(nan inf) <3 x float> @_Z14test_exp_half3 // NO_HALF: %elt.exp = call reassoc nnan ninf nsz arcp afn <3 x float> @llvm.exp.v3f32( // NO_HALF: ret <3 x float> %elt.exp half3 test_exp_half3(half3 p0) { return exp(p0); } -// NATIVE_HALF-LABEL: define noundef nofpclass(nan inf) <4 x half> @_Z14test_exp_half4 +// NATIVE_HALF-LABEL: define hidden noundef nofpclass(nan inf) <4 x half> @_Z14test_exp_half4 // NATIVE_HALF: %elt.exp = call reassoc nnan ninf nsz arcp afn <4 x half> @llvm.exp.v4f16 // NATIVE_HALF: ret <4 x half> %elt.exp -// NO_HALF-LABEL: define noundef nofpclass(nan inf) <4 x float> @_Z14test_exp_half4 +// NO_HALF-LABEL: define hidden noundef nofpclass(nan inf) <4 x float> @_Z14test_exp_half4 // NO_HALF: %elt.exp = call reassoc nnan ninf nsz arcp afn <4 x float> @llvm.exp.v4f32( // NO_HALF: ret <4 x float> %elt.exp half4 test_exp_half4(half4 p0) { return exp(p0); } -// CHECK-LABEL: define noundef nofpclass(nan inf) float @_Z14test_exp_float +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) float @_Z14test_exp_float // CHECK: %elt.exp = call reassoc nnan ninf nsz arcp afn float @llvm.exp.f32( // CHECK: ret float %elt.exp float test_exp_float(float p0) { return exp(p0); } -// CHECK-LABEL: define noundef nofpclass(nan inf) <2 x float> @_Z15test_exp_float2 +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) <2 x float> @_Z15test_exp_float2 // CHECK: %elt.exp = call reassoc nnan ninf nsz arcp afn <2 x float> @llvm.exp.v2f32 // CHECK: ret <2 x float> %elt.exp float2 test_exp_float2(float2 p0) { return exp(p0); } -// CHECK-LABEL: define noundef nofpclass(nan inf) <3 x float> @_Z15test_exp_float3 +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) <3 x float> @_Z15test_exp_float3 // CHECK: %elt.exp = call reassoc nnan ninf nsz arcp afn <3 x float> @llvm.exp.v3f32 // CHECK: ret <3 x float> %elt.exp float3 test_exp_float3(float3 p0) { return exp(p0); } -// CHECK-LABEL: define noundef nofpclass(nan inf) <4 x float> @_Z15test_exp_float4 +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) <4 x float> @_Z15test_exp_float4 // CHECK: %elt.exp = call reassoc nnan ninf nsz arcp afn <4 x float> @llvm.exp.v4f32 // CHECK: ret <4 x float> %elt.exp float4 test_exp_float4(float4 p0) { return exp(p0); } diff --git a/external/llvm-project/clang/test/CodeGenHLSL/builtins/exp2-overloads.hlsl b/external/llvm-project/clang/test/CodeGenHLSL/builtins/exp2-overloads.hlsl index ef522afc244a..20482777a18d 100644 --- a/external/llvm-project/clang/test/CodeGenHLSL/builtins/exp2-overloads.hlsl +++ b/external/llvm-project/clang/test/CodeGenHLSL/builtins/exp2-overloads.hlsl @@ -2,87 +2,87 @@ // RUN: -emit-llvm -disable-llvm-passes -o - | \ // RUN: FileCheck %s --check-prefixes=CHECK -// CHECK-LABEL: define noundef nofpclass(nan inf) float {{.*}}test_exp2_double +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) float {{.*}}test_exp2_double // CHECK: %elt.exp2 = call reassoc nnan ninf nsz arcp afn float @llvm.exp2.f32( // CHECK: ret float %elt.exp2 float test_exp2_double(double p0) { return exp2(p0); } -// CHECK-LABEL: define noundef nofpclass(nan inf) <2 x float> {{.*}}test_exp2_double2 +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) <2 x float> {{.*}}test_exp2_double2 // CHECK: %elt.exp2 = call reassoc nnan ninf nsz arcp afn <2 x float> @llvm.exp2.v2f32 // CHECK: ret <2 x float> %elt.exp2 float2 test_exp2_double2(double2 p0) { return exp2(p0); } -// CHECK-LABEL: define noundef nofpclass(nan inf) <3 x float> {{.*}}test_exp2_double3 +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) <3 x float> {{.*}}test_exp2_double3 // CHECK: %elt.exp2 = call reassoc nnan ninf nsz arcp afn <3 x float> @llvm.exp2.v3f32 // CHECK: ret <3 x float> %elt.exp2 float3 test_exp2_double3(double3 p0) { return exp2(p0); } -// CHECK-LABEL: define noundef nofpclass(nan inf) <4 x float> {{.*}}test_exp2_double4 +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) <4 x float> {{.*}}test_exp2_double4 // CHECK: %elt.exp2 = call reassoc nnan ninf nsz arcp afn <4 x float> @llvm.exp2.v4f32 // CHECK: ret <4 x float> %elt.exp2 float4 test_exp2_double4(double4 p0) { return exp2(p0); } -// CHECK-LABEL: define noundef nofpclass(nan inf) float {{.*}}test_exp2_int +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) float {{.*}}test_exp2_int // CHECK: %elt.exp2 = call reassoc nnan ninf nsz arcp afn float @llvm.exp2.f32( // CHECK: ret float %elt.exp2 float test_exp2_int(int p0) { return exp2(p0); } -// CHECK-LABEL: define noundef nofpclass(nan inf) <2 x float> {{.*}}test_exp2_int2 +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) <2 x float> {{.*}}test_exp2_int2 // CHECK: %elt.exp2 = call reassoc nnan ninf nsz arcp afn <2 x float> @llvm.exp2.v2f32 // CHECK: ret <2 x float> %elt.exp2 float2 test_exp2_int2(int2 p0) { return exp2(p0); } -// CHECK-LABEL: define noundef nofpclass(nan inf) <3 x float> {{.*}}test_exp2_int3 +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) <3 x float> {{.*}}test_exp2_int3 // CHECK: %elt.exp2 = call reassoc nnan ninf nsz arcp afn <3 x float> @llvm.exp2.v3f32 // CHECK: ret <3 x float> %elt.exp2 float3 test_exp2_int3(int3 p0) { return exp2(p0); } -// CHECK-LABEL: define noundef nofpclass(nan inf) <4 x float> {{.*}}test_exp2_int4 +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) <4 x float> {{.*}}test_exp2_int4 // CHECK: %elt.exp2 = call reassoc nnan ninf nsz arcp afn <4 x float> @llvm.exp2.v4f32 // CHECK: ret <4 x float> %elt.exp2 float4 test_exp2_int4(int4 p0) { return exp2(p0); } -// CHECK-LABEL: define noundef nofpclass(nan inf) float {{.*}}test_exp2_uint +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) float {{.*}}test_exp2_uint // CHECK: %elt.exp2 = call reassoc nnan ninf nsz arcp afn float @llvm.exp2.f32( // CHECK: ret float %elt.exp2 float test_exp2_uint(uint p0) { return exp2(p0); } -// CHECK-LABEL: define noundef nofpclass(nan inf) <2 x float> {{.*}}test_exp2_uint2 +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) <2 x float> {{.*}}test_exp2_uint2 // CHECK: %elt.exp2 = call reassoc nnan ninf nsz arcp afn <2 x float> @llvm.exp2.v2f32 // CHECK: ret <2 x float> %elt.exp2 float2 test_exp2_uint2(uint2 p0) { return exp2(p0); } -// CHECK-LABEL: define noundef nofpclass(nan inf) <3 x float> {{.*}}test_exp2_uint3 +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) <3 x float> {{.*}}test_exp2_uint3 // CHECK: %elt.exp2 = call reassoc nnan ninf nsz arcp afn <3 x float> @llvm.exp2.v3f32 // CHECK: ret <3 x float> %elt.exp2 float3 test_exp2_uint3(uint3 p0) { return exp2(p0); } -// CHECK-LABEL: define noundef nofpclass(nan inf) <4 x float> {{.*}}test_exp2_uint4 +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) <4 x float> {{.*}}test_exp2_uint4 // CHECK: %elt.exp2 = call reassoc nnan ninf nsz arcp afn <4 x float> @llvm.exp2.v4f32 // CHECK: ret <4 x float> %elt.exp2 float4 test_exp2_uint4(uint4 p0) { return exp2(p0); } -// CHECK-LABEL: define noundef nofpclass(nan inf) float {{.*}}test_exp2_int64_t +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) float {{.*}}test_exp2_int64_t // CHECK: %elt.exp2 = call reassoc nnan ninf nsz arcp afn float @llvm.exp2.f32( // CHECK: ret float %elt.exp2 float test_exp2_int64_t(int64_t p0) { return exp2(p0); } -// CHECK-LABEL: define noundef nofpclass(nan inf) <2 x float> {{.*}}test_exp2_int64_t2 +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) <2 x float> {{.*}}test_exp2_int64_t2 // CHECK: %elt.exp2 = call reassoc nnan ninf nsz arcp afn <2 x float> @llvm.exp2.v2f32 // CHECK: ret <2 x float> %elt.exp2 float2 test_exp2_int64_t2(int64_t2 p0) { return exp2(p0); } -// CHECK-LABEL: define noundef nofpclass(nan inf) <3 x float> {{.*}}test_exp2_int64_t3 +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) <3 x float> {{.*}}test_exp2_int64_t3 // CHECK: %elt.exp2 = call reassoc nnan ninf nsz arcp afn <3 x float> @llvm.exp2.v3f32 // CHECK: ret <3 x float> %elt.exp2 float3 test_exp2_int64_t3(int64_t3 p0) { return exp2(p0); } -// CHECK-LABEL: define noundef nofpclass(nan inf) <4 x float> {{.*}}test_exp2_int64_t4 +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) <4 x float> {{.*}}test_exp2_int64_t4 // CHECK: %elt.exp2 = call reassoc nnan ninf nsz arcp afn <4 x float> @llvm.exp2.v4f32 // CHECK: ret <4 x float> %elt.exp2 float4 test_exp2_int64_t4(int64_t4 p0) { return exp2(p0); } -// CHECK-LABEL: define noundef nofpclass(nan inf) float {{.*}}test_exp2_uint64_t +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) float {{.*}}test_exp2_uint64_t // CHECK: %elt.exp2 = call reassoc nnan ninf nsz arcp afn float @llvm.exp2.f32( // CHECK: ret float %elt.exp2 float test_exp2_uint64_t(uint64_t p0) { return exp2(p0); } -// CHECK-LABEL: define noundef nofpclass(nan inf) <2 x float> {{.*}}test_exp2_uint64_t2 +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) <2 x float> {{.*}}test_exp2_uint64_t2 // CHECK: %elt.exp2 = call reassoc nnan ninf nsz arcp afn <2 x float> @llvm.exp2.v2f32 // CHECK: ret <2 x float> %elt.exp2 float2 test_exp2_uint64_t2(uint64_t2 p0) { return exp2(p0); } -// CHECK-LABEL: define noundef nofpclass(nan inf) <3 x float> {{.*}}test_exp2_uint64_t3 +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) <3 x float> {{.*}}test_exp2_uint64_t3 // CHECK: %elt.exp2 = call reassoc nnan ninf nsz arcp afn <3 x float> @llvm.exp2.v3f32 // CHECK: ret <3 x float> %elt.exp2 float3 test_exp2_uint64_t3(uint64_t3 p0) { return exp2(p0); } -// CHECK-LABEL: define noundef nofpclass(nan inf) <4 x float> {{.*}}test_exp2_uint64_t4 +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) <4 x float> {{.*}}test_exp2_uint64_t4 // CHECK: %elt.exp2 = call reassoc nnan ninf nsz arcp afn <4 x float> @llvm.exp2.v4f32 // CHECK: ret <4 x float> %elt.exp2 float4 test_exp2_uint64_t4(uint64_t4 p0) { return exp2(p0); } diff --git a/external/llvm-project/clang/test/CodeGenHLSL/builtins/exp2.hlsl b/external/llvm-project/clang/test/CodeGenHLSL/builtins/exp2.hlsl index b067427e4636..a9bbcb0d9bff 100644 --- a/external/llvm-project/clang/test/CodeGenHLSL/builtins/exp2.hlsl +++ b/external/llvm-project/clang/test/CodeGenHLSL/builtins/exp2.hlsl @@ -5,48 +5,48 @@ // RUN: -emit-llvm -disable-llvm-passes -o - | \ // RUN: FileCheck %s --check-prefixes=CHECK,NO_HALF -// NATIVE_HALF-LABEL: define noundef nofpclass(nan inf) half @_Z14test_exp2_half +// NATIVE_HALF-LABEL: define hidden noundef nofpclass(nan inf) half @_Z14test_exp2_half // NATIVE_HALF: %elt.exp2 = call reassoc nnan ninf nsz arcp afn half @llvm.exp2.f16( // NATIVE_HALF: ret half %elt.exp2 -// NO_HALF-LABEL: define noundef nofpclass(nan inf) float @_Z14test_exp2_half +// NO_HALF-LABEL: define hidden noundef nofpclass(nan inf) float @_Z14test_exp2_half // NO_HALF: %elt.exp2 = call reassoc nnan ninf nsz arcp afn float @llvm.exp2.f32( // NO_HALF: ret float %elt.exp2 half test_exp2_half(half p0) { return exp2(p0); } -// NATIVE_HALF-LABEL: define noundef nofpclass(nan inf) <2 x half> @_Z15test_exp2_half2 +// NATIVE_HALF-LABEL: define hidden noundef nofpclass(nan inf) <2 x half> @_Z15test_exp2_half2 // NATIVE_HALF: %elt.exp2 = call reassoc nnan ninf nsz arcp afn <2 x half> @llvm.exp2.v2f16 // NATIVE_HALF: ret <2 x half> %elt.exp2 -// NO_HALF-LABEL: define noundef nofpclass(nan inf) <2 x float> @_Z15test_exp2_half2 +// NO_HALF-LABEL: define hidden noundef nofpclass(nan inf) <2 x float> @_Z15test_exp2_half2 // NO_HALF: %elt.exp2 = call reassoc nnan ninf nsz arcp afn <2 x float> @llvm.exp2.v2f32( // NO_HALF: ret <2 x float> %elt.exp2 half2 test_exp2_half2(half2 p0) { return exp2(p0); } -// NATIVE_HALF-LABEL: define noundef nofpclass(nan inf) <3 x half> @_Z15test_exp2_half3 +// NATIVE_HALF-LABEL: define hidden noundef nofpclass(nan inf) <3 x half> @_Z15test_exp2_half3 // NATIVE_HALF: %elt.exp2 = call reassoc nnan ninf nsz arcp afn <3 x half> @llvm.exp2.v3f16 // NATIVE_HALF: ret <3 x half> %elt.exp2 -// NO_HALF-LABEL: define noundef nofpclass(nan inf) <3 x float> @_Z15test_exp2_half3 +// NO_HALF-LABEL: define hidden noundef nofpclass(nan inf) <3 x float> @_Z15test_exp2_half3 // NO_HALF: %elt.exp2 = call reassoc nnan ninf nsz arcp afn <3 x float> @llvm.exp2.v3f32( // NO_HALF: ret <3 x float> %elt.exp2 half3 test_exp2_half3(half3 p0) { return exp2(p0); } -// NATIVE_HALF-LABEL: define noundef nofpclass(nan inf) <4 x half> @_Z15test_exp2_half4 +// NATIVE_HALF-LABEL: define hidden noundef nofpclass(nan inf) <4 x half> @_Z15test_exp2_half4 // NATIVE_HALF: %elt.exp2 = call reassoc nnan ninf nsz arcp afn <4 x half> @llvm.exp2.v4f16 // NATIVE_HALF: ret <4 x half> %elt.exp2 -// NO_HALF-LABEL: define noundef nofpclass(nan inf) <4 x float> @_Z15test_exp2_half4 +// NO_HALF-LABEL: define hidden noundef nofpclass(nan inf) <4 x float> @_Z15test_exp2_half4 // NO_HALF: %elt.exp2 = call reassoc nnan ninf nsz arcp afn <4 x float> @llvm.exp2.v4f32( // NO_HALF: ret <4 x float> %elt.exp2 half4 test_exp2_half4(half4 p0) { return exp2(p0); } -// CHECK-LABEL: define noundef nofpclass(nan inf) float @_Z15test_exp2_float +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) float @_Z15test_exp2_float // CHECK: %elt.exp2 = call reassoc nnan ninf nsz arcp afn float @llvm.exp2.f32( // CHECK: ret float %elt.exp2 float test_exp2_float(float p0) { return exp2(p0); } -// CHECK-LABEL: define noundef nofpclass(nan inf) <2 x float> @_Z16test_exp2_float2 +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) <2 x float> @_Z16test_exp2_float2 // CHECK: %elt.exp2 = call reassoc nnan ninf nsz arcp afn <2 x float> @llvm.exp2.v2f32 // CHECK: ret <2 x float> %elt.exp2 float2 test_exp2_float2(float2 p0) { return exp2(p0); } -// CHECK-LABEL: define noundef nofpclass(nan inf) <3 x float> @_Z16test_exp2_float3 +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) <3 x float> @_Z16test_exp2_float3 // CHECK: %elt.exp2 = call reassoc nnan ninf nsz arcp afn <3 x float> @llvm.exp2.v3f32 // CHECK: ret <3 x float> %elt.exp2 float3 test_exp2_float3(float3 p0) { return exp2(p0); } -// CHECK-LABEL: define noundef nofpclass(nan inf) <4 x float> @_Z16test_exp2_float4 +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) <4 x float> @_Z16test_exp2_float4 // CHECK: %elt.exp2 = call reassoc nnan ninf nsz arcp afn <4 x float> @llvm.exp2.v4f32 // CHECK: ret <4 x float> %elt.exp2 float4 test_exp2_float4(float4 p0) { return exp2(p0); } diff --git a/external/llvm-project/clang/test/CodeGenHLSL/builtins/firstbithigh.hlsl b/external/llvm-project/clang/test/CodeGenHLSL/builtins/firstbithigh.hlsl index debf6b6d3e3f..a71b1878f8b5 100644 --- a/external/llvm-project/clang/test/CodeGenHLSL/builtins/firstbithigh.hlsl +++ b/external/llvm-project/clang/test/CodeGenHLSL/builtins/firstbithigh.hlsl @@ -151,3 +151,11 @@ uint3 test_firstbithigh_long3(int64_t3 p0) { uint4 test_firstbithigh_long4(int64_t4 p0) { return firstbithigh(p0); } + +// CHECK-LABEL: test_firstbithigh_upcast +// CHECK: [[FBH:%.*]] = call <4 x i32> @llvm.[[TARGET]].firstbituhigh.v4i32(<4 x i32> %{{.*}}) +// CHECK: [[CONV:%.*]] = zext <4 x i32> [[FBH]] to <4 x i64> +// CHECK: ret <4 x i64> [[CONV]] +uint64_t4 test_firstbithigh_upcast(uint4 p0) { + return firstbithigh(p0); +} diff --git a/external/llvm-project/clang/test/CodeGenHLSL/builtins/firstbitlow.hlsl b/external/llvm-project/clang/test/CodeGenHLSL/builtins/firstbitlow.hlsl index 5d490fabc5bc..007db0c9c2ad 100644 --- a/external/llvm-project/clang/test/CodeGenHLSL/builtins/firstbitlow.hlsl +++ b/external/llvm-project/clang/test/CodeGenHLSL/builtins/firstbitlow.hlsl @@ -151,3 +151,11 @@ uint3 test_firstbitlow_long3(int64_t3 p0) { uint4 test_firstbitlow_long4(int64_t4 p0) { return firstbitlow(p0); } + +// CHECK-LABEL: test_firstbitlow_upcast +// CHECK: [[FBL:%.*]] = call <4 x i32> @llvm.[[TARGET]].firstbitlow.v4i32(<4 x i32> %{{.*}}) +// CHECK: [[CONV:%.*]] = zext <4 x i32> [[FBL]] to <4 x i64> +// CHECK: ret <4 x i64> [[CONV]] +uint64_t4 test_firstbitlow_upcast(uint4 p0) { + return firstbitlow(p0); +} diff --git a/external/llvm-project/clang/test/CodeGenHLSL/builtins/floor-overloads.hlsl b/external/llvm-project/clang/test/CodeGenHLSL/builtins/floor-overloads.hlsl index 26d83443ea48..1e413e53f333 100644 --- a/external/llvm-project/clang/test/CodeGenHLSL/builtins/floor-overloads.hlsl +++ b/external/llvm-project/clang/test/CodeGenHLSL/builtins/floor-overloads.hlsl @@ -4,67 +4,67 @@ using hlsl::floor; -// CHECK-LABEL: define noundef nofpclass(nan inf) float {{.*}}test_floor_double +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) float {{.*}}test_floor_double // CHECK: call reassoc nnan ninf nsz arcp afn float @llvm.floor.f32( float test_floor_double(double p0) { return floor(p0); } -// CHECK-LABEL: define noundef nofpclass(nan inf) <2 x float> {{.*}}test_floor_double2 +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) <2 x float> {{.*}}test_floor_double2 // CHECK: call reassoc nnan ninf nsz arcp afn <2 x float> @llvm.floor.v2f32( float2 test_floor_double2(double2 p0) { return floor(p0); } -// CHECK-LABEL: define noundef nofpclass(nan inf) <3 x float> {{.*}}test_floor_double3 +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) <3 x float> {{.*}}test_floor_double3 // CHECK: call reassoc nnan ninf nsz arcp afn <3 x float> @llvm.floor.v3f32( float3 test_floor_double3(double3 p0) { return floor(p0); } -// CHECK-LABEL: define noundef nofpclass(nan inf) <4 x float> {{.*}}test_floor_double4 +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) <4 x float> {{.*}}test_floor_double4 // CHECK: call reassoc nnan ninf nsz arcp afn <4 x float> @llvm.floor.v4f32( float4 test_floor_double4(double4 p0) { return floor(p0); } -// CHECK-LABEL: define noundef nofpclass(nan inf) float {{.*}}test_floor_int +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) float {{.*}}test_floor_int // CHECK: call reassoc nnan ninf nsz arcp afn float @llvm.floor.f32( float test_floor_int(int p0) { return floor(p0); } -// CHECK-LABEL: define noundef nofpclass(nan inf) <2 x float> {{.*}}test_floor_int2 +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) <2 x float> {{.*}}test_floor_int2 // CHECK: call reassoc nnan ninf nsz arcp afn <2 x float> @llvm.floor.v2f32( float2 test_floor_int2(int2 p0) { return floor(p0); } -// CHECK-LABEL: define noundef nofpclass(nan inf) <3 x float> {{.*}}test_floor_int3 +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) <3 x float> {{.*}}test_floor_int3 // CHECK: call reassoc nnan ninf nsz arcp afn <3 x float> @llvm.floor.v3f32( float3 test_floor_int3(int3 p0) { return floor(p0); } -// CHECK-LABEL: define noundef nofpclass(nan inf) <4 x float> {{.*}}test_floor_int4 +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) <4 x float> {{.*}}test_floor_int4 // CHECK: call reassoc nnan ninf nsz arcp afn <4 x float> @llvm.floor.v4f32( float4 test_floor_int4(int4 p0) { return floor(p0); } -// CHECK-LABEL: define noundef nofpclass(nan inf) float {{.*}}test_floor_uint +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) float {{.*}}test_floor_uint // CHECK: call reassoc nnan ninf nsz arcp afn float @llvm.floor.f32( float test_floor_uint(uint p0) { return floor(p0); } -// CHECK-LABEL: define noundef nofpclass(nan inf) <2 x float> {{.*}}test_floor_uint2 +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) <2 x float> {{.*}}test_floor_uint2 // CHECK: call reassoc nnan ninf nsz arcp afn <2 x float> @llvm.floor.v2f32( float2 test_floor_uint2(uint2 p0) { return floor(p0); } -// CHECK-LABEL: define noundef nofpclass(nan inf) <3 x float> {{.*}}test_floor_uint3 +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) <3 x float> {{.*}}test_floor_uint3 // CHECK: call reassoc nnan ninf nsz arcp afn <3 x float> @llvm.floor.v3f32( float3 test_floor_uint3(uint3 p0) { return floor(p0); } -// CHECK-LABEL: define noundef nofpclass(nan inf) <4 x float> {{.*}}test_floor_uint4 +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) <4 x float> {{.*}}test_floor_uint4 // CHECK: call reassoc nnan ninf nsz arcp afn <4 x float> @llvm.floor.v4f32( float4 test_floor_uint4(uint4 p0) { return floor(p0); } -// CHECK-LABEL: define noundef nofpclass(nan inf) float {{.*}}test_floor_int64_t +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) float {{.*}}test_floor_int64_t // CHECK: call reassoc nnan ninf nsz arcp afn float @llvm.floor.f32( float test_floor_int64_t(int64_t p0) { return floor(p0); } -// CHECK-LABEL: define noundef nofpclass(nan inf) <2 x float> {{.*}}test_floor_int64_t2 +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) <2 x float> {{.*}}test_floor_int64_t2 // CHECK: call reassoc nnan ninf nsz arcp afn <2 x float> @llvm.floor.v2f32( float2 test_floor_int64_t2(int64_t2 p0) { return floor(p0); } -// CHECK-LABEL: define noundef nofpclass(nan inf) <3 x float> {{.*}}test_floor_int64_t3 +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) <3 x float> {{.*}}test_floor_int64_t3 // CHECK: call reassoc nnan ninf nsz arcp afn <3 x float> @llvm.floor.v3f32( float3 test_floor_int64_t3(int64_t3 p0) { return floor(p0); } -// CHECK-LABEL: define noundef nofpclass(nan inf) <4 x float> {{.*}}test_floor_int64_t4 +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) <4 x float> {{.*}}test_floor_int64_t4 // CHECK: call reassoc nnan ninf nsz arcp afn <4 x float> @llvm.floor.v4f32( float4 test_floor_int64_t4(int64_t4 p0) { return floor(p0); } -// CHECK-LABEL: define noundef nofpclass(nan inf) float {{.*}}test_floor_uint64_t +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) float {{.*}}test_floor_uint64_t // CHECK: call reassoc nnan ninf nsz arcp afn float @llvm.floor.f32( float test_floor_uint64_t(uint64_t p0) { return floor(p0); } -// CHECK-LABEL: define noundef nofpclass(nan inf) <2 x float> {{.*}}test_floor_uint64_t2 +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) <2 x float> {{.*}}test_floor_uint64_t2 // CHECK: call reassoc nnan ninf nsz arcp afn <2 x float> @llvm.floor.v2f32( float2 test_floor_uint64_t2(uint64_t2 p0) { return floor(p0); } -// CHECK-LABEL: define noundef nofpclass(nan inf) <3 x float> {{.*}}test_floor_uint64_t3 +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) <3 x float> {{.*}}test_floor_uint64_t3 // CHECK: call reassoc nnan ninf nsz arcp afn <3 x float> @llvm.floor.v3f32( float3 test_floor_uint64_t3(uint64_t3 p0) { return floor(p0); } -// CHECK-LABEL: define noundef nofpclass(nan inf) <4 x float> {{.*}}test_floor_uint64_t4 +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) <4 x float> {{.*}}test_floor_uint64_t4 // CHECK: call reassoc nnan ninf nsz arcp afn <4 x float> @llvm.floor.v4f32( float4 test_floor_uint64_t4(uint64_t4 p0) { return floor(p0); } diff --git a/external/llvm-project/clang/test/CodeGenHLSL/builtins/floor.hlsl b/external/llvm-project/clang/test/CodeGenHLSL/builtins/floor.hlsl index f610baeeefd4..b3ff58317981 100644 --- a/external/llvm-project/clang/test/CodeGenHLSL/builtins/floor.hlsl +++ b/external/llvm-project/clang/test/CodeGenHLSL/builtins/floor.hlsl @@ -7,36 +7,36 @@ using hlsl::floor; -// NATIVE_HALF-LABEL: define noundef nofpclass(nan inf) half @_Z15test_floor_half +// NATIVE_HALF-LABEL: define hidden noundef nofpclass(nan inf) half @_Z15test_floor_half // NATIVE_HALF: call reassoc nnan ninf nsz arcp afn half @llvm.floor.f16( -// NO_HALF-LABEL: define noundef nofpclass(nan inf) float @_Z15test_floor_half +// NO_HALF-LABEL: define hidden noundef nofpclass(nan inf) float @_Z15test_floor_half // NO_HALF: call reassoc nnan ninf nsz arcp afn float @llvm.floor.f32(float %0) half test_floor_half(half p0) { return floor(p0); } -// NATIVE_HALF-LABEL: define noundef nofpclass(nan inf) <2 x half> @_Z16test_floor_half2 +// NATIVE_HALF-LABEL: define hidden noundef nofpclass(nan inf) <2 x half> @_Z16test_floor_half2 // NATIVE_HALF: call reassoc nnan ninf nsz arcp afn <2 x half> @llvm.floor.v2f16( -// NO_HALF-LABEL: define noundef nofpclass(nan inf) <2 x float> @_Z16test_floor_half2 +// NO_HALF-LABEL: define hidden noundef nofpclass(nan inf) <2 x float> @_Z16test_floor_half2 // NO_HALF: call reassoc nnan ninf nsz arcp afn <2 x float> @llvm.floor.v2f32( half2 test_floor_half2(half2 p0) { return floor(p0); } -// NATIVE_HALF-LABEL: define noundef nofpclass(nan inf) <3 x half> @_Z16test_floor_half3 +// NATIVE_HALF-LABEL: define hidden noundef nofpclass(nan inf) <3 x half> @_Z16test_floor_half3 // NATIVE_HALF: call reassoc nnan ninf nsz arcp afn <3 x half> @llvm.floor.v3f16( -// NO_HALF-LABEL: define noundef nofpclass(nan inf) <3 x float> @_Z16test_floor_half3 +// NO_HALF-LABEL: define hidden noundef nofpclass(nan inf) <3 x float> @_Z16test_floor_half3 // NO_HALF: call reassoc nnan ninf nsz arcp afn <3 x float> @llvm.floor.v3f32( half3 test_floor_half3(half3 p0) { return floor(p0); } -// NATIVE_HALF-LABEL: define noundef nofpclass(nan inf) <4 x half> @_Z16test_floor_half4 +// NATIVE_HALF-LABEL: define hidden noundef nofpclass(nan inf) <4 x half> @_Z16test_floor_half4 // NATIVE_HALF: call reassoc nnan ninf nsz arcp afn <4 x half> @llvm.floor.v4f16( -// NO_HALF-LABEL: define noundef nofpclass(nan inf) <4 x float> @_Z16test_floor_half4 +// NO_HALF-LABEL: define hidden noundef nofpclass(nan inf) <4 x float> @_Z16test_floor_half4 // NO_HALF: call reassoc nnan ninf nsz arcp afn <4 x float> @llvm.floor.v4f32( half4 test_floor_half4(half4 p0) { return floor(p0); } -// CHECK-LABEL: define noundef nofpclass(nan inf) float @_Z16test_floor_float +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) float @_Z16test_floor_float // CHECK: call reassoc nnan ninf nsz arcp afn float @llvm.floor.f32( float test_floor_float(float p0) { return floor(p0); } -// CHECK-LABEL: define noundef nofpclass(nan inf) <2 x float> @_Z17test_floor_float2 +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) <2 x float> @_Z17test_floor_float2 // CHECK: call reassoc nnan ninf nsz arcp afn <2 x float> @llvm.floor.v2f32( float2 test_floor_float2(float2 p0) { return floor(p0); } -// CHECK-LABEL: define noundef nofpclass(nan inf) <3 x float> @_Z17test_floor_float3 +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) <3 x float> @_Z17test_floor_float3 // CHECK: call reassoc nnan ninf nsz arcp afn <3 x float> @llvm.floor.v3f32( float3 test_floor_float3(float3 p0) { return floor(p0); } -// CHECK-LABEL: define noundef nofpclass(nan inf) <4 x float> @_Z17test_floor_float4 +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) <4 x float> @_Z17test_floor_float4 // CHECK: call reassoc nnan ninf nsz arcp afn <4 x float> @llvm.floor.v4f32( float4 test_floor_float4(float4 p0) { return floor(p0); } diff --git a/external/llvm-project/clang/test/CodeGenHLSL/builtins/fmod.hlsl b/external/llvm-project/clang/test/CodeGenHLSL/builtins/fmod.hlsl index 7ecc5854b398..cc91c0b67f6c 100644 --- a/external/llvm-project/clang/test/CodeGenHLSL/builtins/fmod.hlsl +++ b/external/llvm-project/clang/test/CodeGenHLSL/builtins/fmod.hlsl @@ -4,7 +4,7 @@ // // RUN: %clang_cc1 -finclude-default-header -x hlsl -triple \ // RUN: dxil-pc-shadermodel6.3-library %s -fnative-half-type \ -// RUN: -emit-llvm -o - | FileCheck %s -DFNATTRS="noundef nofpclass(nan inf)" \ +// RUN: -emit-llvm -o - | FileCheck %s -DFNATTRS="hidden noundef nofpclass(nan inf)" \ // RUN: -DTYPE=half -DINT_TYPE=f16 --check-prefixes=DXCHECK // @@ -12,7 +12,7 @@ // // RUN: %clang_cc1 -finclude-default-header -x hlsl -triple \ // RUN: dxil-pc-shadermodel6.3-library %s -emit-llvm \ -// RUN: -o - | FileCheck %s -DFNATTRS="noundef nofpclass(nan inf)" \ +// RUN: -o - | FileCheck %s -DFNATTRS="hidden noundef nofpclass(nan inf)" \ // RUN: -DTYPE=float -DINT_TYPE=f32 --check-prefixes=DXCHECK @@ -23,7 +23,7 @@ // RUN: %clang_cc1 -finclude-default-header -x hlsl -triple \ // RUN: spirv-unknown-vulkan-compute %s -fnative-half-type \ // RUN: -emit-llvm -o - | FileCheck %s \ -// RUN: -DFNATTRS="spir_func noundef nofpclass(nan inf)" -DTYPE=half +// RUN: -DFNATTRS="hidden spir_func noundef nofpclass(nan inf)" -DTYPE=half // // ---------- No Native Half support test ----------- @@ -31,7 +31,7 @@ // RUN: %clang_cc1 -finclude-default-header -x hlsl -triple \ // RUN: spirv-unknown-vulkan-compute %s -emit-llvm \ // RUN: -o - | FileCheck %s \ -// RUN: -DFNATTRS="spir_func noundef nofpclass(nan inf)" -DTYPE=float +// RUN: -DFNATTRS="hidden spir_func noundef nofpclass(nan inf)" -DTYPE=float diff --git a/external/llvm-project/clang/test/CodeGenHLSL/builtins/frac-overloads.hlsl b/external/llvm-project/clang/test/CodeGenHLSL/builtins/frac-overloads.hlsl index b0e844bd8a8d..7a3f7b006948 100644 --- a/external/llvm-project/clang/test/CodeGenHLSL/builtins/frac-overloads.hlsl +++ b/external/llvm-project/clang/test/CodeGenHLSL/builtins/frac-overloads.hlsl @@ -1,11 +1,11 @@ // RUN: %clang_cc1 -std=hlsl202x -finclude-default-header -x hlsl -triple \ // RUN: dxil-pc-shadermodel6.3-library %s -emit-llvm -disable-llvm-passes \ // RUN: -o - | FileCheck %s --check-prefixes=CHECK \ -// RUN: -DFNATTRS="noundef nofpclass(nan inf)" -DTARGET=dx +// RUN: -DFNATTRS="hidden noundef nofpclass(nan inf)" -DTARGET=dx // RUN: %clang_cc1 -std=hlsl202x -finclude-default-header -x hlsl -triple \ // RUN: spirv-unknown-vulkan-compute %s -emit-llvm -disable-llvm-passes \ // RUN: -o - | FileCheck %s --check-prefixes=CHECK \ -// RUN: -DFNATTRS="spir_func noundef nofpclass(nan inf)" -DTARGET=spv +// RUN: -DFNATTRS="hidden spir_func noundef nofpclass(nan inf)" -DTARGET=spv // CHECK: define [[FNATTRS]] float @ // CHECK: %hlsl.frac = call reassoc nnan ninf nsz arcp afn float @llvm.[[TARGET]].frac.f32( diff --git a/external/llvm-project/clang/test/CodeGenHLSL/builtins/frac.hlsl b/external/llvm-project/clang/test/CodeGenHLSL/builtins/frac.hlsl index 7b105ce84359..d8397407cd01 100644 --- a/external/llvm-project/clang/test/CodeGenHLSL/builtins/frac.hlsl +++ b/external/llvm-project/clang/test/CodeGenHLSL/builtins/frac.hlsl @@ -2,20 +2,20 @@ // RUN: dxil-pc-shadermodel6.3-library %s -fnative-half-type \ // RUN: -emit-llvm -disable-llvm-passes -o - | FileCheck %s \ // RUN: --check-prefixes=CHECK,NATIVE_HALF \ -// RUN: -DFNATTRS="noundef nofpclass(nan inf)" -DTARGET=dx +// RUN: -DFNATTRS="hidden noundef nofpclass(nan inf)" -DTARGET=dx // RUN: %clang_cc1 -finclude-default-header -x hlsl -triple \ // RUN: dxil-pc-shadermodel6.3-library %s -emit-llvm -disable-llvm-passes \ // RUN: -o - | FileCheck %s --check-prefixes=CHECK,NO_HALF \ -// RUN: -DFNATTRS="noundef nofpclass(nan inf)" -DTARGET=dx +// RUN: -DFNATTRS="hidden noundef nofpclass(nan inf)" -DTARGET=dx // RUN: %clang_cc1 -finclude-default-header -x hlsl -triple \ // RUN: spirv-unknown-vulkan-compute %s -fnative-half-type \ // RUN: -emit-llvm -disable-llvm-passes -o - | FileCheck %s \ // RUN: --check-prefixes=CHECK,NATIVE_HALF \ -// RUN: -DFNATTRS="spir_func noundef nofpclass(nan inf)" -DTARGET=spv +// RUN: -DFNATTRS="hidden spir_func noundef nofpclass(nan inf)" -DTARGET=spv // RUN: %clang_cc1 -finclude-default-header -x hlsl -triple \ // RUN: spirv-unknown-vulkan-compute %s -emit-llvm -disable-llvm-passes \ // RUN: -o - | FileCheck %s --check-prefixes=CHECK,NO_HALF \ -// RUN: -DFNATTRS="spir_func noundef nofpclass(nan inf)" -DTARGET=spv +// RUN: -DFNATTRS="hidden spir_func noundef nofpclass(nan inf)" -DTARGET=spv // NATIVE_HALF: define [[FNATTRS]] half @ // NATIVE_HALF: %hlsl.frac = call reassoc nnan ninf nsz arcp afn half @llvm.[[TARGET]].frac.f16( diff --git a/external/llvm-project/clang/test/CodeGenHLSL/builtins/hlsl_resource_t.hlsl b/external/llvm-project/clang/test/CodeGenHLSL/builtins/hlsl_resource_t.hlsl index 6d2ae6535ecb..24114b11c760 100644 --- a/external/llvm-project/clang/test/CodeGenHLSL/builtins/hlsl_resource_t.hlsl +++ b/external/llvm-project/clang/test/CodeGenHLSL/builtins/hlsl_resource_t.hlsl @@ -6,9 +6,9 @@ using handle_float_t = __hlsl_resource_t [[hlsl::resource_class(UAV)]] [[hlsl::c // CHECK: %"class.hlsl::StructuredBuffer" = type { target("dx.RawBuffer", %struct.MyStruct, 0, 0) // CHECK: %struct.MyStruct = type <{ <4 x float>, <2 x i32> }> -// CHECK: define void @_Z2faU9_Res_u_CTfu17__hlsl_resource_t(target("dx.TypedBuffer", float, 1, 0, 0) %a) +// CHECK: define hidden void @_Z2faU9_Res_u_CTfu17__hlsl_resource_t(target("dx.TypedBuffer", float, 1, 0, 0) %a) // CHECK: call void @_Z4foo1U9_Res_u_CTfu17__hlsl_resource_t(target("dx.TypedBuffer", float, 1, 0, 0) %0) -// CHECK: declare void @_Z4foo1U9_Res_u_CTfu17__hlsl_resource_t(target("dx.TypedBuffer", float, 1, 0, 0)) +// CHECK: declare hidden void @_Z4foo1U9_Res_u_CTfu17__hlsl_resource_t(target("dx.TypedBuffer", float, 1, 0, 0)) void foo1(handle_float_t res); @@ -16,14 +16,14 @@ void fa(handle_float_t a) { foo1(a); } -// CHECK: define void @_Z2fbU9_Res_u_CTfu17__hlsl_resource_t(target("dx.TypedBuffer", float, 1, 0, 0) %a) +// CHECK: define hidden void @_Z2fbU9_Res_u_CTfu17__hlsl_resource_t(target("dx.TypedBuffer", float, 1, 0, 0) %a) void fb(handle_float_t a) { handle_float_t b = a; } -// CHECK: define void @_Z2fcN4hlsl8RWBufferIDv4_fEE(ptr noundef byval(%"class.hlsl::RWBuffer") align 4 %a) +// CHECK: define hidden void @_Z2fcN4hlsl8RWBufferIDv4_fEE(ptr noundef byval(%"class.hlsl::RWBuffer") align 4 %a) // CHECK: call void @_Z4foo2N4hlsl8RWBufferIDv4_fEE(ptr noundef byval(%"class.hlsl::RWBuffer") align 4 %agg.tmp) -// CHECK: declare void @_Z4foo2N4hlsl8RWBufferIDv4_fEE(ptr noundef byval(%"class.hlsl::RWBuffer") align 4) +// CHECK: declare hidden void @_Z4foo2N4hlsl8RWBufferIDv4_fEE(ptr noundef byval(%"class.hlsl::RWBuffer") align 4) void foo2(RWBuffer buf); void fc(RWBuffer a) { @@ -39,9 +39,9 @@ struct MyStruct { int2 i; }; -// CHECK: define void @_Z2feN4hlsl16StructuredBufferI8MyStructEE(ptr noundef byval(%"class.hlsl::StructuredBuffer") align 4 %a) +// CHECK: define hidden void @_Z2feN4hlsl16StructuredBufferI8MyStructEE(ptr noundef byval(%"class.hlsl::StructuredBuffer") align 4 %a) // CHECK: call void @_Z4foo3N4hlsl16StructuredBufferI8MyStructEE(ptr noundef byval(%"class.hlsl::StructuredBuffer") align 4 %agg.tmp) -// CHECK: declare void @_Z4foo3N4hlsl16StructuredBufferI8MyStructEE(ptr noundef byval(%"class.hlsl::StructuredBuffer") align 4) +// CHECK: declare hidden void @_Z4foo3N4hlsl16StructuredBufferI8MyStructEE(ptr noundef byval(%"class.hlsl::StructuredBuffer") align 4) void foo3(StructuredBuffer buf); void fe(StructuredBuffer a) { diff --git a/external/llvm-project/clang/test/CodeGenHLSL/builtins/isinf-overloads.hlsl b/external/llvm-project/clang/test/CodeGenHLSL/builtins/isinf-overloads.hlsl index ace209003ce4..f39cba9ace6e 100644 --- a/external/llvm-project/clang/test/CodeGenHLSL/builtins/isinf-overloads.hlsl +++ b/external/llvm-project/clang/test/CodeGenHLSL/builtins/isinf-overloads.hlsl @@ -2,19 +2,19 @@ // RUN: dxil-pc-shadermodel6.3-library %s -emit-llvm -disable-llvm-passes \ // RUN: -o - | FileCheck %s -// CHECK: define noundef i1 @ +// CHECK: define hidden noundef i1 @ // CHECK: %dx.isinf = call i1 @llvm.dx.isinf.f32( // CHECK: ret i1 %dx.isinf bool test_isinf_double(double p0) { return isinf(p0); } -// CHECK: define noundef <2 x i1> @ +// CHECK: define hidden noundef <2 x i1> @ // CHECK: %dx.isinf = call <2 x i1> @llvm.dx.isinf.v2f32 // CHECK: ret <2 x i1> %dx.isinf bool2 test_isinf_double2(double2 p0) { return isinf(p0); } -// CHECK: define noundef <3 x i1> @ +// CHECK: define hidden noundef <3 x i1> @ // CHECK: %dx.isinf = call <3 x i1> @llvm.dx.isinf.v3f32 // CHECK: ret <3 x i1> %dx.isinf bool3 test_isinf_double3(double3 p0) { return isinf(p0); } -// CHECK: define noundef <4 x i1> @ +// CHECK: define hidden noundef <4 x i1> @ // CHECK: %dx.isinf = call <4 x i1> @llvm.dx.isinf.v4f32 // CHECK: ret <4 x i1> %dx.isinf bool4 test_isinf_double4(double4 p0) { return isinf(p0); } diff --git a/external/llvm-project/clang/test/CodeGenHLSL/builtins/isinf.hlsl b/external/llvm-project/clang/test/CodeGenHLSL/builtins/isinf.hlsl index df44fc4a91df..4d53daaafb69 100644 --- a/external/llvm-project/clang/test/CodeGenHLSL/builtins/isinf.hlsl +++ b/external/llvm-project/clang/test/CodeGenHLSL/builtins/isinf.hlsl @@ -6,40 +6,40 @@ // RUN: dxil-pc-shadermodel6.3-library %s -emit-llvm -disable-llvm-passes \ // RUN: -o - | FileCheck %s --check-prefixes=CHECK,NO_HALF -// CHECK: define noundef i1 @ +// CHECK: define hidden noundef i1 @ // NATIVE_HALF: %dx.isinf = call i1 @llvm.dx.isinf.f16( // NO_HALF: %dx.isinf = call i1 @llvm.dx.isinf.f32( // CHECK: ret i1 %dx.isinf bool test_isinf_half(half p0) { return isinf(p0); } -// CHECK: define noundef <2 x i1> @ +// CHECK: define hidden noundef <2 x i1> @ // NATIVE_HALF: %dx.isinf = call <2 x i1> @llvm.dx.isinf.v2f16 // NO_HALF: %dx.isinf = call <2 x i1> @llvm.dx.isinf.v2f32( // CHECK: ret <2 x i1> %dx.isinf bool2 test_isinf_half2(half2 p0) { return isinf(p0); } -// NATIVE_HALF: define noundef <3 x i1> @ +// NATIVE_HALF: define hidden noundef <3 x i1> @ // NATIVE_HALF: %dx.isinf = call <3 x i1> @llvm.dx.isinf.v3f16 // NO_HALF: %dx.isinf = call <3 x i1> @llvm.dx.isinf.v3f32( // CHECK: ret <3 x i1> %dx.isinf bool3 test_isinf_half3(half3 p0) { return isinf(p0); } -// NATIVE_HALF: define noundef <4 x i1> @ +// NATIVE_HALF: define hidden noundef <4 x i1> @ // NATIVE_HALF: %dx.isinf = call <4 x i1> @llvm.dx.isinf.v4f16 // NO_HALF: %dx.isinf = call <4 x i1> @llvm.dx.isinf.v4f32( // CHECK: ret <4 x i1> %dx.isinf bool4 test_isinf_half4(half4 p0) { return isinf(p0); } -// CHECK: define noundef i1 @ +// CHECK: define hidden noundef i1 @ // CHECK: %dx.isinf = call i1 @llvm.dx.isinf.f32( // CHECK: ret i1 %dx.isinf bool test_isinf_float(float p0) { return isinf(p0); } -// CHECK: define noundef <2 x i1> @ +// CHECK: define hidden noundef <2 x i1> @ // CHECK: %dx.isinf = call <2 x i1> @llvm.dx.isinf.v2f32 // CHECK: ret <2 x i1> %dx.isinf bool2 test_isinf_float2(float2 p0) { return isinf(p0); } -// CHECK: define noundef <3 x i1> @ +// CHECK: define hidden noundef <3 x i1> @ // CHECK: %dx.isinf = call <3 x i1> @llvm.dx.isinf.v3f32 // CHECK: ret <3 x i1> %dx.isinf bool3 test_isinf_float3(float3 p0) { return isinf(p0); } -// CHECK: define noundef <4 x i1> @ +// CHECK: define hidden noundef <4 x i1> @ // CHECK: %dx.isinf = call <4 x i1> @llvm.dx.isinf.v4f32 // CHECK: ret <4 x i1> %dx.isinf bool4 test_isinf_float4(float4 p0) { return isinf(p0); } diff --git a/external/llvm-project/clang/test/CodeGenHLSL/builtins/ldexp.hlsl b/external/llvm-project/clang/test/CodeGenHLSL/builtins/ldexp.hlsl index ea0d1348c6e4..f8fa06c39f2a 100644 --- a/external/llvm-project/clang/test/CodeGenHLSL/builtins/ldexp.hlsl +++ b/external/llvm-project/clang/test/CodeGenHLSL/builtins/ldexp.hlsl @@ -1,48 +1,48 @@ // RUN: %clang_cc1 -finclude-default-header -x hlsl -triple dxil-pc-shadermodel6.3-library %s -fnative-half-type -emit-llvm -disable-llvm-passes -o - | FileCheck %s -// CHECK-LABEL: define linkonce_odr noundef nofpclass(nan inf) half @_ZN4hlsl8__detail10ldexp_implIDhEET_S2_S2_ +// CHECK-LABEL: define linkonce_odr hidden noundef nofpclass(nan inf) half @_ZN4hlsl8__detail10ldexp_implIDhEET_S2_S2_ // CHECK: %elt.exp2 = call reassoc nnan ninf nsz arcp afn half @llvm.exp2.f16(half %{{.*}}) // CHECK: %mul = fmul reassoc nnan ninf nsz arcp afn half %elt.exp2, %{{.*}} // CHECK: ret half %mul half test_ldexp_half(half X, half Exp) { return ldexp(X, Exp); } -// CHECK-LABEL: define linkonce_odr noundef nofpclass(nan inf) <2 x half> @_ZN4hlsl8__detail10ldexp_implIDv2_DhEET_S3_S3_ +// CHECK-LABEL: define linkonce_odr hidden noundef nofpclass(nan inf) <2 x half> @_ZN4hlsl8__detail10ldexp_implIDv2_DhEET_S3_S3_ // CHECK: %elt.exp2 = call reassoc nnan ninf nsz arcp afn <2 x half> @llvm.exp2.v2f16(<2 x half> %{{.*}}) // CHECK: %mul = fmul reassoc nnan ninf nsz arcp afn <2 x half> %elt.exp2, %{{.*}} // CHECK: ret <2 x half> %mul half2 test_ldexp_half2(half2 X, half2 Exp) { return ldexp(X, Exp); } -// CHECK-LABEL: define linkonce_odr noundef nofpclass(nan inf) <3 x half> @_ZN4hlsl8__detail10ldexp_implIDv3_DhEET_S3_S3_ +// CHECK-LABEL: define linkonce_odr hidden noundef nofpclass(nan inf) <3 x half> @_ZN4hlsl8__detail10ldexp_implIDv3_DhEET_S3_S3_ // CHECK: %elt.exp2 = call reassoc nnan ninf nsz arcp afn <3 x half> @llvm.exp2.v3f16(<3 x half> %{{.*}}) // CHECK: %mul = fmul reassoc nnan ninf nsz arcp afn <3 x half> %elt.exp2, %{{.*}} // CHECK: ret <3 x half> %mul half3 test_ldexp_half3(half3 X, half3 Exp) { return ldexp(X, Exp); } -// CHECK-LABEL: define linkonce_odr noundef nofpclass(nan inf) <4 x half> @_ZN4hlsl8__detail10ldexp_implIDv4_DhEET_S3_S3_ +// CHECK-LABEL: define linkonce_odr hidden noundef nofpclass(nan inf) <4 x half> @_ZN4hlsl8__detail10ldexp_implIDv4_DhEET_S3_S3_ // CHECK: %elt.exp2 = call reassoc nnan ninf nsz arcp afn <4 x half> @llvm.exp2.v4f16(<4 x half> %{{.*}}) // CHECK: %mul = fmul reassoc nnan ninf nsz arcp afn <4 x half> %elt.exp2, %{{.*}} // CHECK: ret <4 x half> %mul half4 test_ldexp_half4(half4 X, half4 Exp) { return ldexp(X, Exp); } -// CHECK-LABEL: define linkonce_odr noundef nofpclass(nan inf) float @_ZN4hlsl8__detail10ldexp_implIfEET_S2_S2_ +// CHECK-LABEL: define linkonce_odr hidden noundef nofpclass(nan inf) float @_ZN4hlsl8__detail10ldexp_implIfEET_S2_S2_ // CHECK: %elt.exp2 = call reassoc nnan ninf nsz arcp afn float @llvm.exp2.f32(float %{{.*}}) // CHECK: %mul = fmul reassoc nnan ninf nsz arcp afn float %elt.exp2, %{{.*}} // CHECK: ret float %mul float test_ldexp_float(float X, float Exp) { return ldexp(X, Exp); } -// CHECK-LABEL: define linkonce_odr noundef nofpclass(nan inf) <2 x float> @_ZN4hlsl8__detail10ldexp_implIDv2_fEET_S3_S3_ +// CHECK-LABEL: define linkonce_odr hidden noundef nofpclass(nan inf) <2 x float> @_ZN4hlsl8__detail10ldexp_implIDv2_fEET_S3_S3_ // CHECK: %elt.exp2 = call reassoc nnan ninf nsz arcp afn <2 x float> @llvm.exp2.v2f32(<2 x float> %{{.*}}) // CHECK: %mul = fmul reassoc nnan ninf nsz arcp afn <2 x float> %elt.exp2, %{{.*}} // CHECK: ret <2 x float> %mul float2 test_ldexp_float2(float2 X, float2 Exp) { return ldexp(X, Exp); } -// CHECK-LABEL: define linkonce_odr noundef nofpclass(nan inf) <3 x float> @_ZN4hlsl8__detail10ldexp_implIDv3_fEET_S3_S3_ +// CHECK-LABEL: define linkonce_odr hidden noundef nofpclass(nan inf) <3 x float> @_ZN4hlsl8__detail10ldexp_implIDv3_fEET_S3_S3_ // CHECK: %elt.exp2 = call reassoc nnan ninf nsz arcp afn <3 x float> @llvm.exp2.v3f32(<3 x float> %{{.*}}) // CHECK: %mul = fmul reassoc nnan ninf nsz arcp afn <3 x float> %elt.exp2, %{{.*}} // CHECK: ret <3 x float> %mul float3 test_ldexp_float3(float3 X, float3 Exp) { return ldexp(X, Exp); } -// CHECK-LABEL: define linkonce_odr noundef nofpclass(nan inf) <4 x float> @_ZN4hlsl8__detail10ldexp_implIDv4_fEET_S3_S3_ +// CHECK-LABEL: define linkonce_odr hidden noundef nofpclass(nan inf) <4 x float> @_ZN4hlsl8__detail10ldexp_implIDv4_fEET_S3_S3_ // CHECK: %elt.exp2 = call reassoc nnan ninf nsz arcp afn <4 x float> @llvm.exp2.v4f32(<4 x float> %{{.*}}) // CHECK: %mul = fmul reassoc nnan ninf nsz arcp afn <4 x float> %elt.exp2, %{{.*}} // CHECK: ret <4 x float> %mul diff --git a/external/llvm-project/clang/test/CodeGenHLSL/builtins/length.hlsl b/external/llvm-project/clang/test/CodeGenHLSL/builtins/length.hlsl index 0b17d03d7097..9297c35abfd1 100644 --- a/external/llvm-project/clang/test/CodeGenHLSL/builtins/length.hlsl +++ b/external/llvm-project/clang/test/CodeGenHLSL/builtins/length.hlsl @@ -8,16 +8,13 @@ // RUN: -emit-llvm -O1 -o - | FileCheck %s --check-prefix=SPVCHECK -// DXCHECK-LABEL: define noundef nofpclass(nan inf) half @_Z16test_length_halfDh( -// - -// CHECK-LABEL: define noundef nofpclass(nan inf) half @_Z16test_length_halfDh( +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) half @_Z16test_length_halfDh( // CHECK-SAME: half noundef nofpclass(nan inf) [[P0:%.*]]) local_unnamed_addr #[[ATTR0:[0-9]+]] { // CHECK-NEXT: [[ENTRY:.*:]] // CHECK-NEXT: [[ELT_ABS_I:%.*]] = tail call reassoc nnan ninf nsz arcp afn noundef half @llvm.fabs.f16(half nofpclass(nan inf) [[P0]]) // CHECK-NEXT: ret half [[ELT_ABS_I]] // -// SPVCHECK-LABEL: define spir_func noundef nofpclass(nan inf) half @_Z16test_length_halfDh( +// SPVCHECK-LABEL: define hidden spir_func noundef nofpclass(nan inf) half @_Z16test_length_halfDh( // SPVCHECK-SAME: half noundef nofpclass(nan inf) [[P0:%.*]]) local_unnamed_addr #[[ATTR0:[0-9]+]] { // SPVCHECK-NEXT: [[ENTRY:.*:]] // SPVCHECK-NEXT: [[ELT_ABS_I:%.*]] = tail call reassoc nnan ninf nsz arcp afn noundef half @llvm.fabs.f16(half nofpclass(nan inf) [[P0]]) @@ -28,18 +25,14 @@ half test_length_half(half p0) return length(p0); } -// DXCHECK-LABEL: define noundef nofpclass(nan inf) half @_Z17test_length_half2Dv2_Dh( -// - - -// CHECK-LABEL: define noundef nofpclass(nan inf) half @_Z17test_length_half2Dv2_Dh( +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) half @_Z17test_length_half2Dv2_Dh( // CHECK-SAME: <2 x half> noundef nofpclass(nan inf) [[P0:%.*]]) local_unnamed_addr #[[ATTR0]] { // CHECK-NEXT: [[ENTRY:.*:]] // CHECK-NEXT: [[HLSL_DOT_I:%.*]] = tail call reassoc nnan ninf nsz arcp afn half @llvm.dx.fdot.v2f16(<2 x half> nofpclass(nan inf) [[P0]], <2 x half> nofpclass(nan inf) [[P0]]) // CHECK-NEXT: [[TMP0:%.*]] = tail call reassoc nnan ninf nsz arcp afn noundef half @llvm.sqrt.f16(half [[HLSL_DOT_I]]) // CHECK-NEXT: ret half [[TMP0]] // -// SPVCHECK-LABEL: define spir_func noundef nofpclass(nan inf) half @_Z17test_length_half2Dv2_Dh( +// SPVCHECK-LABEL: define hidden spir_func noundef nofpclass(nan inf) half @_Z17test_length_half2Dv2_Dh( // SPVCHECK-SAME: <2 x half> noundef nofpclass(nan inf) [[P0:%.*]]) local_unnamed_addr #[[ATTR0]] { // SPVCHECK-NEXT: [[ENTRY:.*:]] // SPVCHECK-NEXT: [[SPV_LENGTH_I:%.*]] = tail call reassoc nnan ninf nsz arcp afn noundef half @llvm.spv.length.v2f16(<2 x half> nofpclass(nan inf) [[P0]]) @@ -50,15 +43,14 @@ half test_length_half2(half2 p0) return length(p0); } -// DXCHECK-LABEL: define noundef nofpclass(nan inf) half @_Z17test_length_half3Dv3_Dh( -// CHECK-LABEL: define noundef nofpclass(nan inf) half @_Z17test_length_half3Dv3_Dh( +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) half @_Z17test_length_half3Dv3_Dh( // CHECK-SAME: <3 x half> noundef nofpclass(nan inf) [[P0:%.*]]) local_unnamed_addr #[[ATTR0]] { // CHECK-NEXT: [[ENTRY:.*:]] // CHECK-NEXT: [[HLSL_DOT_I:%.*]] = tail call reassoc nnan ninf nsz arcp afn half @llvm.dx.fdot.v3f16(<3 x half> nofpclass(nan inf) [[P0]], <3 x half> nofpclass(nan inf) [[P0]]) // CHECK-NEXT: [[TMP0:%.*]] = tail call reassoc nnan ninf nsz arcp afn noundef half @llvm.sqrt.f16(half [[HLSL_DOT_I]]) // CHECK-NEXT: ret half [[TMP0]] // -// SPVCHECK-LABEL: define spir_func noundef nofpclass(nan inf) half @_Z17test_length_half3Dv3_Dh( +// SPVCHECK-LABEL: define hidden spir_func noundef nofpclass(nan inf) half @_Z17test_length_half3Dv3_Dh( // SPVCHECK-SAME: <3 x half> noundef nofpclass(nan inf) [[P0:%.*]]) local_unnamed_addr #[[ATTR0]] { // SPVCHECK-NEXT: [[ENTRY:.*:]] // SPVCHECK-NEXT: [[SPV_LENGTH_I:%.*]] = tail call reassoc nnan ninf nsz arcp afn noundef half @llvm.spv.length.v3f16(<3 x half> nofpclass(nan inf) [[P0]]) @@ -69,15 +61,14 @@ half test_length_half3(half3 p0) return length(p0); } -// DXCHECK-LABEL: define noundef nofpclass(nan inf) half @_Z17test_length_half4Dv4_Dh( -// CHECK-LABEL: define noundef nofpclass(nan inf) half @_Z17test_length_half4Dv4_Dh( +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) half @_Z17test_length_half4Dv4_Dh( // CHECK-SAME: <4 x half> noundef nofpclass(nan inf) [[P0:%.*]]) local_unnamed_addr #[[ATTR0]] { // CHECK-NEXT: [[ENTRY:.*:]] // CHECK-NEXT: [[HLSL_DOT_I:%.*]] = tail call reassoc nnan ninf nsz arcp afn half @llvm.dx.fdot.v4f16(<4 x half> nofpclass(nan inf) [[P0]], <4 x half> nofpclass(nan inf) [[P0]]) // CHECK-NEXT: [[TMP0:%.*]] = tail call reassoc nnan ninf nsz arcp afn noundef half @llvm.sqrt.f16(half [[HLSL_DOT_I]]) // CHECK-NEXT: ret half [[TMP0]] // -// SPVCHECK-LABEL: define spir_func noundef nofpclass(nan inf) half @_Z17test_length_half4Dv4_Dh( +// SPVCHECK-LABEL: define hidden spir_func noundef nofpclass(nan inf) half @_Z17test_length_half4Dv4_Dh( // SPVCHECK-SAME: <4 x half> noundef nofpclass(nan inf) [[P0:%.*]]) local_unnamed_addr #[[ATTR0]] { // SPVCHECK-NEXT: [[ENTRY:.*:]] // SPVCHECK-NEXT: [[SPV_LENGTH_I:%.*]] = tail call reassoc nnan ninf nsz arcp afn noundef half @llvm.spv.length.v4f16(<4 x half> nofpclass(nan inf) [[P0]]) @@ -88,14 +79,13 @@ half test_length_half4(half4 p0) return length(p0); } -// DXCHECK-LABEL: define noundef nofpclass(nan inf) float @_Z17test_length_floatf( -// CHECK-LABEL: define noundef nofpclass(nan inf) float @_Z17test_length_floatf( +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) float @_Z17test_length_floatf( // CHECK-SAME: float noundef nofpclass(nan inf) [[P0:%.*]]) local_unnamed_addr #[[ATTR0]] { // CHECK-NEXT: [[ENTRY:.*:]] // CHECK-NEXT: [[ELT_ABS_I:%.*]] = tail call reassoc nnan ninf nsz arcp afn noundef float @llvm.fabs.f32(float nofpclass(nan inf) [[P0]]) // CHECK-NEXT: ret float [[ELT_ABS_I]] // -// SPVCHECK-LABEL: define spir_func noundef nofpclass(nan inf) float @_Z17test_length_floatf( +// SPVCHECK-LABEL: define hidden spir_func noundef nofpclass(nan inf) float @_Z17test_length_floatf( // SPVCHECK-SAME: float noundef nofpclass(nan inf) [[P0:%.*]]) local_unnamed_addr #[[ATTR0]] { // SPVCHECK-NEXT: [[ENTRY:.*:]] // SPVCHECK-NEXT: [[ELT_ABS_I:%.*]] = tail call reassoc nnan ninf nsz arcp afn noundef float @llvm.fabs.f32(float nofpclass(nan inf) [[P0]]) @@ -106,15 +96,14 @@ float test_length_float(float p0) return length(p0); } -// DXCHECK-LABEL: define noundef nofpclass(nan inf) float @_Z18test_length_float2Dv2_f( -// CHECK-LABEL: define noundef nofpclass(nan inf) float @_Z18test_length_float2Dv2_f( +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) float @_Z18test_length_float2Dv2_f( // CHECK-SAME: <2 x float> noundef nofpclass(nan inf) [[P0:%.*]]) local_unnamed_addr #[[ATTR0]] { // CHECK-NEXT: [[ENTRY:.*:]] // CHECK-NEXT: [[HLSL_DOT_I:%.*]] = tail call reassoc nnan ninf nsz arcp afn float @llvm.dx.fdot.v2f32(<2 x float> nofpclass(nan inf) [[P0]], <2 x float> nofpclass(nan inf) [[P0]]) // CHECK-NEXT: [[TMP0:%.*]] = tail call reassoc nnan ninf nsz arcp afn noundef float @llvm.sqrt.f32(float [[HLSL_DOT_I]]) // CHECK-NEXT: ret float [[TMP0]] // -// SPVCHECK-LABEL: define spir_func noundef nofpclass(nan inf) float @_Z18test_length_float2Dv2_f( +// SPVCHECK-LABEL: define hidden spir_func noundef nofpclass(nan inf) float @_Z18test_length_float2Dv2_f( // SPVCHECK-SAME: <2 x float> noundef nofpclass(nan inf) [[P0:%.*]]) local_unnamed_addr #[[ATTR0]] { // SPVCHECK-NEXT: [[ENTRY:.*:]] // SPVCHECK-NEXT: [[SPV_LENGTH_I:%.*]] = tail call reassoc nnan ninf nsz arcp afn noundef float @llvm.spv.length.v2f32(<2 x float> nofpclass(nan inf) [[P0]]) @@ -125,15 +114,14 @@ float test_length_float2(float2 p0) return length(p0); } -// DXCHECK-LABEL: define noundef nofpclass(nan inf) float @_Z18test_length_float3Dv3_f( -// CHECK-LABEL: define noundef nofpclass(nan inf) float @_Z18test_length_float3Dv3_f( +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) float @_Z18test_length_float3Dv3_f( // CHECK-SAME: <3 x float> noundef nofpclass(nan inf) [[P0:%.*]]) local_unnamed_addr #[[ATTR0]] { // CHECK-NEXT: [[ENTRY:.*:]] // CHECK-NEXT: [[HLSL_DOT_I:%.*]] = tail call reassoc nnan ninf nsz arcp afn float @llvm.dx.fdot.v3f32(<3 x float> nofpclass(nan inf) [[P0]], <3 x float> nofpclass(nan inf) [[P0]]) // CHECK-NEXT: [[TMP0:%.*]] = tail call reassoc nnan ninf nsz arcp afn noundef float @llvm.sqrt.f32(float [[HLSL_DOT_I]]) // CHECK-NEXT: ret float [[TMP0]] // -// SPVCHECK-LABEL: define spir_func noundef nofpclass(nan inf) float @_Z18test_length_float3Dv3_f( +// SPVCHECK-LABEL: define hidden spir_func noundef nofpclass(nan inf) float @_Z18test_length_float3Dv3_f( // SPVCHECK-SAME: <3 x float> noundef nofpclass(nan inf) [[P0:%.*]]) local_unnamed_addr #[[ATTR0]] { // SPVCHECK-NEXT: [[ENTRY:.*:]] // SPVCHECK-NEXT: [[SPV_LENGTH_I:%.*]] = tail call reassoc nnan ninf nsz arcp afn noundef float @llvm.spv.length.v3f32(<3 x float> nofpclass(nan inf) [[P0]]) @@ -144,15 +132,14 @@ float test_length_float3(float3 p0) return length(p0); } -// DXCHECK-LABEL: define noundef nofpclass(nan inf) float @_Z18test_length_float4Dv4_f( -// CHECK-LABEL: define noundef nofpclass(nan inf) float @_Z18test_length_float4Dv4_f( +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) float @_Z18test_length_float4Dv4_f( // CHECK-SAME: <4 x float> noundef nofpclass(nan inf) [[P0:%.*]]) local_unnamed_addr #[[ATTR0]] { // CHECK-NEXT: [[ENTRY:.*:]] // CHECK-NEXT: [[HLSL_DOT_I:%.*]] = tail call reassoc nnan ninf nsz arcp afn float @llvm.dx.fdot.v4f32(<4 x float> nofpclass(nan inf) [[P0]], <4 x float> nofpclass(nan inf) [[P0]]) // CHECK-NEXT: [[TMP0:%.*]] = tail call reassoc nnan ninf nsz arcp afn noundef float @llvm.sqrt.f32(float [[HLSL_DOT_I]]) // CHECK-NEXT: ret float [[TMP0]] // -// SPVCHECK-LABEL: define spir_func noundef nofpclass(nan inf) float @_Z18test_length_float4Dv4_f( +// SPVCHECK-LABEL: define hidden spir_func noundef nofpclass(nan inf) float @_Z18test_length_float4Dv4_f( // SPVCHECK-SAME: <4 x float> noundef nofpclass(nan inf) [[P0:%.*]]) local_unnamed_addr #[[ATTR0]] { // SPVCHECK-NEXT: [[ENTRY:.*:]] // SPVCHECK-NEXT: [[SPV_LENGTH_I:%.*]] = tail call reassoc nnan ninf nsz arcp afn noundef float @llvm.spv.length.v4f32(<4 x float> nofpclass(nan inf) [[P0]]) diff --git a/external/llvm-project/clang/test/CodeGenHLSL/builtins/lerp-overloads.hlsl b/external/llvm-project/clang/test/CodeGenHLSL/builtins/lerp-overloads.hlsl index 3cb14f8555ca..3b13e43873c7 100644 --- a/external/llvm-project/clang/test/CodeGenHLSL/builtins/lerp-overloads.hlsl +++ b/external/llvm-project/clang/test/CodeGenHLSL/builtins/lerp-overloads.hlsl @@ -1,7 +1,7 @@ -// RUN: %clang_cc1 -std=hlsl202x -finclude-default-header -x hlsl -triple dxil-pc-shadermodel6.3-library %s -fnative-half-type -emit-llvm -o - | FileCheck %s --check-prefixes=CHECK,NATIVE_HALF -DFNATTRS="noundef nofpclass(nan inf)" -DTARGET=dx -// RUN: %clang_cc1 -std=hlsl202x -finclude-default-header -x hlsl -triple dxil-pc-shadermodel6.3-library %s -emit-llvm -o - | FileCheck %s --check-prefixes=CHECK,NO_HALF -DFNATTRS="noundef nofpclass(nan inf)" -DTARGET=dx -// RUN: %clang_cc1 -std=hlsl202x -finclude-default-header -x hlsl -triple spirv-unknown-vulkan-compute %s -fnative-half-type -emit-llvm -o - | FileCheck %s --check-prefixes=CHECK,NATIVE_HALF -DFNATTRS="spir_func noundef nofpclass(nan inf)" -DTARGET=spv -// RUN: %clang_cc1 -std=hlsl202x -finclude-default-header -x hlsl -triple spirv-unknown-vulkan-compute %s -emit-llvm -o - | FileCheck %s --check-prefixes=CHECK,NO_HALF -DFNATTRS="spir_func noundef nofpclass(nan inf)" -DTARGET=spv +// RUN: %clang_cc1 -std=hlsl202x -finclude-default-header -x hlsl -triple dxil-pc-shadermodel6.3-library %s -fnative-half-type -emit-llvm -o - | FileCheck %s --check-prefixes=CHECK,NATIVE_HALF -DFNATTRS="hidden noundef nofpclass(nan inf)" -DTARGET=dx +// RUN: %clang_cc1 -std=hlsl202x -finclude-default-header -x hlsl -triple dxil-pc-shadermodel6.3-library %s -emit-llvm -o - | FileCheck %s --check-prefixes=CHECK,NO_HALF -DFNATTRS="hidden noundef nofpclass(nan inf)" -DTARGET=dx +// RUN: %clang_cc1 -std=hlsl202x -finclude-default-header -x hlsl -triple spirv-unknown-vulkan-compute %s -fnative-half-type -emit-llvm -o - | FileCheck %s --check-prefixes=CHECK,NATIVE_HALF -DFNATTRS="hidden spir_func noundef nofpclass(nan inf)" -DTARGET=spv +// RUN: %clang_cc1 -std=hlsl202x -finclude-default-header -x hlsl -triple spirv-unknown-vulkan-compute %s -emit-llvm -o - | FileCheck %s --check-prefixes=CHECK,NO_HALF -DFNATTRS="hidden spir_func noundef nofpclass(nan inf)" -DTARGET=spv // CHECK: define [[FNATTRS]] float @_Z16test_lerp_doubled( // CHECK: [[CONV0:%.*]] = fptrunc {{.*}} double %{{.*}} to float diff --git a/external/llvm-project/clang/test/CodeGenHLSL/builtins/log-overloads.hlsl b/external/llvm-project/clang/test/CodeGenHLSL/builtins/log-overloads.hlsl index 5c63d630c3f3..d7aacdc486ac 100644 --- a/external/llvm-project/clang/test/CodeGenHLSL/builtins/log-overloads.hlsl +++ b/external/llvm-project/clang/test/CodeGenHLSL/builtins/log-overloads.hlsl @@ -2,67 +2,67 @@ // RUN: -emit-llvm -disable-llvm-passes -o - | \ // RUN: FileCheck %s --check-prefixes=CHECK -// CHECK-LABEL: define noundef nofpclass(nan inf) float {{.*}}test_log_double +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) float {{.*}}test_log_double // CHECK: call reassoc nnan ninf nsz arcp afn float @llvm.log.f32( float test_log_double(double p0) { return log(p0); } -// CHECK-LABEL: define noundef nofpclass(nan inf) <2 x float> {{.*}}test_log_double2 +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) <2 x float> {{.*}}test_log_double2 // CHECK: call reassoc nnan ninf nsz arcp afn <2 x float> @llvm.log.v2f32 float2 test_log_double2(double2 p0) { return log(p0); } -// CHECK-LABEL: define noundef nofpclass(nan inf) <3 x float> {{.*}}test_log_double3 +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) <3 x float> {{.*}}test_log_double3 // CHECK: call reassoc nnan ninf nsz arcp afn <3 x float> @llvm.log.v3f32 float3 test_log_double3(double3 p0) { return log(p0); } -// CHECK-LABEL: define noundef nofpclass(nan inf) <4 x float> {{.*}}test_log_double4 +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) <4 x float> {{.*}}test_log_double4 // CHECK: call reassoc nnan ninf nsz arcp afn <4 x float> @llvm.log.v4f32 float4 test_log_double4(double4 p0) { return log(p0); } -// CHECK-LABEL: define noundef nofpclass(nan inf) float {{.*}}test_log_int +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) float {{.*}}test_log_int // CHECK: call reassoc nnan ninf nsz arcp afn float @llvm.log.f32( float test_log_int(int p0) { return log(p0); } -// CHECK-LABEL: define noundef nofpclass(nan inf) <2 x float> {{.*}}test_log_int2 +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) <2 x float> {{.*}}test_log_int2 // CHECK: call reassoc nnan ninf nsz arcp afn <2 x float> @llvm.log.v2f32 float2 test_log_int2(int2 p0) { return log(p0); } -// CHECK-LABEL: define noundef nofpclass(nan inf) <3 x float> {{.*}}test_log_int3 +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) <3 x float> {{.*}}test_log_int3 // CHECK: call reassoc nnan ninf nsz arcp afn <3 x float> @llvm.log.v3f32 float3 test_log_int3(int3 p0) { return log(p0); } -// CHECK-LABEL: define noundef nofpclass(nan inf) <4 x float> {{.*}}test_log_int4 +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) <4 x float> {{.*}}test_log_int4 // CHECK: call reassoc nnan ninf nsz arcp afn <4 x float> @llvm.log.v4f32 float4 test_log_int4(int4 p0) { return log(p0); } -// CHECK-LABEL: define noundef nofpclass(nan inf) float {{.*}}test_log_uint +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) float {{.*}}test_log_uint // CHECK: call reassoc nnan ninf nsz arcp afn float @llvm.log.f32( float test_log_uint(uint p0) { return log(p0); } -// CHECK-LABEL: define noundef nofpclass(nan inf) <2 x float> {{.*}}test_log_uint2 +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) <2 x float> {{.*}}test_log_uint2 // CHECK: call reassoc nnan ninf nsz arcp afn <2 x float> @llvm.log.v2f32 float2 test_log_uint2(uint2 p0) { return log(p0); } -// CHECK-LABEL: define noundef nofpclass(nan inf) <3 x float> {{.*}}test_log_uint3 +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) <3 x float> {{.*}}test_log_uint3 // CHECK: call reassoc nnan ninf nsz arcp afn <3 x float> @llvm.log.v3f32 float3 test_log_uint3(uint3 p0) { return log(p0); } -// CHECK-LABEL: define noundef nofpclass(nan inf) <4 x float> {{.*}}test_log_uint4 +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) <4 x float> {{.*}}test_log_uint4 // CHECK: call reassoc nnan ninf nsz arcp afn <4 x float> @llvm.log.v4f32 float4 test_log_uint4(uint4 p0) { return log(p0); } -// CHECK-LABEL: define noundef nofpclass(nan inf) float {{.*}}test_log_int64_t +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) float {{.*}}test_log_int64_t // CHECK: call reassoc nnan ninf nsz arcp afn float @llvm.log.f32( float test_log_int64_t(int64_t p0) { return log(p0); } -// CHECK-LABEL: define noundef nofpclass(nan inf) <2 x float> {{.*}}test_log_int64_t2 +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) <2 x float> {{.*}}test_log_int64_t2 // CHECK: call reassoc nnan ninf nsz arcp afn <2 x float> @llvm.log.v2f32 float2 test_log_int64_t2(int64_t2 p0) { return log(p0); } -// CHECK-LABEL: define noundef nofpclass(nan inf) <3 x float> {{.*}}test_log_int64_t3 +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) <3 x float> {{.*}}test_log_int64_t3 // CHECK: call reassoc nnan ninf nsz arcp afn <3 x float> @llvm.log.v3f32 float3 test_log_int64_t3(int64_t3 p0) { return log(p0); } -// CHECK-LABEL: define noundef nofpclass(nan inf) <4 x float> {{.*}}test_log_int64_t4 +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) <4 x float> {{.*}}test_log_int64_t4 // CHECK: call reassoc nnan ninf nsz arcp afn <4 x float> @llvm.log.v4f32 float4 test_log_int64_t4(int64_t4 p0) { return log(p0); } -// CHECK-LABEL: define noundef nofpclass(nan inf) float {{.*}}test_log_uint64_t +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) float {{.*}}test_log_uint64_t // CHECK: call reassoc nnan ninf nsz arcp afn float @llvm.log.f32( float test_log_uint64_t(uint64_t p0) { return log(p0); } -// CHECK-LABEL: define noundef nofpclass(nan inf) <2 x float> {{.*}}test_log_uint64_t2 +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) <2 x float> {{.*}}test_log_uint64_t2 // CHECK: call reassoc nnan ninf nsz arcp afn <2 x float> @llvm.log.v2f32 float2 test_log_uint64_t2(uint64_t2 p0) { return log(p0); } -// CHECK-LABEL: define noundef nofpclass(nan inf) <3 x float> {{.*}}test_log_uint64_t3 +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) <3 x float> {{.*}}test_log_uint64_t3 // CHECK: call reassoc nnan ninf nsz arcp afn <3 x float> @llvm.log.v3f32 float3 test_log_uint64_t3(uint64_t3 p0) { return log(p0); } -// CHECK-LABEL: define noundef nofpclass(nan inf) <4 x float> {{.*}}test_log_uint64_t4 +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) <4 x float> {{.*}}test_log_uint64_t4 // CHECK: call reassoc nnan ninf nsz arcp afn <4 x float> @llvm.log.v4f32 float4 test_log_uint64_t4(uint64_t4 p0) { return log(p0); } diff --git a/external/llvm-project/clang/test/CodeGenHLSL/builtins/log.hlsl b/external/llvm-project/clang/test/CodeGenHLSL/builtins/log.hlsl index e489939594a5..0136c1a052ed 100644 --- a/external/llvm-project/clang/test/CodeGenHLSL/builtins/log.hlsl +++ b/external/llvm-project/clang/test/CodeGenHLSL/builtins/log.hlsl @@ -5,36 +5,36 @@ // RUN: -emit-llvm -disable-llvm-passes -o - | \ // RUN: FileCheck %s --check-prefixes=CHECK,NO_HALF -// NATIVE_HALF-LABEL: define noundef nofpclass(nan inf) half @_Z13test_log_half +// NATIVE_HALF-LABEL: define hidden noundef nofpclass(nan inf) half @_Z13test_log_half // NATIVE_HALF: call reassoc nnan ninf nsz arcp afn half @llvm.log.f16( -// NO_HALF-LABEL: define noundef nofpclass(nan inf) float @_Z13test_log_half +// NO_HALF-LABEL: define hidden noundef nofpclass(nan inf) float @_Z13test_log_half // NO_HALF: call reassoc nnan ninf nsz arcp afn float @llvm.log.f32( half test_log_half(half p0) { return log(p0); } -// NATIVE_HALF-LABEL: define noundef nofpclass(nan inf) <2 x half> @_Z14test_log_half2 +// NATIVE_HALF-LABEL: define hidden noundef nofpclass(nan inf) <2 x half> @_Z14test_log_half2 // NATIVE_HALF: call reassoc nnan ninf nsz arcp afn <2 x half> @llvm.log.v2f16 -// NO_HALF-LABEL: define noundef nofpclass(nan inf) <2 x float> @_Z14test_log_half2 +// NO_HALF-LABEL: define hidden noundef nofpclass(nan inf) <2 x float> @_Z14test_log_half2 // NO_HALF: call reassoc nnan ninf nsz arcp afn <2 x float> @llvm.log.v2f32( half2 test_log_half2(half2 p0) { return log(p0); } -// NATIVE_HALF-LABEL: define noundef nofpclass(nan inf) <3 x half> @_Z14test_log_half3 +// NATIVE_HALF-LABEL: define hidden noundef nofpclass(nan inf) <3 x half> @_Z14test_log_half3 // NATIVE_HALF: call reassoc nnan ninf nsz arcp afn <3 x half> @llvm.log.v3f16 -// NO_HALF-LABEL: define noundef nofpclass(nan inf) <3 x float> @_Z14test_log_half3 +// NO_HALF-LABEL: define hidden noundef nofpclass(nan inf) <3 x float> @_Z14test_log_half3 // NO_HALF: call reassoc nnan ninf nsz arcp afn <3 x float> @llvm.log.v3f32( half3 test_log_half3(half3 p0) { return log(p0); } -// NATIVE_HALF-LABEL: define noundef nofpclass(nan inf) <4 x half> @_Z14test_log_half4 +// NATIVE_HALF-LABEL: define hidden noundef nofpclass(nan inf) <4 x half> @_Z14test_log_half4 // NATIVE_HALF: call reassoc nnan ninf nsz arcp afn <4 x half> @llvm.log.v4f16 -// NO_HALF-LABEL: define noundef nofpclass(nan inf) <4 x float> @_Z14test_log_half4 +// NO_HALF-LABEL: define hidden noundef nofpclass(nan inf) <4 x float> @_Z14test_log_half4 // NO_HALF: call reassoc nnan ninf nsz arcp afn <4 x float> @llvm.log.v4f32( half4 test_log_half4(half4 p0) { return log(p0); } -// CHECK-LABEL: define noundef nofpclass(nan inf) float @_Z14test_log_float +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) float @_Z14test_log_float // CHECK: call reassoc nnan ninf nsz arcp afn float @llvm.log.f32( float test_log_float(float p0) { return log(p0); } -// CHECK-LABEL: define noundef nofpclass(nan inf) <2 x float> @_Z15test_log_float2 +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) <2 x float> @_Z15test_log_float2 // CHECK: call reassoc nnan ninf nsz arcp afn <2 x float> @llvm.log.v2f32 float2 test_log_float2(float2 p0) { return log(p0); } -// CHECK-LABEL: define noundef nofpclass(nan inf) <3 x float> @_Z15test_log_float3 +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) <3 x float> @_Z15test_log_float3 // CHECK: call reassoc nnan ninf nsz arcp afn <3 x float> @llvm.log.v3f32 float3 test_log_float3(float3 p0) { return log(p0); } -// CHECK-LABEL: define noundef nofpclass(nan inf) <4 x float> @_Z15test_log_float4 +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) <4 x float> @_Z15test_log_float4 // CHECK: call reassoc nnan ninf nsz arcp afn <4 x float> @llvm.log.v4f32 float4 test_log_float4(float4 p0) { return log(p0); } diff --git a/external/llvm-project/clang/test/CodeGenHLSL/builtins/log10-overloads.hlsl b/external/llvm-project/clang/test/CodeGenHLSL/builtins/log10-overloads.hlsl index 1a0539c3517d..e408f4a5d45c 100644 --- a/external/llvm-project/clang/test/CodeGenHLSL/builtins/log10-overloads.hlsl +++ b/external/llvm-project/clang/test/CodeGenHLSL/builtins/log10-overloads.hlsl @@ -2,67 +2,67 @@ // RUN: -emit-llvm -disable-llvm-passes -o - | \ // RUN: FileCheck %s --check-prefixes=CHECK -// CHECK-LABEL: define noundef nofpclass(nan inf) float {{.*}}test_log10_double +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) float {{.*}}test_log10_double // CHECK: call reassoc nnan ninf nsz arcp afn float @llvm.log10.f32( float test_log10_double(double p0) { return log10(p0); } -// CHECK-LABEL: define noundef nofpclass(nan inf) <2 x float> {{.*}}test_log10_double2 +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) <2 x float> {{.*}}test_log10_double2 // CHECK: call reassoc nnan ninf nsz arcp afn <2 x float> @llvm.log10.v2f32 float2 test_log10_double2(double2 p0) { return log10(p0); } -// CHECK-LABEL: define noundef nofpclass(nan inf) <3 x float> {{.*}}test_log10_double3 +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) <3 x float> {{.*}}test_log10_double3 // CHECK: call reassoc nnan ninf nsz arcp afn <3 x float> @llvm.log10.v3f32 float3 test_log10_double3(double3 p0) { return log10(p0); } -// CHECK-LABEL: define noundef nofpclass(nan inf) <4 x float> {{.*}}test_log10_double4 +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) <4 x float> {{.*}}test_log10_double4 // CHECK: call reassoc nnan ninf nsz arcp afn <4 x float> @llvm.log10.v4f32 float4 test_log10_double4(double4 p0) { return log10(p0); } -// CHECK-LABEL: define noundef nofpclass(nan inf) float {{.*}}test_log10_int +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) float {{.*}}test_log10_int // CHECK: call reassoc nnan ninf nsz arcp afn float @llvm.log10.f32( float test_log10_int(int p0) { return log10(p0); } -// CHECK-LABEL: define noundef nofpclass(nan inf) <2 x float> {{.*}}test_log10_int2 +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) <2 x float> {{.*}}test_log10_int2 // CHECK: call reassoc nnan ninf nsz arcp afn <2 x float> @llvm.log10.v2f32 float2 test_log10_int2(int2 p0) { return log10(p0); } -// CHECK-LABEL: define noundef nofpclass(nan inf) <3 x float> {{.*}}test_log10_int3 +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) <3 x float> {{.*}}test_log10_int3 // CHECK: call reassoc nnan ninf nsz arcp afn <3 x float> @llvm.log10.v3f32 float3 test_log10_int3(int3 p0) { return log10(p0); } -// CHECK-LABEL: define noundef nofpclass(nan inf) <4 x float> {{.*}}test_log10_int4 +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) <4 x float> {{.*}}test_log10_int4 // CHECK: call reassoc nnan ninf nsz arcp afn <4 x float> @llvm.log10.v4f32 float4 test_log10_int4(int4 p0) { return log10(p0); } -// CHECK-LABEL: define noundef nofpclass(nan inf) float {{.*}}test_log10_uint +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) float {{.*}}test_log10_uint // CHECK: call reassoc nnan ninf nsz arcp afn float @llvm.log10.f32( float test_log10_uint(uint p0) { return log10(p0); } -// CHECK-LABEL: define noundef nofpclass(nan inf) <2 x float> {{.*}}test_log10_uint2 +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) <2 x float> {{.*}}test_log10_uint2 // CHECK: call reassoc nnan ninf nsz arcp afn <2 x float> @llvm.log10.v2f32 float2 test_log10_uint2(uint2 p0) { return log10(p0); } -// CHECK-LABEL: define noundef nofpclass(nan inf) <3 x float> {{.*}}test_log10_uint3 +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) <3 x float> {{.*}}test_log10_uint3 // CHECK: call reassoc nnan ninf nsz arcp afn <3 x float> @llvm.log10.v3f32 float3 test_log10_uint3(uint3 p0) { return log10(p0); } -// CHECK-LABEL: define noundef nofpclass(nan inf) <4 x float> {{.*}}test_log10_uint4 +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) <4 x float> {{.*}}test_log10_uint4 // CHECK: call reassoc nnan ninf nsz arcp afn <4 x float> @llvm.log10.v4f32 float4 test_log10_uint4(uint4 p0) { return log10(p0); } -// CHECK-LABEL: define noundef nofpclass(nan inf) float {{.*}}test_log10_int64_t +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) float {{.*}}test_log10_int64_t // CHECK: call reassoc nnan ninf nsz arcp afn float @llvm.log10.f32( float test_log10_int64_t(int64_t p0) { return log10(p0); } -// CHECK-LABEL: define noundef nofpclass(nan inf) <2 x float> {{.*}}test_log10_int64_t2 +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) <2 x float> {{.*}}test_log10_int64_t2 // CHECK: call reassoc nnan ninf nsz arcp afn <2 x float> @llvm.log10.v2f32 float2 test_log10_int64_t2(int64_t2 p0) { return log10(p0); } -// CHECK-LABEL: define noundef nofpclass(nan inf) <3 x float> {{.*}}test_log10_int64_t3 +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) <3 x float> {{.*}}test_log10_int64_t3 // CHECK: call reassoc nnan ninf nsz arcp afn <3 x float> @llvm.log10.v3f32 float3 test_log10_int64_t3(int64_t3 p0) { return log10(p0); } -// CHECK-LABEL: define noundef nofpclass(nan inf) <4 x float> {{.*}}test_log10_int64_t4 +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) <4 x float> {{.*}}test_log10_int64_t4 // CHECK: call reassoc nnan ninf nsz arcp afn <4 x float> @llvm.log10.v4f32 float4 test_log10_int64_t4(int64_t4 p0) { return log10(p0); } -// CHECK-LABEL: define noundef nofpclass(nan inf) float {{.*}}test_log10_uint64_t +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) float {{.*}}test_log10_uint64_t // CHECK: call reassoc nnan ninf nsz arcp afn float @llvm.log10.f32( float test_log10_uint64_t(uint64_t p0) { return log10(p0); } -// CHECK-LABEL: define noundef nofpclass(nan inf) <2 x float> {{.*}}test_log10_uint64_t2 +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) <2 x float> {{.*}}test_log10_uint64_t2 // CHECK: call reassoc nnan ninf nsz arcp afn <2 x float> @llvm.log10.v2f32 float2 test_log10_uint64_t2(uint64_t2 p0) { return log10(p0); } -// CHECK-LABEL: define noundef nofpclass(nan inf) <3 x float> {{.*}}test_log10_uint64_t3 +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) <3 x float> {{.*}}test_log10_uint64_t3 // CHECK: call reassoc nnan ninf nsz arcp afn <3 x float> @llvm.log10.v3f32 float3 test_log10_uint64_t3(uint64_t3 p0) { return log10(p0); } -// CHECK-LABEL: define noundef nofpclass(nan inf) <4 x float> {{.*}}test_log10_uint64_t4 +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) <4 x float> {{.*}}test_log10_uint64_t4 // CHECK: call reassoc nnan ninf nsz arcp afn <4 x float> @llvm.log10.v4f32 float4 test_log10_uint64_t4(uint64_t4 p0) { return log10(p0); } diff --git a/external/llvm-project/clang/test/CodeGenHLSL/builtins/log10.hlsl b/external/llvm-project/clang/test/CodeGenHLSL/builtins/log10.hlsl index 37c8e837c45a..6a75444143b1 100644 --- a/external/llvm-project/clang/test/CodeGenHLSL/builtins/log10.hlsl +++ b/external/llvm-project/clang/test/CodeGenHLSL/builtins/log10.hlsl @@ -5,36 +5,36 @@ // RUN: -emit-llvm -disable-llvm-passes -o - | \ // RUN: FileCheck %s --check-prefixes=CHECK,NO_HALF -// NATIVE_HALF-LABEL: define noundef nofpclass(nan inf) half @_Z15test_log10_half +// NATIVE_HALF-LABEL: define hidden noundef nofpclass(nan inf) half @_Z15test_log10_half // NATIVE_HALF: call reassoc nnan ninf nsz arcp afn half @llvm.log10.f16( -// NO_HALF-LABEL: define noundef nofpclass(nan inf) float @_Z15test_log10_half +// NO_HALF-LABEL: define hidden noundef nofpclass(nan inf) float @_Z15test_log10_half // NO_HALF: call reassoc nnan ninf nsz arcp afn float @llvm.log10.f32( half test_log10_half(half p0) { return log10(p0); } -// NATIVE_HALF-LABEL: define noundef nofpclass(nan inf) <2 x half> @_Z16test_log10_half2 +// NATIVE_HALF-LABEL: define hidden noundef nofpclass(nan inf) <2 x half> @_Z16test_log10_half2 // NATIVE_HALF: call reassoc nnan ninf nsz arcp afn <2 x half> @llvm.log10.v2f16 -// NO_HALF-LABEL: define noundef nofpclass(nan inf) <2 x float> @_Z16test_log10_half2 +// NO_HALF-LABEL: define hidden noundef nofpclass(nan inf) <2 x float> @_Z16test_log10_half2 // NO_HALF: call reassoc nnan ninf nsz arcp afn <2 x float> @llvm.log10.v2f32( half2 test_log10_half2(half2 p0) { return log10(p0); } -// NATIVE_HALF-LABEL: define noundef nofpclass(nan inf) <3 x half> @_Z16test_log10_half3 +// NATIVE_HALF-LABEL: define hidden noundef nofpclass(nan inf) <3 x half> @_Z16test_log10_half3 // NATIVE_HALF: call reassoc nnan ninf nsz arcp afn <3 x half> @llvm.log10.v3f16 -// NO_HALF-LABEL: define noundef nofpclass(nan inf) <3 x float> @_Z16test_log10_half3 +// NO_HALF-LABEL: define hidden noundef nofpclass(nan inf) <3 x float> @_Z16test_log10_half3 // NO_HALF: call reassoc nnan ninf nsz arcp afn <3 x float> @llvm.log10.v3f32( half3 test_log10_half3(half3 p0) { return log10(p0); } -// NATIVE_HALF-LABEL: define noundef nofpclass(nan inf) <4 x half> @_Z16test_log10_half4 +// NATIVE_HALF-LABEL: define hidden noundef nofpclass(nan inf) <4 x half> @_Z16test_log10_half4 // NATIVE_HALF: call reassoc nnan ninf nsz arcp afn <4 x half> @llvm.log10.v4f16 -// NO_HALF-LABEL: define noundef nofpclass(nan inf) <4 x float> @_Z16test_log10_half4 +// NO_HALF-LABEL: define hidden noundef nofpclass(nan inf) <4 x float> @_Z16test_log10_half4 // NO_HALF: call reassoc nnan ninf nsz arcp afn <4 x float> @llvm.log10.v4f32( half4 test_log10_half4(half4 p0) { return log10(p0); } -// CHECK-LABEL: define noundef nofpclass(nan inf) float @_Z16test_log10_float +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) float @_Z16test_log10_float // CHECK: call reassoc nnan ninf nsz arcp afn float @llvm.log10.f32( float test_log10_float(float p0) { return log10(p0); } -// CHECK-LABEL: define noundef nofpclass(nan inf) <2 x float> @_Z17test_log10_float2 +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) <2 x float> @_Z17test_log10_float2 // CHECK: call reassoc nnan ninf nsz arcp afn <2 x float> @llvm.log10.v2f32 float2 test_log10_float2(float2 p0) { return log10(p0); } -// CHECK-LABEL: define noundef nofpclass(nan inf) <3 x float> @_Z17test_log10_float3 +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) <3 x float> @_Z17test_log10_float3 // CHECK: call reassoc nnan ninf nsz arcp afn <3 x float> @llvm.log10.v3f32 float3 test_log10_float3(float3 p0) { return log10(p0); } -// CHECK-LABEL: define noundef nofpclass(nan inf) <4 x float> @_Z17test_log10_float4 +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) <4 x float> @_Z17test_log10_float4 // CHECK: call reassoc nnan ninf nsz arcp afn <4 x float> @llvm.log10.v4f32 float4 test_log10_float4(float4 p0) { return log10(p0); } diff --git a/external/llvm-project/clang/test/CodeGenHLSL/builtins/log2-overloads.hlsl b/external/llvm-project/clang/test/CodeGenHLSL/builtins/log2-overloads.hlsl index c35b50d8e490..f88d5ab84921 100644 --- a/external/llvm-project/clang/test/CodeGenHLSL/builtins/log2-overloads.hlsl +++ b/external/llvm-project/clang/test/CodeGenHLSL/builtins/log2-overloads.hlsl @@ -2,67 +2,67 @@ // RUN: -emit-llvm -disable-llvm-passes -o - | \ // RUN: FileCheck %s --check-prefixes=CHECK -// CHECK-LABEL: define noundef nofpclass(nan inf) float {{.*}}test_log2_double +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) float {{.*}}test_log2_double // CHECK: call reassoc nnan ninf nsz arcp afn float @llvm.log2.f32( float test_log2_double(double p0) { return log2(p0); } -// CHECK-LABEL: define noundef nofpclass(nan inf) <2 x float> {{.*}}test_log2_double2 +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) <2 x float> {{.*}}test_log2_double2 // CHECK: call reassoc nnan ninf nsz arcp afn <2 x float> @llvm.log2.v2f32 float2 test_log2_double2(double2 p0) { return log2(p0); } -// CHECK-LABEL: define noundef nofpclass(nan inf) <3 x float> {{.*}}test_log2_double3 +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) <3 x float> {{.*}}test_log2_double3 // CHECK: call reassoc nnan ninf nsz arcp afn <3 x float> @llvm.log2.v3f32 float3 test_log2_double3(double3 p0) { return log2(p0); } -// CHECK-LABEL: define noundef nofpclass(nan inf) <4 x float> {{.*}}test_log2_double4 +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) <4 x float> {{.*}}test_log2_double4 // CHECK: call reassoc nnan ninf nsz arcp afn <4 x float> @llvm.log2.v4f32 float4 test_log2_double4(double4 p0) { return log2(p0); } -// CHECK-LABEL: define noundef nofpclass(nan inf) float {{.*}}test_log2_int +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) float {{.*}}test_log2_int // CHECK: call reassoc nnan ninf nsz arcp afn float @llvm.log2.f32( float test_log2_int(int p0) { return log2(p0); } -// CHECK-LABEL: define noundef nofpclass(nan inf) <2 x float> {{.*}}test_log2_int2 +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) <2 x float> {{.*}}test_log2_int2 // CHECK: call reassoc nnan ninf nsz arcp afn <2 x float> @llvm.log2.v2f32 float2 test_log2_int2(int2 p0) { return log2(p0); } -// CHECK-LABEL: define noundef nofpclass(nan inf) <3 x float> {{.*}}test_log2_int3 +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) <3 x float> {{.*}}test_log2_int3 // CHECK: call reassoc nnan ninf nsz arcp afn <3 x float> @llvm.log2.v3f32 float3 test_log2_int3(int3 p0) { return log2(p0); } -// CHECK-LABEL: define noundef nofpclass(nan inf) <4 x float> {{.*}}test_log2_int4 +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) <4 x float> {{.*}}test_log2_int4 // CHECK: call reassoc nnan ninf nsz arcp afn <4 x float> @llvm.log2.v4f32 float4 test_log2_int4(int4 p0) { return log2(p0); } -// CHECK-LABEL: define noundef nofpclass(nan inf) float {{.*}}test_log2_uint +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) float {{.*}}test_log2_uint // CHECK: call reassoc nnan ninf nsz arcp afn float @llvm.log2.f32( float test_log2_uint(uint p0) { return log2(p0); } -// CHECK-LABEL: define noundef nofpclass(nan inf) <2 x float> {{.*}}test_log2_uint2 +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) <2 x float> {{.*}}test_log2_uint2 // CHECK: call reassoc nnan ninf nsz arcp afn <2 x float> @llvm.log2.v2f32 float2 test_log2_uint2(uint2 p0) { return log2(p0); } -// CHECK-LABEL: define noundef nofpclass(nan inf) <3 x float> {{.*}}test_log2_uint3 +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) <3 x float> {{.*}}test_log2_uint3 // CHECK: call reassoc nnan ninf nsz arcp afn <3 x float> @llvm.log2.v3f32 float3 test_log2_uint3(uint3 p0) { return log2(p0); } -// CHECK-LABEL: define noundef nofpclass(nan inf) <4 x float> {{.*}}test_log2_uint4 +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) <4 x float> {{.*}}test_log2_uint4 // CHECK: call reassoc nnan ninf nsz arcp afn <4 x float> @llvm.log2.v4f32 float4 test_log2_uint4(uint4 p0) { return log2(p0); } -// CHECK-LABEL: define noundef nofpclass(nan inf) float {{.*}}test_log2_int64_t +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) float {{.*}}test_log2_int64_t // CHECK: call reassoc nnan ninf nsz arcp afn float @llvm.log2.f32( float test_log2_int64_t(int64_t p0) { return log2(p0); } -// CHECK-LABEL: define noundef nofpclass(nan inf) <2 x float> {{.*}}test_log2_int64_t2 +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) <2 x float> {{.*}}test_log2_int64_t2 // CHECK: call reassoc nnan ninf nsz arcp afn <2 x float> @llvm.log2.v2f32 float2 test_log2_int64_t2(int64_t2 p0) { return log2(p0); } -// CHECK-LABEL: define noundef nofpclass(nan inf) <3 x float> {{.*}}test_log2_int64_t3 +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) <3 x float> {{.*}}test_log2_int64_t3 // CHECK: call reassoc nnan ninf nsz arcp afn <3 x float> @llvm.log2.v3f32 float3 test_log2_int64_t3(int64_t3 p0) { return log2(p0); } -// CHECK-LABEL: define noundef nofpclass(nan inf) <4 x float> {{.*}}test_log2_int64_t4 +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) <4 x float> {{.*}}test_log2_int64_t4 // CHECK: call reassoc nnan ninf nsz arcp afn <4 x float> @llvm.log2.v4f32 float4 test_log2_int64_t4(int64_t4 p0) { return log2(p0); } -// CHECK-LABEL: define noundef nofpclass(nan inf) float {{.*}}test_log2_uint64_t +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) float {{.*}}test_log2_uint64_t // CHECK: call reassoc nnan ninf nsz arcp afn float @llvm.log2.f32( float test_log2_uint64_t(uint64_t p0) { return log2(p0); } -// CHECK-LABEL: define noundef nofpclass(nan inf) <2 x float> {{.*}}test_log2_uint64_t2 +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) <2 x float> {{.*}}test_log2_uint64_t2 // CHECK: call reassoc nnan ninf nsz arcp afn <2 x float> @llvm.log2.v2f32 float2 test_log2_uint64_t2(uint64_t2 p0) { return log2(p0); } -// CHECK-LABEL: define noundef nofpclass(nan inf) <3 x float> {{.*}}test_log2_uint64_t3 +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) <3 x float> {{.*}}test_log2_uint64_t3 // CHECK: call reassoc nnan ninf nsz arcp afn <3 x float> @llvm.log2.v3f32 float3 test_log2_uint64_t3(uint64_t3 p0) { return log2(p0); } -// CHECK-LABEL: define noundef nofpclass(nan inf) <4 x float> {{.*}}test_log2_uint64_t4 +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) <4 x float> {{.*}}test_log2_uint64_t4 // CHECK: call reassoc nnan ninf nsz arcp afn <4 x float> @llvm.log2.v4f32 float4 test_log2_uint64_t4(uint64_t4 p0) { return log2(p0); } diff --git a/external/llvm-project/clang/test/CodeGenHLSL/builtins/log2.hlsl b/external/llvm-project/clang/test/CodeGenHLSL/builtins/log2.hlsl index 5159d5bb0fa4..84d73c181089 100644 --- a/external/llvm-project/clang/test/CodeGenHLSL/builtins/log2.hlsl +++ b/external/llvm-project/clang/test/CodeGenHLSL/builtins/log2.hlsl @@ -5,36 +5,36 @@ // RUN: -emit-llvm -disable-llvm-passes -o - | \ // RUN: FileCheck %s --check-prefixes=CHECK,NO_HALF -// NATIVE_HALF-LABEL: define noundef nofpclass(nan inf) half @_Z14test_log2_half +// NATIVE_HALF-LABEL: define hidden noundef nofpclass(nan inf) half @_Z14test_log2_half // NATIVE_HALF: call reassoc nnan ninf nsz arcp afn half @llvm.log2.f16( -// NO_HALF-LABEL: define noundef nofpclass(nan inf) float @_Z14test_log2_half +// NO_HALF-LABEL: define hidden noundef nofpclass(nan inf) float @_Z14test_log2_half // NO_HALF: call reassoc nnan ninf nsz arcp afn float @llvm.log2.f32( half test_log2_half(half p0) { return log2(p0); } -// NATIVE_HALF-LABEL: define noundef nofpclass(nan inf) <2 x half> @_Z15test_log2_half2 +// NATIVE_HALF-LABEL: define hidden noundef nofpclass(nan inf) <2 x half> @_Z15test_log2_half2 // NATIVE_HALF: call reassoc nnan ninf nsz arcp afn <2 x half> @llvm.log2.v2f16 -// NO_HALF-LABEL: define noundef nofpclass(nan inf) <2 x float> @_Z15test_log2_half2 +// NO_HALF-LABEL: define hidden noundef nofpclass(nan inf) <2 x float> @_Z15test_log2_half2 // NO_HALF: call reassoc nnan ninf nsz arcp afn <2 x float> @llvm.log2.v2f32( half2 test_log2_half2(half2 p0) { return log2(p0); } -// NATIVE_HALF-LABEL: define noundef nofpclass(nan inf) <3 x half> @_Z15test_log2_half3 +// NATIVE_HALF-LABEL: define hidden noundef nofpclass(nan inf) <3 x half> @_Z15test_log2_half3 // NATIVE_HALF: call reassoc nnan ninf nsz arcp afn <3 x half> @llvm.log2.v3f16 -// NO_HALF-LABEL: define noundef nofpclass(nan inf) <3 x float> @_Z15test_log2_half3 +// NO_HALF-LABEL: define hidden noundef nofpclass(nan inf) <3 x float> @_Z15test_log2_half3 // NO_HALF: call reassoc nnan ninf nsz arcp afn <3 x float> @llvm.log2.v3f32( half3 test_log2_half3(half3 p0) { return log2(p0); } -// NATIVE_HALF-LABEL: define noundef nofpclass(nan inf) <4 x half> @_Z15test_log2_half4 +// NATIVE_HALF-LABEL: define hidden noundef nofpclass(nan inf) <4 x half> @_Z15test_log2_half4 // NATIVE_HALF: call reassoc nnan ninf nsz arcp afn <4 x half> @llvm.log2.v4f16 -// NO_HALF-LABEL: define noundef nofpclass(nan inf) <4 x float> @_Z15test_log2_half4 +// NO_HALF-LABEL: define hidden noundef nofpclass(nan inf) <4 x float> @_Z15test_log2_half4 // NO_HALF: call reassoc nnan ninf nsz arcp afn <4 x float> @llvm.log2.v4f32( half4 test_log2_half4(half4 p0) { return log2(p0); } -// CHECK-LABEL: define noundef nofpclass(nan inf) float @_Z15test_log2_float +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) float @_Z15test_log2_float // CHECK: call reassoc nnan ninf nsz arcp afn float @llvm.log2.f32( float test_log2_float(float p0) { return log2(p0); } -// CHECK-LABEL: define noundef nofpclass(nan inf) <2 x float> @_Z16test_log2_float2 +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) <2 x float> @_Z16test_log2_float2 // CHECK: call reassoc nnan ninf nsz arcp afn <2 x float> @llvm.log2.v2f32 float2 test_log2_float2(float2 p0) { return log2(p0); } -// CHECK-LABEL: define noundef nofpclass(nan inf) <3 x float> @_Z16test_log2_float3 +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) <3 x float> @_Z16test_log2_float3 // CHECK: call reassoc nnan ninf nsz arcp afn <3 x float> @llvm.log2.v3f32 float3 test_log2_float3(float3 p0) { return log2(p0); } -// CHECK-LABEL: define noundef nofpclass(nan inf) <4 x float> @_Z16test_log2_float4 +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) <4 x float> @_Z16test_log2_float4 // CHECK: call reassoc nnan ninf nsz arcp afn <4 x float> @llvm.log2.v4f32 float4 test_log2_float4(float4 p0) { return log2(p0); } diff --git a/external/llvm-project/clang/test/CodeGenHLSL/builtins/max-overloads.hlsl b/external/llvm-project/clang/test/CodeGenHLSL/builtins/max-overloads.hlsl index d952398a6a59..cd7013ba7582 100644 --- a/external/llvm-project/clang/test/CodeGenHLSL/builtins/max-overloads.hlsl +++ b/external/llvm-project/clang/test/CodeGenHLSL/builtins/max-overloads.hlsl @@ -4,14 +4,14 @@ // RUN: -emit-llvm -o - | FileCheck %s --check-prefixes=CHECK,NO_HALF #ifdef __HLSL_ENABLE_16_BIT -// NATIVE_HALF-LABEL: define noundef <4 x i16> {{.*}}test_max_short4_mismatch +// NATIVE_HALF-LABEL: define hidden noundef <4 x i16> {{.*}}test_max_short4_mismatch // NATIVE_HALF: [[CONV0:%.*]] = insertelement <4 x i16> poison, i16 %{{.*}}, i64 0 // NATIVE_HALF: [[CONV1:%.*]] = shufflevector <4 x i16> [[CONV0]], <4 x i16> poison, <4 x i32> zeroinitializer // NATIVE_HALF: [[MAX:%.*]] = call noundef <4 x i16> @llvm.smax.v4i16(<4 x i16> %{{.*}}, <4 x i16> [[CONV1]]) // NATIVE_HALF: ret <4 x i16> [[MAX]] int16_t4 test_max_short4_mismatch(int16_t4 p0, int16_t p1) { return max(p0, p1); } -// NATIVE_HALF-LABEL: define noundef <4 x i16> {{.*}}test_max_ushort4_mismatch +// NATIVE_HALF-LABEL: define hidden noundef <4 x i16> {{.*}}test_max_ushort4_mismatch // NATIVE_HALF: [[CONV0:%.*]] = insertelement <4 x i16> poison, i16 %{{.*}}, i64 0 // NATIVE_HALF: [[CONV1:%.*]] = shufflevector <4 x i16> [[CONV0]], <4 x i16> poison, <4 x i32> zeroinitializer // NATIVE_HALF: [[MAX:%.*]] = call noundef <4 x i16> @llvm.umax.v4i16(<4 x i16> %{{.*}}, <4 x i16> [[CONV1]]) @@ -19,61 +19,61 @@ int16_t4 test_max_short4_mismatch(int16_t4 p0, int16_t p1) { return max(p0, p1); uint16_t4 test_max_ushort4_mismatch(uint16_t4 p0, uint16_t p1) { return max(p0, p1); } #endif -// CHECK-LABEL: define noundef <4 x i32> {{.*}}test_max_int4_mismatch +// CHECK-LABEL: define hidden noundef <4 x i32> {{.*}}test_max_int4_mismatch // CHECK: [[CONV0:%.*]] = insertelement <4 x i32> poison, i32 %{{.*}}, i64 0 // CHECK: [[CONV1:%.*]] = shufflevector <4 x i32> [[CONV0]], <4 x i32> poison, <4 x i32> zeroinitializer // CHECK: [[MAX:%.*]] = call noundef <4 x i32> @llvm.smax.v4i32(<4 x i32> %{{.*}}, <4 x i32> [[CONV1]]) // CHECK: ret <4 x i32> [[MAX]] int4 test_max_int4_mismatch(int4 p0, int p1) { return max(p0, p1); } -// CHECK-LABEL: define noundef <4 x i32> {{.*}}test_max_uint4_mismatch +// CHECK-LABEL: define hidden noundef <4 x i32> {{.*}}test_max_uint4_mismatch // CHECK: [[CONV0:%.*]] = insertelement <4 x i32> poison, i32 %{{.*}}, i64 0 // CHECK: [[CONV1:%.*]] = shufflevector <4 x i32> [[CONV0]], <4 x i32> poison, <4 x i32> zeroinitializer // CHECK: [[MAX:%.*]] = call noundef <4 x i32> @llvm.umax.v4i32(<4 x i32> %{{.*}}, <4 x i32> [[CONV1]]) // CHECK: ret <4 x i32> [[MAX]] uint4 test_max_uint4_mismatch(uint4 p0, uint p1) { return max(p0, p1); } -// CHECK-LABEL: define noundef <4 x i64> {{.*}}test_max_long4_mismatch +// CHECK-LABEL: define hidden noundef <4 x i64> {{.*}}test_max_long4_mismatch // CHECK: [[CONV0:%.*]] = insertelement <4 x i64> poison, i64 %{{.*}}, i64 0 // CHECK: [[CONV1:%.*]] = shufflevector <4 x i64> [[CONV0]], <4 x i64> poison, <4 x i32> zeroinitializer // CHECK: [[MAX:%.*]] = call noundef <4 x i64> @llvm.smax.v4i64(<4 x i64> %{{.*}}, <4 x i64> [[CONV1]]) // CHECK: ret <4 x i64> [[MAX]] int64_t4 test_max_long4_mismatch(int64_t4 p0, int64_t p1) { return max(p0, p1); } -// CHECK-LABEL: define noundef <4 x i64> {{.*}}test_max_ulong4_mismatch +// CHECK-LABEL: define hidden noundef <4 x i64> {{.*}}test_max_ulong4_mismatch // CHECK: [[CONV0:%.*]] = insertelement <4 x i64> poison, i64 %{{.*}}, i64 0 // CHECK: [[CONV1:%.*]] = shufflevector <4 x i64> [[CONV0]], <4 x i64> poison, <4 x i32> zeroinitializer // CHECK: [[MAX:%.*]] = call noundef <4 x i64> @llvm.umax.v4i64(<4 x i64> %{{.*}}, <4 x i64> [[CONV1]]) // CHECK: ret <4 x i64> [[MAX]] uint64_t4 test_max_ulong4_mismatch(uint64_t4 p0, uint64_t p1) { return max(p0, p1); } -// NATIVE_HALF-LABEL: define noundef nofpclass(nan inf) <4 x half> {{.*}}test_max_half4_mismatch +// NATIVE_HALF-LABEL: define hidden noundef nofpclass(nan inf) <4 x half> {{.*}}test_max_half4_mismatch // NATIVE_HALF: [[CONV0:%.*]] = insertelement <4 x half> poison, half %{{.*}}, i64 0 // NATIVE_HALF: [[CONV1:%.*]] = shufflevector <4 x half> [[CONV0]], <4 x half> poison, <4 x i32> zeroinitializer // NATIVE_HALF: [[MAX:%.*]] = call reassoc nnan ninf nsz arcp afn noundef <4 x half> @llvm.maxnum.v4f16(<4 x half> %{{.*}}, <4 x half> [[CONV1]]) // NATIVE_HALF: ret <4 x half> [[MAX]] -// NO_HALF-LABEL: define noundef nofpclass(nan inf) <4 x float> {{.*}}test_max_half4_mismatch +// NO_HALF-LABEL: define hidden noundef nofpclass(nan inf) <4 x float> {{.*}}test_max_half4_mismatch // NO_HALF: [[CONV0:%.*]] = insertelement <4 x float> poison, float %{{.*}}, i64 0 // NO_HALF: [[CONV1:%.*]] = shufflevector <4 x float> [[CONV0]], <4 x float> poison, <4 x i32> zeroinitializer // NO_HALF: [[MAX:%.*]] = call reassoc nnan ninf nsz arcp afn noundef <4 x float> @llvm.maxnum.v4f32(<4 x float> %{{.*}}, <4 x float> [[CONV1]]) // NO_HALF: ret <4 x float> [[MAX]] half4 test_max_half4_mismatch(half4 p0, half p1) { return max(p0, p1); } -// CHECK-LABEL: define noundef nofpclass(nan inf) <4 x float> {{.*}}test_max_float4_mismatch +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) <4 x float> {{.*}}test_max_float4_mismatch // CHECK: [[CONV0:%.*]] = insertelement <4 x float> poison, float %{{.*}}, i64 0 // CHECK: [[CONV1:%.*]] = shufflevector <4 x float> [[CONV0]], <4 x float> poison, <4 x i32> zeroinitializer // CHECK: [[MAX:%.*]] = call reassoc nnan ninf nsz arcp afn noundef <4 x float> @llvm.maxnum.v4f32(<4 x float> %{{.*}}, <4 x float> [[CONV1]]) // CHECK: ret <4 x float> [[MAX]] float4 test_max_float4_mismatch(float4 p0, float p1) { return max(p0, p1); } -// CHECK-LABEL: define noundef nofpclass(nan inf) <4 x double> {{.*}}test_max_double4_mismatch +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) <4 x double> {{.*}}test_max_double4_mismatch // CHECK: [[CONV0:%.*]] = insertelement <4 x double> poison, double %{{.*}}, i64 0 // CHECK: [[CONV1:%.*]] = shufflevector <4 x double> [[CONV0]], <4 x double> poison, <4 x i32> zeroinitializer // CHECK: [[MAX:%.*]] = call reassoc nnan ninf nsz arcp afn noundef <4 x double> @llvm.maxnum.v4f64(<4 x double> %{{.*}}, <4 x double> [[CONV1]]) // CHECK: ret <4 x double> [[MAX]] double4 test_max_double4_mismatch(double4 p0, double p1) { return max(p0, p1); } -// CHECK-LABEL: define noundef nofpclass(nan inf) <4 x double> {{.*}}test_max_double4_mismatch2 +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) <4 x double> {{.*}}test_max_double4_mismatch2 // CHECK: [[CONV0:%.*]] = insertelement <4 x double> poison, double %{{.*}}, i64 0 // CHECK: [[CONV1:%.*]] = shufflevector <4 x double> [[CONV0]], <4 x double> poison, <4 x i32> zeroinitializer // CHECK: [[MAX:%.*]] = call reassoc nnan ninf nsz arcp afn noundef <4 x double> @llvm.maxnum.v4f64(<4 x double> [[CONV1]], <4 x double> %{{.*}}) diff --git a/external/llvm-project/clang/test/CodeGenHLSL/builtins/max.hlsl b/external/llvm-project/clang/test/CodeGenHLSL/builtins/max.hlsl index 0b767335556e..fab53a160c85 100644 --- a/external/llvm-project/clang/test/CodeGenHLSL/builtins/max.hlsl +++ b/external/llvm-project/clang/test/CodeGenHLSL/builtins/max.hlsl @@ -6,128 +6,128 @@ // RUN: FileCheck %s --check-prefixes=CHECK,NO_HALF #ifdef __HLSL_ENABLE_16_BIT -// NATIVE_HALF-LABEL: define noundef i16 @_Z14test_max_short +// NATIVE_HALF-LABEL: define hidden noundef i16 @_Z14test_max_short // NATIVE_HALF: call i16 @llvm.smax.i16( int16_t test_max_short(int16_t p0, int16_t p1) { return max(p0, p1); } -// NATIVE_HALF-LABEL: define noundef <2 x i16> @_Z15test_max_short2 +// NATIVE_HALF-LABEL: define hidden noundef <2 x i16> @_Z15test_max_short2 // NATIVE_HALF: call <2 x i16> @llvm.smax.v2i16( int16_t2 test_max_short2(int16_t2 p0, int16_t2 p1) { return max(p0, p1); } -// NATIVE_HALF-LABEL: define noundef <3 x i16> @_Z15test_max_short3 +// NATIVE_HALF-LABEL: define hidden noundef <3 x i16> @_Z15test_max_short3 // NATIVE_HALF: call <3 x i16> @llvm.smax.v3i16 int16_t3 test_max_short3(int16_t3 p0, int16_t3 p1) { return max(p0, p1); } -// NATIVE_HALF-LABEL: define noundef <4 x i16> @_Z15test_max_short4 +// NATIVE_HALF-LABEL: define hidden noundef <4 x i16> @_Z15test_max_short4 // NATIVE_HALF: call <4 x i16> @llvm.smax.v4i16 int16_t4 test_max_short4(int16_t4 p0, int16_t4 p1) { return max(p0, p1); } -// NATIVE_HALF-LABEL: define noundef i16 @_Z15test_max_ushort +// NATIVE_HALF-LABEL: define hidden noundef i16 @_Z15test_max_ushort // NATIVE_HALF: call i16 @llvm.umax.i16( uint16_t test_max_ushort(uint16_t p0, uint16_t p1) { return max(p0, p1); } -// NATIVE_HALF-LABEL: define noundef <2 x i16> @_Z16test_max_ushort2 +// NATIVE_HALF-LABEL: define hidden noundef <2 x i16> @_Z16test_max_ushort2 // NATIVE_HALF: call <2 x i16> @llvm.umax.v2i16 uint16_t2 test_max_ushort2(uint16_t2 p0, uint16_t2 p1) { return max(p0, p1); } -// NATIVE_HALF-LABEL: define noundef <3 x i16> @_Z16test_max_ushort3 +// NATIVE_HALF-LABEL: define hidden noundef <3 x i16> @_Z16test_max_ushort3 // NATIVE_HALF: call <3 x i16> @llvm.umax.v3i16 uint16_t3 test_max_ushort3(uint16_t3 p0, uint16_t3 p1) { return max(p0, p1); } -// NATIVE_HALF-LABEL: define noundef <4 x i16> @_Z16test_max_ushort4 +// NATIVE_HALF-LABEL: define hidden noundef <4 x i16> @_Z16test_max_ushort4 // NATIVE_HALF: call <4 x i16> @llvm.umax.v4i16 uint16_t4 test_max_ushort4(uint16_t4 p0, uint16_t4 p1) { return max(p0, p1); } #endif -// CHECK-LABEL: define noundef i32 @_Z12test_max_int +// CHECK-LABEL: define hidden noundef i32 @_Z12test_max_int // CHECK: call i32 @llvm.smax.i32( int test_max_int(int p0, int p1) { return max(p0, p1); } -// CHECK-LABEL: define noundef <2 x i32> @_Z13test_max_int2 +// CHECK-LABEL: define hidden noundef <2 x i32> @_Z13test_max_int2 // CHECK: call <2 x i32> @llvm.smax.v2i32 int2 test_max_int2(int2 p0, int2 p1) { return max(p0, p1); } -// CHECK-LABEL: define noundef <3 x i32> @_Z13test_max_int3 +// CHECK-LABEL: define hidden noundef <3 x i32> @_Z13test_max_int3 // CHECK: call <3 x i32> @llvm.smax.v3i32 int3 test_max_int3(int3 p0, int3 p1) { return max(p0, p1); } -// CHECK-LABEL: define noundef <4 x i32> @_Z13test_max_int4 +// CHECK-LABEL: define hidden noundef <4 x i32> @_Z13test_max_int4 // CHECK: call <4 x i32> @llvm.smax.v4i32 int4 test_max_int4(int4 p0, int4 p1) { return max(p0, p1); } -// CHECK-LABEL: define noundef i32 @_Z13test_max_uint +// CHECK-LABEL: define hidden noundef i32 @_Z13test_max_uint // CHECK: call i32 @llvm.umax.i32( int test_max_uint(uint p0, uint p1) { return max(p0, p1); } -// CHECK-LABEL: define noundef <2 x i32> @_Z14test_max_uint2 +// CHECK-LABEL: define hidden noundef <2 x i32> @_Z14test_max_uint2 // CHECK: call <2 x i32> @llvm.umax.v2i32 uint2 test_max_uint2(uint2 p0, uint2 p1) { return max(p0, p1); } -// CHECK-LABEL: define noundef <3 x i32> @_Z14test_max_uint3 +// CHECK-LABEL: define hidden noundef <3 x i32> @_Z14test_max_uint3 // CHECK: call <3 x i32> @llvm.umax.v3i32 uint3 test_max_uint3(uint3 p0, uint3 p1) { return max(p0, p1); } -// CHECK-LABEL: define noundef <4 x i32> @_Z14test_max_uint4 +// CHECK-LABEL: define hidden noundef <4 x i32> @_Z14test_max_uint4 // CHECK: call <4 x i32> @llvm.umax.v4i32 uint4 test_max_uint4(uint4 p0, uint4 p1) { return max(p0, p1); } -// CHECK-LABEL: define noundef i64 @_Z13test_max_long +// CHECK-LABEL: define hidden noundef i64 @_Z13test_max_long // CHECK: call i64 @llvm.smax.i64( int64_t test_max_long(int64_t p0, int64_t p1) { return max(p0, p1); } -// CHECK-LABEL: define noundef <2 x i64> @_Z14test_max_long2 +// CHECK-LABEL: define hidden noundef <2 x i64> @_Z14test_max_long2 // CHECK: call <2 x i64> @llvm.smax.v2i64 int64_t2 test_max_long2(int64_t2 p0, int64_t2 p1) { return max(p0, p1); } -// CHECK-LABEL: define noundef <3 x i64> @_Z14test_max_long3 +// CHECK-LABEL: define hidden noundef <3 x i64> @_Z14test_max_long3 // CHECK: call <3 x i64> @llvm.smax.v3i64 int64_t3 test_max_long3(int64_t3 p0, int64_t3 p1) { return max(p0, p1); } -// CHECK-LABEL: define noundef <4 x i64> @_Z14test_max_long4 +// CHECK-LABEL: define hidden noundef <4 x i64> @_Z14test_max_long4 // CHECK: call <4 x i64> @llvm.smax.v4i64 int64_t4 test_max_long4(int64_t4 p0, int64_t4 p1) { return max(p0, p1); } -// CHECK-LABEL: define noundef i64 @_Z14test_max_ulong +// CHECK-LABEL: define hidden noundef i64 @_Z14test_max_ulong // CHECK: call i64 @llvm.umax.i64( uint64_t test_max_ulong(uint64_t p0, uint64_t p1) { return max(p0, p1); } -// CHECK-LABEL: define noundef <2 x i64> @_Z15test_max_ulong2 +// CHECK-LABEL: define hidden noundef <2 x i64> @_Z15test_max_ulong2 // CHECK: call <2 x i64> @llvm.umax.v2i64 uint64_t2 test_max_ulong2(uint64_t2 p0, uint64_t2 p1) { return max(p0, p1); } -// CHECK-LABEL: define noundef <3 x i64> @_Z15test_max_ulong3 +// CHECK-LABEL: define hidden noundef <3 x i64> @_Z15test_max_ulong3 // CHECK: call <3 x i64> @llvm.umax.v3i64 uint64_t3 test_max_ulong3(uint64_t3 p0, uint64_t3 p1) { return max(p0, p1); } -// CHECK-LABEL: define noundef <4 x i64> @_Z15test_max_ulong4 +// CHECK-LABEL: define hidden noundef <4 x i64> @_Z15test_max_ulong4 // CHECK: call <4 x i64> @llvm.umax.v4i64 uint64_t4 test_max_ulong4(uint64_t4 p0, uint64_t4 p1) { return max(p0, p1); } -// NATIVE_HALF-LABEL: define noundef nofpclass(nan inf) half @_Z13test_max_half +// NATIVE_HALF-LABEL: define hidden noundef nofpclass(nan inf) half @_Z13test_max_half // NATIVE_HALF: call reassoc nnan ninf nsz arcp afn half @llvm.maxnum.f16( -// NO_HALF-LABEL: define noundef nofpclass(nan inf) float @_Z13test_max_half +// NO_HALF-LABEL: define hidden noundef nofpclass(nan inf) float @_Z13test_max_half // NO_HALF: call reassoc nnan ninf nsz arcp afn float @llvm.maxnum.f32( half test_max_half(half p0, half p1) { return max(p0, p1); } -// NATIVE_HALF-LABEL: define noundef nofpclass(nan inf) <2 x half> @_Z14test_max_half2 +// NATIVE_HALF-LABEL: define hidden noundef nofpclass(nan inf) <2 x half> @_Z14test_max_half2 // NATIVE_HALF: call reassoc nnan ninf nsz arcp afn <2 x half> @llvm.maxnum.v2f16 -// NO_HALF-LABEL: define noundef nofpclass(nan inf) <2 x float> @_Z14test_max_half2 +// NO_HALF-LABEL: define hidden noundef nofpclass(nan inf) <2 x float> @_Z14test_max_half2 // NO_HALF: call reassoc nnan ninf nsz arcp afn <2 x float> @llvm.maxnum.v2f32( half2 test_max_half2(half2 p0, half2 p1) { return max(p0, p1); } -// NATIVE_HALF-LABEL: define noundef nofpclass(nan inf) <3 x half> @_Z14test_max_half3 +// NATIVE_HALF-LABEL: define hidden noundef nofpclass(nan inf) <3 x half> @_Z14test_max_half3 // NATIVE_HALF: call reassoc nnan ninf nsz arcp afn <3 x half> @llvm.maxnum.v3f16 -// NO_HALF-LABEL: define noundef nofpclass(nan inf) <3 x float> @_Z14test_max_half3 +// NO_HALF-LABEL: define hidden noundef nofpclass(nan inf) <3 x float> @_Z14test_max_half3 // NO_HALF: call reassoc nnan ninf nsz arcp afn <3 x float> @llvm.maxnum.v3f32( half3 test_max_half3(half3 p0, half3 p1) { return max(p0, p1); } -// NATIVE_HALF-LABEL: define noundef nofpclass(nan inf) <4 x half> @_Z14test_max_half4 +// NATIVE_HALF-LABEL: define hidden noundef nofpclass(nan inf) <4 x half> @_Z14test_max_half4 // NATIVE_HALF: call reassoc nnan ninf nsz arcp afn <4 x half> @llvm.maxnum.v4f16 -// NO_HALF-LABEL: define noundef nofpclass(nan inf) <4 x float> @_Z14test_max_half4 +// NO_HALF-LABEL: define hidden noundef nofpclass(nan inf) <4 x float> @_Z14test_max_half4 // NO_HALF: call reassoc nnan ninf nsz arcp afn <4 x float> @llvm.maxnum.v4f32( half4 test_max_half4(half4 p0, half4 p1) { return max(p0, p1); } -// CHECK-LABEL: define noundef nofpclass(nan inf) float @_Z14test_max_float +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) float @_Z14test_max_float // CHECK: call reassoc nnan ninf nsz arcp afn float @llvm.maxnum.f32( float test_max_float(float p0, float p1) { return max(p0, p1); } -// CHECK-LABEL: define noundef nofpclass(nan inf) <2 x float> @_Z15test_max_float2 +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) <2 x float> @_Z15test_max_float2 // CHECK: call reassoc nnan ninf nsz arcp afn <2 x float> @llvm.maxnum.v2f32 float2 test_max_float2(float2 p0, float2 p1) { return max(p0, p1); } -// CHECK-LABEL: define noundef nofpclass(nan inf) <3 x float> @_Z15test_max_float3 +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) <3 x float> @_Z15test_max_float3 // CHECK: call reassoc nnan ninf nsz arcp afn <3 x float> @llvm.maxnum.v3f32 float3 test_max_float3(float3 p0, float3 p1) { return max(p0, p1); } -// CHECK-LABEL: define noundef nofpclass(nan inf) <4 x float> @_Z15test_max_float4 +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) <4 x float> @_Z15test_max_float4 // CHECK: call reassoc nnan ninf nsz arcp afn <4 x float> @llvm.maxnum.v4f32 float4 test_max_float4(float4 p0, float4 p1) { return max(p0, p1); } -// CHECK-LABEL: define noundef nofpclass(nan inf) double @_Z15test_max_double +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) double @_Z15test_max_double // CHECK: call reassoc nnan ninf nsz arcp afn double @llvm.maxnum.f64( double test_max_double(double p0, double p1) { return max(p0, p1); } -// CHECK-LABEL: define noundef nofpclass(nan inf) <2 x double> @_Z16test_max_double2 +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) <2 x double> @_Z16test_max_double2 // CHECK: call reassoc nnan ninf nsz arcp afn <2 x double> @llvm.maxnum.v2f64 double2 test_max_double2(double2 p0, double2 p1) { return max(p0, p1); } -// CHECK-LABEL: define noundef nofpclass(nan inf) <3 x double> @_Z16test_max_double3 +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) <3 x double> @_Z16test_max_double3 // CHECK: call reassoc nnan ninf nsz arcp afn <3 x double> @llvm.maxnum.v3f64 double3 test_max_double3(double3 p0, double3 p1) { return max(p0, p1); } -// CHECK-LABEL: define noundef nofpclass(nan inf) <4 x double> @_Z16test_max_double4 +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) <4 x double> @_Z16test_max_double4 // CHECK: call reassoc nnan ninf nsz arcp afn <4 x double> @llvm.maxnum.v4f64 double4 test_max_double4(double4 p0, double4 p1) { return max(p0, p1); } diff --git a/external/llvm-project/clang/test/CodeGenHLSL/builtins/min-overloads.hlsl b/external/llvm-project/clang/test/CodeGenHLSL/builtins/min-overloads.hlsl index 5c200f488c24..f81fa128ce9c 100644 --- a/external/llvm-project/clang/test/CodeGenHLSL/builtins/min-overloads.hlsl +++ b/external/llvm-project/clang/test/CodeGenHLSL/builtins/min-overloads.hlsl @@ -4,14 +4,14 @@ // RUN: -emit-llvm -o - | FileCheck %s --check-prefixes=CHECK,NO_HALF #ifdef __HLSL_ENABLE_16_BIT -// NATIVE_HALF-LABEL: define noundef <4 x i16> {{.*}}test_min_short4_mismatch +// NATIVE_HALF-LABEL: define hidden noundef <4 x i16> {{.*}}test_min_short4_mismatch // NATIVE_HALF: [[CONV0:%.*]] = insertelement <4 x i16> poison, i16 %{{.*}}, i64 0 // NATIVE_HALF: [[CONV1:%.*]] = shufflevector <4 x i16> [[CONV0]], <4 x i16> poison, <4 x i32> zeroinitializer // NATIVE_HALF: [[MIN:%.*]] = call noundef <4 x i16> @llvm.smin.v4i16(<4 x i16> %{{.*}}, <4 x i16> [[CONV1]]) // NATIVE_HALF: ret <4 x i16> [[MIN]] int16_t4 test_min_short4_mismatch(int16_t4 p0, int16_t p1) { return min(p0, p1); } -// NATIVE_HALF-LABEL: define noundef <4 x i16> {{.*}}test_min_ushort4_mismatch +// NATIVE_HALF-LABEL: define hidden noundef <4 x i16> {{.*}}test_min_ushort4_mismatch // NATIVE_HALF: [[CONV0:%.*]] = insertelement <4 x i16> poison, i16 %{{.*}}, i64 0 // NATIVE_HALF: [[CONV1:%.*]] = shufflevector <4 x i16> [[CONV0]], <4 x i16> poison, <4 x i32> zeroinitializer // NATIVE_HALF: [[MIN:%.*]] = call noundef <4 x i16> @llvm.umin.v4i16(<4 x i16> %{{.*}}, <4 x i16> [[CONV1]]) @@ -19,61 +19,61 @@ int16_t4 test_min_short4_mismatch(int16_t4 p0, int16_t p1) { return min(p0, p1); uint16_t4 test_min_ushort4_mismatch(uint16_t4 p0, uint16_t p1) { return min(p0, p1); } #endif -// CHECK-LABEL: define noundef <4 x i32> {{.*}}test_min_int4_mismatch +// CHECK-LABEL: define hidden noundef <4 x i32> {{.*}}test_min_int4_mismatch // CHECK: [[CONV0:%.*]] = insertelement <4 x i32> poison, i32 %{{.*}}, i64 0 // CHECK: [[CONV1:%.*]] = shufflevector <4 x i32> [[CONV0]], <4 x i32> poison, <4 x i32> zeroinitializer // CHECK: [[MIN:%.*]] = call noundef <4 x i32> @llvm.smin.v4i32(<4 x i32> %{{.*}}, <4 x i32> [[CONV1]]) // CHECK: ret <4 x i32> [[MIN]] int4 test_min_int4_mismatch(int4 p0, int p1) { return min(p0, p1); } -// CHECK-LABEL: define noundef <4 x i32> {{.*}}test_min_uint4_mismatch +// CHECK-LABEL: define hidden noundef <4 x i32> {{.*}}test_min_uint4_mismatch // CHECK: [[CONV0:%.*]] = insertelement <4 x i32> poison, i32 %{{.*}}, i64 0 // CHECK: [[CONV1:%.*]] = shufflevector <4 x i32> [[CONV0]], <4 x i32> poison, <4 x i32> zeroinitializer // CHECK: [[MIN:%.*]] = call noundef <4 x i32> @llvm.umin.v4i32(<4 x i32> %{{.*}}, <4 x i32> [[CONV1]]) // CHECK: ret <4 x i32> [[MIN]] uint4 test_min_uint4_mismatch(uint4 p0, uint p1) { return min(p0, p1); } -// CHECK-LABEL: define noundef <4 x i64> {{.*}}test_min_long4_mismatch +// CHECK-LABEL: define hidden noundef <4 x i64> {{.*}}test_min_long4_mismatch // CHECK: [[CONV0:%.*]] = insertelement <4 x i64> poison, i64 %{{.*}}, i64 0 // CHECK: [[CONV1:%.*]] = shufflevector <4 x i64> [[CONV0]], <4 x i64> poison, <4 x i32> zeroinitializer // CHECK: [[MIN:%.*]] = call noundef <4 x i64> @llvm.smin.v4i64(<4 x i64> %{{.*}}, <4 x i64> [[CONV1]]) // CHECK: ret <4 x i64> [[MIN]] int64_t4 test_min_long4_mismatch(int64_t4 p0, int64_t p1) { return min(p0, p1); } -// CHECK-LABEL: define noundef <4 x i64> {{.*}}test_min_ulong4_mismatch +// CHECK-LABEL: define hidden noundef <4 x i64> {{.*}}test_min_ulong4_mismatch // CHECK: [[CONV0:%.*]] = insertelement <4 x i64> poison, i64 %{{.*}}, i64 0 // CHECK: [[CONV1:%.*]] = shufflevector <4 x i64> [[CONV0]], <4 x i64> poison, <4 x i32> zeroinitializer // CHECK: [[MIN:%.*]] = call noundef <4 x i64> @llvm.umin.v4i64(<4 x i64> %{{.*}}, <4 x i64> [[CONV1]]) // CHECK: ret <4 x i64> [[MIN]] uint64_t4 test_min_ulong4_mismatch(uint64_t4 p0, uint64_t p1) { return min(p0, p1); } -// NATIVE_HALF-LABEL: define noundef nofpclass(nan inf) <4 x half> {{.*}}test_min_half4_mismatch +// NATIVE_HALF-LABEL: define hidden noundef nofpclass(nan inf) <4 x half> {{.*}}test_min_half4_mismatch // NATIVE_HALF: [[CONV0:%.*]] = insertelement <4 x half> poison, half %{{.*}}, i64 0 // NATIVE_HALF: [[CONV1:%.*]] = shufflevector <4 x half> [[CONV0]], <4 x half> poison, <4 x i32> zeroinitializer // NATIVE_HALF: [[MIN:%.*]] = call reassoc nnan ninf nsz arcp afn noundef <4 x half> @llvm.minnum.v4f16(<4 x half> %{{.*}}, <4 x half> [[CONV1]]) // NATIVE_HALF: ret <4 x half> [[MIN]] -// NO_HALF-LABEL: define noundef nofpclass(nan inf) <4 x float> {{.*}}test_min_half4_mismatch +// NO_HALF-LABEL: define hidden noundef nofpclass(nan inf) <4 x float> {{.*}}test_min_half4_mismatch // NO_HALF: [[CONV0:%.*]] = insertelement <4 x float> poison, float %{{.*}}, i64 0 // NO_HALF: [[CONV1:%.*]] = shufflevector <4 x float> [[CONV0]], <4 x float> poison, <4 x i32> zeroinitializer // NO_HALF: [[MIN:%.*]] = call reassoc nnan ninf nsz arcp afn noundef <4 x float> @llvm.minnum.v4f32(<4 x float> %{{.*}}, <4 x float> [[CONV1]]) // NO_HALF: ret <4 x float> [[MIN]] half4 test_min_half4_mismatch(half4 p0, half p1) { return min(p0, p1); } -// CHECK-LABEL: define noundef nofpclass(nan inf) <4 x float> {{.*}}test_min_float4_mismatch +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) <4 x float> {{.*}}test_min_float4_mismatch // CHECK: [[CONV0:%.*]] = insertelement <4 x float> poison, float %{{.*}}, i64 0 // CHECK: [[CONV1:%.*]] = shufflevector <4 x float> [[CONV0]], <4 x float> poison, <4 x i32> zeroinitializer // CHECK: [[MIN:%.*]] = call reassoc nnan ninf nsz arcp afn noundef <4 x float> @llvm.minnum.v4f32(<4 x float> %{{.*}}, <4 x float> [[CONV1]]) // CHECK: ret <4 x float> [[MIN]] float4 test_min_float4_mismatch(float4 p0, float p1) { return min(p0, p1); } -// CHECK-LABEL: define noundef nofpclass(nan inf) <4 x double> {{.*}}test_min_double4_mismatch +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) <4 x double> {{.*}}test_min_double4_mismatch // CHECK: [[CONV0:%.*]] = insertelement <4 x double> poison, double %{{.*}}, i64 0 // CHECK: [[CONV1:%.*]] = shufflevector <4 x double> [[CONV0]], <4 x double> poison, <4 x i32> zeroinitializer // CHECK: [[MIN:%.*]] = call reassoc nnan ninf nsz arcp afn noundef <4 x double> @llvm.minnum.v4f64(<4 x double> %{{.*}}, <4 x double> [[CONV1]]) // CHECK: ret <4 x double> [[MIN]] double4 test_min_double4_mismatch(double4 p0, double p1) { return min(p0, p1); } -// CHECK-LABEL: define noundef nofpclass(nan inf) <4 x double> {{.*}}test_min_double4_mismatch2 +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) <4 x double> {{.*}}test_min_double4_mismatch2 // CHECK: [[CONV0:%.*]] = insertelement <4 x double> poison, double %{{.*}}, i64 0 // CHECK: [[CONV1:%.*]] = shufflevector <4 x double> [[CONV0]], <4 x double> poison, <4 x i32> zeroinitializer // CHECK: [[MIN:%.*]] = call reassoc nnan ninf nsz arcp afn noundef <4 x double> @llvm.minnum.v4f64(<4 x double> [[CONV1]], <4 x double> %{{.*}}) diff --git a/external/llvm-project/clang/test/CodeGenHLSL/builtins/min.hlsl b/external/llvm-project/clang/test/CodeGenHLSL/builtins/min.hlsl index 508d8b68ea45..b3e8fedff9b1 100644 --- a/external/llvm-project/clang/test/CodeGenHLSL/builtins/min.hlsl +++ b/external/llvm-project/clang/test/CodeGenHLSL/builtins/min.hlsl @@ -6,131 +6,131 @@ // RUN: FileCheck %s --check-prefixes=CHECK,NO_HALF #ifdef __HLSL_ENABLE_16_BIT -// NATIVE_HALF-LABEL: define noundef i16 @_Z14test_min_short +// NATIVE_HALF-LABEL: define hidden noundef i16 @_Z14test_min_short // NATIVE_HALF: call i16 @llvm.smin.i16( int16_t test_min_short(int16_t p0, int16_t p1) { return min(p0, p1); } -// NATIVE_HALF-LABEL: define noundef <2 x i16> @_Z15test_min_short2 +// NATIVE_HALF-LABEL: define hidden noundef <2 x i16> @_Z15test_min_short2 // NATIVE_HALF: call <2 x i16> @llvm.smin.v2i16( int16_t2 test_min_short2(int16_t2 p0, int16_t2 p1) { return min(p0, p1); } -// NATIVE_HALF-LABEL: define noundef <3 x i16> @_Z15test_min_short3 +// NATIVE_HALF-LABEL: define hidden noundef <3 x i16> @_Z15test_min_short3 // NATIVE_HALF: call <3 x i16> @llvm.smin.v3i16 int16_t3 test_min_short3(int16_t3 p0, int16_t3 p1) { return min(p0, p1); } -// NATIVE_HALF-LABEL: define noundef <4 x i16> @_Z15test_min_short4 +// NATIVE_HALF-LABEL: define hidden noundef <4 x i16> @_Z15test_min_short4 // NATIVE_HALF: call <4 x i16> @llvm.smin.v4i16 int16_t4 test_min_short4(int16_t4 p0, int16_t4 p1) { return min(p0, p1); } -// NATIVE_HALF-LABEL: define noundef i16 @_Z15test_min_ushort +// NATIVE_HALF-LABEL: define hidden noundef i16 @_Z15test_min_ushort // NATIVE_HALF: call i16 @llvm.umin.i16( uint16_t test_min_ushort(uint16_t p0, uint16_t p1) { return min(p0, p1); } -// NATIVE_HALF-LABEL: define noundef <2 x i16> @_Z16test_min_ushort2 +// NATIVE_HALF-LABEL: define hidden noundef <2 x i16> @_Z16test_min_ushort2 // NATIVE_HALF: call <2 x i16> @llvm.umin.v2i16 uint16_t2 test_min_ushort2(uint16_t2 p0, uint16_t2 p1) { return min(p0, p1); } -// NATIVE_HALF-LABEL: define noundef <3 x i16> @_Z16test_min_ushort3 +// NATIVE_HALF-LABEL: define hidden noundef <3 x i16> @_Z16test_min_ushort3 // NATIVE_HALF: call <3 x i16> @llvm.umin.v3i16 uint16_t3 test_min_ushort3(uint16_t3 p0, uint16_t3 p1) { return min(p0, p1); } -// NATIVE_HALF-LABEL: define noundef <4 x i16> @_Z16test_min_ushort4 +// NATIVE_HALF-LABEL: define hidden noundef <4 x i16> @_Z16test_min_ushort4 // NATIVE_HALF: call <4 x i16> @llvm.umin.v4i16 uint16_t4 test_min_ushort4(uint16_t4 p0, uint16_t4 p1) { return min(p0, p1); } #endif -// CHECK-LABEL: define noundef i32 @_Z12test_min_int +// CHECK-LABEL: define hidden noundef i32 @_Z12test_min_int // CHECK: call i32 @llvm.smin.i32( int test_min_int(int p0, int p1) { return min(p0, p1); } -// CHECK-LABEL: define noundef <2 x i32> @_Z13test_min_int2 +// CHECK-LABEL: define hidden noundef <2 x i32> @_Z13test_min_int2 // CHECK: call <2 x i32> @llvm.smin.v2i32 int2 test_min_int2(int2 p0, int2 p1) { return min(p0, p1); } -// CHECK-LABEL: define noundef <3 x i32> @_Z13test_min_int3 +// CHECK-LABEL: define hidden noundef <3 x i32> @_Z13test_min_int3 // CHECK: call <3 x i32> @llvm.smin.v3i32 int3 test_min_int3(int3 p0, int3 p1) { return min(p0, p1); } -// CHECK-LABEL: define noundef <4 x i32> @_Z13test_min_int4 +// CHECK-LABEL: define hidden noundef <4 x i32> @_Z13test_min_int4 // CHECK: call <4 x i32> @llvm.smin.v4i32 int4 test_min_int4(int4 p0, int4 p1) { return min(p0, p1); } -// CHECK-LABEL: define noundef i32 @_Z13test_min_uint +// CHECK-LABEL: define hidden noundef i32 @_Z13test_min_uint // CHECK: call i32 @llvm.umin.i32( int test_min_uint(uint p0, uint p1) { return min(p0, p1); } -// CHECK-LABEL: define noundef <2 x i32> @_Z14test_min_uint2 +// CHECK-LABEL: define hidden noundef <2 x i32> @_Z14test_min_uint2 // CHECK: call <2 x i32> @llvm.umin.v2i32 uint2 test_min_uint2(uint2 p0, uint2 p1) { return min(p0, p1); } -// CHECK-LABEL: define noundef <3 x i32> @_Z14test_min_uint3 +// CHECK-LABEL: define hidden noundef <3 x i32> @_Z14test_min_uint3 // CHECK: call <3 x i32> @llvm.umin.v3i32 uint3 test_min_uint3(uint3 p0, uint3 p1) { return min(p0, p1); } -// CHECK-LABEL: define noundef <4 x i32> @_Z14test_min_uint4 +// CHECK-LABEL: define hidden noundef <4 x i32> @_Z14test_min_uint4 // CHECK: call <4 x i32> @llvm.umin.v4i32 uint4 test_min_uint4(uint4 p0, uint4 p1) { return min(p0, p1); } -// CHECK-LABEL: define noundef i64 @_Z13test_min_long +// CHECK-LABEL: define hidden noundef i64 @_Z13test_min_long // CHECK: call i64 @llvm.smin.i64( int64_t test_min_long(int64_t p0, int64_t p1) { return min(p0, p1); } -// CHECK-LABEL: define noundef <2 x i64> @_Z14test_min_long2 +// CHECK-LABEL: define hidden noundef <2 x i64> @_Z14test_min_long2 // CHECK: call <2 x i64> @llvm.smin.v2i64 int64_t2 test_min_long2(int64_t2 p0, int64_t2 p1) { return min(p0, p1); } -// CHECK-LABEL: define noundef <3 x i64> @_Z14test_min_long3 +// CHECK-LABEL: define hidden noundef <3 x i64> @_Z14test_min_long3 // CHECK: call <3 x i64> @llvm.smin.v3i64 int64_t3 test_min_long3(int64_t3 p0, int64_t3 p1) { return min(p0, p1); } -// CHECK-LABEL: define noundef <4 x i64> @_Z14test_min_long4 +// CHECK-LABEL: define hidden noundef <4 x i64> @_Z14test_min_long4 // CHECK: call <4 x i64> @llvm.smin.v4i64 int64_t4 test_min_long4(int64_t4 p0, int64_t4 p1) { return min(p0, p1); } -// CHECK-LABEL: define noundef i64 @_Z14test_min_ulong +// CHECK-LABEL: define hidden noundef i64 @_Z14test_min_ulong // CHECK: call i64 @llvm.umin.i64( uint64_t test_min_ulong(uint64_t p0, uint64_t p1) { return min(p0, p1); } -// CHECK-LABEL: define noundef <2 x i64> @_Z15test_min_ulong2 +// CHECK-LABEL: define hidden noundef <2 x i64> @_Z15test_min_ulong2 // CHECK: call <2 x i64> @llvm.umin.v2i64 uint64_t2 test_min_ulong2(uint64_t2 p0, uint64_t2 p1) { return min(p0, p1); } -// CHECK-LABEL: define noundef <3 x i64> @_Z15test_min_ulong3 +// CHECK-LABEL: define hidden noundef <3 x i64> @_Z15test_min_ulong3 // CHECK: call <3 x i64> @llvm.umin.v3i64 uint64_t3 test_min_ulong3(uint64_t3 p0, uint64_t3 p1) { return min(p0, p1); } -// CHECK-LABEL: define noundef <4 x i64> @_Z15test_min_ulong4 +// CHECK-LABEL: define hidden noundef <4 x i64> @_Z15test_min_ulong4 // CHECK: call <4 x i64> @llvm.umin.v4i64 uint64_t4 test_min_ulong4(uint64_t4 p0, uint64_t4 p1) { return min(p0, p1); } -// NATIVE_HALF-LABEL: define noundef nofpclass(nan inf) half @_Z13test_min_half +// NATIVE_HALF-LABEL: define hidden noundef nofpclass(nan inf) half @_Z13test_min_half // NATIVE_HALF: call reassoc nnan ninf nsz arcp afn half @llvm.minnum.f16( -// NO_HALF-LABEL: define noundef nofpclass(nan inf) float @_Z13test_min_half +// NO_HALF-LABEL: define hidden noundef nofpclass(nan inf) float @_Z13test_min_half // NO_HALF: call reassoc nnan ninf nsz arcp afn float @llvm.minnum.f32( half test_min_half(half p0, half p1) { return min(p0, p1); } -// NATIVE_HALF-LABEL: define noundef nofpclass(nan inf) <2 x half> @_Z14test_min_half2 +// NATIVE_HALF-LABEL: define hidden noundef nofpclass(nan inf) <2 x half> @_Z14test_min_half2 // NATIVE_HALF: call reassoc nnan ninf nsz arcp afn <2 x half> @llvm.minnum.v2f16 -// NO_HALF-LABEL: define noundef nofpclass(nan inf) <2 x float> @_Z14test_min_half2 +// NO_HALF-LABEL: define hidden noundef nofpclass(nan inf) <2 x float> @_Z14test_min_half2 // NO_HALF: call reassoc nnan ninf nsz arcp afn <2 x float> @llvm.minnum.v2f32( half2 test_min_half2(half2 p0, half2 p1) { return min(p0, p1); } -// NATIVE_HALF-LABEL: define noundef nofpclass(nan inf) <3 x half> @_Z14test_min_half3 +// NATIVE_HALF-LABEL: define hidden noundef nofpclass(nan inf) <3 x half> @_Z14test_min_half3 // NATIVE_HALF: call reassoc nnan ninf nsz arcp afn <3 x half> @llvm.minnum.v3f16 -// NO_HALF-LABEL: define noundef nofpclass(nan inf) <3 x float> @_Z14test_min_half3 +// NO_HALF-LABEL: define hidden noundef nofpclass(nan inf) <3 x float> @_Z14test_min_half3 // NO_HALF: call reassoc nnan ninf nsz arcp afn <3 x float> @llvm.minnum.v3f32( half3 test_min_half3(half3 p0, half3 p1) { return min(p0, p1); } -// NATIVE_HALF-LABEL: define noundef nofpclass(nan inf) <4 x half> @_Z14test_min_half4 +// NATIVE_HALF-LABEL: define hidden noundef nofpclass(nan inf) <4 x half> @_Z14test_min_half4 // NATIVE_HALF: call reassoc nnan ninf nsz arcp afn <4 x half> @llvm.minnum.v4f16 -// NO_HALF-LABEL: define noundef nofpclass(nan inf) <4 x float> @_Z14test_min_half4 +// NO_HALF-LABEL: define hidden noundef nofpclass(nan inf) <4 x float> @_Z14test_min_half4 // NO_HALF: call reassoc nnan ninf nsz arcp afn <4 x float> @llvm.minnum.v4f32( half4 test_min_half4(half4 p0, half4 p1) { return min(p0, p1); } -// CHECK-LABEL: define noundef nofpclass(nan inf) float @_Z14test_min_float +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) float @_Z14test_min_float // CHECK: call reassoc nnan ninf nsz arcp afn float @llvm.minnum.f32( float test_min_float(float p0, float p1) { return min(p0, p1); } -// CHECK-LABEL: define noundef nofpclass(nan inf) <2 x float> @_Z15test_min_float2 +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) <2 x float> @_Z15test_min_float2 // CHECK: call reassoc nnan ninf nsz arcp afn <2 x float> @llvm.minnum.v2f32 float2 test_min_float2(float2 p0, float2 p1) { return min(p0, p1); } -// CHECK-LABEL: define noundef nofpclass(nan inf) <3 x float> @_Z15test_min_float3 +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) <3 x float> @_Z15test_min_float3 // CHECK: call reassoc nnan ninf nsz arcp afn <3 x float> @llvm.minnum.v3f32 float3 test_min_float3(float3 p0, float3 p1) { return min(p0, p1); } -// CHECK-LABEL: define noundef nofpclass(nan inf) <4 x float> @_Z15test_min_float4 +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) <4 x float> @_Z15test_min_float4 // CHECK: call reassoc nnan ninf nsz arcp afn <4 x float> @llvm.minnum.v4f32 float4 test_min_float4(float4 p0, float4 p1) { return min(p0, p1); } -// CHECK-LABEL: define noundef nofpclass(nan inf) double @_Z15test_min_double +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) double @_Z15test_min_double // CHECK: call reassoc nnan ninf nsz arcp afn double @llvm.minnum.f64( double test_min_double(double p0, double p1) { return min(p0, p1); } -// CHECK-LABEL: define noundef nofpclass(nan inf) <2 x double> @_Z16test_min_double2 +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) <2 x double> @_Z16test_min_double2 // CHECK: call reassoc nnan ninf nsz arcp afn <2 x double> @llvm.minnum.v2f64 double2 test_min_double2(double2 p0, double2 p1) { return min(p0, p1); } -// CHECK-LABEL: define noundef nofpclass(nan inf) <3 x double> @_Z16test_min_double3 +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) <3 x double> @_Z16test_min_double3 // CHECK: call reassoc nnan ninf nsz arcp afn <3 x double> @llvm.minnum.v3f64 double3 test_min_double3(double3 p0, double3 p1) { return min(p0, p1); } -// CHECK-LABEL: define noundef nofpclass(nan inf) <4 x double> @_Z16test_min_double4 +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) <4 x double> @_Z16test_min_double4 // CHECK: call reassoc nnan ninf nsz arcp afn <4 x double> @llvm.minnum.v4f64 double4 test_min_double4(double4 p0, double4 p1) { return min(p0, p1); } -// CHECK-LABEL: define noundef nofpclass(nan inf) <4 x double> {{.*}}test_min_double4_mismatch +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) <4 x double> {{.*}}test_min_double4_mismatch // CHECK: call reassoc nnan ninf nsz arcp afn <4 x double> @llvm.minnum.v4f64 double4 test_min_double4_mismatch(double4 p0, double p1) { return min(p0, p1); } diff --git a/external/llvm-project/clang/test/CodeGenHLSL/builtins/normalize-overloads.hlsl b/external/llvm-project/clang/test/CodeGenHLSL/builtins/normalize-overloads.hlsl index e9baa25fc640..52ff7da94c4f 100644 --- a/external/llvm-project/clang/test/CodeGenHLSL/builtins/normalize-overloads.hlsl +++ b/external/llvm-project/clang/test/CodeGenHLSL/builtins/normalize-overloads.hlsl @@ -1,11 +1,11 @@ // RUN: %clang_cc1 -std=hlsl202x -finclude-default-header -x hlsl -triple \ // RUN: dxil-pc-shadermodel6.3-library %s -emit-llvm -disable-llvm-passes \ // RUN: -o - | FileCheck %s --check-prefixes=CHECK \ -// RUN: -DFNATTRS="noundef nofpclass(nan inf)" -DTARGET=dx +// RUN: -DFNATTRS="hidden noundef nofpclass(nan inf)" -DTARGET=dx // RUN: %clang_cc1 -std=hlsl202x -finclude-default-header -x hlsl -triple \ // RUN: spirv-unknown-vulkan-compute %s -emit-llvm -disable-llvm-passes \ // RUN: -o - | FileCheck %s --check-prefixes=CHECK \ -// RUN: -DFNATTRS="spir_func noundef nofpclass(nan inf)" -DTARGET=spv +// RUN: -DFNATTRS="hidden spir_func noundef nofpclass(nan inf)" -DTARGET=spv // CHECK: define [[FNATTRS]] float @ // CHECK: call reassoc nnan ninf nsz arcp afn float @llvm.[[TARGET]].normalize.f32(float diff --git a/external/llvm-project/clang/test/CodeGenHLSL/builtins/normalize.hlsl b/external/llvm-project/clang/test/CodeGenHLSL/builtins/normalize.hlsl index 830fc26b7acf..cc2378756a50 100644 --- a/external/llvm-project/clang/test/CodeGenHLSL/builtins/normalize.hlsl +++ b/external/llvm-project/clang/test/CodeGenHLSL/builtins/normalize.hlsl @@ -2,20 +2,20 @@ // RUN: dxil-pc-shadermodel6.3-library %s -fnative-half-type \ // RUN: -emit-llvm -disable-llvm-passes -o - | FileCheck %s \ // RUN: --check-prefixes=CHECK,NATIVE_HALF \ -// RUN: -DFNATTRS="noundef nofpclass(nan inf)" -DTARGET=dx +// RUN: -DFNATTRS="hidden noundef nofpclass(nan inf)" -DTARGET=dx // RUN: %clang_cc1 -finclude-default-header -x hlsl -triple \ // RUN: dxil-pc-shadermodel6.3-library %s -emit-llvm -disable-llvm-passes \ // RUN: -o - | FileCheck %s --check-prefixes=CHECK,NO_HALF \ -// RUN: -DFNATTRS="noundef nofpclass(nan inf)" -DTARGET=dx +// RUN: -DFNATTRS="hidden noundef nofpclass(nan inf)" -DTARGET=dx // RUN: %clang_cc1 -finclude-default-header -x hlsl -triple \ // RUN: spirv-unknown-vulkan-compute %s -fnative-half-type \ // RUN: -emit-llvm -disable-llvm-passes -o - | FileCheck %s \ // RUN: --check-prefixes=CHECK,NATIVE_HALF \ -// RUN: -DFNATTRS="spir_func noundef nofpclass(nan inf)" -DTARGET=spv +// RUN: -DFNATTRS="hidden spir_func noundef nofpclass(nan inf)" -DTARGET=spv // RUN: %clang_cc1 -finclude-default-header -x hlsl -triple \ // RUN: spirv-unknown-vulkan-compute %s -emit-llvm -disable-llvm-passes \ // RUN: -o - | FileCheck %s --check-prefixes=CHECK,NO_HALF \ -// RUN: -DFNATTRS="spir_func noundef nofpclass(nan inf)" -DTARGET=spv +// RUN: -DFNATTRS="hidden spir_func noundef nofpclass(nan inf)" -DTARGET=spv // NATIVE_HALF: define [[FNATTRS]] half @ // NATIVE_HALF: call reassoc nnan ninf nsz arcp afn half @llvm.[[TARGET]].normalize.f16(half diff --git a/external/llvm-project/clang/test/CodeGenHLSL/builtins/or.hlsl b/external/llvm-project/clang/test/CodeGenHLSL/builtins/or.hlsl index 69c57c5455f7..66cc5572a75b 100644 --- a/external/llvm-project/clang/test/CodeGenHLSL/builtins/or.hlsl +++ b/external/llvm-project/clang/test/CodeGenHLSL/builtins/or.hlsl @@ -2,7 +2,7 @@ // RUN: dxil-pc-shadermodel6.3-library %s \ // RUN: -emit-llvm -disable-llvm-passes -o - | FileCheck %s -//CHECK-LABEL: define noundef i1 @_Z14test_or_scalarbb( +//CHECK-LABEL: define hidden noundef i1 @_Z14test_or_scalarbb( //CHECK-SAME: i1 noundef [[X:%.*]], i1 noundef [[Y:%.*]]) #[[ATTR0:[0-9]+]] { //CHECK-NEXT: entry: //CHECK: [[HLSL_OR:%.*]] = or i1 [[A:%.*]], [[B:%.*]] @@ -12,7 +12,7 @@ bool test_or_scalar(bool x, bool y) return or(x, y); } -//CHECK-LABEL: define noundef <2 x i1> @_Z13test_or_bool2Dv2_bS_( +//CHECK-LABEL: define hidden noundef <2 x i1> @_Z13test_or_bool2Dv2_bS_( //CHECK-SAME: <2 x i1> noundef [[X:%.*]], <2 x i1> noundef [[Y:%.*]]) #[[ATTR0]] { //CHECK-NEXT: entry: //CHECK: [[HLSL_OR:%.*]] = or <2 x i1> [[A:%.*]], [[B:%.*]] @@ -22,7 +22,7 @@ bool2 test_or_bool2(bool2 x, bool2 y) return or(x, y); } -//CHECK-LABEL: define noundef <3 x i1> @_Z13test_or_bool3Dv3_bS_( +//CHECK-LABEL: define hidden noundef <3 x i1> @_Z13test_or_bool3Dv3_bS_( //CHECK-SAME: <3 x i1> noundef [[X:%.*]], <3 x i1> noundef [[Y:%.*]]) #[[ATTR0]] { //CHECK-NEXT: entry: //CHECK: [[HLSL_OR:%.*]] = or <3 x i1> [[A:%.*]], [[B:%.*]] @@ -32,7 +32,7 @@ bool3 test_or_bool3(bool3 x, bool3 y) return or(x, y); } -//CHECK-LABEL: define noundef <4 x i1> @_Z13test_or_bool4Dv4_bS_( +//CHECK-LABEL: define hidden noundef <4 x i1> @_Z13test_or_bool4Dv4_bS_( //CHECK-SAME: <4 x i1> noundef [[X:%.*]], <4 x i1> noundef [[Y:%.*]]) #[[ATTR0]] { //CHECK-NEXT: entry: //CHECK: [[HLSL_OR:%.*]] = or <4 x i1> [[A:%.*]], [[B:%.*]] @@ -42,7 +42,7 @@ bool4 test_or_bool4(bool4 x, bool4 y) return or(x, y); } -//CHECK-LABEL: define noundef i1 @_Z11test_or_intii( +//CHECK-LABEL: define hidden noundef i1 @_Z11test_or_intii( //CHECK-SAME: i32 noundef [[X:%.*]], i32 noundef [[Y:%.*]]) #[[ATTR0]] { //CHECK-NEXT: entry: //CHECK: [[TOBBOL:%.*]] = icmp ne i32 [[A:%.*]], 0 @@ -54,7 +54,7 @@ bool test_or_int(int x, int y) return or(x, y); } -//CHECK-LABEL: define noundef <4 x i1> @_Z12test_or_int4Dv4_iS_( +//CHECK-LABEL: define hidden noundef <4 x i1> @_Z12test_or_int4Dv4_iS_( //CHECK-SAME: <4 x i32> noundef [[X:%.*]], <4 x i32> noundef [[Y:%.*]]) #[[ATTR0]] { //CHECK-NEXT: entry: //CHECK: [[TOBOOL:%.*]] = icmp ne <4 x i32> [[A:%.*]], zeroinitializer @@ -66,7 +66,7 @@ bool4 test_or_int4(int4 x, int4 y) return or(x, y); } -//CHECK-LABEL: define noundef <4 x i1> @_Z14test_or_float4Dv4_fS_( +//CHECK-LABEL: define hidden noundef <4 x i1> @_Z14test_or_float4Dv4_fS_( //CHECK-SAME: <4 x float> noundef nofpclass(nan inf) [[X:%.*]], <4 x float> noundef nofpclass(nan inf) [[Y:%.*]]) #[[ATTR0]] { //CHECK-NEXT: entry: //CHECK: [[TOBOOL:%.*]] = fcmp reassoc nnan ninf nsz arcp afn une <4 x float> [[A:%.*]], zeroinitializer diff --git a/external/llvm-project/clang/test/CodeGenHLSL/builtins/pow-overloads.hlsl b/external/llvm-project/clang/test/CodeGenHLSL/builtins/pow-overloads.hlsl index 39003aef7b7b..0d1f3d3546a3 100644 --- a/external/llvm-project/clang/test/CodeGenHLSL/builtins/pow-overloads.hlsl +++ b/external/llvm-project/clang/test/CodeGenHLSL/builtins/pow-overloads.hlsl @@ -2,125 +2,125 @@ // RUN: -emit-llvm -o - | FileCheck %s --check-prefixes=CHECK \ // RUN: -DFLOATATTRS="reassoc nnan ninf nsz arcp afn" -// CHECK-LABEL: define noundef nofpclass(nan inf) float {{.*}}test_pow_double +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) float {{.*}}test_pow_double // CHECK: [[CONV0:%.*]] = fptrunc [[FLOATATTRS]] double %{{.*}} to float // CHECK: [[CONV1:%.*]] = fptrunc [[FLOATATTRS]] double %{{.*}} to float // CHECK: [[POW:%.*]] = call [[FLOATATTRS]] noundef float @llvm.pow.f32(float [[CONV0]], float [[CONV1]]) // CHECK: ret float [[POW]] float test_pow_double(double p0, double p1) { return pow(p0, p1); } -// CHECK-LABEL: define noundef nofpclass(nan inf) <2 x float> {{.*}}test_pow_double2 +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) <2 x float> {{.*}}test_pow_double2 // CHECK: [[CONV0:%.*]] = fptrunc [[FLOATATTRS]] <2 x double> %{{.*}} to <2 x float> // CHECK: [[CONV1:%.*]] = fptrunc [[FLOATATTRS]] <2 x double> %{{.*}} to <2 x float> // CHECK: [[POW:%.*]] = call [[FLOATATTRS]] noundef <2 x float> @llvm.pow.v2f32(<2 x float> [[CONV0]], <2 x float> [[CONV1]]) // CHECK: ret <2 x float> [[POW]] float2 test_pow_double2(double2 p0, double2 p1) { return pow(p0, p1); } -// CHECK-LABEL: define noundef nofpclass(nan inf) <3 x float> {{.*}}test_pow_double3 +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) <3 x float> {{.*}}test_pow_double3 // CHECK: [[CONV0:%.*]] = fptrunc [[FLOATATTRS]] <3 x double> %{{.*}} to <3 x float> // CHECK: [[CONV1:%.*]] = fptrunc [[FLOATATTRS]] <3 x double> %{{.*}} to <3 x float> // CHECK: [[POW:%.*]] = call [[FLOATATTRS]] noundef <3 x float> @llvm.pow.v3f32(<3 x float> [[CONV0]], <3 x float> [[CONV1]]) // CHECK: ret <3 x float> [[POW]] float3 test_pow_double3(double3 p0, double3 p1) { return pow(p0, p1); } -// CHECK-LABEL: define noundef nofpclass(nan inf) <4 x float> {{.*}}test_pow_double4 +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) <4 x float> {{.*}}test_pow_double4 // CHECK: [[CONV0:%.*]] = fptrunc [[FLOATATTRS]] <4 x double> %{{.*}} to <4 x float> // CHECK: [[CONV1:%.*]] = fptrunc [[FLOATATTRS]] <4 x double> %{{.*}} to <4 x float> // CHECK: [[POW:%.*]] = call [[FLOATATTRS]] noundef <4 x float> @llvm.pow.v4f32(<4 x float> [[CONV0]], <4 x float> [[CONV1]]) // CHECK: ret <4 x float> [[POW]] float4 test_pow_double4(double4 p0, double4 p1) { return pow(p0, p1); } -// CHECK-LABEL: define noundef nofpclass(nan inf) float {{.*}}test_pow_int +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) float {{.*}}test_pow_int // CHECK: [[CONV0:%.*]] = sitofp i32 %{{.*}} to float // CHECK: [[CONV1:%.*]] = sitofp i32 %{{.*}} to float // CHECK: [[POW:%.*]] = call [[FLOATATTRS]] noundef float @llvm.pow.f32(float [[CONV0]], float [[CONV1]]) // CHECK: ret float [[POW]] float test_pow_int(int p0, int p1) { return pow(p0, p1); } -// CHECK-LABEL: define noundef nofpclass(nan inf) <2 x float> {{.*}}test_pow_int2 +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) <2 x float> {{.*}}test_pow_int2 // CHECK: [[CONV0:%.*]] = sitofp <2 x i32> %{{.*}} to <2 x float> // CHECK: [[CONV1:%.*]] = sitofp <2 x i32> %{{.*}} to <2 x float> // CHECK: [[POW:%.*]] = call [[FLOATATTRS]] noundef <2 x float> @llvm.pow.v2f32(<2 x float> [[CONV0]], <2 x float> [[CONV1]]) // CHECK: ret <2 x float> [[POW]] float2 test_pow_int2(int2 p0, int2 p1) { return pow(p0, p1); } -// CHECK-LABEL: define noundef nofpclass(nan inf) <3 x float> {{.*}}test_pow_int3 +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) <3 x float> {{.*}}test_pow_int3 // CHECK: [[CONV0:%.*]] = sitofp <3 x i32> %{{.*}} to <3 x float> // CHECK: [[CONV1:%.*]] = sitofp <3 x i32> %{{.*}} to <3 x float> // CHECK: [[POW:%.*]] = call [[FLOATATTRS]] noundef <3 x float> @llvm.pow.v3f32(<3 x float> [[CONV0]], <3 x float> [[CONV1]]) // CHECK: ret <3 x float> [[POW]] float3 test_pow_int3(int3 p0, int3 p1) { return pow(p0, p1); } -// CHECK-LABEL: define noundef nofpclass(nan inf) <4 x float> {{.*}}test_pow_int4 +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) <4 x float> {{.*}}test_pow_int4 // CHECK: [[CONV0:%.*]] = sitofp <4 x i32> %{{.*}} to <4 x float> // CHECK: [[CONV1:%.*]] = sitofp <4 x i32> %{{.*}} to <4 x float> // CHECK: [[POW:%.*]] = call [[FLOATATTRS]] noundef <4 x float> @llvm.pow.v4f32(<4 x float> [[CONV0]], <4 x float> [[CONV1]]) // CHECK: ret <4 x float> [[POW]] float4 test_pow_int4(int4 p0, int4 p1) { return pow(p0, p1); } -// CHECK-LABEL: define noundef nofpclass(nan inf) float {{.*}}test_pow_uint +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) float {{.*}}test_pow_uint // CHECK: [[CONV0:%.*]] = uitofp i32 %{{.*}} to float // CHECK: [[CONV1:%.*]] = uitofp i32 %{{.*}} to float // CHECK: [[POW:%.*]] = call [[FLOATATTRS]] noundef float @llvm.pow.f32(float [[CONV0]], float [[CONV1]]) // CHECK: ret float [[POW]] float test_pow_uint(uint p0, uint p1) { return pow(p0, p1); } -// CHECK-LABEL: define noundef nofpclass(nan inf) <2 x float> {{.*}}test_pow_uint2 +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) <2 x float> {{.*}}test_pow_uint2 // CHECK: [[CONV0:%.*]] = uitofp <2 x i32> %{{.*}} to <2 x float> // CHECK: [[CONV1:%.*]] = uitofp <2 x i32> %{{.*}} to <2 x float> // CHECK: [[POW:%.*]] = call [[FLOATATTRS]] noundef <2 x float> @llvm.pow.v2f32(<2 x float> [[CONV0]], <2 x float> [[CONV1]]) // CHECK: ret <2 x float> [[POW]] float2 test_pow_uint2(uint2 p0, uint2 p1) { return pow(p0, p1); } -// CHECK-LABEL: define noundef nofpclass(nan inf) <3 x float> {{.*}}test_pow_uint3 +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) <3 x float> {{.*}}test_pow_uint3 // CHECK: [[CONV0:%.*]] = uitofp <3 x i32> %{{.*}} to <3 x float> // CHECK: [[CONV1:%.*]] = uitofp <3 x i32> %{{.*}} to <3 x float> // CHECK: [[POW:%.*]] = call [[FLOATATTRS]] noundef <3 x float> @llvm.pow.v3f32(<3 x float> [[CONV0]], <3 x float> [[CONV1]]) // CHECK: ret <3 x float> [[POW]] float3 test_pow_uint3(uint3 p0, uint3 p1) { return pow(p0, p1); } -// CHECK-LABEL: define noundef nofpclass(nan inf) <4 x float> {{.*}}test_pow_uint4 +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) <4 x float> {{.*}}test_pow_uint4 // CHECK: [[CONV0:%.*]] = uitofp <4 x i32> %{{.*}} to <4 x float> // CHECK: [[CONV1:%.*]] = uitofp <4 x i32> %{{.*}} to <4 x float> // CHECK: [[POW:%.*]] = call [[FLOATATTRS]] noundef <4 x float> @llvm.pow.v4f32(<4 x float> [[CONV0]], <4 x float> [[CONV1]]) // CHECK: ret <4 x float> [[POW]] float4 test_pow_uint4(uint4 p0, uint4 p1) { return pow(p0, p1); } -// CHECK-LABEL: define noundef nofpclass(nan inf) float {{.*}}test_pow_int64_t +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) float {{.*}}test_pow_int64_t // CHECK: [[CONV0:%.*]] = sitofp i64 %{{.*}} to float // CHECK: [[CONV1:%.*]] = sitofp i64 %{{.*}} to float // CHECK: [[POW:%.*]] = call [[FLOATATTRS]] noundef float @llvm.pow.f32(float [[CONV0]], float [[CONV1]]) // CHECK: ret float [[POW]] float test_pow_int64_t(int64_t p0, int64_t p1) { return pow(p0, p1); } -// CHECK-LABEL: define noundef nofpclass(nan inf) <2 x float> {{.*}}test_pow_int64_t2 +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) <2 x float> {{.*}}test_pow_int64_t2 // CHECK: [[CONV0:%.*]] = sitofp <2 x i64> %{{.*}} to <2 x float> // CHECK: [[CONV1:%.*]] = sitofp <2 x i64> %{{.*}} to <2 x float> // CHECK: [[POW:%.*]] = call [[FLOATATTRS]] noundef <2 x float> @llvm.pow.v2f32(<2 x float> [[CONV0]], <2 x float> [[CONV1]]) // CHECK: ret <2 x float> [[POW]] float2 test_pow_int64_t2(int64_t2 p0, int64_t2 p1) { return pow(p0, p1); } -// CHECK-LABEL: define noundef nofpclass(nan inf) <3 x float> {{.*}}test_pow_int64_t3 +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) <3 x float> {{.*}}test_pow_int64_t3 // CHECK: [[CONV0:%.*]] = sitofp <3 x i64> %{{.*}} to <3 x float> // CHECK: [[CONV1:%.*]] = sitofp <3 x i64> %{{.*}} to <3 x float> // CHECK: [[POW:%.*]] = call [[FLOATATTRS]] noundef <3 x float> @llvm.pow.v3f32(<3 x float> [[CONV0]], <3 x float> [[CONV1]]) // CHECK: ret <3 x float> [[POW]] float3 test_pow_int64_t3(int64_t3 p0, int64_t3 p1) { return pow(p0, p1); } -// CHECK-LABEL: define noundef nofpclass(nan inf) <4 x float> {{.*}}test_pow_int64_t4 +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) <4 x float> {{.*}}test_pow_int64_t4 // CHECK: [[CONV0:%.*]] = sitofp <4 x i64> %{{.*}} to <4 x float> // CHECK: [[CONV1:%.*]] = sitofp <4 x i64> %{{.*}} to <4 x float> // CHECK: [[POW:%.*]] = call [[FLOATATTRS]] noundef <4 x float> @llvm.pow.v4f32(<4 x float> [[CONV0]], <4 x float> [[CONV1]]) // CHECK: ret <4 x float> [[POW]] float4 test_pow_int64_t4(int64_t4 p0, int64_t4 p1) { return pow(p0, p1); } -// CHECK-LABEL: define noundef nofpclass(nan inf) float {{.*}}test_pow_uint64_t +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) float {{.*}}test_pow_uint64_t // CHECK: [[CONV0:%.*]] = uitofp i64 %{{.*}} to float // CHECK: [[CONV1:%.*]] = uitofp i64 %{{.*}} to float // CHECK: [[POW:%.*]] = call [[FLOATATTRS]] noundef float @llvm.pow.f32(float [[CONV0]], float [[CONV1]]) // CHECK: ret float [[POW]] float test_pow_uint64_t(uint64_t p0, uint64_t p1) { return pow(p0, p1); } -// CHECK-LABEL: define noundef nofpclass(nan inf) <2 x float> {{.*}}test_pow_uint64_t2 +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) <2 x float> {{.*}}test_pow_uint64_t2 // CHECK: [[CONV0:%.*]] = uitofp <2 x i64> %{{.*}} to <2 x float> // CHECK: [[CONV1:%.*]] = uitofp <2 x i64> %{{.*}} to <2 x float> // CHECK: [[POW:%.*]] = call [[FLOATATTRS]] noundef <2 x float> @llvm.pow.v2f32(<2 x float> [[CONV0]], <2 x float> [[CONV1]]) // CHECK: ret <2 x float> [[POW]] float2 test_pow_uint64_t2(uint64_t2 p0, uint64_t2 p1) { return pow(p0, p1); } -// CHECK-LABEL: define noundef nofpclass(nan inf) <3 x float> {{.*}}test_pow_uint64_t3 +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) <3 x float> {{.*}}test_pow_uint64_t3 // CHECK: [[CONV0:%.*]] = uitofp <3 x i64> %{{.*}} to <3 x float> // CHECK: [[CONV1:%.*]] = uitofp <3 x i64> %{{.*}} to <3 x float> // CHECK: [[POW:%.*]] = call [[FLOATATTRS]] noundef <3 x float> @llvm.pow.v3f32(<3 x float> [[CONV0]], <3 x float> [[CONV1]]) // CHECK: ret <3 x float> [[POW]] float3 test_pow_uint64_t3(uint64_t3 p0, uint64_t3 p1) { return pow(p0, p1); } -// CHECK-LABEL: define noundef nofpclass(nan inf) <4 x float> {{.*}}test_pow_uint64_t4 +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) <4 x float> {{.*}}test_pow_uint64_t4 // CHECK: [[CONV0:%.*]] = uitofp <4 x i64> %{{.*}} to <4 x float> // CHECK: [[CONV1:%.*]] = uitofp <4 x i64> %{{.*}} to <4 x float> // CHECK: [[POW:%.*]] = call [[FLOATATTRS]] noundef <4 x float> @llvm.pow.v4f32(<4 x float> [[CONV0]], <4 x float> [[CONV1]]) diff --git a/external/llvm-project/clang/test/CodeGenHLSL/builtins/pow.hlsl b/external/llvm-project/clang/test/CodeGenHLSL/builtins/pow.hlsl index fd21f1b94c57..fcde755e15fc 100644 --- a/external/llvm-project/clang/test/CodeGenHLSL/builtins/pow.hlsl +++ b/external/llvm-project/clang/test/CodeGenHLSL/builtins/pow.hlsl @@ -5,36 +5,36 @@ // RUN: -emit-llvm -disable-llvm-passes -o - | \ // RUN: FileCheck %s --check-prefixes=CHECK,NO_HALF -// NATIVE_HALF-LABEL: define noundef nofpclass(nan inf) half @_Z13test_pow_half +// NATIVE_HALF-LABEL: define hidden noundef nofpclass(nan inf) half @_Z13test_pow_half // NATIVE_HALF: call reassoc nnan ninf nsz arcp afn half @llvm.pow.f16( -// NO_HALF-LABEL: define noundef nofpclass(nan inf) float @_Z13test_pow_half +// NO_HALF-LABEL: define hidden noundef nofpclass(nan inf) float @_Z13test_pow_half // NO_HALF: call reassoc nnan ninf nsz arcp afn float @llvm.pow.f32( half test_pow_half(half p0, half p1) { return pow(p0, p1); } -// NATIVE_HALF-LABEL: define noundef nofpclass(nan inf) <2 x half> @_Z14test_pow_half2 +// NATIVE_HALF-LABEL: define hidden noundef nofpclass(nan inf) <2 x half> @_Z14test_pow_half2 // NATIVE_HALF: call reassoc nnan ninf nsz arcp afn <2 x half> @llvm.pow.v2f16 -// NO_HALF-LABEL: define noundef nofpclass(nan inf) <2 x float> @_Z14test_pow_half2 +// NO_HALF-LABEL: define hidden noundef nofpclass(nan inf) <2 x float> @_Z14test_pow_half2 // NO_HALF: call reassoc nnan ninf nsz arcp afn <2 x float> @llvm.pow.v2f32( half2 test_pow_half2(half2 p0, half2 p1) { return pow(p0, p1); } -// NATIVE_HALF-LABEL: define noundef nofpclass(nan inf) <3 x half> @_Z14test_pow_half3 +// NATIVE_HALF-LABEL: define hidden noundef nofpclass(nan inf) <3 x half> @_Z14test_pow_half3 // NATIVE_HALF: call reassoc nnan ninf nsz arcp afn <3 x half> @llvm.pow.v3f16 -// NO_HALF-LABEL: define noundef nofpclass(nan inf) <3 x float> @_Z14test_pow_half3 +// NO_HALF-LABEL: define hidden noundef nofpclass(nan inf) <3 x float> @_Z14test_pow_half3 // NO_HALF: call reassoc nnan ninf nsz arcp afn <3 x float> @llvm.pow.v3f32( half3 test_pow_half3(half3 p0, half3 p1) { return pow(p0, p1); } -// NATIVE_HALF-LABEL: define noundef nofpclass(nan inf) <4 x half> @_Z14test_pow_half4 +// NATIVE_HALF-LABEL: define hidden noundef nofpclass(nan inf) <4 x half> @_Z14test_pow_half4 // NATIVE_HALF: call reassoc nnan ninf nsz arcp afn <4 x half> @llvm.pow.v4f16 -// NO_HALF-LABEL: define noundef nofpclass(nan inf) <4 x float> @_Z14test_pow_half4 +// NO_HALF-LABEL: define hidden noundef nofpclass(nan inf) <4 x float> @_Z14test_pow_half4 // NO_HALF: call reassoc nnan ninf nsz arcp afn <4 x float> @llvm.pow.v4f32( half4 test_pow_half4(half4 p0, half4 p1) { return pow(p0, p1); } -// CHECK-LABEL: define noundef nofpclass(nan inf) float @_Z14test_pow_float +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) float @_Z14test_pow_float // CHECK: call reassoc nnan ninf nsz arcp afn float @llvm.pow.f32( float test_pow_float(float p0, float p1) { return pow(p0, p1); } -// CHECK-LABEL: define noundef nofpclass(nan inf) <2 x float> @_Z15test_pow_float2 +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) <2 x float> @_Z15test_pow_float2 // CHECK: call reassoc nnan ninf nsz arcp afn <2 x float> @llvm.pow.v2f32 float2 test_pow_float2(float2 p0, float2 p1) { return pow(p0, p1); } -// CHECK-LABEL: define noundef nofpclass(nan inf) <3 x float> @_Z15test_pow_float3 +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) <3 x float> @_Z15test_pow_float3 // CHECK: call reassoc nnan ninf nsz arcp afn <3 x float> @llvm.pow.v3f32 float3 test_pow_float3(float3 p0, float3 p1) { return pow(p0, p1); } -// CHECK-LABEL: define noundef nofpclass(nan inf) <4 x float> @_Z15test_pow_float4 +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) <4 x float> @_Z15test_pow_float4 // CHECK: call reassoc nnan ninf nsz arcp afn <4 x float> @llvm.pow.v4f32 float4 test_pow_float4(float4 p0, float4 p1) { return pow(p0, p1); } diff --git a/external/llvm-project/clang/test/CodeGenHLSL/builtins/radians-overloads.hlsl b/external/llvm-project/clang/test/CodeGenHLSL/builtins/radians-overloads.hlsl index d0cfc7b60265..4b12f590edcd 100644 --- a/external/llvm-project/clang/test/CodeGenHLSL/builtins/radians-overloads.hlsl +++ b/external/llvm-project/clang/test/CodeGenHLSL/builtins/radians-overloads.hlsl @@ -1,11 +1,11 @@ // RUN: %clang_cc1 -std=hlsl202x -finclude-default-header -x hlsl -triple \ // RUN: dxil-pc-shadermodel6.3-library %s -emit-llvm -disable-llvm-passes \ // RUN: -o - | FileCheck %s --check-prefixes=CHECK \ -// RUN: -DTARGET=dx -DFNATTRS="noundef nofpclass(nan inf)" +// RUN: -DTARGET=dx -DFNATTRS="hidden noundef nofpclass(nan inf)" // RUN: %clang_cc1 -std=hlsl202x -finclude-default-header -x hlsl -triple \ // RUN: spirv-unknown-vulkan-compute %s -emit-llvm -disable-llvm-passes \ // RUN: -o - | FileCheck %s --check-prefixes=CHECK \ -// RUN: -DTARGET=spv -DFNATTRS="spir_func noundef nofpclass(nan inf)" +// RUN: -DTARGET=spv -DFNATTRS="hidden spir_func noundef nofpclass(nan inf)" // CHECK: define [[FNATTRS]] float @ // CHECK: %{{.*}} = call reassoc nnan ninf nsz arcp afn float @llvm.[[TARGET]].radians.f32( diff --git a/external/llvm-project/clang/test/CodeGenHLSL/builtins/radians.hlsl b/external/llvm-project/clang/test/CodeGenHLSL/builtins/radians.hlsl index efdeb9f6e142..f281747fbf29 100644 --- a/external/llvm-project/clang/test/CodeGenHLSL/builtins/radians.hlsl +++ b/external/llvm-project/clang/test/CodeGenHLSL/builtins/radians.hlsl @@ -2,20 +2,20 @@ // RUN: dxil-pc-shadermodel6.3-library %s -fnative-half-type \ // RUN: -emit-llvm -disable-llvm-passes -o - | FileCheck %s \ // RUN: --check-prefixes=CHECK,NATIVE_HALF \ -// RUN: -DTARGET=dx -DFNATTRS="noundef nofpclass(nan inf)" +// RUN: -DTARGET=dx -DFNATTRS="hidden noundef nofpclass(nan inf)" // RUN: %clang_cc1 -finclude-default-header -x hlsl -triple \ // RUN: dxil-pc-shadermodel6.3-library %s -emit-llvm -disable-llvm-passes \ // RUN: -o - | FileCheck %s --check-prefixes=CHECK,NO_HALF \ -// RUN: -DTARGET=dx -DFNATTRS="noundef nofpclass(nan inf)" +// RUN: -DTARGET=dx -DFNATTRS="hidden noundef nofpclass(nan inf)" // RUN: %clang_cc1 -finclude-default-header -x hlsl -triple \ // RUN: spirv-unknown-vulkan-compute %s -fnative-half-type \ // RUN: -emit-llvm -disable-llvm-passes -o - | FileCheck %s \ // RUN: --check-prefixes=CHECK,NATIVE_HALF \ -// RUN: -DTARGET=spv -DFNATTRS="spir_func noundef nofpclass(nan inf)" +// RUN: -DTARGET=spv -DFNATTRS="hidden spir_func noundef nofpclass(nan inf)" // RUN: %clang_cc1 -finclude-default-header -x hlsl -triple \ // RUN: spirv-unknown-vulkan-compute %s -emit-llvm -disable-llvm-passes \ // RUN: -o - | FileCheck %s --check-prefixes=CHECK,NO_HALF \ -// RUN: -DTARGET=spv -DFNATTRS="spir_func noundef nofpclass(nan inf)" +// RUN: -DTARGET=spv -DFNATTRS="hidden spir_func noundef nofpclass(nan inf)" // NATIVE_HALF: define [[FNATTRS]] half @ diff --git a/external/llvm-project/clang/test/CodeGenHLSL/builtins/rcp.hlsl b/external/llvm-project/clang/test/CodeGenHLSL/builtins/rcp.hlsl index 8f07f3a03153..cdfaa3c5f1ee 100644 --- a/external/llvm-project/clang/test/CodeGenHLSL/builtins/rcp.hlsl +++ b/external/llvm-project/clang/test/CodeGenHLSL/builtins/rcp.hlsl @@ -13,90 +13,90 @@ // RUN: spirv-unknown-vulkan-compute %s -emit-llvm -disable-llvm-passes \ // RUN: -o - | FileCheck %s --check-prefixes=CHECK,NO_HALF,SPIR_NO_HALF,SPIR_CHECK -// DXIL_NATIVE_HALF: define noundef nofpclass(nan inf) half @ -// SPIR_NATIVE_HALF: define spir_func noundef nofpclass(nan inf) half @ +// DXIL_NATIVE_HALF: define hidden noundef nofpclass(nan inf) half @ +// SPIR_NATIVE_HALF: define hidden spir_func noundef nofpclass(nan inf) half @ // NATIVE_HALF: %hlsl.rcp = fdiv reassoc nnan ninf nsz arcp afn half 0xH3C00, %{{.*}} // NATIVE_HALF: ret half %hlsl.rcp -// DXIL_NO_HALF: define noundef nofpclass(nan inf) float @ -// SPIR_NO_HALF: define spir_func noundef nofpclass(nan inf) float @ +// DXIL_NO_HALF: define hidden noundef nofpclass(nan inf) float @ +// SPIR_NO_HALF: define hidden spir_func noundef nofpclass(nan inf) float @ // NO_HALF: %hlsl.rcp = fdiv reassoc nnan ninf nsz arcp afn float 1.000000e+00, %{{.*}} // NO_HALF: ret float %hlsl.rcp half test_rcp_half(half p0) { return rcp(p0); } -// DXIL_NATIVE_HALF: define noundef nofpclass(nan inf) <2 x half> @ -// SPIR_NATIVE_HALF: define spir_func noundef nofpclass(nan inf) <2 x half> @ +// DXIL_NATIVE_HALF: define hidden noundef nofpclass(nan inf) <2 x half> @ +// SPIR_NATIVE_HALF: define hidden spir_func noundef nofpclass(nan inf) <2 x half> @ // NATIVE_HALF: %hlsl.rcp = fdiv reassoc nnan ninf nsz arcp afn <2 x half> splat (half 0xH3C00), %{{.*}} // NATIVE_HALF: ret <2 x half> %hlsl.rcp -// DXIL_NO_HALF: define noundef nofpclass(nan inf) <2 x float> @ -// SPIR_NO_HALF: define spir_func noundef nofpclass(nan inf) <2 x float> @ +// DXIL_NO_HALF: define hidden noundef nofpclass(nan inf) <2 x float> @ +// SPIR_NO_HALF: define hidden spir_func noundef nofpclass(nan inf) <2 x float> @ // NO_HALF: %hlsl.rcp = fdiv reassoc nnan ninf nsz arcp afn <2 x float> splat (float 1.000000e+00), %{{.*}} // NO_HALF: ret <2 x float> %hlsl.rcp half2 test_rcp_half2(half2 p0) { return rcp(p0); } -// DXIL_NATIVE_HALF: define noundef nofpclass(nan inf) <3 x half> @ -// SPIR_NATIVE_HALF: define spir_func noundef nofpclass(nan inf) <3 x half> @ +// DXIL_NATIVE_HALF: define hidden noundef nofpclass(nan inf) <3 x half> @ +// SPIR_NATIVE_HALF: define hidden spir_func noundef nofpclass(nan inf) <3 x half> @ // NATIVE_HALF: %hlsl.rcp = fdiv reassoc nnan ninf nsz arcp afn <3 x half> splat (half 0xH3C00), %{{.*}} // NATIVE_HALF: ret <3 x half> %hlsl.rcp -// DXIL_NO_HALF: define noundef nofpclass(nan inf) <3 x float> @ -// SPIR_NO_HALF: define spir_func noundef nofpclass(nan inf) <3 x float> @ +// DXIL_NO_HALF: define hidden noundef nofpclass(nan inf) <3 x float> @ +// SPIR_NO_HALF: define hidden spir_func noundef nofpclass(nan inf) <3 x float> @ // NO_HALF: %hlsl.rcp = fdiv reassoc nnan ninf nsz arcp afn <3 x float> splat (float 1.000000e+00), %{{.*}} // NO_HALF: ret <3 x float> %hlsl.rcp half3 test_rcp_half3(half3 p0) { return rcp(p0); } -// DXIL_NATIVE_HALF: define noundef nofpclass(nan inf) <4 x half> @ -// SPIR_NATIVE_HALF: define spir_func noundef nofpclass(nan inf) <4 x half> @ +// DXIL_NATIVE_HALF: define hidden noundef nofpclass(nan inf) <4 x half> @ +// SPIR_NATIVE_HALF: define hidden spir_func noundef nofpclass(nan inf) <4 x half> @ // NATIVE_HALF: %hlsl.rcp = fdiv reassoc nnan ninf nsz arcp afn <4 x half> splat (half 0xH3C00), %{{.*}} // NATIVE_HALF: ret <4 x half> %hlsl.rcp -// DXIL_NO_HALF: define noundef nofpclass(nan inf) <4 x float> @ -// SPIR_NO_HALF: define spir_func noundef nofpclass(nan inf) <4 x float> @ +// DXIL_NO_HALF: define hidden noundef nofpclass(nan inf) <4 x float> @ +// SPIR_NO_HALF: define hidden spir_func noundef nofpclass(nan inf) <4 x float> @ // NO_HALF: %hlsl.rcp = fdiv reassoc nnan ninf nsz arcp afn <4 x float> splat (float 1.000000e+00), %{{.*}} // NO_HALF: ret <4 x float> %hlsl.rcp half4 test_rcp_half4(half4 p0) { return rcp(p0); } -// DXIL_CHECK: define noundef nofpclass(nan inf) float @ -// SPIR_CHECK: define spir_func noundef nofpclass(nan inf) float @ +// DXIL_CHECK: define hidden noundef nofpclass(nan inf) float @ +// SPIR_CHECK: define hidden spir_func noundef nofpclass(nan inf) float @ // CHECK: %hlsl.rcp = fdiv reassoc nnan ninf nsz arcp afn float 1.000000e+00, %{{.*}} // CHECK: ret float %hlsl.rcp float test_rcp_float(float p0) { return rcp(p0); } -// DXIL_CHECK: define noundef nofpclass(nan inf) <2 x float> @ -// SPIR_CHECK: define spir_func noundef nofpclass(nan inf) <2 x float> @ +// DXIL_CHECK: define hidden noundef nofpclass(nan inf) <2 x float> @ +// SPIR_CHECK: define hidden spir_func noundef nofpclass(nan inf) <2 x float> @ // CHECK: %hlsl.rcp = fdiv reassoc nnan ninf nsz arcp afn <2 x float> splat (float 1.000000e+00), %{{.*}} // CHECK: ret <2 x float> %hlsl.rcp float2 test_rcp_float2(float2 p0) { return rcp(p0); } -// DXIL_CHECK: define noundef nofpclass(nan inf) <3 x float> @ -// SPIR_CHECK: define spir_func noundef nofpclass(nan inf) <3 x float> @ +// DXIL_CHECK: define hidden noundef nofpclass(nan inf) <3 x float> @ +// SPIR_CHECK: define hidden spir_func noundef nofpclass(nan inf) <3 x float> @ // CHECK: %hlsl.rcp = fdiv reassoc nnan ninf nsz arcp afn <3 x float> splat (float 1.000000e+00), %{{.*}} // CHECK: ret <3 x float> %hlsl.rcp float3 test_rcp_float3(float3 p0) { return rcp(p0); } -// DXIL_CHECK: define noundef nofpclass(nan inf) <4 x float> @ -// SPIR_CHECK: define spir_func noundef nofpclass(nan inf) <4 x float> @ +// DXIL_CHECK: define hidden noundef nofpclass(nan inf) <4 x float> @ +// SPIR_CHECK: define hidden spir_func noundef nofpclass(nan inf) <4 x float> @ // CHECK: %hlsl.rcp = fdiv reassoc nnan ninf nsz arcp afn <4 x float> splat (float 1.000000e+00), %{{.*}} // CHECK: ret <4 x float> %hlsl.rcp float4 test_rcp_float4(float4 p0) { return rcp(p0); } -// DXIL_CHECK: define noundef nofpclass(nan inf) double @ -// SPIR_CHECK: define spir_func noundef nofpclass(nan inf) double @ +// DXIL_CHECK: define hidden noundef nofpclass(nan inf) double @ +// SPIR_CHECK: define hidden spir_func noundef nofpclass(nan inf) double @ // CHECK: %hlsl.rcp = fdiv reassoc nnan ninf nsz arcp afn double 1.000000e+00, %{{.*}} // CHECK: ret double %hlsl.rcp double test_rcp_double(double p0) { return rcp(p0); } -// DXIL_CHECK: define noundef nofpclass(nan inf) <2 x double> @ -// SPIR_CHECK: define spir_func noundef nofpclass(nan inf) <2 x double> @ +// DXIL_CHECK: define hidden noundef nofpclass(nan inf) <2 x double> @ +// SPIR_CHECK: define hidden spir_func noundef nofpclass(nan inf) <2 x double> @ // CHECK: %hlsl.rcp = fdiv reassoc nnan ninf nsz arcp afn <2 x double> splat (double 1.000000e+00), %{{.*}} // CHECK: ret <2 x double> %hlsl.rcp double2 test_rcp_double2(double2 p0) { return rcp(p0); } -// DXIL_CHECK: define noundef nofpclass(nan inf) <3 x double> @ -// SPIR_CHECK: define spir_func noundef nofpclass(nan inf) <3 x double> @ +// DXIL_CHECK: define hidden noundef nofpclass(nan inf) <3 x double> @ +// SPIR_CHECK: define hidden spir_func noundef nofpclass(nan inf) <3 x double> @ // CHECK: %hlsl.rcp = fdiv reassoc nnan ninf nsz arcp afn <3 x double> splat (double 1.000000e+00), %{{.*}} // CHECK: ret <3 x double> %hlsl.rcp double3 test_rcp_double3(double3 p0) { return rcp(p0); } -// DXIL_CHECK: define noundef nofpclass(nan inf) <4 x double> @ -// SPIR_CHECK: define spir_func noundef nofpclass(nan inf) <4 x double> @ +// DXIL_CHECK: define hidden noundef nofpclass(nan inf) <4 x double> @ +// SPIR_CHECK: define hidden spir_func noundef nofpclass(nan inf) <4 x double> @ // CHECK: %hlsl.rcp = fdiv reassoc nnan ninf nsz arcp afn <4 x double> splat (double 1.000000e+00), %{{.*}} // CHECK: ret <4 x double> %hlsl.rcp double4 test_rcp_double4(double4 p0) { return rcp(p0); } diff --git a/external/llvm-project/clang/test/CodeGenHLSL/builtins/reflect.hlsl b/external/llvm-project/clang/test/CodeGenHLSL/builtins/reflect.hlsl index c082e63ac1da..65fefd801ffe 100644 --- a/external/llvm-project/clang/test/CodeGenHLSL/builtins/reflect.hlsl +++ b/external/llvm-project/clang/test/CodeGenHLSL/builtins/reflect.hlsl @@ -6,7 +6,7 @@ // RUN: spirv-unknown-vulkan-compute %s -fnative-half-type \ // RUN: -emit-llvm -O1 -o - | FileCheck %s --check-prefix=SPVCHECK -// CHECK-LABEL: define noundef nofpclass(nan inf) half @_Z17test_reflect_halfDhDh( +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) half @_Z17test_reflect_halfDhDh( // CHECK-SAME: half noundef nofpclass(nan inf) [[I:%.*]], half noundef nofpclass(nan inf) [[N:%.*]]) local_unnamed_addr #[[ATTR0:[0-9]+]] { // CHECK-NEXT: [[ENTRY:.*:]] // CHECK-NEXT: [[MUL_I:%.*]] = fmul reassoc nnan ninf nsz arcp afn half [[I]], 0xH4000 @@ -15,7 +15,7 @@ // CHECK-NEXT: [[SUB_I:%.*]] = fsub reassoc nnan ninf nsz arcp afn half [[I]], [[MUL2_I]] // CHECK-NEXT: ret half [[SUB_I]] // -// SPVCHECK-LABEL: define spir_func noundef nofpclass(nan inf) half @_Z17test_reflect_halfDhDh( +// SPVCHECK-LABEL: define hidden spir_func noundef nofpclass(nan inf) half @_Z17test_reflect_halfDhDh( // SPVCHECK-SAME: half noundef nofpclass(nan inf) [[I:%.*]], half noundef nofpclass(nan inf) [[N:%.*]]) local_unnamed_addr #[[ATTR0:[0-9]+]] { // SPVCHECK-NEXT: [[ENTRY:.*:]] // SPVCHECK-NEXT: [[MUL_I:%.*]] = fmul reassoc nnan ninf nsz arcp afn half [[I]], 0xH4000 @@ -28,7 +28,7 @@ half test_reflect_half(half I, half N) { return reflect(I, N); } -// CHECK-LABEL: define noundef nofpclass(nan inf) <2 x half> @_Z18test_reflect_half2Dv2_DhS_( +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) <2 x half> @_Z18test_reflect_half2Dv2_DhS_( // CHECK-SAME: <2 x half> noundef nofpclass(nan inf) [[I:%.*]], <2 x half> noundef nofpclass(nan inf) [[N:%.*]]) local_unnamed_addr #[[ATTR0]] { // CHECK-NEXT: [[ENTRY:.*:]] // CHECK-NEXT: [[HLSL_DOT_I:%.*]] = tail call reassoc nnan ninf nsz arcp afn half @llvm.dx.fdot.v2f16(<2 x half> nofpclass(nan inf) [[I]], <2 x half> nofpclass(nan inf) [[N]]) @@ -39,7 +39,7 @@ half test_reflect_half(half I, half N) { // CHECK-NEXT: [[SUB_I:%.*]] = fsub reassoc nnan ninf nsz arcp afn <2 x half> [[I]], [[MUL1_I]] // CHECK-NEXT: ret <2 x half> [[SUB_I]] // -// SPVCHECK-LABEL: define spir_func noundef nofpclass(nan inf) <2 x half> @_Z18test_reflect_half2Dv2_DhS_( +// SPVCHECK-LABEL: define hidden spir_func noundef nofpclass(nan inf) <2 x half> @_Z18test_reflect_half2Dv2_DhS_( // SPVCHECK-SAME: <2 x half> noundef nofpclass(nan inf) [[I:%.*]], <2 x half> noundef nofpclass(nan inf) [[N:%.*]]) local_unnamed_addr #[[ATTR0]] { // SPVCHECK-NEXT: [[ENTRY:.*:]] // SPVCHECK-NEXT: [[SPV_REFLECT_I:%.*]] = tail call reassoc nnan ninf nsz arcp afn noundef <2 x half> @llvm.spv.reflect.v2f16(<2 x half> nofpclass(nan inf) [[I]], <2 x half> nofpclass(nan inf) [[N]]) @@ -49,7 +49,7 @@ half2 test_reflect_half2(half2 I, half2 N) { return reflect(I, N); } -// CHECK-LABEL: define noundef nofpclass(nan inf) <3 x half> @_Z18test_reflect_half3Dv3_DhS_( +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) <3 x half> @_Z18test_reflect_half3Dv3_DhS_( // CHECK-SAME: <3 x half> noundef nofpclass(nan inf) [[I:%.*]], <3 x half> noundef nofpclass(nan inf) [[N:%.*]]) local_unnamed_addr #[[ATTR0]] { // CHECK-NEXT: [[ENTRY:.*:]] // CHECK-NEXT: [[HLSL_DOT_I:%.*]] = tail call reassoc nnan ninf nsz arcp afn half @llvm.dx.fdot.v3f16(<3 x half> nofpclass(nan inf) [[I]], <3 x half> nofpclass(nan inf) [[N]]) @@ -60,7 +60,7 @@ half2 test_reflect_half2(half2 I, half2 N) { // CHECK-NEXT: [[SUB_I:%.*]] = fsub reassoc nnan ninf nsz arcp afn <3 x half> [[I]], [[MUL1_I]] // CHECK-NEXT: ret <3 x half> [[SUB_I]] // -// SPVCHECK-LABEL: define spir_func noundef nofpclass(nan inf) <3 x half> @_Z18test_reflect_half3Dv3_DhS_( +// SPVCHECK-LABEL: define hidden spir_func noundef nofpclass(nan inf) <3 x half> @_Z18test_reflect_half3Dv3_DhS_( // SPVCHECK-SAME: <3 x half> noundef nofpclass(nan inf) [[I:%.*]], <3 x half> noundef nofpclass(nan inf) [[N:%.*]]) local_unnamed_addr #[[ATTR0]] { // SPVCHECK-NEXT: [[ENTRY:.*:]] // SPVCHECK-NEXT: [[SPV_REFLECT_I:%.*]] = tail call reassoc nnan ninf nsz arcp afn noundef <3 x half> @llvm.spv.reflect.v3f16(<3 x half> nofpclass(nan inf) [[I]], <3 x half> nofpclass(nan inf) [[N]]) @@ -70,7 +70,7 @@ half3 test_reflect_half3(half3 I, half3 N) { return reflect(I, N); } -// CHECK-LABEL: define noundef nofpclass(nan inf) <4 x half> @_Z18test_reflect_half4Dv4_DhS_( +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) <4 x half> @_Z18test_reflect_half4Dv4_DhS_( // CHECK-SAME: <4 x half> noundef nofpclass(nan inf) [[I:%.*]], <4 x half> noundef nofpclass(nan inf) [[N:%.*]]) local_unnamed_addr #[[ATTR0]] { // CHECK-NEXT: [[ENTRY:.*:]] // CHECK-NEXT: [[HLSL_DOT_I:%.*]] = tail call reassoc nnan ninf nsz arcp afn half @llvm.dx.fdot.v4f16(<4 x half> nofpclass(nan inf) [[I]], <4 x half> nofpclass(nan inf) [[N]]) @@ -81,7 +81,7 @@ half3 test_reflect_half3(half3 I, half3 N) { // CHECK-NEXT: [[SUB_I:%.*]] = fsub reassoc nnan ninf nsz arcp afn <4 x half> [[I]], [[MUL1_I]] // CHECK-NEXT: ret <4 x half> [[SUB_I]] // -// SPVCHECK-LABEL: define spir_func noundef nofpclass(nan inf) <4 x half> @_Z18test_reflect_half4Dv4_DhS_( +// SPVCHECK-LABEL: define hidden spir_func noundef nofpclass(nan inf) <4 x half> @_Z18test_reflect_half4Dv4_DhS_( // SPVCHECK-SAME: <4 x half> noundef nofpclass(nan inf) [[I:%.*]], <4 x half> noundef nofpclass(nan inf) [[N:%.*]]) local_unnamed_addr #[[ATTR0]] { // SPVCHECK-NEXT: [[ENTRY:.*:]] // SPVCHECK-NEXT: [[SPV_REFLECT_I:%.*]] = tail call reassoc nnan ninf nsz arcp afn noundef <4 x half> @llvm.spv.reflect.v4f16(<4 x half> nofpclass(nan inf) [[I]], <4 x half> nofpclass(nan inf) [[N]]) @@ -91,7 +91,7 @@ half4 test_reflect_half4(half4 I, half4 N) { return reflect(I, N); } -// CHECK-LABEL: define noundef nofpclass(nan inf) float @_Z18test_reflect_floatff( +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) float @_Z18test_reflect_floatff( // CHECK-SAME: float noundef nofpclass(nan inf) [[I:%.*]], float noundef nofpclass(nan inf) [[N:%.*]]) local_unnamed_addr #[[ATTR0]] { // CHECK-NEXT: [[ENTRY:.*:]] // CHECK-NEXT: [[MUL_I:%.*]] = fmul reassoc nnan ninf nsz arcp afn float [[I]], 2.000000e+00 @@ -100,7 +100,7 @@ half4 test_reflect_half4(half4 I, half4 N) { // CHECK-NEXT: [[SUB_I:%.*]] = fsub reassoc nnan ninf nsz arcp afn float [[I]], [[MUL2_I]] // CHECK-NEXT: ret float [[SUB_I]] // -// SPVCHECK-LABEL: define spir_func noundef nofpclass(nan inf) float @_Z18test_reflect_floatff( +// SPVCHECK-LABEL: define hidden spir_func noundef nofpclass(nan inf) float @_Z18test_reflect_floatff( // SPVCHECK-SAME: float noundef nofpclass(nan inf) [[I:%.*]], float noundef nofpclass(nan inf) [[N:%.*]]) local_unnamed_addr #[[ATTR0]] { // SPVCHECK-NEXT: [[ENTRY:.*:]] // SPVCHECK-NEXT: [[MUL_I:%.*]] = fmul reassoc nnan ninf nsz arcp afn float [[I]], 2.000000e+00 @@ -113,7 +113,7 @@ float test_reflect_float(float I, float N) { return reflect(I, N); } -// CHECK-LABEL: define noundef nofpclass(nan inf) <2 x float> @_Z19test_reflect_float2Dv2_fS_( +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) <2 x float> @_Z19test_reflect_float2Dv2_fS_( // CHECK-SAME: <2 x float> noundef nofpclass(nan inf) [[I:%.*]], <2 x float> noundef nofpclass(nan inf) [[N:%.*]]) local_unnamed_addr #[[ATTR0]] { // CHECK-NEXT: [[ENTRY:.*:]] // CHECK-NEXT: [[HLSL_DOT_I:%.*]] = tail call reassoc nnan ninf nsz arcp afn float @llvm.dx.fdot.v2f32(<2 x float> nofpclass(nan inf) [[I]], <2 x float> nofpclass(nan inf) [[N]]) @@ -124,7 +124,7 @@ float test_reflect_float(float I, float N) { // CHECK-NEXT: [[SUB_I:%.*]] = fsub reassoc nnan ninf nsz arcp afn <2 x float> [[I]], [[MUL1_I]] // CHECK-NEXT: ret <2 x float> [[SUB_I]] // -// SPVCHECK-LABEL: define spir_func noundef nofpclass(nan inf) <2 x float> @_Z19test_reflect_float2Dv2_fS_( +// SPVCHECK-LABEL: define hidden spir_func noundef nofpclass(nan inf) <2 x float> @_Z19test_reflect_float2Dv2_fS_( // SPVCHECK-SAME: <2 x float> noundef nofpclass(nan inf) [[I:%.*]], <2 x float> noundef nofpclass(nan inf) [[N:%.*]]) local_unnamed_addr #[[ATTR0]] { // SPVCHECK-NEXT: [[ENTRY:.*:]] // SPVCHECK-NEXT: [[SPV_REFLECT_I:%.*]] = tail call reassoc nnan ninf nsz arcp afn noundef <2 x float> @llvm.spv.reflect.v2f32(<2 x float> nofpclass(nan inf) [[I]], <2 x float> nofpclass(nan inf) [[N]]) @@ -134,7 +134,7 @@ float2 test_reflect_float2(float2 I, float2 N) { return reflect(I, N); } -// CHECK-LABEL: define noundef nofpclass(nan inf) <3 x float> @_Z19test_reflect_float3Dv3_fS_( +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) <3 x float> @_Z19test_reflect_float3Dv3_fS_( // CHECK-SAME: <3 x float> noundef nofpclass(nan inf) [[I:%.*]], <3 x float> noundef nofpclass(nan inf) [[N:%.*]]) local_unnamed_addr #[[ATTR0]] { // CHECK-NEXT: [[ENTRY:.*:]] // CHECK-NEXT: [[HLSL_DOT_I:%.*]] = tail call reassoc nnan ninf nsz arcp afn float @llvm.dx.fdot.v3f32(<3 x float> nofpclass(nan inf) [[I]], <3 x float> nofpclass(nan inf) [[N]]) @@ -145,7 +145,7 @@ float2 test_reflect_float2(float2 I, float2 N) { // CHECK-NEXT: [[SUB_I:%.*]] = fsub reassoc nnan ninf nsz arcp afn <3 x float> [[I]], [[MUL1_I]] // CHECK-NEXT: ret <3 x float> [[SUB_I]] // -// SPVCHECK-LABEL: define spir_func noundef nofpclass(nan inf) <3 x float> @_Z19test_reflect_float3Dv3_fS_( +// SPVCHECK-LABEL: define hidden spir_func noundef nofpclass(nan inf) <3 x float> @_Z19test_reflect_float3Dv3_fS_( // SPVCHECK-SAME: <3 x float> noundef nofpclass(nan inf) [[I:%.*]], <3 x float> noundef nofpclass(nan inf) [[N:%.*]]) local_unnamed_addr #[[ATTR0]] { // SPVCHECK-NEXT: [[ENTRY:.*:]] // SPVCHECK-NEXT: [[SPV_REFLECT_I:%.*]] = tail call reassoc nnan ninf nsz arcp afn noundef <3 x float> @llvm.spv.reflect.v3f32(<3 x float> nofpclass(nan inf) [[I]], <3 x float> nofpclass(nan inf) [[N]]) @@ -155,7 +155,7 @@ float3 test_reflect_float3(float3 I, float3 N) { return reflect(I, N); } -// CHECK-LABEL: define noundef nofpclass(nan inf) <4 x float> @_Z19test_reflect_float4Dv4_fS_( +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) <4 x float> @_Z19test_reflect_float4Dv4_fS_( // CHECK-SAME: <4 x float> noundef nofpclass(nan inf) [[I:%.*]], <4 x float> noundef nofpclass(nan inf) [[N:%.*]]) local_unnamed_addr #[[ATTR0]] { // CHECK-NEXT: [[ENTRY:.*:]] // CHECK-NEXT: [[HLSL_DOT_I:%.*]] = tail call reassoc nnan ninf nsz arcp afn float @llvm.dx.fdot.v4f32(<4 x float> nofpclass(nan inf) [[I]], <4 x float> nofpclass(nan inf) [[N]]) @@ -166,7 +166,7 @@ float3 test_reflect_float3(float3 I, float3 N) { // CHECK-NEXT: [[SUB_I:%.*]] = fsub reassoc nnan ninf nsz arcp afn <4 x float> [[I]], [[MUL1_I]] // CHECK-NEXT: ret <4 x float> [[SUB_I]] // -// SPVCHECK-LABEL: define spir_func noundef nofpclass(nan inf) <4 x float> @_Z19test_reflect_float4Dv4_fS_( +// SPVCHECK-LABEL: define hidden spir_func noundef nofpclass(nan inf) <4 x float> @_Z19test_reflect_float4Dv4_fS_( // SPVCHECK-SAME: <4 x float> noundef nofpclass(nan inf) [[I:%.*]], <4 x float> noundef nofpclass(nan inf) [[N:%.*]]) local_unnamed_addr #[[ATTR0]] { // SPVCHECK-NEXT: [[ENTRY:.*:]] // SPVCHECK-NEXT: [[SPV_REFLECT_I:%.*]] = tail call reassoc nnan ninf nsz arcp afn noundef <4 x float> @llvm.spv.reflect.v4f32(<4 x float> nofpclass(nan inf) [[I]], <4 x float> nofpclass(nan inf) [[N]]) diff --git a/external/llvm-project/clang/test/CodeGenHLSL/builtins/reversebits.hlsl b/external/llvm-project/clang/test/CodeGenHLSL/builtins/reversebits.hlsl index fe137b9cae4e..91375c8f4eb8 100644 --- a/external/llvm-project/clang/test/CodeGenHLSL/builtins/reversebits.hlsl +++ b/external/llvm-project/clang/test/CodeGenHLSL/builtins/reversebits.hlsl @@ -3,25 +3,25 @@ // RUN: -emit-llvm -disable-llvm-passes -O3 -o - | FileCheck %s #ifdef __HLSL_ENABLE_16_BIT -// CHECK: define noundef i16 @ +// CHECK: define hidden noundef i16 @ // CHECK: call i16 @llvm.bitreverse.i16( uint16_t test_bitreverse_ushort(uint16_t p0) { return reversebits(p0); } -// CHECK: define noundef <2 x i16> @ +// CHECK: define hidden noundef <2 x i16> @ // CHECK: call <2 x i16> @llvm.bitreverse.v2i16 uint16_t2 test_bitreverse_ushort2(uint16_t2 p0) { return reversebits(p0); } -// CHECK: define noundef <3 x i16> @ +// CHECK: define hidden noundef <3 x i16> @ // CHECK: call <3 x i16> @llvm.bitreverse.v3i16 uint16_t3 test_bitreverse_ushort3(uint16_t3 p0) { return reversebits(p0); } -// CHECK: define noundef <4 x i16> @ +// CHECK: define hidden noundef <4 x i16> @ // CHECK: call <4 x i16> @llvm.bitreverse.v4i16 uint16_t4 test_bitreverse_ushort4(uint16_t4 p0) { @@ -29,50 +29,50 @@ uint16_t4 test_bitreverse_ushort4(uint16_t4 p0) } #endif -// CHECK: define noundef i32 @ +// CHECK: define hidden noundef i32 @ // CHECK: call i32 @llvm.bitreverse.i32( int test_bitreverse_uint(uint p0) { return reversebits(p0); } -// CHECK: define noundef <2 x i32> @ +// CHECK: define hidden noundef <2 x i32> @ // CHECK: call <2 x i32> @llvm.bitreverse.v2i32 uint2 test_bitreverse_uint2(uint2 p0) { return reversebits(p0); } -// CHECK: define noundef <3 x i32> @ +// CHECK: define hidden noundef <3 x i32> @ // CHECK: call <3 x i32> @llvm.bitreverse.v3i32 uint3 test_bitreverse_uint3(uint3 p0) { return reversebits(p0); } -// CHECK: define noundef <4 x i32> @ +// CHECK: define hidden noundef <4 x i32> @ // CHECK: call <4 x i32> @llvm.bitreverse.v4i32 uint4 test_bitreverse_uint4(uint4 p0) { return reversebits(p0); } -// CHECK: define noundef i64 @ +// CHECK: define hidden noundef i64 @ // CHECK: call i64 @llvm.bitreverse.i64( uint64_t test_bitreverse_long(uint64_t p0) { return reversebits(p0); } -// CHECK: define noundef <2 x i64> @ +// CHECK: define hidden noundef <2 x i64> @ // CHECK: call <2 x i64> @llvm.bitreverse.v2i64 uint64_t2 test_bitreverse_long2(uint64_t2 p0) { return reversebits(p0); } -// CHECK: define noundef <3 x i64> @ +// CHECK: define hidden noundef <3 x i64> @ // CHECK: call <3 x i64> @llvm.bitreverse.v3i64 uint64_t3 test_bitreverse_long3(uint64_t3 p0) { return reversebits(p0); } -// CHECK: define noundef <4 x i64> @ +// CHECK: define hidden noundef <4 x i64> @ // CHECK: call <4 x i64> @llvm.bitreverse.v4i64 uint64_t4 test_bitreverse_long4(uint64_t4 p0) { diff --git a/external/llvm-project/clang/test/CodeGenHLSL/builtins/round-overloads.hlsl b/external/llvm-project/clang/test/CodeGenHLSL/builtins/round-overloads.hlsl index 109633a64d34..3b07fcec064d 100644 --- a/external/llvm-project/clang/test/CodeGenHLSL/builtins/round-overloads.hlsl +++ b/external/llvm-project/clang/test/CodeGenHLSL/builtins/round-overloads.hlsl @@ -2,87 +2,87 @@ // RUN: -emit-llvm -disable-llvm-passes -o - | \ // RUN: FileCheck %s --check-prefixes=CHECK -// CHECK-LABEL: define noundef nofpclass(nan inf) float {{.*}}test_round_double +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) float {{.*}}test_round_double // CHECK: %elt.roundeven = call reassoc nnan ninf nsz arcp afn float @llvm.roundeven.f32( // CHECK: ret float %elt.roundeven float test_round_double(double p0) { return round(p0); } -// CHECK-LABEL: define noundef nofpclass(nan inf) <2 x float> {{.*}}test_round_double2 +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) <2 x float> {{.*}}test_round_double2 // CHECK: %elt.roundeven = call reassoc nnan ninf nsz arcp afn <2 x float> @llvm.roundeven.v2f32 // CHECK: ret <2 x float> %elt.roundeven float2 test_round_double2(double2 p0) { return round(p0); } -// CHECK-LABEL: define noundef nofpclass(nan inf) <3 x float> {{.*}}test_round_double3 +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) <3 x float> {{.*}}test_round_double3 // CHECK: %elt.roundeven = call reassoc nnan ninf nsz arcp afn <3 x float> @llvm.roundeven.v3f32 // CHECK: ret <3 x float> %elt.roundeven float3 test_round_double3(double3 p0) { return round(p0); } -// CHECK-LABEL: define noundef nofpclass(nan inf) <4 x float> {{.*}}test_round_double4 +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) <4 x float> {{.*}}test_round_double4 // CHECK: %elt.roundeven = call reassoc nnan ninf nsz arcp afn <4 x float> @llvm.roundeven.v4f32 // CHECK: ret <4 x float> %elt.roundeven float4 test_round_double4(double4 p0) { return round(p0); } -// CHECK-LABEL: define noundef nofpclass(nan inf) float {{.*}}test_round_int +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) float {{.*}}test_round_int // CHECK: %elt.roundeven = call reassoc nnan ninf nsz arcp afn float @llvm.roundeven.f32( // CHECK: ret float %elt.roundeven float test_round_int(int p0) { return round(p0); } -// CHECK-LABEL: define noundef nofpclass(nan inf) <2 x float> {{.*}}test_round_int2 +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) <2 x float> {{.*}}test_round_int2 // CHECK: %elt.roundeven = call reassoc nnan ninf nsz arcp afn <2 x float> @llvm.roundeven.v2f32 // CHECK: ret <2 x float> %elt.roundeven float2 test_round_int2(int2 p0) { return round(p0); } -// CHECK-LABEL: define noundef nofpclass(nan inf) <3 x float> {{.*}}test_round_int3 +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) <3 x float> {{.*}}test_round_int3 // CHECK: %elt.roundeven = call reassoc nnan ninf nsz arcp afn <3 x float> @llvm.roundeven.v3f32 // CHECK: ret <3 x float> %elt.roundeven float3 test_round_int3(int3 p0) { return round(p0); } -// CHECK-LABEL: define noundef nofpclass(nan inf) <4 x float> {{.*}}test_round_int4 +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) <4 x float> {{.*}}test_round_int4 // CHECK: %elt.roundeven = call reassoc nnan ninf nsz arcp afn <4 x float> @llvm.roundeven.v4f32 // CHECK: ret <4 x float> %elt.roundeven float4 test_round_int4(int4 p0) { return round(p0); } -// CHECK-LABEL: define noundef nofpclass(nan inf) float {{.*}}test_round_uint +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) float {{.*}}test_round_uint // CHECK: %elt.roundeven = call reassoc nnan ninf nsz arcp afn float @llvm.roundeven.f32( // CHECK: ret float %elt.roundeven float test_round_uint(uint p0) { return round(p0); } -// CHECK-LABEL: define noundef nofpclass(nan inf) <2 x float> {{.*}}test_round_uint2 +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) <2 x float> {{.*}}test_round_uint2 // CHECK: %elt.roundeven = call reassoc nnan ninf nsz arcp afn <2 x float> @llvm.roundeven.v2f32 // CHECK: ret <2 x float> %elt.roundeven float2 test_round_uint2(uint2 p0) { return round(p0); } -// CHECK-LABEL: define noundef nofpclass(nan inf) <3 x float> {{.*}}test_round_uint3 +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) <3 x float> {{.*}}test_round_uint3 // CHECK: %elt.roundeven = call reassoc nnan ninf nsz arcp afn <3 x float> @llvm.roundeven.v3f32 // CHECK: ret <3 x float> %elt.roundeven float3 test_round_uint3(uint3 p0) { return round(p0); } -// CHECK-LABEL: define noundef nofpclass(nan inf) <4 x float> {{.*}}test_round_uint4 +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) <4 x float> {{.*}}test_round_uint4 // CHECK: %elt.roundeven = call reassoc nnan ninf nsz arcp afn <4 x float> @llvm.roundeven.v4f32 // CHECK: ret <4 x float> %elt.roundeven float4 test_round_uint4(uint4 p0) { return round(p0); } -// CHECK-LABEL: define noundef nofpclass(nan inf) float {{.*}}test_round_int64_t +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) float {{.*}}test_round_int64_t // CHECK: %elt.roundeven = call reassoc nnan ninf nsz arcp afn float @llvm.roundeven.f32( // CHECK: ret float %elt.roundeven float test_round_int64_t(int64_t p0) { return round(p0); } -// CHECK-LABEL: define noundef nofpclass(nan inf) <2 x float> {{.*}}test_round_int64_t2 +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) <2 x float> {{.*}}test_round_int64_t2 // CHECK: %elt.roundeven = call reassoc nnan ninf nsz arcp afn <2 x float> @llvm.roundeven.v2f32 // CHECK: ret <2 x float> %elt.roundeven float2 test_round_int64_t2(int64_t2 p0) { return round(p0); } -// CHECK-LABEL: define noundef nofpclass(nan inf) <3 x float> {{.*}}test_round_int64_t3 +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) <3 x float> {{.*}}test_round_int64_t3 // CHECK: %elt.roundeven = call reassoc nnan ninf nsz arcp afn <3 x float> @llvm.roundeven.v3f32 // CHECK: ret <3 x float> %elt.roundeven float3 test_round_int64_t3(int64_t3 p0) { return round(p0); } -// CHECK-LABEL: define noundef nofpclass(nan inf) <4 x float> {{.*}}test_round_int64_t4 +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) <4 x float> {{.*}}test_round_int64_t4 // CHECK: %elt.roundeven = call reassoc nnan ninf nsz arcp afn <4 x float> @llvm.roundeven.v4f32 // CHECK: ret <4 x float> %elt.roundeven float4 test_round_int64_t4(int64_t4 p0) { return round(p0); } -// CHECK-LABEL: define noundef nofpclass(nan inf) float {{.*}}test_round_uint64_t +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) float {{.*}}test_round_uint64_t // CHECK: %elt.roundeven = call reassoc nnan ninf nsz arcp afn float @llvm.roundeven.f32( // CHECK: ret float %elt.roundeven float test_round_uint64_t(uint64_t p0) { return round(p0); } -// CHECK-LABEL: define noundef nofpclass(nan inf) <2 x float> {{.*}}test_round_uint64_t2 +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) <2 x float> {{.*}}test_round_uint64_t2 // CHECK: %elt.roundeven = call reassoc nnan ninf nsz arcp afn <2 x float> @llvm.roundeven.v2f32 // CHECK: ret <2 x float> %elt.roundeven float2 test_round_uint64_t2(uint64_t2 p0) { return round(p0); } -// CHECK-LABEL: define noundef nofpclass(nan inf) <3 x float> {{.*}}test_round_uint64_t3 +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) <3 x float> {{.*}}test_round_uint64_t3 // CHECK: %elt.roundeven = call reassoc nnan ninf nsz arcp afn <3 x float> @llvm.roundeven.v3f32 // CHECK: ret <3 x float> %elt.roundeven float3 test_round_uint64_t3(uint64_t3 p0) { return round(p0); } -// CHECK-LABEL: define noundef nofpclass(nan inf) <4 x float> {{.*}}test_round_uint64_t4 +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) <4 x float> {{.*}}test_round_uint64_t4 // CHECK: %elt.roundeven = call reassoc nnan ninf nsz arcp afn <4 x float> @llvm.roundeven.v4f32 // CHECK: ret <4 x float> %elt.roundeven float4 test_round_uint64_t4(uint64_t4 p0) { return round(p0); } diff --git a/external/llvm-project/clang/test/CodeGenHLSL/builtins/round.hlsl b/external/llvm-project/clang/test/CodeGenHLSL/builtins/round.hlsl index a945a9677abb..755f2e86fb11 100644 --- a/external/llvm-project/clang/test/CodeGenHLSL/builtins/round.hlsl +++ b/external/llvm-project/clang/test/CodeGenHLSL/builtins/round.hlsl @@ -5,48 +5,48 @@ // RUN: -emit-llvm -disable-llvm-passes -o - | \ // RUN: FileCheck %s --check-prefixes=CHECK,NO_HALF -// NATIVE_HALF-LABEL: define noundef nofpclass(nan inf) half @_Z15test_round_half +// NATIVE_HALF-LABEL: define hidden noundef nofpclass(nan inf) half @_Z15test_round_half // NATIVE_HALF: %elt.roundeven = call reassoc nnan ninf nsz arcp afn half @llvm.roundeven.f16( // NATIVE_HALF: ret half %elt.roundeven -// NO_HALF-LABEL: define noundef nofpclass(nan inf) float @_Z15test_round_half +// NO_HALF-LABEL: define hidden noundef nofpclass(nan inf) float @_Z15test_round_half // NO_HALF: %elt.roundeven = call reassoc nnan ninf nsz arcp afn float @llvm.roundeven.f32( // NO_HALF: ret float %elt.roundeven half test_round_half(half p0) { return round(p0); } -// NATIVE_HALF-LABEL: define noundef nofpclass(nan inf) <2 x half> @_Z16test_round_half2 +// NATIVE_HALF-LABEL: define hidden noundef nofpclass(nan inf) <2 x half> @_Z16test_round_half2 // NATIVE_HALF: %elt.roundeven = call reassoc nnan ninf nsz arcp afn <2 x half> @llvm.roundeven.v2f16 // NATIVE_HALF: ret <2 x half> %elt.roundeven -// NO_HALF-LABEL: define noundef nofpclass(nan inf) <2 x float> @_Z16test_round_half2 +// NO_HALF-LABEL: define hidden noundef nofpclass(nan inf) <2 x float> @_Z16test_round_half2 // NO_HALF: %elt.roundeven = call reassoc nnan ninf nsz arcp afn <2 x float> @llvm.roundeven.v2f32( // NO_HALF: ret <2 x float> %elt.roundeven half2 test_round_half2(half2 p0) { return round(p0); } -// NATIVE_HALF-LABEL: define noundef nofpclass(nan inf) <3 x half> @_Z16test_round_half3 +// NATIVE_HALF-LABEL: define hidden noundef nofpclass(nan inf) <3 x half> @_Z16test_round_half3 // NATIVE_HALF: %elt.roundeven = call reassoc nnan ninf nsz arcp afn <3 x half> @llvm.roundeven.v3f16 // NATIVE_HALF: ret <3 x half> %elt.roundeven -// NO_HALF-LABEL: define noundef nofpclass(nan inf) <3 x float> @_Z16test_round_half3 +// NO_HALF-LABEL: define hidden noundef nofpclass(nan inf) <3 x float> @_Z16test_round_half3 // NO_HALF: %elt.roundeven = call reassoc nnan ninf nsz arcp afn <3 x float> @llvm.roundeven.v3f32( // NO_HALF: ret <3 x float> %elt.roundeven half3 test_round_half3(half3 p0) { return round(p0); } -// NATIVE_HALF-LABEL: define noundef nofpclass(nan inf) <4 x half> @_Z16test_round_half4 +// NATIVE_HALF-LABEL: define hidden noundef nofpclass(nan inf) <4 x half> @_Z16test_round_half4 // NATIVE_HALF: %elt.roundeven = call reassoc nnan ninf nsz arcp afn <4 x half> @llvm.roundeven.v4f16 // NATIVE_HALF: ret <4 x half> %elt.roundeven -// NO_HALF-LABEL: define noundef nofpclass(nan inf) <4 x float> @_Z16test_round_half4 +// NO_HALF-LABEL: define hidden noundef nofpclass(nan inf) <4 x float> @_Z16test_round_half4 // NO_HALF: %elt.roundeven = call reassoc nnan ninf nsz arcp afn <4 x float> @llvm.roundeven.v4f32( // NO_HALF: ret <4 x float> %elt.roundeven half4 test_round_half4(half4 p0) { return round(p0); } -// CHECK-LABEL: define noundef nofpclass(nan inf) float @_Z16test_round_float +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) float @_Z16test_round_float // CHECK: %elt.roundeven = call reassoc nnan ninf nsz arcp afn float @llvm.roundeven.f32( // CHECK: ret float %elt.roundeven float test_round_float(float p0) { return round(p0); } -// CHECK-LABEL: define noundef nofpclass(nan inf) <2 x float> @_Z17test_round_float2 +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) <2 x float> @_Z17test_round_float2 // CHECK: %elt.roundeven = call reassoc nnan ninf nsz arcp afn <2 x float> @llvm.roundeven.v2f32 // CHECK: ret <2 x float> %elt.roundeven float2 test_round_float2(float2 p0) { return round(p0); } -// CHECK-LABEL: define noundef nofpclass(nan inf) <3 x float> @_Z17test_round_float3 +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) <3 x float> @_Z17test_round_float3 // CHECK: %elt.roundeven = call reassoc nnan ninf nsz arcp afn <3 x float> @llvm.roundeven.v3f32 // CHECK: ret <3 x float> %elt.roundeven float3 test_round_float3(float3 p0) { return round(p0); } -// CHECK-LABEL: define noundef nofpclass(nan inf) <4 x float> @_Z17test_round_float4 +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) <4 x float> @_Z17test_round_float4 // CHECK: %elt.roundeven = call reassoc nnan ninf nsz arcp afn <4 x float> @llvm.roundeven.v4f32 // CHECK: ret <4 x float> %elt.roundeven float4 test_round_float4(float4 p0) { return round(p0); } diff --git a/external/llvm-project/clang/test/CodeGenHLSL/builtins/rsqrt-overloads.hlsl b/external/llvm-project/clang/test/CodeGenHLSL/builtins/rsqrt-overloads.hlsl index 09f21f366b9d..262f306b9257 100644 --- a/external/llvm-project/clang/test/CodeGenHLSL/builtins/rsqrt-overloads.hlsl +++ b/external/llvm-project/clang/test/CodeGenHLSL/builtins/rsqrt-overloads.hlsl @@ -1,11 +1,11 @@ // RUN: %clang_cc1 -std=hlsl202x -finclude-default-header -x hlsl -triple \ // RUN: dxil-pc-shadermodel6.3-library %s -emit-llvm -disable-llvm-passes \ // RUN: -o - | FileCheck %s --check-prefixes=CHECK \ -// RUN: -DFNATTRS="noundef nofpclass(nan inf)" -DTARGET=dx +// RUN: -DFNATTRS="hidden noundef nofpclass(nan inf)" -DTARGET=dx // RUN: %clang_cc1 -std=hlsl202x -finclude-default-header -x hlsl -triple \ // RUN: spirv-unknown-vulkan-compute %s -emit-llvm -disable-llvm-passes \ // RUN: -o - | FileCheck %s --check-prefixes=CHECK \ -// RUN: -DFNATTRS="spir_func noundef nofpclass(nan inf)" -DTARGET=spv +// RUN: -DFNATTRS="hidden spir_func noundef nofpclass(nan inf)" -DTARGET=spv // CHECK: define [[FNATTRS]] float @ // CHECK: %hlsl.rsqrt = call reassoc nnan ninf nsz arcp afn float @llvm.[[TARGET]].rsqrt.f32( diff --git a/external/llvm-project/clang/test/CodeGenHLSL/builtins/rsqrt.hlsl b/external/llvm-project/clang/test/CodeGenHLSL/builtins/rsqrt.hlsl index 6c9b1f643713..9c398fd6f06c 100644 --- a/external/llvm-project/clang/test/CodeGenHLSL/builtins/rsqrt.hlsl +++ b/external/llvm-project/clang/test/CodeGenHLSL/builtins/rsqrt.hlsl @@ -2,20 +2,20 @@ // RUN: dxil-pc-shadermodel6.3-library %s -fnative-half-type \ // RUN: -emit-llvm -disable-llvm-passes -o - | FileCheck %s \ // RUN: --check-prefixes=CHECK,NATIVE_HALF \ -// RUN: -DFNATTRS="noundef nofpclass(nan inf)" -DTARGET=dx +// RUN: -DFNATTRS="hidden noundef nofpclass(nan inf)" -DTARGET=dx // RUN: %clang_cc1 -finclude-default-header -x hlsl -triple \ // RUN: dxil-pc-shadermodel6.3-library %s -emit-llvm -disable-llvm-passes \ // RUN: -o - | FileCheck %s --check-prefixes=CHECK,NO_HALF \ -// RUN: -DFNATTRS="noundef nofpclass(nan inf)" -DTARGET=dx +// RUN: -DFNATTRS="hidden noundef nofpclass(nan inf)" -DTARGET=dx // RUN: %clang_cc1 -finclude-default-header -x hlsl -triple \ // RUN: spirv-unknown-vulkan-compute %s -fnative-half-type \ // RUN: -emit-llvm -disable-llvm-passes -o - | FileCheck %s \ // RUN: --check-prefixes=CHECK,NATIVE_HALF \ -// RUN: -DFNATTRS="spir_func noundef nofpclass(nan inf)" -DTARGET=spv +// RUN: -DFNATTRS="hidden spir_func noundef nofpclass(nan inf)" -DTARGET=spv // RUN: %clang_cc1 -finclude-default-header -x hlsl -triple \ // RUN: spirv-unknown-vulkan-compute %s -emit-llvm -disable-llvm-passes \ // RUN: -o - | FileCheck %s --check-prefixes=CHECK,NO_HALF \ -// RUN: -DFNATTRS="spir_func noundef nofpclass(nan inf)" -DTARGET=spv +// RUN: -DFNATTRS="hidden spir_func noundef nofpclass(nan inf)" -DTARGET=spv // NATIVE_HALF: define [[FNATTRS]] half @ // NATIVE_HALF: %hlsl.rsqrt = call reassoc nnan ninf nsz arcp afn half @llvm.[[TARGET]].rsqrt.f16( diff --git a/external/llvm-project/clang/test/CodeGenHLSL/builtins/sign.hlsl b/external/llvm-project/clang/test/CodeGenHLSL/builtins/sign.hlsl index 8cc910933f46..cbdb92938893 100644 --- a/external/llvm-project/clang/test/CodeGenHLSL/builtins/sign.hlsl +++ b/external/llvm-project/clang/test/CodeGenHLSL/builtins/sign.hlsl @@ -2,20 +2,20 @@ // RUN: dxil-pc-shadermodel6.3-library %s -fnative-half-type \ // RUN: -emit-llvm -disable-llvm-passes -o - | FileCheck %s \ // RUN: --check-prefixes=CHECK,NATIVE_HALF \ -// RUN: -DTARGET=dx -DFNATTRS=noundef +// RUN: -DTARGET=dx -DFNATTRS="hidden noundef" // RUN: %clang_cc1 -finclude-default-header -x hlsl -triple \ // RUN: dxil-pc-shadermodel6.3-library %s -emit-llvm -disable-llvm-passes \ // RUN: -o - | FileCheck %s --check-prefixes=CHECK,NO_HALF \ -// RUN: -DTARGET=dx -DFNATTRS=noundef +// RUN: -DTARGET=dx -DFNATTRS="hidden noundef" // RUN: %clang_cc1 -finclude-default-header -x hlsl -triple \ // RUN: spirv-unknown-vulkan-compute %s -fnative-half-type \ // RUN: -emit-llvm -disable-llvm-passes -o - | FileCheck %s \ // RUN: --check-prefixes=CHECK,NATIVE_HALF \ -// RUN: -DTARGET=spv -DFNATTRS="spir_func noundef" +// RUN: -DTARGET=spv -DFNATTRS="hidden spir_func noundef" // RUN: %clang_cc1 -finclude-default-header -x hlsl -triple \ // RUN: spirv-unknown-vulkan-compute %s -emit-llvm -disable-llvm-passes \ // RUN: -o - | FileCheck %s --check-prefixes=CHECK,NO_HALF \ -// RUN: -DTARGET=spv -DFNATTRS="spir_func noundef" +// RUN: -DTARGET=spv -DFNATTRS="hidden spir_func noundef" // NATIVE_HALF: define [[FNATTRS]] i32 @ // NATIVE_HALF: %hlsl.sign = call i32 @llvm.[[TARGET]].sign.f16( diff --git a/external/llvm-project/clang/test/CodeGenHLSL/builtins/sin-overloads.hlsl b/external/llvm-project/clang/test/CodeGenHLSL/builtins/sin-overloads.hlsl index a5522e4f28b7..e471cb3d42c5 100644 --- a/external/llvm-project/clang/test/CodeGenHLSL/builtins/sin-overloads.hlsl +++ b/external/llvm-project/clang/test/CodeGenHLSL/builtins/sin-overloads.hlsl @@ -2,67 +2,67 @@ // RUN: -emit-llvm -disable-llvm-passes -o - | \ // RUN: FileCheck %s --check-prefixes=CHECK -// CHECK-LABEL: define noundef nofpclass(nan inf) float {{.*}}test_sin_double +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) float {{.*}}test_sin_double // CHECK: call reassoc nnan ninf nsz arcp afn float @llvm.sin.f32( float test_sin_double(double p0) { return sin(p0); } -// CHECK-LABEL: define noundef nofpclass(nan inf) <2 x float> {{.*}}test_sin_double2 +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) <2 x float> {{.*}}test_sin_double2 // CHECK: call reassoc nnan ninf nsz arcp afn <2 x float> @llvm.sin.v2f32 float2 test_sin_double2(double2 p0) { return sin(p0); } -// CHECK-LABEL: define noundef nofpclass(nan inf) <3 x float> {{.*}}test_sin_double3 +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) <3 x float> {{.*}}test_sin_double3 // CHECK: call reassoc nnan ninf nsz arcp afn <3 x float> @llvm.sin.v3f32 float3 test_sin_double3(double3 p0) { return sin(p0); } -// CHECK-LABEL: define noundef nofpclass(nan inf) <4 x float> {{.*}}test_sin_double4 +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) <4 x float> {{.*}}test_sin_double4 // CHECK: call reassoc nnan ninf nsz arcp afn <4 x float> @llvm.sin.v4f32 float4 test_sin_double4(double4 p0) { return sin(p0); } -// CHECK-LABEL: define noundef nofpclass(nan inf) float {{.*}}test_sin_int +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) float {{.*}}test_sin_int // CHECK: call reassoc nnan ninf nsz arcp afn float @llvm.sin.f32( float test_sin_int(int p0) { return sin(p0); } -// CHECK-LABEL: define noundef nofpclass(nan inf) <2 x float> {{.*}}test_sin_int2 +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) <2 x float> {{.*}}test_sin_int2 // CHECK: call reassoc nnan ninf nsz arcp afn <2 x float> @llvm.sin.v2f32 float2 test_sin_int2(int2 p0) { return sin(p0); } -// CHECK-LABEL: define noundef nofpclass(nan inf) <3 x float> {{.*}}test_sin_int3 +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) <3 x float> {{.*}}test_sin_int3 // CHECK: call reassoc nnan ninf nsz arcp afn <3 x float> @llvm.sin.v3f32 float3 test_sin_int3(int3 p0) { return sin(p0); } -// CHECK-LABEL: define noundef nofpclass(nan inf) <4 x float> {{.*}}test_sin_int4 +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) <4 x float> {{.*}}test_sin_int4 // CHECK: call reassoc nnan ninf nsz arcp afn <4 x float> @llvm.sin.v4f32 float4 test_sin_int4(int4 p0) { return sin(p0); } -// CHECK-LABEL: define noundef nofpclass(nan inf) float {{.*}}test_sin_uint +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) float {{.*}}test_sin_uint // CHECK: call reassoc nnan ninf nsz arcp afn float @llvm.sin.f32( float test_sin_uint(uint p0) { return sin(p0); } -// CHECK-LABEL: define noundef nofpclass(nan inf) <2 x float> {{.*}}test_sin_uint2 +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) <2 x float> {{.*}}test_sin_uint2 // CHECK: call reassoc nnan ninf nsz arcp afn <2 x float> @llvm.sin.v2f32 float2 test_sin_uint2(uint2 p0) { return sin(p0); } -// CHECK-LABEL: define noundef nofpclass(nan inf) <3 x float> {{.*}}test_sin_uint3 +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) <3 x float> {{.*}}test_sin_uint3 // CHECK: call reassoc nnan ninf nsz arcp afn <3 x float> @llvm.sin.v3f32 float3 test_sin_uint3(uint3 p0) { return sin(p0); } -// CHECK-LABEL: define noundef nofpclass(nan inf) <4 x float> {{.*}}test_sin_uint4 +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) <4 x float> {{.*}}test_sin_uint4 // CHECK: call reassoc nnan ninf nsz arcp afn <4 x float> @llvm.sin.v4f32 float4 test_sin_uint4(uint4 p0) { return sin(p0); } -// CHECK-LABEL: define noundef nofpclass(nan inf) float {{.*}}test_sin_int64_t +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) float {{.*}}test_sin_int64_t // CHECK: call reassoc nnan ninf nsz arcp afn float @llvm.sin.f32( float test_sin_int64_t(int64_t p0) { return sin(p0); } -// CHECK-LABEL: define noundef nofpclass(nan inf) <2 x float> {{.*}}test_sin_int64_t2 +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) <2 x float> {{.*}}test_sin_int64_t2 // CHECK: call reassoc nnan ninf nsz arcp afn <2 x float> @llvm.sin.v2f32 float2 test_sin_int64_t2(int64_t2 p0) { return sin(p0); } -// CHECK-LABEL: define noundef nofpclass(nan inf) <3 x float> {{.*}}test_sin_int64_t3 +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) <3 x float> {{.*}}test_sin_int64_t3 // CHECK: call reassoc nnan ninf nsz arcp afn <3 x float> @llvm.sin.v3f32 float3 test_sin_int64_t3(int64_t3 p0) { return sin(p0); } -// CHECK-LABEL: define noundef nofpclass(nan inf) <4 x float> {{.*}}test_sin_int64_t4 +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) <4 x float> {{.*}}test_sin_int64_t4 // CHECK: call reassoc nnan ninf nsz arcp afn <4 x float> @llvm.sin.v4f32 float4 test_sin_int64_t4(int64_t4 p0) { return sin(p0); } -// CHECK-LABEL: define noundef nofpclass(nan inf) float {{.*}}test_sin_uint64_t +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) float {{.*}}test_sin_uint64_t // CHECK: call reassoc nnan ninf nsz arcp afn float @llvm.sin.f32( float test_sin_uint64_t(uint64_t p0) { return sin(p0); } -// CHECK-LABEL: define noundef nofpclass(nan inf) <2 x float> {{.*}}test_sin_uint64_t2 +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) <2 x float> {{.*}}test_sin_uint64_t2 // CHECK: call reassoc nnan ninf nsz arcp afn <2 x float> @llvm.sin.v2f32 float2 test_sin_uint64_t2(uint64_t2 p0) { return sin(p0); } -// CHECK-LABEL: define noundef nofpclass(nan inf) <3 x float> {{.*}}test_sin_uint64_t3 +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) <3 x float> {{.*}}test_sin_uint64_t3 // CHECK: call reassoc nnan ninf nsz arcp afn <3 x float> @llvm.sin.v3f32 float3 test_sin_uint64_t3(uint64_t3 p0) { return sin(p0); } -// CHECK-LABEL: define noundef nofpclass(nan inf) <4 x float> {{.*}}test_sin_uint64_t4 +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) <4 x float> {{.*}}test_sin_uint64_t4 // CHECK: call reassoc nnan ninf nsz arcp afn <4 x float> @llvm.sin.v4f32 float4 test_sin_uint64_t4(uint64_t4 p0) { return sin(p0); } diff --git a/external/llvm-project/clang/test/CodeGenHLSL/builtins/sin.hlsl b/external/llvm-project/clang/test/CodeGenHLSL/builtins/sin.hlsl index 69c657239ef9..9bbe97997aa3 100644 --- a/external/llvm-project/clang/test/CodeGenHLSL/builtins/sin.hlsl +++ b/external/llvm-project/clang/test/CodeGenHLSL/builtins/sin.hlsl @@ -5,36 +5,36 @@ // RUN: -emit-llvm -disable-llvm-passes -o - | \ // RUN: FileCheck %s --check-prefixes=CHECK,NO_HALF -// NATIVE_HALF-LABEL: define noundef nofpclass(nan inf) half @_Z13test_sin_half +// NATIVE_HALF-LABEL: define hidden noundef nofpclass(nan inf) half @_Z13test_sin_half // NATIVE_HALF: call reassoc nnan ninf nsz arcp afn half @llvm.sin.f16( -// NO_HALF-LABEL: define noundef nofpclass(nan inf) float @_Z13test_sin_half +// NO_HALF-LABEL: define hidden noundef nofpclass(nan inf) float @_Z13test_sin_half // NO_HALF: call reassoc nnan ninf nsz arcp afn float @llvm.sin.f32( half test_sin_half(half p0) { return sin(p0); } -// NATIVE_HALF-LABEL: define noundef nofpclass(nan inf) <2 x half> @_Z14test_sin_half2 +// NATIVE_HALF-LABEL: define hidden noundef nofpclass(nan inf) <2 x half> @_Z14test_sin_half2 // NATIVE_HALF: call reassoc nnan ninf nsz arcp afn <2 x half> @llvm.sin.v2f16 -// NO_HALF-LABEL: define noundef nofpclass(nan inf) <2 x float> @_Z14test_sin_half2 +// NO_HALF-LABEL: define hidden noundef nofpclass(nan inf) <2 x float> @_Z14test_sin_half2 // NO_HALF: call reassoc nnan ninf nsz arcp afn <2 x float> @llvm.sin.v2f32( half2 test_sin_half2(half2 p0) { return sin(p0); } -// NATIVE_HALF-LABEL: define noundef nofpclass(nan inf) <3 x half> @_Z14test_sin_half3 +// NATIVE_HALF-LABEL: define hidden noundef nofpclass(nan inf) <3 x half> @_Z14test_sin_half3 // NATIVE_HALF: call reassoc nnan ninf nsz arcp afn <3 x half> @llvm.sin.v3f16 -// NO_HALF-LABEL: define noundef nofpclass(nan inf) <3 x float> @_Z14test_sin_half3 +// NO_HALF-LABEL: define hidden noundef nofpclass(nan inf) <3 x float> @_Z14test_sin_half3 // NO_HALF: call reassoc nnan ninf nsz arcp afn <3 x float> @llvm.sin.v3f32( half3 test_sin_half3(half3 p0) { return sin(p0); } -// NATIVE_HALF-LABEL: define noundef nofpclass(nan inf) <4 x half> @_Z14test_sin_half4 +// NATIVE_HALF-LABEL: define hidden noundef nofpclass(nan inf) <4 x half> @_Z14test_sin_half4 // NATIVE_HALF: call reassoc nnan ninf nsz arcp afn <4 x half> @llvm.sin.v4f16 -// NO_HALF-LABEL: define noundef nofpclass(nan inf) <4 x float> @_Z14test_sin_half4 +// NO_HALF-LABEL: define hidden noundef nofpclass(nan inf) <4 x float> @_Z14test_sin_half4 // NO_HALF: call reassoc nnan ninf nsz arcp afn <4 x float> @llvm.sin.v4f32( half4 test_sin_half4(half4 p0) { return sin(p0); } -// CHECK-LABEL: define noundef nofpclass(nan inf) float @_Z14test_sin_float +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) float @_Z14test_sin_float // CHECK: call reassoc nnan ninf nsz arcp afn float @llvm.sin.f32( float test_sin_float(float p0) { return sin(p0); } -// CHECK-LABEL: define noundef nofpclass(nan inf) <2 x float> @_Z15test_sin_float2 +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) <2 x float> @_Z15test_sin_float2 // CHECK: call reassoc nnan ninf nsz arcp afn <2 x float> @llvm.sin.v2f32 float2 test_sin_float2(float2 p0) { return sin(p0); } -// CHECK-LABEL: define noundef nofpclass(nan inf) <3 x float> @_Z15test_sin_float3 +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) <3 x float> @_Z15test_sin_float3 // CHECK: call reassoc nnan ninf nsz arcp afn <3 x float> @llvm.sin.v3f32 float3 test_sin_float3(float3 p0) { return sin(p0); } -// CHECK-LABEL: define noundef nofpclass(nan inf) <4 x float> @_Z15test_sin_float4 +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) <4 x float> @_Z15test_sin_float4 // CHECK: call reassoc nnan ninf nsz arcp afn <4 x float> @llvm.sin.v4f32 float4 test_sin_float4(float4 p0) { return sin(p0); } diff --git a/external/llvm-project/clang/test/CodeGenHLSL/builtins/smoothstep.hlsl b/external/llvm-project/clang/test/CodeGenHLSL/builtins/smoothstep.hlsl index d3e5c1059029..bef64ce77d47 100644 --- a/external/llvm-project/clang/test/CodeGenHLSL/builtins/smoothstep.hlsl +++ b/external/llvm-project/clang/test/CodeGenHLSL/builtins/smoothstep.hlsl @@ -6,7 +6,7 @@ // RUN: spirv-unknown-vulkan-compute %s -fnative-half-type \ // RUN: -emit-llvm -O1 -o - | FileCheck %s --check-prefix=SPVCHECK -// CHECK-LABEL: define noundef nofpclass(nan inf) half @_Z20test_smoothstep_halfDhDhDh( +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) half @_Z20test_smoothstep_halfDhDhDh( // CHECK-SAME: half noundef nofpclass(nan inf) [[MIN:%.*]], half noundef nofpclass(nan inf) [[MAX:%.*]], half noundef nofpclass(nan inf) [[X:%.*]]) local_unnamed_addr #[[ATTR0:[0-9]+]] { // CHECK-NEXT: [[ENTRY:.*:]] // CHECK-NEXT: [[SUB_I:%.*]] = fsub reassoc nnan ninf nsz arcp afn half [[X]], [[MIN]] @@ -19,7 +19,7 @@ // CHECK-NEXT: [[MUL4_I:%.*]] = fmul reassoc nnan ninf nsz arcp afn half [[TMP0]], [[SUB2_I]] // CHECK-NEXT: ret half [[MUL4_I]] // -// SPVCHECK-LABEL: define spir_func noundef nofpclass(nan inf) half @_Z20test_smoothstep_halfDhDhDh( +// SPVCHECK-LABEL: define hidden spir_func noundef nofpclass(nan inf) half @_Z20test_smoothstep_halfDhDhDh( // SPVCHECK-SAME: half noundef nofpclass(nan inf) [[MIN:%.*]], half noundef nofpclass(nan inf) [[MAX:%.*]], half noundef nofpclass(nan inf) [[X:%.*]]) local_unnamed_addr #[[ATTR0:[0-9]+]] { // SPVCHECK-NEXT: [[ENTRY:.*:]] // SPVCHECK-NEXT: [[SPV_SMOOTHSTEP_I:%.*]] = tail call reassoc nnan ninf nsz arcp afn noundef half @llvm.spv.smoothstep.f16(half nofpclass(nan inf) [[MIN]], half nofpclass(nan inf) [[MAX]], half nofpclass(nan inf) [[X]]) @@ -27,7 +27,7 @@ // half test_smoothstep_half(half Min, half Max, half X) { return smoothstep(Min, Max, X); } -// CHECK-LABEL: define noundef nofpclass(nan inf) <2 x half> @_Z21test_smoothstep_half2Dv2_DhS_S_( +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) <2 x half> @_Z21test_smoothstep_half2Dv2_DhS_S_( // CHECK-SAME: <2 x half> noundef nofpclass(nan inf) [[MIN:%.*]], <2 x half> noundef nofpclass(nan inf) [[MAX:%.*]], <2 x half> noundef nofpclass(nan inf) [[X:%.*]]) local_unnamed_addr #[[ATTR0]] { // CHECK-NEXT: [[ENTRY:.*:]] // CHECK-NEXT: [[SUB_I:%.*]] = fsub reassoc nnan ninf nsz arcp afn <2 x half> [[X]], [[MIN]] @@ -40,7 +40,7 @@ half test_smoothstep_half(half Min, half Max, half X) { return smoothstep(Min, M // CHECK-NEXT: [[MUL4_I:%.*]] = fmul reassoc nnan ninf nsz arcp afn <2 x half> [[TMP0]], [[SUB2_I]] // CHECK-NEXT: ret <2 x half> [[MUL4_I]] // -// SPVCHECK-LABEL: define spir_func noundef nofpclass(nan inf) <2 x half> @_Z21test_smoothstep_half2Dv2_DhS_S_( +// SPVCHECK-LABEL: define hidden spir_func noundef nofpclass(nan inf) <2 x half> @_Z21test_smoothstep_half2Dv2_DhS_S_( // SPVCHECK-SAME: <2 x half> noundef nofpclass(nan inf) [[MIN:%.*]], <2 x half> noundef nofpclass(nan inf) [[MAX:%.*]], <2 x half> noundef nofpclass(nan inf) [[X:%.*]]) local_unnamed_addr #[[ATTR0]] { // SPVCHECK-NEXT: [[ENTRY:.*:]] // SPVCHECK-NEXT: [[SPV_SMOOTHSTEP_I:%.*]] = tail call reassoc nnan ninf nsz arcp afn noundef <2 x half> @llvm.spv.smoothstep.v2f16(<2 x half> nofpclass(nan inf) [[MIN]], <2 x half> nofpclass(nan inf) [[MAX]], <2 x half> nofpclass(nan inf) [[X]]) @@ -48,7 +48,7 @@ half test_smoothstep_half(half Min, half Max, half X) { return smoothstep(Min, M // half2 test_smoothstep_half2(half2 Min, half2 Max, half2 X) { return smoothstep(Min, Max, X); } -// CHECK-LABEL: define noundef nofpclass(nan inf) <3 x half> @_Z21test_smoothstep_half3Dv3_DhS_S_( +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) <3 x half> @_Z21test_smoothstep_half3Dv3_DhS_S_( // CHECK-SAME: <3 x half> noundef nofpclass(nan inf) [[MIN:%.*]], <3 x half> noundef nofpclass(nan inf) [[MAX:%.*]], <3 x half> noundef nofpclass(nan inf) [[X:%.*]]) local_unnamed_addr #[[ATTR0]] { // CHECK-NEXT: [[ENTRY:.*:]] // CHECK-NEXT: [[SUB_I:%.*]] = fsub reassoc nnan ninf nsz arcp afn <3 x half> [[X]], [[MIN]] @@ -61,7 +61,7 @@ half2 test_smoothstep_half2(half2 Min, half2 Max, half2 X) { return smoothstep(M // CHECK-NEXT: [[MUL4_I:%.*]] = fmul reassoc nnan ninf nsz arcp afn <3 x half> [[TMP0]], [[SUB2_I]] // CHECK-NEXT: ret <3 x half> [[MUL4_I]] // -// SPVCHECK-LABEL: define spir_func noundef nofpclass(nan inf) <3 x half> @_Z21test_smoothstep_half3Dv3_DhS_S_( +// SPVCHECK-LABEL: define hidden spir_func noundef nofpclass(nan inf) <3 x half> @_Z21test_smoothstep_half3Dv3_DhS_S_( // SPVCHECK-SAME: <3 x half> noundef nofpclass(nan inf) [[MIN:%.*]], <3 x half> noundef nofpclass(nan inf) [[MAX:%.*]], <3 x half> noundef nofpclass(nan inf) [[X:%.*]]) local_unnamed_addr #[[ATTR0]] { // SPVCHECK-NEXT: [[ENTRY:.*:]] // SPVCHECK-NEXT: [[SPV_SMOOTHSTEP_I:%.*]] = tail call reassoc nnan ninf nsz arcp afn noundef <3 x half> @llvm.spv.smoothstep.v3f16(<3 x half> nofpclass(nan inf) [[MIN]], <3 x half> nofpclass(nan inf) [[MAX]], <3 x half> nofpclass(nan inf) [[X]]) @@ -69,7 +69,7 @@ half2 test_smoothstep_half2(half2 Min, half2 Max, half2 X) { return smoothstep(M // half3 test_smoothstep_half3(half3 Min, half3 Max, half3 X) { return smoothstep(Min, Max, X); } -// CHECK-LABEL: define noundef nofpclass(nan inf) <4 x half> @_Z21test_smoothstep_half4Dv4_DhS_S_( +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) <4 x half> @_Z21test_smoothstep_half4Dv4_DhS_S_( // CHECK-SAME: <4 x half> noundef nofpclass(nan inf) [[MIN:%.*]], <4 x half> noundef nofpclass(nan inf) [[MAX:%.*]], <4 x half> noundef nofpclass(nan inf) [[X:%.*]]) local_unnamed_addr #[[ATTR0]] { // CHECK-NEXT: [[ENTRY:.*:]] // CHECK-NEXT: [[SUB_I:%.*]] = fsub reassoc nnan ninf nsz arcp afn <4 x half> [[X]], [[MIN]] @@ -82,7 +82,7 @@ half3 test_smoothstep_half3(half3 Min, half3 Max, half3 X) { return smoothstep(M // CHECK-NEXT: [[MUL4_I:%.*]] = fmul reassoc nnan ninf nsz arcp afn <4 x half> [[TMP0]], [[SUB2_I]] // CHECK-NEXT: ret <4 x half> [[MUL4_I]] // -// SPVCHECK-LABEL: define spir_func noundef nofpclass(nan inf) <4 x half> @_Z21test_smoothstep_half4Dv4_DhS_S_( +// SPVCHECK-LABEL: define hidden spir_func noundef nofpclass(nan inf) <4 x half> @_Z21test_smoothstep_half4Dv4_DhS_S_( // SPVCHECK-SAME: <4 x half> noundef nofpclass(nan inf) [[MIN:%.*]], <4 x half> noundef nofpclass(nan inf) [[MAX:%.*]], <4 x half> noundef nofpclass(nan inf) [[X:%.*]]) local_unnamed_addr #[[ATTR0]] { // SPVCHECK-NEXT: [[ENTRY:.*:]] // SPVCHECK-NEXT: [[SPV_SMOOTHSTEP_I:%.*]] = tail call reassoc nnan ninf nsz arcp afn noundef <4 x half> @llvm.spv.smoothstep.v4f16(<4 x half> nofpclass(nan inf) [[MIN]], <4 x half> nofpclass(nan inf) [[MAX]], <4 x half> nofpclass(nan inf) [[X]]) @@ -90,7 +90,7 @@ half3 test_smoothstep_half3(half3 Min, half3 Max, half3 X) { return smoothstep(M // half4 test_smoothstep_half4(half4 Min, half4 Max, half4 X) { return smoothstep(Min, Max, X); } -// CHECK-LABEL: define noundef nofpclass(nan inf) float @_Z21test_smoothstep_floatfff( +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) float @_Z21test_smoothstep_floatfff( // CHECK-SAME: float noundef nofpclass(nan inf) [[MIN:%.*]], float noundef nofpclass(nan inf) [[MAX:%.*]], float noundef nofpclass(nan inf) [[X:%.*]]) local_unnamed_addr #[[ATTR0]] { // CHECK-NEXT: [[ENTRY:.*:]] // CHECK-NEXT: [[SUB_I:%.*]] = fsub reassoc nnan ninf nsz arcp afn float [[X]], [[MIN]] @@ -103,7 +103,7 @@ half4 test_smoothstep_half4(half4 Min, half4 Max, half4 X) { return smoothstep(M // CHECK-NEXT: [[MUL4_I:%.*]] = fmul reassoc nnan ninf nsz arcp afn float [[TMP0]], [[SUB2_I]] // CHECK-NEXT: ret float [[MUL4_I]] // -// SPVCHECK-LABEL: define spir_func noundef nofpclass(nan inf) float @_Z21test_smoothstep_floatfff( +// SPVCHECK-LABEL: define hidden spir_func noundef nofpclass(nan inf) float @_Z21test_smoothstep_floatfff( // SPVCHECK-SAME: float noundef nofpclass(nan inf) [[MIN:%.*]], float noundef nofpclass(nan inf) [[MAX:%.*]], float noundef nofpclass(nan inf) [[X:%.*]]) local_unnamed_addr #[[ATTR0]] { // SPVCHECK-NEXT: [[ENTRY:.*:]] // SPVCHECK-NEXT: [[SPV_SMOOTHSTEP_I:%.*]] = tail call reassoc nnan ninf nsz arcp afn noundef float @llvm.spv.smoothstep.f32(float nofpclass(nan inf) [[MIN]], float nofpclass(nan inf) [[MAX]], float nofpclass(nan inf) [[X]]) @@ -111,7 +111,7 @@ half4 test_smoothstep_half4(half4 Min, half4 Max, half4 X) { return smoothstep(M // float test_smoothstep_float(float Min, float Max, float X) { return smoothstep(Min, Max, X); } -// CHECK-LABEL: define noundef nofpclass(nan inf) <2 x float> @_Z22test_smoothstep_float2Dv2_fS_S_( +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) <2 x float> @_Z22test_smoothstep_float2Dv2_fS_S_( // CHECK-SAME: <2 x float> noundef nofpclass(nan inf) [[MIN:%.*]], <2 x float> noundef nofpclass(nan inf) [[MAX:%.*]], <2 x float> noundef nofpclass(nan inf) [[X:%.*]]) local_unnamed_addr #[[ATTR0]] { // CHECK-NEXT: [[ENTRY:.*:]] // CHECK-NEXT: [[SUB_I:%.*]] = fsub reassoc nnan ninf nsz arcp afn <2 x float> [[X]], [[MIN]] @@ -124,7 +124,7 @@ float test_smoothstep_float(float Min, float Max, float X) { return smoothstep(M // CHECK-NEXT: [[MUL4_I:%.*]] = fmul reassoc nnan ninf nsz arcp afn <2 x float> [[TMP0]], [[SUB2_I]] // CHECK-NEXT: ret <2 x float> [[MUL4_I]] // -// SPVCHECK-LABEL: define spir_func noundef nofpclass(nan inf) <2 x float> @_Z22test_smoothstep_float2Dv2_fS_S_( +// SPVCHECK-LABEL: define hidden spir_func noundef nofpclass(nan inf) <2 x float> @_Z22test_smoothstep_float2Dv2_fS_S_( // SPVCHECK-SAME: <2 x float> noundef nofpclass(nan inf) [[MIN:%.*]], <2 x float> noundef nofpclass(nan inf) [[MAX:%.*]], <2 x float> noundef nofpclass(nan inf) [[X:%.*]]) local_unnamed_addr #[[ATTR0]] { // SPVCHECK-NEXT: [[ENTRY:.*:]] // SPVCHECK-NEXT: [[SPV_SMOOTHSTEP_I:%.*]] = tail call reassoc nnan ninf nsz arcp afn noundef <2 x float> @llvm.spv.smoothstep.v2f32(<2 x float> nofpclass(nan inf) [[MIN]], <2 x float> nofpclass(nan inf) [[MAX]], <2 x float> nofpclass(nan inf) [[X]]) @@ -132,7 +132,7 @@ float test_smoothstep_float(float Min, float Max, float X) { return smoothstep(M // float2 test_smoothstep_float2(float2 Min, float2 Max, float2 X) { return smoothstep(Min, Max, X); } -// CHECK-LABEL: define noundef nofpclass(nan inf) <3 x float> @_Z22test_smoothstep_float3Dv3_fS_S_( +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) <3 x float> @_Z22test_smoothstep_float3Dv3_fS_S_( // CHECK-SAME: <3 x float> noundef nofpclass(nan inf) [[MIN:%.*]], <3 x float> noundef nofpclass(nan inf) [[MAX:%.*]], <3 x float> noundef nofpclass(nan inf) [[X:%.*]]) local_unnamed_addr #[[ATTR0]] { // CHECK-NEXT: [[ENTRY:.*:]] // CHECK-NEXT: [[SUB_I:%.*]] = fsub reassoc nnan ninf nsz arcp afn <3 x float> [[X]], [[MIN]] @@ -145,7 +145,7 @@ float2 test_smoothstep_float2(float2 Min, float2 Max, float2 X) { return smooths // CHECK-NEXT: [[MUL4_I:%.*]] = fmul reassoc nnan ninf nsz arcp afn <3 x float> [[TMP0]], [[SUB2_I]] // CHECK-NEXT: ret <3 x float> [[MUL4_I]] // -// SPVCHECK-LABEL: define spir_func noundef nofpclass(nan inf) <3 x float> @_Z22test_smoothstep_float3Dv3_fS_S_( +// SPVCHECK-LABEL: define hidden spir_func noundef nofpclass(nan inf) <3 x float> @_Z22test_smoothstep_float3Dv3_fS_S_( // SPVCHECK-SAME: <3 x float> noundef nofpclass(nan inf) [[MIN:%.*]], <3 x float> noundef nofpclass(nan inf) [[MAX:%.*]], <3 x float> noundef nofpclass(nan inf) [[X:%.*]]) local_unnamed_addr #[[ATTR0]] { // SPVCHECK-NEXT: [[ENTRY:.*:]] // SPVCHECK-NEXT: [[SPV_SMOOTHSTEP_I:%.*]] = tail call reassoc nnan ninf nsz arcp afn noundef <3 x float> @llvm.spv.smoothstep.v3f32(<3 x float> nofpclass(nan inf) [[MIN]], <3 x float> nofpclass(nan inf) [[MAX]], <3 x float> nofpclass(nan inf) [[X]]) @@ -153,7 +153,7 @@ float2 test_smoothstep_float2(float2 Min, float2 Max, float2 X) { return smooths // float3 test_smoothstep_float3(float3 Min, float3 Max, float3 X) { return smoothstep(Min, Max, X); } -// CHECK-LABEL: define noundef nofpclass(nan inf) <4 x float> @_Z22test_smoothstep_float4Dv4_fS_S_( +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) <4 x float> @_Z22test_smoothstep_float4Dv4_fS_S_( // CHECK-SAME: <4 x float> noundef nofpclass(nan inf) [[MIN:%.*]], <4 x float> noundef nofpclass(nan inf) [[MAX:%.*]], <4 x float> noundef nofpclass(nan inf) [[X:%.*]]) local_unnamed_addr #[[ATTR0]] { // CHECK-NEXT: [[ENTRY:.*:]] // CHECK-NEXT: [[SUB_I:%.*]] = fsub reassoc nnan ninf nsz arcp afn <4 x float> [[X]], [[MIN]] @@ -166,7 +166,7 @@ float3 test_smoothstep_float3(float3 Min, float3 Max, float3 X) { return smooths // CHECK-NEXT: [[MUL4_I:%.*]] = fmul reassoc nnan ninf nsz arcp afn <4 x float> [[TMP0]], [[SUB2_I]] // CHECK-NEXT: ret <4 x float> [[MUL4_I]] // -// SPVCHECK-LABEL: define spir_func noundef nofpclass(nan inf) <4 x float> @_Z22test_smoothstep_float4Dv4_fS_S_( +// SPVCHECK-LABEL: define hidden spir_func noundef nofpclass(nan inf) <4 x float> @_Z22test_smoothstep_float4Dv4_fS_S_( // SPVCHECK-SAME: <4 x float> noundef nofpclass(nan inf) [[MIN:%.*]], <4 x float> noundef nofpclass(nan inf) [[MAX:%.*]], <4 x float> noundef nofpclass(nan inf) [[X:%.*]]) local_unnamed_addr #[[ATTR0]] { // SPVCHECK-NEXT: [[ENTRY:.*:]] // SPVCHECK-NEXT: [[SPV_SMOOTHSTEP_I:%.*]] = tail call reassoc nnan ninf nsz arcp afn noundef <4 x float> @llvm.spv.smoothstep.v4f32(<4 x float> nofpclass(nan inf) [[MIN]], <4 x float> nofpclass(nan inf) [[MAX]], <4 x float> nofpclass(nan inf) [[X]]) diff --git a/external/llvm-project/clang/test/CodeGenHLSL/builtins/splitdouble.hlsl b/external/llvm-project/clang/test/CodeGenHLSL/builtins/splitdouble.hlsl index a883c9d5cc35..aeb2b79e9029 100644 --- a/external/llvm-project/clang/test/CodeGenHLSL/builtins/splitdouble.hlsl +++ b/external/llvm-project/clang/test/CodeGenHLSL/builtins/splitdouble.hlsl @@ -8,7 +8,7 @@ // CHECK-NEXT: extractvalue { i32, i32 } [[VALRET]], 0 // CHECK-NEXT: extractvalue { i32, i32 } [[VALRET]], 1 // -// SPIRV: define spir_func {{.*}} i32 {{.*}}test_scalar{{.*}}(double {{.*}} [[VALD:%.*]]) +// SPIRV: define hidden spir_func {{.*}} i32 {{.*}}test_scalar{{.*}}(double {{.*}} [[VALD:%.*]]) // SPIRV-NOT: @llvm.dx.splitdouble.i32 // SPIRV: [[LOAD:%.*]] = load double, ptr [[VALD]].addr, align 8 // SPIRV-NEXT: [[CAST:%.*]] = bitcast double [[LOAD]] to <2 x i32> @@ -26,7 +26,7 @@ uint test_scalar(double D) { // CHECK-NEXT: extractvalue { i32, i32 } [[VALRET]], 0 // CHECK-NEXT: extractvalue { i32, i32 } [[VALRET]], 1 // -// SPIRV: define spir_func {{.*}} <1 x i32> {{.*}}test_double1{{.*}}(<1 x double> {{.*}} [[VALD:%.*]]) +// SPIRV: define hidden spir_func {{.*}} <1 x i32> {{.*}}test_double1{{.*}}(<1 x double> {{.*}} [[VALD:%.*]]) // SPIRV-NOT: @llvm.dx.splitdouble.i32 // SPIRV: [[LOAD:%.*]] = load <1 x double>, ptr [[VALD]].addr, align 8 // SPIRV-NEXT: [[TRUNC:%.*]] = extractelement <1 x double> [[LOAD]], i64 0 @@ -44,7 +44,7 @@ uint1 test_double1(double1 D) { // CHECK-NEXT: extractvalue { <2 x i32>, <2 x i32> } [[VALRET]], 0 // CHECK-NEXT: extractvalue { <2 x i32>, <2 x i32> } [[VALRET]], 1 // -// SPIRV: define spir_func {{.*}} <2 x i32> {{.*}}test_vector2{{.*}}(<2 x double> {{.*}} [[VALD:%.*]]) +// SPIRV: define hidden spir_func {{.*}} <2 x i32> {{.*}}test_vector2{{.*}}(<2 x double> {{.*}} [[VALD:%.*]]) // SPIRV-NOT: @llvm.dx.splitdouble.i32 // SPIRV: [[LOAD:%.*]] = load <2 x double>, ptr [[VALD]].addr, align 16 // SPIRV-NEXT: [[CAST1:%.*]] = bitcast <2 x double> [[LOAD]] to <4 x i32> @@ -61,7 +61,7 @@ uint2 test_vector2(double2 D) { // CHECK-NEXT: extractvalue { <3 x i32>, <3 x i32> } [[VALRET]], 0 // CHECK-NEXT: extractvalue { <3 x i32>, <3 x i32> } [[VALRET]], 1 // -// SPIRV: define spir_func {{.*}} <3 x i32> {{.*}}test_vector3{{.*}}(<3 x double> {{.*}} [[VALD:%.*]]) +// SPIRV: define hidden spir_func {{.*}} <3 x i32> {{.*}}test_vector3{{.*}}(<3 x double> {{.*}} [[VALD:%.*]]) // SPIRV-NOT: @llvm.dx.splitdouble.i32 // SPIRV: [[LOAD:%.*]] = load <3 x double>, ptr [[VALD]].addr, align 32 // SPIRV-NEXT: [[CAST1:%.*]] = bitcast <3 x double> [[LOAD]] to <6 x i32> @@ -78,7 +78,7 @@ uint3 test_vector3(double3 D) { // CHECK-NEXT: extractvalue { <4 x i32>, <4 x i32> } [[VALRET]], 0 // CHECK-NEXT: extractvalue { <4 x i32>, <4 x i32> } [[VALRET]], 1 // -// SPIRV: define spir_func {{.*}} <4 x i32> {{.*}}test_vector4{{.*}}(<4 x double> {{.*}} [[VALD:%.*]]) +// SPIRV: define hidden spir_func {{.*}} <4 x i32> {{.*}}test_vector4{{.*}}(<4 x double> {{.*}} [[VALD:%.*]]) // SPIRV-NOT: @llvm.dx.splitdouble.i32 // SPIRV: [[LOAD:%.*]] = load <4 x double>, ptr [[VALD]].addr, align 32 // SPIRV-NEXT: [[CAST1:%.*]] = bitcast <4 x double> [[LOAD]] to <8 x i32> diff --git a/external/llvm-project/clang/test/CodeGenHLSL/builtins/sqrt-overloads.hlsl b/external/llvm-project/clang/test/CodeGenHLSL/builtins/sqrt-overloads.hlsl index 48b74c9db5c6..d4de244f38b3 100644 --- a/external/llvm-project/clang/test/CodeGenHLSL/builtins/sqrt-overloads.hlsl +++ b/external/llvm-project/clang/test/CodeGenHLSL/builtins/sqrt-overloads.hlsl @@ -2,87 +2,87 @@ // RUN: -emit-llvm -disable-llvm-passes -o - | \ // RUN: FileCheck %s --check-prefixes=CHECK -// CHECK-LABEL: define noundef nofpclass(nan inf) float {{.*}}test_sqrt_double +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) float {{.*}}test_sqrt_double // CHECK: %{{.*}} = call reassoc nnan ninf nsz arcp afn float @llvm.sqrt.f32( // CHECK: ret float %{{.*}} float test_sqrt_double(double p0) { return sqrt(p0); } -// CHECK-LABEL: define noundef nofpclass(nan inf) <2 x float> {{.*}}test_sqrt_double2 +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) <2 x float> {{.*}}test_sqrt_double2 // CHECK: %{{.*}} = call reassoc nnan ninf nsz arcp afn <2 x float> @llvm.sqrt.v2f32 // CHECK: ret <2 x float> %{{.*}} float2 test_sqrt_double2(double2 p0) { return sqrt(p0); } -// CHECK-LABEL: define noundef nofpclass(nan inf) <3 x float> {{.*}}test_sqrt_double3 +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) <3 x float> {{.*}}test_sqrt_double3 // CHECK: %{{.*}} = call reassoc nnan ninf nsz arcp afn <3 x float> @llvm.sqrt.v3f32 // CHECK: ret <3 x float> %{{.*}} float3 test_sqrt_double3(double3 p0) { return sqrt(p0); } -// CHECK-LABEL: define noundef nofpclass(nan inf) <4 x float> {{.*}}test_sqrt_double4 +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) <4 x float> {{.*}}test_sqrt_double4 // CHECK: %{{.*}} = call reassoc nnan ninf nsz arcp afn <4 x float> @llvm.sqrt.v4f32 // CHECK: ret <4 x float> %{{.*}} float4 test_sqrt_double4(double4 p0) { return sqrt(p0); } -// CHECK-LABEL: define noundef nofpclass(nan inf) float {{.*}}test_sqrt_int +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) float {{.*}}test_sqrt_int // CHECK: %{{.*}} = call reassoc nnan ninf nsz arcp afn float @llvm.sqrt.f32( // CHECK: ret float %{{.*}} float test_sqrt_int(int p0) { return sqrt(p0); } -// CHECK-LABEL: define noundef nofpclass(nan inf) <2 x float> {{.*}}test_sqrt_int2 +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) <2 x float> {{.*}}test_sqrt_int2 // CHECK: %{{.*}} = call reassoc nnan ninf nsz arcp afn <2 x float> @llvm.sqrt.v2f32 // CHECK: ret <2 x float> %{{.*}} float2 test_sqrt_int2(int2 p0) { return sqrt(p0); } -// CHECK-LABEL: define noundef nofpclass(nan inf) <3 x float> {{.*}}test_sqrt_int3 +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) <3 x float> {{.*}}test_sqrt_int3 // CHECK: %{{.*}} = call reassoc nnan ninf nsz arcp afn <3 x float> @llvm.sqrt.v3f32 // CHECK: ret <3 x float> %{{.*}} float3 test_sqrt_int3(int3 p0) { return sqrt(p0); } -// CHECK-LABEL: define noundef nofpclass(nan inf) <4 x float> {{.*}}test_sqrt_int4 +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) <4 x float> {{.*}}test_sqrt_int4 // CHECK: %{{.*}} = call reassoc nnan ninf nsz arcp afn <4 x float> @llvm.sqrt.v4f32 // CHECK: ret <4 x float> %{{.*}} float4 test_sqrt_int4(int4 p0) { return sqrt(p0); } -// CHECK-LABEL: define noundef nofpclass(nan inf) float {{.*}}test_sqrt_uint +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) float {{.*}}test_sqrt_uint // CHECK: %{{.*}} = call reassoc nnan ninf nsz arcp afn float @llvm.sqrt.f32( // CHECK: ret float %{{.*}} float test_sqrt_uint(uint p0) { return sqrt(p0); } -// CHECK-LABEL: define noundef nofpclass(nan inf) <2 x float> {{.*}}test_sqrt_uint2 +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) <2 x float> {{.*}}test_sqrt_uint2 // CHECK: %{{.*}} = call reassoc nnan ninf nsz arcp afn <2 x float> @llvm.sqrt.v2f32 // CHECK: ret <2 x float> %{{.*}} float2 test_sqrt_uint2(uint2 p0) { return sqrt(p0); } -// CHECK-LABEL: define noundef nofpclass(nan inf) <3 x float> {{.*}}test_sqrt_uint3 +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) <3 x float> {{.*}}test_sqrt_uint3 // CHECK: %{{.*}} = call reassoc nnan ninf nsz arcp afn <3 x float> @llvm.sqrt.v3f32 // CHECK: ret <3 x float> %{{.*}} float3 test_sqrt_uint3(uint3 p0) { return sqrt(p0); } -// CHECK-LABEL: define noundef nofpclass(nan inf) <4 x float> {{.*}}test_sqrt_uint4 +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) <4 x float> {{.*}}test_sqrt_uint4 // CHECK: %{{.*}} = call reassoc nnan ninf nsz arcp afn <4 x float> @llvm.sqrt.v4f32 // CHECK: ret <4 x float> %{{.*}} float4 test_sqrt_uint4(uint4 p0) { return sqrt(p0); } -// CHECK-LABEL: define noundef nofpclass(nan inf) float {{.*}}test_sqrt_int64_t +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) float {{.*}}test_sqrt_int64_t // CHECK: %{{.*}} = call reassoc nnan ninf nsz arcp afn float @llvm.sqrt.f32( // CHECK: ret float %{{.*}} float test_sqrt_int64_t(int64_t p0) { return sqrt(p0); } -// CHECK-LABEL: define noundef nofpclass(nan inf) <2 x float> {{.*}}test_sqrt_int64_t2 +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) <2 x float> {{.*}}test_sqrt_int64_t2 // CHECK: %{{.*}} = call reassoc nnan ninf nsz arcp afn <2 x float> @llvm.sqrt.v2f32 // CHECK: ret <2 x float> %{{.*}} float2 test_sqrt_int64_t2(int64_t2 p0) { return sqrt(p0); } -// CHECK-LABEL: define noundef nofpclass(nan inf) <3 x float> {{.*}}test_sqrt_int64_t3 +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) <3 x float> {{.*}}test_sqrt_int64_t3 // CHECK: %{{.*}} = call reassoc nnan ninf nsz arcp afn <3 x float> @llvm.sqrt.v3f32 // CHECK: ret <3 x float> %{{.*}} float3 test_sqrt_int64_t3(int64_t3 p0) { return sqrt(p0); } -// CHECK-LABEL: define noundef nofpclass(nan inf) <4 x float> {{.*}}test_sqrt_int64_t4 +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) <4 x float> {{.*}}test_sqrt_int64_t4 // CHECK: %{{.*}} = call reassoc nnan ninf nsz arcp afn <4 x float> @llvm.sqrt.v4f32 // CHECK: ret <4 x float> %{{.*}} float4 test_sqrt_int64_t4(int64_t4 p0) { return sqrt(p0); } -// CHECK-LABEL: define noundef nofpclass(nan inf) float {{.*}}test_sqrt_uint64_t +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) float {{.*}}test_sqrt_uint64_t // CHECK: %{{.*}} = call reassoc nnan ninf nsz arcp afn float @llvm.sqrt.f32( // CHECK: ret float %{{.*}} float test_sqrt_uint64_t(uint64_t p0) { return sqrt(p0); } -// CHECK-LABEL: define noundef nofpclass(nan inf) <2 x float> {{.*}}test_sqrt_uint64_t2 +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) <2 x float> {{.*}}test_sqrt_uint64_t2 // CHECK: %{{.*}} = call reassoc nnan ninf nsz arcp afn <2 x float> @llvm.sqrt.v2f32 // CHECK: ret <2 x float> %{{.*}} float2 test_sqrt_uint64_t2(uint64_t2 p0) { return sqrt(p0); } -// CHECK-LABEL: define noundef nofpclass(nan inf) <3 x float> {{.*}}test_sqrt_uint64_t3 +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) <3 x float> {{.*}}test_sqrt_uint64_t3 // CHECK: %{{.*}} = call reassoc nnan ninf nsz arcp afn <3 x float> @llvm.sqrt.v3f32 // CHECK: ret <3 x float> %{{.*}} float3 test_sqrt_uint64_t3(uint64_t3 p0) { return sqrt(p0); } -// CHECK-LABEL: define noundef nofpclass(nan inf) <4 x float> {{.*}}test_sqrt_uint64_t4 +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) <4 x float> {{.*}}test_sqrt_uint64_t4 // CHECK: %{{.*}} = call reassoc nnan ninf nsz arcp afn <4 x float> @llvm.sqrt.v4f32 // CHECK: ret <4 x float> %{{.*}} float4 test_sqrt_uint64_t4(uint64_t4 p0) { return sqrt(p0); } diff --git a/external/llvm-project/clang/test/CodeGenHLSL/builtins/sqrt.hlsl b/external/llvm-project/clang/test/CodeGenHLSL/builtins/sqrt.hlsl index 94d966f0bef8..31839f6bc177 100644 --- a/external/llvm-project/clang/test/CodeGenHLSL/builtins/sqrt.hlsl +++ b/external/llvm-project/clang/test/CodeGenHLSL/builtins/sqrt.hlsl @@ -5,48 +5,48 @@ // RUN: -emit-llvm -disable-llvm-passes -o - | \ // RUN: FileCheck %s --check-prefixes=CHECK,NO_HALF -// NATIVE_HALF-LABEL: define noundef nofpclass(nan inf) half @_Z14test_sqrt_half +// NATIVE_HALF-LABEL: define hidden noundef nofpclass(nan inf) half @_Z14test_sqrt_half // NATIVE_HALF: %{{.*}} = call reassoc nnan ninf nsz arcp afn half @llvm.sqrt.f16( // NATIVE_HALF: ret half %{{.*}} -// NO_HALF-LABEL: define noundef nofpclass(nan inf) float @_Z14test_sqrt_half +// NO_HALF-LABEL: define hidden noundef nofpclass(nan inf) float @_Z14test_sqrt_half // NO_HALF: %{{.*}} = call reassoc nnan ninf nsz arcp afn float @llvm.sqrt.f32( // NO_HALF: ret float %{{.*}} half test_sqrt_half(half p0) { return sqrt(p0); } -// NATIVE_HALF-LABEL: define noundef nofpclass(nan inf) <2 x half> @_Z15test_sqrt_half2 +// NATIVE_HALF-LABEL: define hidden noundef nofpclass(nan inf) <2 x half> @_Z15test_sqrt_half2 // NATIVE_HALF: %{{.*}} = call reassoc nnan ninf nsz arcp afn <2 x half> @llvm.sqrt.v2f16 // NATIVE_HALF: ret <2 x half> %{{.*}} -// NO_HALF-LABEL: define noundef nofpclass(nan inf) <2 x float> @_Z15test_sqrt_half2 +// NO_HALF-LABEL: define hidden noundef nofpclass(nan inf) <2 x float> @_Z15test_sqrt_half2 // NO_HALF: %{{.*}} = call reassoc nnan ninf nsz arcp afn <2 x float> @llvm.sqrt.v2f32( // NO_HALF: ret <2 x float> %{{.*}} half2 test_sqrt_half2(half2 p0) { return sqrt(p0); } -// NATIVE_HALF-LABEL: define noundef nofpclass(nan inf) <3 x half> @_Z15test_sqrt_half3 +// NATIVE_HALF-LABEL: define hidden noundef nofpclass(nan inf) <3 x half> @_Z15test_sqrt_half3 // NATIVE_HALF: %{{.*}} = call reassoc nnan ninf nsz arcp afn <3 x half> @llvm.sqrt.v3f16 // NATIVE_HALF: ret <3 x half> %{{.*}} -// NO_HALF-LABEL: define noundef nofpclass(nan inf) <3 x float> @_Z15test_sqrt_half3 +// NO_HALF-LABEL: define hidden noundef nofpclass(nan inf) <3 x float> @_Z15test_sqrt_half3 // NO_HALF: %{{.*}} = call reassoc nnan ninf nsz arcp afn <3 x float> @llvm.sqrt.v3f32( // NO_HALF: ret <3 x float> %{{.*}} half3 test_sqrt_half3(half3 p0) { return sqrt(p0); } -// NATIVE_HALF-LABEL: define noundef nofpclass(nan inf) <4 x half> @_Z15test_sqrt_half4 +// NATIVE_HALF-LABEL: define hidden noundef nofpclass(nan inf) <4 x half> @_Z15test_sqrt_half4 // NATIVE_HALF: %{{.*}} = call reassoc nnan ninf nsz arcp afn <4 x half> @llvm.sqrt.v4f16 // NATIVE_HALF: ret <4 x half> %{{.*}} -// NO_HALF-LABEL: define noundef nofpclass(nan inf) <4 x float> @_Z15test_sqrt_half4 +// NO_HALF-LABEL: define hidden noundef nofpclass(nan inf) <4 x float> @_Z15test_sqrt_half4 // NO_HALF: %{{.*}} = call reassoc nnan ninf nsz arcp afn <4 x float> @llvm.sqrt.v4f32( // NO_HALF: ret <4 x float> %{{.*}} half4 test_sqrt_half4(half4 p0) { return sqrt(p0); } -// CHECK-LABEL: define noundef nofpclass(nan inf) float @_Z15test_sqrt_float +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) float @_Z15test_sqrt_float // CHECK: %{{.*}} = call reassoc nnan ninf nsz arcp afn float @llvm.sqrt.f32( // CHECK: ret float %{{.*}} float test_sqrt_float(float p0) { return sqrt(p0); } -// CHECK-LABEL: define noundef nofpclass(nan inf) <2 x float> @_Z16test_sqrt_float2 +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) <2 x float> @_Z16test_sqrt_float2 // CHECK: %{{.*}} = call reassoc nnan ninf nsz arcp afn <2 x float> @llvm.sqrt.v2f32 // CHECK: ret <2 x float> %{{.*}} float2 test_sqrt_float2(float2 p0) { return sqrt(p0); } -// CHECK-LABEL: define noundef nofpclass(nan inf) <3 x float> @_Z16test_sqrt_float3 +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) <3 x float> @_Z16test_sqrt_float3 // CHECK: %{{.*}} = call reassoc nnan ninf nsz arcp afn <3 x float> @llvm.sqrt.v3f32 // CHECK: ret <3 x float> %{{.*}} float3 test_sqrt_float3(float3 p0) { return sqrt(p0); } -// CHECK-LABEL: define noundef nofpclass(nan inf) <4 x float> @_Z16test_sqrt_float4 +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) <4 x float> @_Z16test_sqrt_float4 // CHECK: %{{.*}} = call reassoc nnan ninf nsz arcp afn <4 x float> @llvm.sqrt.v4f32 // CHECK: ret <4 x float> %{{.*}} float4 test_sqrt_float4(float4 p0) { return sqrt(p0); } diff --git a/external/llvm-project/clang/test/CodeGenHLSL/builtins/step-overloads.hlsl b/external/llvm-project/clang/test/CodeGenHLSL/builtins/step-overloads.hlsl index d3b979254391..f55a8f8aff92 100644 --- a/external/llvm-project/clang/test/CodeGenHLSL/builtins/step-overloads.hlsl +++ b/external/llvm-project/clang/test/CodeGenHLSL/builtins/step-overloads.hlsl @@ -1,11 +1,11 @@ // RUN: %clang_cc1 -std=hlsl202x -finclude-default-header -x hlsl -triple \ // RUN: dxil-pc-shadermodel6.3-library %s -emit-llvm -disable-llvm-passes \ // RUN: -o - | FileCheck %s --check-prefixes=CHECK \ -// RUN: -DFNATTRS="noundef nofpclass(nan inf)" -DTARGET=dx +// RUN: -DFNATTRS="hidden noundef nofpclass(nan inf)" -DTARGET=dx // RUN: %clang_cc1 -std=hlsl202x -finclude-default-header -x hlsl -triple \ // RUN: spirv-unknown-vulkan-compute %s -emit-llvm -disable-llvm-passes \ // RUN: -o - | FileCheck %s --check-prefixes=CHECK \ -// RUN: -DFNATTRS="spir_func noundef nofpclass(nan inf)" -DTARGET=spv +// RUN: -DFNATTRS="hidden spir_func noundef nofpclass(nan inf)" -DTARGET=spv // CHECK: define [[FNATTRS]] float @ // CHECK: call reassoc nnan ninf nsz arcp afn float @llvm.[[TARGET]].step.f32(float diff --git a/external/llvm-project/clang/test/CodeGenHLSL/builtins/step.hlsl b/external/llvm-project/clang/test/CodeGenHLSL/builtins/step.hlsl index 49d09e5c6fe6..be0ffbd79464 100644 --- a/external/llvm-project/clang/test/CodeGenHLSL/builtins/step.hlsl +++ b/external/llvm-project/clang/test/CodeGenHLSL/builtins/step.hlsl @@ -2,20 +2,20 @@ // RUN: dxil-pc-shadermodel6.3-library %s -fnative-half-type \ // RUN: -emit-llvm -disable-llvm-passes -o - | FileCheck %s \ // RUN: --check-prefixes=CHECK,NATIVE_HALF \ -// RUN: -DFNATTRS="noundef nofpclass(nan inf)" -DTARGET=dx +// RUN: -DFNATTRS="hidden noundef nofpclass(nan inf)" -DTARGET=dx // RUN: %clang_cc1 -finclude-default-header -x hlsl -triple \ // RUN: dxil-pc-shadermodel6.3-library %s -emit-llvm -disable-llvm-passes \ // RUN: -o - | FileCheck %s --check-prefixes=CHECK,NO_HALF \ -// RUN: -DFNATTRS="noundef nofpclass(nan inf)" -DTARGET=dx +// RUN: -DFNATTRS="hidden noundef nofpclass(nan inf)" -DTARGET=dx // RUN: %clang_cc1 -finclude-default-header -x hlsl -triple \ // RUN: spirv-unknown-vulkan-compute %s -fnative-half-type \ // RUN: -emit-llvm -disable-llvm-passes -o - | FileCheck %s \ // RUN: --check-prefixes=CHECK,NATIVE_HALF \ -// RUN: -DFNATTRS="spir_func noundef nofpclass(nan inf)" -DTARGET=spv +// RUN: -DFNATTRS="hidden spir_func noundef nofpclass(nan inf)" -DTARGET=spv // RUN: %clang_cc1 -finclude-default-header -x hlsl -triple \ // RUN: spirv-unknown-vulkan-compute %s -emit-llvm -disable-llvm-passes \ // RUN: -o - | FileCheck %s --check-prefixes=CHECK,NO_HALF \ -// RUN: -DFNATTRS="spir_func noundef nofpclass(nan inf)" -DTARGET=spv +// RUN: -DFNATTRS="hidden spir_func noundef nofpclass(nan inf)" -DTARGET=spv // NATIVE_HALF: define [[FNATTRS]] half @ // NATIVE_HALF: call reassoc nnan ninf nsz arcp afn half @llvm.[[TARGET]].step.f16(half diff --git a/external/llvm-project/clang/test/CodeGenHLSL/builtins/trunc-overloads.hlsl b/external/llvm-project/clang/test/CodeGenHLSL/builtins/trunc-overloads.hlsl index d913aabfb406..51eb20c58e40 100644 --- a/external/llvm-project/clang/test/CodeGenHLSL/builtins/trunc-overloads.hlsl +++ b/external/llvm-project/clang/test/CodeGenHLSL/builtins/trunc-overloads.hlsl @@ -2,82 +2,82 @@ // RUN: -emit-llvm -disable-llvm-passes -o - | \ // RUN: FileCheck %s --check-prefixes=CHECK -// CHECK-LABEL: define noundef nofpclass(nan inf) float {{.*}}test_trunc_double +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) float {{.*}}test_trunc_double // CHECK: call reassoc nnan ninf nsz arcp afn float @llvm.trunc.f32( float test_trunc_double(double p0) { return trunc(p0); } -// CHECK-LABEL: define noundef nofpclass(nan inf) <2 x float> {{.*}}test_trunc_double2 +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) <2 x float> {{.*}}test_trunc_double2 // CHECK: call reassoc nnan ninf nsz arcp afn <2 x float> @llvm.trunc.v2f32 float2 test_trunc_double2(double2 p0) { return trunc(p0); } -// CHECK-LABEL: define noundef nofpclass(nan inf) <3 x float> {{.*}}test_trunc_double3 +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) <3 x float> {{.*}}test_trunc_double3 // CHECK: call reassoc nnan ninf nsz arcp afn <3 x float> @llvm.trunc.v3f32 float3 test_trunc_double3(double3 p0) { return trunc(p0); } -// CHECK-LABEL: define noundef nofpclass(nan inf) <4 x float> {{.*}}test_trunc_double4 +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) <4 x float> {{.*}}test_trunc_double4 // CHECK: call reassoc nnan ninf nsz arcp afn <4 x float> @llvm.trunc.v4f32 float4 test_trunc_double4(double4 p0) { return trunc(p0); } -// CHECK-LABEL: define noundef nofpclass(nan inf) float {{.*}}test_trunc_int +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) float {{.*}}test_trunc_int // CHECK: call reassoc nnan ninf nsz arcp afn float @llvm.trunc.f32( float test_trunc_int(int p0) { return trunc(p0); } -// CHECK-LABEL: define noundef nofpclass(nan inf) <2 x float> {{.*}}test_trunc_int2 +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) <2 x float> {{.*}}test_trunc_int2 // CHECK: call reassoc nnan ninf nsz arcp afn <2 x float> @llvm.trunc.v2f32 float2 test_trunc_int2(int2 p0) { return trunc(p0); } -// CHECK-LABEL: define noundef nofpclass(nan inf) <3 x float> {{.*}}test_trunc_int3 +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) <3 x float> {{.*}}test_trunc_int3 // CHECK: call reassoc nnan ninf nsz arcp afn <3 x float> @llvm.trunc.v3f32 float3 test_trunc_int3(int3 p0) { return trunc(p0); } -// CHECK-LABEL: define noundef nofpclass(nan inf) <4 x float> {{.*}}test_trunc_int4 +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) <4 x float> {{.*}}test_trunc_int4 // CHECK: call reassoc nnan ninf nsz arcp afn <4 x float> @llvm.trunc.v4f32 float4 test_trunc_int4(int4 p0) { return trunc(p0); } -// CHECK-LABEL: define noundef nofpclass(nan inf) float {{.*}}test_trunc_uint +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) float {{.*}}test_trunc_uint // CHECK: call reassoc nnan ninf nsz arcp afn float @llvm.trunc.f32( float test_trunc_uint(uint p0) { return trunc(p0); } -// CHECK-LABEL: define noundef nofpclass(nan inf) <2 x float> {{.*}}test_trunc_uint2 +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) <2 x float> {{.*}}test_trunc_uint2 // CHECK: call reassoc nnan ninf nsz arcp afn <2 x float> @llvm.trunc.v2f32 float2 test_trunc_uint2(uint2 p0) { return trunc(p0); } -// CHECK-LABEL: define noundef nofpclass(nan inf) <3 x float> {{.*}}test_trunc_uint3 +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) <3 x float> {{.*}}test_trunc_uint3 // CHECK: call reassoc nnan ninf nsz arcp afn <3 x float> @llvm.trunc.v3f32 float3 test_trunc_uint3(uint3 p0) { return trunc(p0); } -// CHECK-LABEL: define noundef nofpclass(nan inf) <4 x float> {{.*}}test_trunc_uint4 +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) <4 x float> {{.*}}test_trunc_uint4 // CHECK: call reassoc nnan ninf nsz arcp afn <4 x float> @llvm.trunc.v4f32 float4 test_trunc_uint4(uint4 p0) { return trunc(p0); } -// CHECK-LABEL: define noundef nofpclass(nan inf) float {{.*}}test_trunc_int64_t +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) float {{.*}}test_trunc_int64_t // CHECK: call reassoc nnan ninf nsz arcp afn float @llvm.trunc.f32( float test_trunc_int64_t(int64_t p0) { return trunc(p0); } -// CHECK-LABEL: define noundef nofpclass(nan inf) <2 x float> {{.*}}test_trunc_int64_t2 +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) <2 x float> {{.*}}test_trunc_int64_t2 // CHECK: call reassoc nnan ninf nsz arcp afn <2 x float> @llvm.trunc.v2f32 float2 test_trunc_int64_t2(int64_t2 p0) { return trunc(p0); } -// CHECK-LABEL: define noundef nofpclass(nan inf) <3 x float> {{.*}}test_trunc_int64_t3 +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) <3 x float> {{.*}}test_trunc_int64_t3 // CHECK: call reassoc nnan ninf nsz arcp afn <3 x float> @llvm.trunc.v3f32 float3 test_trunc_int64_t3(int64_t3 p0) { return trunc(p0); } -// CHECK-LABEL: define noundef nofpclass(nan inf) <4 x float> {{.*}}test_trunc_int64_t4 +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) <4 x float> {{.*}}test_trunc_int64_t4 // CHECK: call reassoc nnan ninf nsz arcp afn <4 x float> @llvm.trunc.v4f32 float4 test_trunc_int64_t4(int64_t4 p0) { return trunc(p0); } -// CHECK-LABEL: define noundef nofpclass(nan inf) float {{.*}}test_trunc_uint64_t +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) float {{.*}}test_trunc_uint64_t // CHECK: call reassoc nnan ninf nsz arcp afn float @llvm.trunc.f32( float test_trunc_uint64_t(uint64_t p0) { return trunc(p0); } -// CHECK-LABEL: define noundef nofpclass(nan inf) <2 x float> {{.*}}test_trunc_uint64_t2 +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) <2 x float> {{.*}}test_trunc_uint64_t2 // CHECK: call reassoc nnan ninf nsz arcp afn <2 x float> @llvm.trunc.v2f32 float2 test_trunc_uint64_t2(uint64_t2 p0) { return trunc(p0); } -// CHECK-LABEL: define noundef nofpclass(nan inf) <3 x float> {{.*}}test_trunc_uint64_t3 +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) <3 x float> {{.*}}test_trunc_uint64_t3 // CHECK: call reassoc nnan ninf nsz arcp afn <3 x float> @llvm.trunc.v3f32 float3 test_trunc_uint64_t3(uint64_t3 p0) { return trunc(p0); } -// CHECK-LABEL: define noundef nofpclass(nan inf) <4 x float> {{.*}}test_trunc_uint64_t4 +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) <4 x float> {{.*}}test_trunc_uint64_t4 // CHECK: call reassoc nnan ninf nsz arcp afn <4 x float> @llvm.trunc.v4f32 float4 test_trunc_uint64_t4(uint64_t4 p0) { return trunc(p0); } diff --git a/external/llvm-project/clang/test/CodeGenHLSL/builtins/trunc.hlsl b/external/llvm-project/clang/test/CodeGenHLSL/builtins/trunc.hlsl index 26de5bf94c3c..c1c6ee4119f0 100644 --- a/external/llvm-project/clang/test/CodeGenHLSL/builtins/trunc.hlsl +++ b/external/llvm-project/clang/test/CodeGenHLSL/builtins/trunc.hlsl @@ -5,42 +5,42 @@ // RUN: -emit-llvm -disable-llvm-passes -o - | \ // RUN: FileCheck %s --check-prefixes=CHECK,NO_HALF -// NATIVE_HALF-LABEL: define noundef nofpclass(nan inf) half @_Z15test_trunc_half +// NATIVE_HALF-LABEL: define hidden noundef nofpclass(nan inf) half @_Z15test_trunc_half // NATIVE_HALF: call reassoc nnan ninf nsz arcp afn half @llvm.trunc.f16( -// NO_HALF-LABEL: define noundef nofpclass(nan inf) float @_Z15test_trunc_half +// NO_HALF-LABEL: define hidden noundef nofpclass(nan inf) float @_Z15test_trunc_half // NO_HALF: call reassoc nnan ninf nsz arcp afn float @llvm.trunc.f32( half test_trunc_half(half p0) { return trunc(p0); } -// NATIVE_HALF-LABEL: define noundef nofpclass(nan inf) <2 x half> @_Z16test_trunc_half2 +// NATIVE_HALF-LABEL: define hidden noundef nofpclass(nan inf) <2 x half> @_Z16test_trunc_half2 // NATIVE_HALF: call reassoc nnan ninf nsz arcp afn <2 x half> @llvm.trunc.v2f16 -// NO_HALF-LABEL: define noundef nofpclass(nan inf) <2 x float> @_Z16test_trunc_half2 +// NO_HALF-LABEL: define hidden noundef nofpclass(nan inf) <2 x float> @_Z16test_trunc_half2 // NO_HALF: call reassoc nnan ninf nsz arcp afn <2 x float> @llvm.trunc.v2f32( half2 test_trunc_half2(half2 p0) { return trunc(p0); } -// NATIVE_HALF-LABEL: define noundef nofpclass(nan inf) <3 x half> @_Z16test_trunc_half3 +// NATIVE_HALF-LABEL: define hidden noundef nofpclass(nan inf) <3 x half> @_Z16test_trunc_half3 // NATIVE_HALF: call reassoc nnan ninf nsz arcp afn <3 x half> @llvm.trunc.v3f16 -// NO_HALF-LABEL: define noundef nofpclass(nan inf) <3 x float> @_Z16test_trunc_half3 +// NO_HALF-LABEL: define hidden noundef nofpclass(nan inf) <3 x float> @_Z16test_trunc_half3 // NO_HALF: call reassoc nnan ninf nsz arcp afn <3 x float> @llvm.trunc.v3f32( half3 test_trunc_half3(half3 p0) { return trunc(p0); } -// NATIVE_HALF-LABEL: define noundef nofpclass(nan inf) <4 x half> @_Z16test_trunc_half4 +// NATIVE_HALF-LABEL: define hidden noundef nofpclass(nan inf) <4 x half> @_Z16test_trunc_half4 // NATIVE_HALF: call reassoc nnan ninf nsz arcp afn <4 x half> @llvm.trunc.v4f16 -// NO_HALF-LABEL: define noundef nofpclass(nan inf) <4 x float> @_Z16test_trunc_half4 +// NO_HALF-LABEL: define hidden noundef nofpclass(nan inf) <4 x float> @_Z16test_trunc_half4 // NO_HALF: call reassoc nnan ninf nsz arcp afn <4 x float> @llvm.trunc.v4f32( half4 test_trunc_half4(half4 p0) { return trunc(p0); } -// CHECK-LABEL: define noundef nofpclass(nan inf) float @_Z16test_trunc_float +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) float @_Z16test_trunc_float // CHECK: call reassoc nnan ninf nsz arcp afn float @llvm.trunc.f32( float test_trunc_float(float p0) { return trunc(p0); } -// CHECK-LABEL: define noundef nofpclass(nan inf) <2 x float> @_Z17test_trunc_float2 +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) <2 x float> @_Z17test_trunc_float2 // CHECK: call reassoc nnan ninf nsz arcp afn <2 x float> @llvm.trunc.v2f32 float2 test_trunc_float2(float2 p0) { return trunc(p0); } -// CHECK-LABEL: define noundef nofpclass(nan inf) <3 x float> @_Z17test_trunc_float3 +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) <3 x float> @_Z17test_trunc_float3 // CHECK: call reassoc nnan ninf nsz arcp afn <3 x float> @llvm.trunc.v3f32 float3 test_trunc_float3(float3 p0) { return trunc(p0); } -// CHECK-LABEL: define noundef nofpclass(nan inf) <4 x float> @_Z17test_trunc_float4 +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) <4 x float> @_Z17test_trunc_float4 // CHECK: call reassoc nnan ninf nsz arcp afn <4 x float> @llvm.trunc.v4f32 float4 test_trunc_float4(float4 p0) { return trunc(p0); } diff --git a/external/llvm-project/clang/test/CodeGenHLSL/builtins/wave_get_lane_index_do_while.hlsl b/external/llvm-project/clang/test/CodeGenHLSL/builtins/wave_get_lane_index_do_while.hlsl index 3ab8048146ad..0df3598a3cc3 100644 --- a/external/llvm-project/clang/test/CodeGenHLSL/builtins/wave_get_lane_index_do_while.hlsl +++ b/external/llvm-project/clang/test/CodeGenHLSL/builtins/wave_get_lane_index_do_while.hlsl @@ -1,7 +1,7 @@ // RUN: %clang_cc1 -std=hlsl2021 -finclude-default-header -x hlsl -triple \ // RUN: spirv-pc-vulkan-library %s -emit-llvm -disable-llvm-passes -o - | FileCheck %s -// CHECK: define spir_func void @{{.*main.*}}() [[A0:#[0-9]+]] { +// CHECK: define hidden spir_func void @{{.*main.*}}() [[A0:#[0-9]+]] { void main() { // CHECK: entry: // CHECK: %[[CT_ENTRY:[0-9]+]] = call token @llvm.experimental.convergence.entry() diff --git a/external/llvm-project/clang/test/CodeGenHLSL/builtins/wave_get_lane_index_simple.hlsl b/external/llvm-project/clang/test/CodeGenHLSL/builtins/wave_get_lane_index_simple.hlsl index 8e1f2d69e743..9034cae25403 100644 --- a/external/llvm-project/clang/test/CodeGenHLSL/builtins/wave_get_lane_index_simple.hlsl +++ b/external/llvm-project/clang/test/CodeGenHLSL/builtins/wave_get_lane_index_simple.hlsl @@ -6,8 +6,8 @@ // RUN: -emit-llvm -disable-llvm-passes -o - | FileCheck %s \ // RUN: --check-prefixes=CHECK,CHECK-DXIL -// CHECK-SPIRV: define spir_func noundef i32 @{{.*test_1.*}}() [[A0:#[0-9]+]] { -// CHECK-DXIL: define noundef i32 @{{.*test_1.*}}() [[A0:#[0-9]+]] { +// CHECK-SPIRV: define hidden spir_func noundef i32 @{{.*test_1.*}}() [[A0:#[0-9]+]] { +// CHECK-DXIL: define hidden noundef i32 @{{.*test_1.*}}() [[A0:#[0-9]+]] { // CHECK-SPIRV: %[[CI:[0-9]+]] = call token @llvm.experimental.convergence.entry() // CHECK-SPIRV: call spir_func i32 @__hlsl_wave_get_lane_index() [ "convergencectrl"(token %[[CI]]) ] // CHECK-DXIL: call i32 @llvm.dx.wave.getlaneindex() diff --git a/external/llvm-project/clang/test/CodeGenHLSL/builtins/wave_get_lane_index_subcall.hlsl b/external/llvm-project/clang/test/CodeGenHLSL/builtins/wave_get_lane_index_subcall.hlsl index 12b120d0c067..a71b988417f0 100644 --- a/external/llvm-project/clang/test/CodeGenHLSL/builtins/wave_get_lane_index_subcall.hlsl +++ b/external/llvm-project/clang/test/CodeGenHLSL/builtins/wave_get_lane_index_subcall.hlsl @@ -1,7 +1,7 @@ // RUN: %clang_cc1 -std=hlsl2021 -finclude-default-header -x hlsl -triple \ // RUN: spirv-pc-vulkan-library %s -emit-llvm -disable-llvm-passes -o - | FileCheck %s -// CHECK: define spir_func noundef i32 @_Z6test_1v() [[A0:#[0-9]+]] { +// CHECK: define hidden spir_func noundef i32 @_Z6test_1v() [[A0:#[0-9]+]] { // CHECK: %[[C1:[0-9]+]] = call token @llvm.experimental.convergence.entry() // CHECK: call spir_func i32 @__hlsl_wave_get_lane_index() [ "convergencectrl"(token %[[C1]]) ] uint test_1() { @@ -10,7 +10,7 @@ uint test_1() { // CHECK-DAG: declare spir_func i32 @__hlsl_wave_get_lane_index() [[A1:#[0-9]+]] -// CHECK: define spir_func noundef i32 @_Z6test_2v() [[A0]] { +// CHECK: define hidden spir_func noundef i32 @_Z6test_2v() [[A0]] { // CHECK: %[[C2:[0-9]+]] = call token @llvm.experimental.convergence.entry() // CHECK: call spir_func noundef i32 @_Z6test_1v() {{#[0-9]+}} [ "convergencectrl"(token %[[C2]]) ] uint test_2() { diff --git a/external/llvm-project/clang/test/CodeGenHLSL/cbuffer.hlsl b/external/llvm-project/clang/test/CodeGenHLSL/cbuffer.hlsl index eebf0f682d3d..b58a49b41eb9 100644 --- a/external/llvm-project/clang/test/CodeGenHLSL/cbuffer.hlsl +++ b/external/llvm-project/clang/test/CodeGenHLSL/cbuffer.hlsl @@ -46,14 +46,14 @@ cbuffer CBScalars : register(b1, space5) { // CHECK: @CBScalars.cb = global target("dx.CBuffer", target("dx.Layout", %__cblayout_CBScalars, // CHECK-SAME: 56, 0, 8, 16, 24, 32, 36, 40, 48)) -// CHECK: @a1 = external addrspace(2) global float, align 4 -// CHECK: @a2 = external addrspace(2) global double, align 8 -// CHECK: @a3 = external addrspace(2) global half, align 2 -// CHECK: @a4 = external addrspace(2) global i64, align 8 -// CHECK: @a5 = external addrspace(2) global i32, align 4 -// CHECK: @a6 = external addrspace(2) global i16, align 2 -// CHECK: @a7 = external addrspace(2) global i32, align 4 -// CHECK: @a8 = external addrspace(2) global i64, align 8 +// CHECK: @a1 = external hidden addrspace(2) global float, align 4 +// CHECK: @a2 = external hidden addrspace(2) global double, align 8 +// CHECK: @a3 = external hidden addrspace(2) global half, align 2 +// CHECK: @a4 = external hidden addrspace(2) global i64, align 8 +// CHECK: @a5 = external hidden addrspace(2) global i32, align 4 +// CHECK: @a6 = external hidden addrspace(2) global i16, align 2 +// CHECK: @a7 = external hidden addrspace(2) global i32, align 4 +// CHECK: @a8 = external hidden addrspace(2) global i64, align 8 // CHECK: @CBScalars.str = private unnamed_addr constant [10 x i8] c"CBScalars\00", align 1 cbuffer CBVectors { @@ -69,13 +69,13 @@ cbuffer CBVectors { // CHECK: @CBVectors.cb = global target("dx.CBuffer", target("dx.Layout", %__cblayout_CBVectors, // CHECK-SAME: 136, 0, 16, 40, 48, 80, 96, 112)) -// CHECK: @b1 = external addrspace(2) global <3 x float>, align 16 -// CHECK: @b2 = external addrspace(2) global <3 x double>, align 32 -// CHECK: @b3 = external addrspace(2) global <2 x half>, align 4 -// CHECK: @b4 = external addrspace(2) global <3 x i64>, align 32 -// CHECK: @b5 = external addrspace(2) global <4 x i32>, align 16 -// CHECK: @b6 = external addrspace(2) global <3 x i16>, align 8 -// CHECK: @b7 = external addrspace(2) global <3 x i64>, align 32 +// CHECK: @b1 = external hidden addrspace(2) global <3 x float>, align 16 +// CHECK: @b2 = external hidden addrspace(2) global <3 x double>, align 32 +// CHECK: @b3 = external hidden addrspace(2) global <2 x half>, align 4 +// CHECK: @b4 = external hidden addrspace(2) global <3 x i64>, align 32 +// CHECK: @b5 = external hidden addrspace(2) global <4 x i32>, align 16 +// CHECK: @b6 = external hidden addrspace(2) global <3 x i16>, align 8 +// CHECK: @b7 = external hidden addrspace(2) global <3 x i64>, align 32 // CHECK: @CBVectors.str = private unnamed_addr constant [10 x i8] c"CBVectors\00", align 1 cbuffer CBArrays : register(b2) { @@ -91,14 +91,14 @@ cbuffer CBArrays : register(b2) { // CHECK: @CBArrays.cb = global target("dx.CBuffer", target("dx.Layout", %__cblayout_CBArrays, // CHECK-SAME: 708, 0, 48, 112, 176, 224, 608, 624, 656)) -// CHECK: @c1 = external addrspace(2) global [3 x float], align 4 -// CHECK: @c2 = external addrspace(2) global [2 x <3 x double>], align 32 -// CHECK: @c3 = external addrspace(2) global [2 x [2 x half]], align 2 -// CHECK: @c4 = external addrspace(2) global [3 x i64], align 8 -// CHECK: @c5 = external addrspace(2) global [2 x [3 x [4 x <4 x i32>]]], align 16 -// CHECK: @c6 = external addrspace(2) global [1 x i16], align 2 -// CHECK: @c7 = external addrspace(2) global [2 x i64], align 8 -// CHECK: @c8 = external addrspace(2) global [4 x i32], align 4 +// CHECK: @c1 = external hidden addrspace(2) global [3 x float], align 4 +// CHECK: @c2 = external hidden addrspace(2) global [2 x <3 x double>], align 32 +// CHECK: @c3 = external hidden addrspace(2) global [2 x [2 x half]], align 2 +// CHECK: @c4 = external hidden addrspace(2) global [3 x i64], align 8 +// CHECK: @c5 = external hidden addrspace(2) global [2 x [3 x [4 x <4 x i32>]]], align 16 +// CHECK: @c6 = external hidden addrspace(2) global [1 x i16], align 2 +// CHECK: @c7 = external hidden addrspace(2) global [2 x i64], align 8 +// CHECK: @c8 = external hidden addrspace(2) global [4 x i32], align 4 // CHECK: @CBArrays.str = private unnamed_addr constant [9 x i8] c"CBArrays\00", align 1 typedef uint32_t4 uint32_t8[2]; @@ -112,8 +112,8 @@ cbuffer CBTypedefArray : register(space2) { // CHECK: @CBTypedefArray.cb = global target("dx.CBuffer", target("dx.Layout", %__cblayout_CBTypedefArray, // CHECK-SAME: 128, 0, 64)) -// CHECK: @t1 = external addrspace(2) global [2 x [2 x <4 x i32>]], align 16 -// CHECK: @t2 = external addrspace(2) global [2 x [2 x <4 x i32>]], align 16 +// CHECK: @t1 = external hidden addrspace(2) global [2 x [2 x <4 x i32>]], align 16 +// CHECK: @t2 = external hidden addrspace(2) global [2 x [2 x <4 x i32>]], align 16 // CHECK: @CBTypedefArray.str = private unnamed_addr constant [15 x i8] c"CBTypedefArray\00", align 1 struct Empty {}; @@ -137,13 +137,13 @@ struct D { // CHECK: @CBStructs.cb = global target("dx.CBuffer", target("dx.Layout", %__cblayout_CBStructs, // CHECK-SAME: 246, 0, 16, 32, 64, 144, 238, 240)) -// CHECK: @a = external addrspace(2) global target("dx.Layout", %A, 8, 0), align 1 -// CHECK: @b = external addrspace(2) global target("dx.Layout", %B, 14, 0, 8), align 1 -// CHECK: @c = external addrspace(2) global target("dx.Layout", %C, 24, 0, 16), align 1 -// CHECK: @array_of_A = external addrspace(2) global [5 x target("dx.Layout", %A, 8, 0)], align 1 -// CHECK: @d = external addrspace(2) global target("dx.Layout", %__cblayout_D, 94, 0), align 1 -// CHECK: @e = external addrspace(2) global half, align 2 -// CHECK: @f = external addrspace(2) global <3 x i16>, align 8 +// CHECK: @a = external hidden addrspace(2) global target("dx.Layout", %A, 8, 0), align 1 +// CHECK: @b = external hidden addrspace(2) global target("dx.Layout", %B, 14, 0, 8), align 1 +// CHECK: @c = external hidden addrspace(2) global target("dx.Layout", %C, 24, 0, 16), align 1 +// CHECK: @array_of_A = external hidden addrspace(2) global [5 x target("dx.Layout", %A, 8, 0)], align 1 +// CHECK: @d = external hidden addrspace(2) global target("dx.Layout", %__cblayout_D, 94, 0), align 1 +// CHECK: @e = external hidden addrspace(2) global half, align 2 +// CHECK: @f = external hidden addrspace(2) global <3 x i16>, align 8 // CHECK: @CBStructs.str = private unnamed_addr constant [10 x i8] c"CBStructs\00", align 1 cbuffer CBStructs { @@ -178,10 +178,10 @@ cbuffer CBClasses { // CHECK: @CBClasses.cb = global target("dx.CBuffer", target("dx.Layout", %__cblayout_CBClasses, // CHECK-SAME: 260, 0, 16, 32, 112)) -// CHECK: @k = external addrspace(2) global target("dx.Layout", %K, 4, 0), align 1 -// CHECK: @l = external addrspace(2) global target("dx.Layout", %L, 8, 0, 4), align 1 -// CHECK: @m = external addrspace(2) global target("dx.Layout", %M, 68, 0), align 1 -// CHECK: @ka = external addrspace(2) global [10 x target("dx.Layout", %K, 4, 0)], align 1 +// CHECK: @k = external hidden addrspace(2) global target("dx.Layout", %K, 4, 0), align 1 +// CHECK: @l = external hidden addrspace(2) global target("dx.Layout", %L, 8, 0, 4), align 1 +// CHECK: @m = external hidden addrspace(2) global target("dx.Layout", %M, 68, 0), align 1 +// CHECK: @ka = external hidden addrspace(2) global [10 x target("dx.Layout", %K, 4, 0)], align 1 // CHECK: @CBClasses.str = private unnamed_addr constant [10 x i8] c"CBClasses\00", align 1 struct Test { @@ -190,16 +190,16 @@ struct Test { // CHECK: @CBMix.cb = global target("dx.CBuffer", target("dx.Layout", %__cblayout_CBMix, // CHECK-SAME: 170, 0, 24, 32, 120, 128, 136, 144, 152, 160, 168)) -// CHECK: @test = external addrspace(2) global [2 x target("dx.Layout", %Test, 8, 0, 4)], align 1 -// CHECK: @f1 = external addrspace(2) global float, align 4 -// CHECK: @f2 = external addrspace(2) global [3 x [2 x <2 x float>]], align 8 -// CHECK: @f3 = external addrspace(2) global float, align 4 -// CHECK: @f4 = external addrspace(2) global target("dx.Layout", %anon, 4, 0), align 1 -// CHECK: @f5 = external addrspace(2) global double, align 8 -// CHECK: @f6 = external addrspace(2) global target("dx.Layout", %anon.0, 8, 0), align 1 -// CHECK: @f7 = external addrspace(2) global float, align 4 -// CHECK: @f8 = external addrspace(2) global <1 x double>, align 8 -// CHECK: @f9 = external addrspace(2) global i16, align 2 +// CHECK: @test = external hidden addrspace(2) global [2 x target("dx.Layout", %Test, 8, 0, 4)], align 1 +// CHECK: @f1 = external hidden addrspace(2) global float, align 4 +// CHECK: @f2 = external hidden addrspace(2) global [3 x [2 x <2 x float>]], align 8 +// CHECK: @f3 = external hidden addrspace(2) global float, align 4 +// CHECK: @f4 = external hidden addrspace(2) global target("dx.Layout", %anon, 4, 0), align 1 +// CHECK: @f5 = external hidden addrspace(2) global double, align 8 +// CHECK: @f6 = external hidden addrspace(2) global target("dx.Layout", %anon.0, 8, 0), align 1 +// CHECK: @f7 = external hidden addrspace(2) global float, align 4 +// CHECK: @f8 = external hidden addrspace(2) global <1 x double>, align 8 +// CHECK: @f9 = external hidden addrspace(2) global i16, align 2 // CHECK: @CBMix.str = private unnamed_addr constant [6 x i8] c"CBMix\00", align 1 cbuffer CBMix { diff --git a/external/llvm-project/clang/test/CodeGenHLSL/cbuffer_and_namespaces.hlsl b/external/llvm-project/clang/test/CodeGenHLSL/cbuffer_and_namespaces.hlsl index 4a7e2597dc0f..33f480bf445e 100644 --- a/external/llvm-project/clang/test/CodeGenHLSL/cbuffer_and_namespaces.hlsl +++ b/external/llvm-project/clang/test/CodeGenHLSL/cbuffer_and_namespaces.hlsl @@ -8,14 +8,14 @@ // CHECK: %"n0::Foo" = type <{ float }> // CHECK: @A.cb = global target("dx.CBuffer", target("dx.Layout", %"n0::n1::__cblayout_A", 4, 0)) -// CHECK: @_ZN2n02n11aE = external addrspace(2) global float, align 4 +// CHECK: @_ZN2n02n11aE = external hidden addrspace(2) global float, align 4 // CHECK: @B.cb = global target("dx.CBuffer", target("dx.Layout", %"n0::__cblayout_B", 4, 0)) -// CHECK: @_ZN2n01aE = external addrspace(2) global float, align 4 +// CHECK: @_ZN2n01aE = external hidden addrspace(2) global float, align 4 // CHECK: @C.cb = global target("dx.CBuffer", target("dx.Layout", %"n0::n2::__cblayout_C", 20, 0, 16)) -// CHECK: @_ZN2n02n21aE = external addrspace(2) global float, align 4 -// CHECK: external addrspace(2) global target("dx.Layout", %"n0::Foo", 4, 0), align 1 +// CHECK: @_ZN2n02n21aE = external hidden addrspace(2) global float, align 4 +// CHECK: external hidden addrspace(2) global target("dx.Layout", %"n0::Foo", 4, 0), align 1 namespace n0 { struct Foo { diff --git a/external/llvm-project/clang/test/CodeGenHLSL/cbuffer_with_packoffset.hlsl b/external/llvm-project/clang/test/CodeGenHLSL/cbuffer_with_packoffset.hlsl index 0d092f0c36c2..16d22a5b1fdd 100644 --- a/external/llvm-project/clang/test/CodeGenHLSL/cbuffer_with_packoffset.hlsl +++ b/external/llvm-project/clang/test/CodeGenHLSL/cbuffer_with_packoffset.hlsl @@ -6,9 +6,9 @@ // CHECK: %__cblayout_CB_1 = type <{ float, <2 x float> }> // CHECK: @CB.cb = global target("dx.CBuffer", target("dx.Layout", %__cblayout_CB, 176, 16, 168, 88)) -// CHECK: @a = external addrspace(2) global float, align 4 -// CHECK: @b = external addrspace(2) global double, align 8 -// CHECK: @c = external addrspace(2) global <2 x i32>, align 8 +// CHECK: @a = external hidden addrspace(2) global float, align 4 +// CHECK: @b = external hidden addrspace(2) global double, align 8 +// CHECK: @c = external hidden addrspace(2) global <2 x i32>, align 8 // CHECK: @CB.str = private unnamed_addr constant [3 x i8] c"CB\00", align 1 cbuffer CB : register(b1, space3) { @@ -18,8 +18,8 @@ cbuffer CB : register(b1, space3) { } // CHECK: @CB.cb.1 = global target("dx.CBuffer", target("dx.Layout", %__cblayout_CB_1, 92, 88, 80)) -// CHECK: @x = external addrspace(2) global float, align 4 -// CHECK: @y = external addrspace(2) global <2 x float>, align 8 +// CHECK: @x = external hidden addrspace(2) global float, align 4 +// CHECK: @y = external hidden addrspace(2) global <2 x float>, align 8 // Missing packoffset annotation will produce a warning. // Element x will be placed after the element y that has an explicit packoffset. diff --git a/external/llvm-project/clang/test/CodeGenHLSL/cbuffer_with_static_global_and_function.hlsl b/external/llvm-project/clang/test/CodeGenHLSL/cbuffer_with_static_global_and_function.hlsl index a6034386ac45..cda231d8d2eb 100644 --- a/external/llvm-project/clang/test/CodeGenHLSL/cbuffer_with_static_global_and_function.hlsl +++ b/external/llvm-project/clang/test/CodeGenHLSL/cbuffer_with_static_global_and_function.hlsl @@ -3,7 +3,7 @@ // CHECK: %__cblayout_A = type <{ float }> // CHECK: @A.cb = global target("dx.CBuffer", target("dx.Layout", %__cblayout_A, 4, 0)) -// CHECK: @a = external addrspace(2) global float, align 4 +// CHECK: @a = external hidden addrspace(2) global float, align 4 // CHECK-DAG: @_ZL1b = internal global float 3.000000e+00, align 4 // CHECK-NOT: @B.cb diff --git a/external/llvm-project/clang/test/CodeGenHLSL/convergence/do.while.hlsl b/external/llvm-project/clang/test/CodeGenHLSL/convergence/do.while.hlsl index 934fe3ea9eb7..9aabbfd54e53 100644 --- a/external/llvm-project/clang/test/CodeGenHLSL/convergence/do.while.hlsl +++ b/external/llvm-project/clang/test/CodeGenHLSL/convergence/do.while.hlsl @@ -8,7 +8,7 @@ void test1() { do { } while (cond()); } -// CHECK-LABEL: define spir_func void @_Z5test1v() +// CHECK-LABEL: define hidden spir_func void @_Z5test1v() // CHECK-SAME: [[A0:#[0-9]+]] { // CHECK: entry: // CHECK: [[T0:%[0-9]+]] = call token @llvm.experimental.convergence.entry() @@ -22,7 +22,7 @@ void test2() { foo(); } while (cond()); } -// CHECK-LABEL: define spir_func void @_Z5test2v() +// CHECK-LABEL: define hidden spir_func void @_Z5test2v() // CHECK-SAME: [[A0]] { // CHECK: entry: // CHECK: [[T0:%[0-9]+]] = call token @llvm.experimental.convergence.entry() @@ -38,7 +38,7 @@ void test3() { foo(); } while (cond()); } -// CHECK-LABEL: define spir_func void @_Z5test3v() +// CHECK-LABEL: define hidden spir_func void @_Z5test3v() // CHECK-SAME: [[A0]] { // CHECK: entry: // CHECK: [[T0:%[0-9]+]] = call token @llvm.experimental.convergence.entry() @@ -57,7 +57,7 @@ void test4() { } } while (cond()); } -// CHECK-LABEL: define spir_func void @_Z5test4v() +// CHECK-LABEL: define hidden spir_func void @_Z5test4v() // CHECK-SAME: [[A0]] { // CHECK: entry: // CHECK: [[T0:%[0-9]+]] = call token @llvm.experimental.convergence.entry() @@ -78,7 +78,7 @@ void test5() { } } while (cond()); } -// CHECK-LABEL: define spir_func void @_Z5test5v() +// CHECK-LABEL: define hidden spir_func void @_Z5test5v() // CHECK-SAME: [[A0]] { // CHECK: entry: // CHECK: [[T0:%[0-9]+]] = call token @llvm.experimental.convergence.entry() diff --git a/external/llvm-project/clang/test/CodeGenHLSL/convergence/for.hlsl b/external/llvm-project/clang/test/CodeGenHLSL/convergence/for.hlsl index 363c6a48839b..b7b11e9959ea 100644 --- a/external/llvm-project/clang/test/CodeGenHLSL/convergence/for.hlsl +++ b/external/llvm-project/clang/test/CodeGenHLSL/convergence/for.hlsl @@ -10,7 +10,7 @@ void test1() { foo(); } } -// CHECK-LABEL: define spir_func void @_Z5test1v() +// CHECK-LABEL: define hidden spir_func void @_Z5test1v() // CHECK-SAME: [[A0:#[0-9]+]] { // CHECK: entry: // CHECK: [[T0:%[0-9]+]] = call token @llvm.experimental.convergence.entry() @@ -23,7 +23,7 @@ void test2() { foo(); } } -// CHECK-LABEL: define spir_func void @_Z5test2v() +// CHECK-LABEL: define hidden spir_func void @_Z5test2v() // CHECK-SAME: [[A0]] { // CHECK: entry: // CHECK: [[T0:%[0-9]+]] = call token @llvm.experimental.convergence.entry() @@ -38,7 +38,7 @@ void test3() { foo(); } } -// CHECK-LABEL: define spir_func void @_Z5test3v() +// CHECK-LABEL: define hidden spir_func void @_Z5test3v() // CHECK-SAME: [[A0]] { // CHECK: entry: // CHECK: [[T0:%[0-9]+]] = call token @llvm.experimental.convergence.entry() @@ -52,7 +52,7 @@ void test4() { foo(); } } -// CHECK-LABEL: define spir_func void @_Z5test4v() +// CHECK-LABEL: define hidden spir_func void @_Z5test4v() // CHECK-SAME: [[A0]] { // CHECK: entry: // CHECK: [[T0:%[0-9]+]] = call token @llvm.experimental.convergence.entry() @@ -67,7 +67,7 @@ void test5() { for (cond();cond2();foo()) { } } -// CHECK-LABEL: define spir_func void @_Z5test5v() +// CHECK-LABEL: define hidden spir_func void @_Z5test5v() // CHECK-SAME: [[A0]] { // CHECK: entry: // CHECK: [[T0:%[0-9]+]] = call token @llvm.experimental.convergence.entry() @@ -86,7 +86,7 @@ void test6() { } } } -// CHECK-LABEL: define spir_func void @_Z5test6v() +// CHECK-LABEL: define hidden spir_func void @_Z5test6v() // CHECK-SAME: [[A0]] { // CHECK: entry: // CHECK: [[T0:%[0-9]+]] = call token @llvm.experimental.convergence.entry() @@ -112,7 +112,7 @@ void test7() { } } } -// CHECK-LABEL: define spir_func void @_Z5test7v() +// CHECK-LABEL: define hidden spir_func void @_Z5test7v() // CHECK-SAME: [[A0]] { // CHECK: entry: // CHECK: [[T0:%[0-9]+]] = call token @llvm.experimental.convergence.entry() diff --git a/external/llvm-project/clang/test/CodeGenHLSL/convergence/while.hlsl b/external/llvm-project/clang/test/CodeGenHLSL/convergence/while.hlsl index 570b4b133671..32579e863100 100644 --- a/external/llvm-project/clang/test/CodeGenHLSL/convergence/while.hlsl +++ b/external/llvm-project/clang/test/CodeGenHLSL/convergence/while.hlsl @@ -8,7 +8,7 @@ void test1() { while (cond()) { } } -// CHECK-LABEL: define spir_func void @_Z5test1v() +// CHECK-LABEL: define hidden spir_func void @_Z5test1v() // CHECK-SAME: [[A0:#[0-9]+]] { // CHECK: entry: // CHECK: [[T0:%[0-9]+]] = call token @llvm.experimental.convergence.entry() @@ -21,7 +21,7 @@ void test2() { foo(); } } -// CHECK-LABEL: define spir_func void @_Z5test2v() +// CHECK-LABEL: define hidden spir_func void @_Z5test2v() // CHECK-SAME: [[A0]] { // CHECK: entry: // CHECK: [[T0:%[0-9]+]] = call token @llvm.experimental.convergence.entry() @@ -38,7 +38,7 @@ void test3() { foo(); } } -// CHECK-LABEL: define spir_func void @_Z5test3v() +// CHECK-LABEL: define hidden spir_func void @_Z5test3v() // CHECK-SAME: [[A0]] { // CHECK: entry: // CHECK: [[T0:%[0-9]+]] = call token @llvm.experimental.convergence.entry() @@ -59,7 +59,7 @@ void test4() { } } } -// CHECK-LABEL: define spir_func void @_Z5test4v() +// CHECK-LABEL: define hidden spir_func void @_Z5test4v() // CHECK-SAME: [[A0]] { // CHECK: entry: // CHECK: [[T0:%[0-9]+]] = call token @llvm.experimental.convergence.entry() @@ -82,7 +82,7 @@ void test5() { } } } -// CHECK-LABEL: define spir_func void @_Z5test5v() +// CHECK-LABEL: define hidden spir_func void @_Z5test5v() // CHECK-SAME: [[A0]] { // CHECK: entry: // CHECK: [[T0:%[0-9]+]] = call token @llvm.experimental.convergence.entry() @@ -107,7 +107,7 @@ void test6() { } } } -// CHECK-LABEL: define spir_func void @_Z5test6v() +// CHECK-LABEL: define hidden spir_func void @_Z5test6v() // CHECK-SAME: [[A0]] { // CHECK: entry: // CHECK: [[T0:%[0-9]+]] = call token @llvm.experimental.convergence.entry() diff --git a/external/llvm-project/clang/test/CodeGenHLSL/default_cbuffer.hlsl b/external/llvm-project/clang/test/CodeGenHLSL/default_cbuffer.hlsl index 557913042e88..ad4d92f8afc0 100644 --- a/external/llvm-project/clang/test/CodeGenHLSL/default_cbuffer.hlsl +++ b/external/llvm-project/clang/test/CodeGenHLSL/default_cbuffer.hlsl @@ -6,14 +6,14 @@ // CHECK: %__cblayout_S = type <{ float }> // DXIL-DAG: @"$Globals.cb" = global target("dx.CBuffer", target("dx.Layout", %"__cblayout_$Globals", 20, 0, 4, 16)) -// DXIL-DAG: @a = external addrspace(2) global float -// DXIL-DAG: @g = external addrspace(2) global float -// DXIL-DAG: @h = external addrspace(2) global target("dx.Layout", %__cblayout_S, 4, 0), align 4 +// DXIL-DAG: @a = external hidden addrspace(2) global float +// DXIL-DAG: @g = external hidden addrspace(2) global float +// DXIL-DAG: @h = external hidden addrspace(2) global target("dx.Layout", %__cblayout_S, 4, 0), align 4 // SPIRV-DAG: @"$Globals.cb" = global target("spirv.VulkanBuffer", target("spirv.Layout", %"__cblayout_$Globals", 20, 0, 4, 16), 2, 0) -// SPIRV-DAG: @a = external addrspace(12) global float -// SPIRV-DAG: @g = external addrspace(12) global float -// SPIRV-DAG: @h = external addrspace(12) global target("spirv.Layout", %__cblayout_S, 4, 0), align 8 +// SPIRV-DAG: @a = external hidden addrspace(12) global float +// SPIRV-DAG: @g = external hidden addrspace(12) global float +// SPIRV-DAG: @h = external hidden addrspace(12) global target("spirv.Layout", %__cblayout_S, 4, 0), align 8 struct EmptyStruct { }; diff --git a/external/llvm-project/clang/test/CodeGenHLSL/default_cbuffer_with_layout.hlsl b/external/llvm-project/clang/test/CodeGenHLSL/default_cbuffer_with_layout.hlsl index 40e3196649a5..1b2cb0e99aa8 100644 --- a/external/llvm-project/clang/test/CodeGenHLSL/default_cbuffer_with_layout.hlsl +++ b/external/llvm-project/clang/test/CodeGenHLSL/default_cbuffer_with_layout.hlsl @@ -4,14 +4,14 @@ // CHECK-SAME: target("dx.Layout", %S, 8, 0) }> // CHECK: %S = type <{ <2 x float> }> -// CHECK-DAG: @b = external addrspace(2) global float, align 4 -// CHECK-DAG: @d = external addrspace(2) global <4 x i32>, align 16 +// CHECK-DAG: @b = external hidden addrspace(2) global float, align 4 +// CHECK-DAG: @d = external hidden addrspace(2) global <4 x i32>, align 16 // CHECK-DAG: @"$Globals.cb" = global target("dx.CBuffer", // CHECK-DAG-SAME: target("dx.Layout", %"__cblayout_$Globals", 144, 120, 16, 32, 64, 128, 112)) -// CHECK-DAG: @a = external addrspace(2) global i32, align 4 -// CHECK-DAG: @c = external addrspace(2) global [4 x double], align 8 -// CHECK-DAG: @e = external addrspace(2) global <4 x float>, align 16 -// CHECK-DAG: @s = external addrspace(2) global target("dx.Layout", %S, 8, 0), align 1 +// CHECK-DAG: @a = external hidden addrspace(2) global i32, align 4 +// CHECK-DAG: @c = external hidden addrspace(2) global [4 x double], align 8 +// CHECK-DAG: @e = external hidden addrspace(2) global <4 x float>, align 16 +// CHECK-DAG: @s = external hidden addrspace(2) global target("dx.Layout", %S, 8, 0), align 1 struct S { float2 v; diff --git a/external/llvm-project/clang/test/CodeGenHLSL/export.hlsl b/external/llvm-project/clang/test/CodeGenHLSL/export.hlsl index 770618ff2e07..e72dbde5188a 100644 --- a/external/llvm-project/clang/test/CodeGenHLSL/export.hlsl +++ b/external/llvm-project/clang/test/CodeGenHLSL/export.hlsl @@ -5,17 +5,15 @@ export void f1() { } -// CHECK: define void @_ZN11MyNamespace2f2Ev() [[Attr]] +// CHECK: define void @_ZN11MyNamespace2f2Ev() namespace MyNamespace { export void f2() { } } export { -// CHECK: define void @_Z2f3v() [[Attr]] -// CHECK: define void @_Z2f4v() [[Attr]] +// CHECK: define void @_Z2f3v() +// CHECK: define void @_Z2f4v() void f3() {} void f4() {} -} - -// CHECK: attributes [[Attr]] = { {{.*}} "hlsl.export" {{.*}} } +} \ No newline at end of file diff --git a/external/llvm-project/clang/test/CodeGenHLSL/group_shared.hlsl b/external/llvm-project/clang/test/CodeGenHLSL/group_shared.hlsl index a562e75b3488..6498c53752d4 100644 --- a/external/llvm-project/clang/test/CodeGenHLSL/group_shared.hlsl +++ b/external/llvm-project/clang/test/CodeGenHLSL/group_shared.hlsl @@ -8,7 +8,7 @@ // RUN: -emit-llvm -disable-llvm-passes -o - | FileCheck %s // Make sure groupshared translated into address space 3. -// CHECK:@a = addrspace(3) global [10 x float] +// CHECK:@a = hidden addrspace(3) global [10 x float] groupshared float a[10]; diff --git a/external/llvm-project/clang/test/CodeGenHLSL/implicit-norecurse-attrib.hlsl b/external/llvm-project/clang/test/CodeGenHLSL/implicit-norecurse-attrib.hlsl index 12d3eeedb590..60238cbf8eff 100644 --- a/external/llvm-project/clang/test/CodeGenHLSL/implicit-norecurse-attrib.hlsl +++ b/external/llvm-project/clang/test/CodeGenHLSL/implicit-norecurse-attrib.hlsl @@ -12,7 +12,7 @@ struct Node { }; // CHECK: Function Attrs:{{.*}}norecurse -// CHECK: define noundef i32 @_Z4FindA100_4Nodej(ptr noundef byval([100 x %struct.Node]) align 1 %SortedTree, i32 noundef %key) [[IntAttr:\#[0-9]+]] +// CHECK: define hidden noundef i32 @_Z4FindA100_4Nodej(ptr noundef byval([100 x %struct.Node]) align 1 %SortedTree, i32 noundef %key) [[Attr:\#[0-9]+]] // CHECK: ret i32 // Find and return value corresponding to key in the SortedTree uint Find(Node SortedTree[MAX], uint key) { @@ -31,7 +31,7 @@ uint Find(Node SortedTree[MAX], uint key) { } // CHECK: Function Attrs:{{.*}}norecurse -// CHECK: define noundef i1 @_Z8InitTreeA100_4NodeN4hlsl8RWBufferIDv4_jEEj(ptr noundef byval([100 x %struct.Node]) align 1 %tree, ptr noundef byval(%"class.hlsl::RWBuffer") align 4 %encodedTree, i32 noundef %maxDepth) [[ExtAttr:\#[0-9]+]] +// CHECK: define noundef i1 @_Z8InitTreeA100_4NodeN4hlsl8RWBufferIDv4_jEEj(ptr noundef byval([100 x %struct.Node]) align 1 %tree, ptr noundef byval(%"class.hlsl::RWBuffer") align 4 %encodedTree, i32 noundef %maxDepth) [[Attr:\#[0-9]+]] // CHECK: ret i1 // Initialize tree with given buffer // Imagine the inout works @@ -52,7 +52,7 @@ RWBuffer gTree; // Mangled entry points are internal // CHECK: Function Attrs:{{.*}}norecurse -// CHECK: define internal void @_Z4mainj(i32 noundef %GI) [[IntAttr]] +// CHECK: define internal void @_Z4mainj(i32 noundef %GI) [[Attr]] // CHECK: ret void // Canonical entry points are external and shader attributed @@ -71,7 +71,7 @@ void main(uint GI : SV_GroupIndex) { // Mangled entry points are internal // CHECK: Function Attrs:{{.*}}norecurse -// CHECK: define internal void @_Z11defaultMainv() [[IntAttr]] +// CHECK: define internal void @_Z11defaultMainv() [[Attr]] // CHECK: ret void // Canonical entry points are external and shader attributed @@ -88,6 +88,5 @@ void defaultMain() { needle = Find(haystack, needle); } -// CHECK: attributes [[IntAttr]] = {{.*}} norecurse -// CHECK: attributes [[ExtAttr]] = {{.*}} norecurse +// CHECK: attributes [[Attr]] = {{.*}} norecurse // CHECK: attributes [[EntryAttr]] = {{.*}} norecurse diff --git a/external/llvm-project/clang/test/CodeGenHLSL/inline-functions.hlsl b/external/llvm-project/clang/test/CodeGenHLSL/inline-functions.hlsl index 4748eeee7475..0c7467e2f972 100644 --- a/external/llvm-project/clang/test/CodeGenHLSL/inline-functions.hlsl +++ b/external/llvm-project/clang/test/CodeGenHLSL/inline-functions.hlsl @@ -15,7 +15,7 @@ float nums[MAX]; // Verify that all functions have the alwaysinline attribute // NOINLINE: Function Attrs: alwaysinline -// NOINLINE: define void @_Z4swapA100_jjj(ptr noundef byval([100 x i32]) align 4 %Buf, i32 noundef %ix1, i32 noundef %ix2) [[IntAttr:\#[0-9]+]] +// NOINLINE: define hidden void @_Z4swapA100_jjj(ptr noundef byval([100 x i32]) align 4 %Buf, i32 noundef %ix1, i32 noundef %ix2) [[Attr:\#[0-9]+]] // NOINLINE: ret void // Swap the values of Buf at indices ix1 and ix2 void swap(unsigned Buf[MAX], unsigned ix1, unsigned ix2) { @@ -25,7 +25,7 @@ void swap(unsigned Buf[MAX], unsigned ix1, unsigned ix2) { } // NOINLINE: Function Attrs: alwaysinline -// NOINLINE: define void @_Z10BubbleSortA100_jj(ptr noundef byval([100 x i32]) align 4 %Buf, i32 noundef %size) [[IntAttr]] +// NOINLINE: define hidden void @_Z10BubbleSortA100_jj(ptr noundef byval([100 x i32]) align 4 %Buf, i32 noundef %size) [[Attr]] // NOINLINE: ret void // Inefficiently sort Buf in place void BubbleSort(unsigned Buf[MAX], unsigned size) { @@ -43,7 +43,7 @@ void BubbleSort(unsigned Buf[MAX], unsigned size) { // Note ExtAttr is the inlined export set of attribs // CHECK: Function Attrs: alwaysinline -// CHECK: define noundef i32 @_Z11RemoveDupesA100_jj(ptr {{[a-z_ ]*}}noundef byval([100 x i32]) align 4 {{.*}}%Buf, i32 noundef %size) {{[a-z_ ]*}}[[ExtAttr:\#[0-9]+]] +// CHECK: define noundef i32 @_Z11RemoveDupesA100_jj(ptr {{[a-z_ ]*}}noundef byval([100 x i32]) align 4 {{.*}}%Buf, i32 noundef %size) {{[a-z_ ]*}}[[Attr:\#[0-9]+]] // CHECK: ret i32 // Sort Buf and remove any duplicate values // returns the number of values left @@ -65,9 +65,9 @@ RWBuffer Indices; // The mangled version of main only remains without inlining // because it has internal linkage from the start -// Note main functions get the norecurse attrib, which IntAttr reflects +// Note main functions get the alwaysinline attrib, which Attr reflects // NOINLINE: Function Attrs: alwaysinline -// NOINLINE: define internal void @_Z4mainj(i32 noundef %GI) [[IntAttr]] +// NOINLINE: define internal void @_Z4mainj(i32 noundef %GI) [[Attr]] // NOINLINE: ret void // The unmangled version is not inlined, EntryAttr reflects that @@ -93,9 +93,9 @@ void main(unsigned int GI : SV_GroupIndex) { // The mangled version of main only remains without inlining // because it has internal linkage from the start -// Note main functions get the norecurse attrib, which IntAttr reflects +// Note main functions get the alwaysinline attrib, which Attr reflects // NOINLINE: Function Attrs: alwaysinline -// NOINLINE: define internal void @_Z6main10v() [[IntAttr]] +// NOINLINE: define internal void @_Z6main10v() [[Attr]] // NOINLINE: ret void // The unmangled version is not inlined, EntryAttr reflects that @@ -113,6 +113,5 @@ void main10() { main(10); } -// NOINLINE: attributes [[IntAttr]] = {{.*}} alwaysinline -// CHECK: attributes [[ExtAttr]] = {{.*}} alwaysinline +// CHECK: attributes [[Attr]] = {{.*}} alwaysinline // CHECK: attributes [[EntryAttr]] = {{.*}} noinline diff --git a/external/llvm-project/clang/test/CodeGenHLSL/no_int_promotion.hlsl b/external/llvm-project/clang/test/CodeGenHLSL/no_int_promotion.hlsl index 78bff3b13810..b4ffcb477f1b 100644 --- a/external/llvm-project/clang/test/CodeGenHLSL/no_int_promotion.hlsl +++ b/external/llvm-project/clang/test/CodeGenHLSL/no_int_promotion.hlsl @@ -10,37 +10,37 @@ int16_t add(int16_t a, int16_t b) { return a + b; } -// CHECK: define noundef <2 x i16> @ +// CHECK: define hidden noundef <2 x i16> @ // CHECK: add <2 x i16> int16_t2 add(int16_t2 a, int16_t2 b) { return a + b; } -// CHECK: define noundef <3 x i16> @ +// CHECK: define hidden noundef <3 x i16> @ // CHECK: add <3 x i16> int16_t3 add(int16_t3 a, int16_t3 b) { return a + b; } -// CHECK: define noundef <4 x i16> @ +// CHECK: define hidden noundef <4 x i16> @ // CHECK: add <4 x i16> int16_t4 add(int16_t4 a, int16_t4 b) { return a + b; } -// CHECK: define noundef i16 @ +// CHECK: define hidden noundef i16 @ // CHECK: add i16 % uint16_t add(uint16_t a, uint16_t b) { return a + b; } -// CHECK: define noundef <2 x i16> @ +// CHECK: define hidden noundef <2 x i16> @ // CHECK: add <2 x i16> uint16_t2 add(uint16_t2 a, uint16_t2 b) { return a + b; } -// CHECK: define noundef <3 x i16> @ +// CHECK: define hidden noundef <3 x i16> @ // CHECK: add <3 x i16> uint16_t3 add(uint16_t3 a, uint16_t3 b) { return a + b; } -// CHECK: define noundef <4 x i16> @ +// CHECK: define hidden noundef <4 x i16> @ // CHECK: add <4 x i16> uint16_t4 add(uint16_t4 a, uint16_t4 b) { return a + b; diff --git a/external/llvm-project/clang/test/CodeGenHLSL/out-of-line-static.hlsl b/external/llvm-project/clang/test/CodeGenHLSL/out-of-line-static.hlsl index 8127a6c2ec1e..57f6c123e50e 100644 --- a/external/llvm-project/clang/test/CodeGenHLSL/out-of-line-static.hlsl +++ b/external/llvm-project/clang/test/CodeGenHLSL/out-of-line-static.hlsl @@ -6,8 +6,8 @@ struct S { }; int S::Value = 1; -// DXIL: @_ZN1S5ValueE = global i32 1, align 4 -// SPIRV: @_ZN1S5ValueE = addrspace(10) global i32 1, align 4 +// DXIL: @_ZN1S5ValueE = hidden global i32 1, align 4 +// SPIRV: @_ZN1S5ValueE = hidden addrspace(10) global i32 1, align 4 [shader("compute")] [numthreads(1,1,1)] diff --git a/external/llvm-project/clang/test/CodeGenHLSL/semantics/SV_Position.ps.hlsl b/external/llvm-project/clang/test/CodeGenHLSL/semantics/SV_Position.ps.hlsl index 58b91fc9264d..bdba38e028ed 100644 --- a/external/llvm-project/clang/test/CodeGenHLSL/semantics/SV_Position.ps.hlsl +++ b/external/llvm-project/clang/test/CodeGenHLSL/semantics/SV_Position.ps.hlsl @@ -1,6 +1,6 @@ // RUN: %clang_cc1 -triple spirv-unknown-vulkan1.3-pixel -x hlsl -emit-llvm -finclude-default-header -disable-llvm-passes -o - %s | FileCheck %s -// CHECK: @sv_position = external thread_local addrspace(7) externally_initialized constant <4 x float>, !spirv.Decorations !0 +// CHECK: @sv_position = external hidden thread_local addrspace(7) externally_initialized constant <4 x float>, !spirv.Decorations !0 // CHECK: define void @main() {{.*}} { float4 main(float4 p : SV_Position) { diff --git a/external/llvm-project/clang/test/CodeGenHLSL/shift-mask.hlsl b/external/llvm-project/clang/test/CodeGenHLSL/shift-mask.hlsl index 7b3890ae560d..41e05330ed1a 100644 --- a/external/llvm-project/clang/test/CodeGenHLSL/shift-mask.hlsl +++ b/external/llvm-project/clang/test/CodeGenHLSL/shift-mask.hlsl @@ -5,7 +5,7 @@ int shl32(int V, int S) { return V << S; } -// CHECK-LABEL: define noundef i32 @_Z5shl32ii(i32 noundef %V, i32 noundef %S) #0 { +// CHECK-LABEL: define hidden noundef i32 @_Z5shl32ii(i32 noundef %V, i32 noundef %S) #0 { // CHECK-DAG: %[[Masked:.*]] = and i32 %{{.*}}, 31 // CHECK-DAG: %{{.*}} = shl i32 %{{.*}}, %[[Masked]] @@ -13,7 +13,7 @@ int shr32(int V, int S) { return V >> S; } -// CHECK-LABEL: define noundef i32 @_Z5shr32ii(i32 noundef %V, i32 noundef %S) #0 { +// CHECK-LABEL: define hidden noundef i32 @_Z5shr32ii(i32 noundef %V, i32 noundef %S) #0 { // CHECK-DAG: %[[Masked:.*]] = and i32 %{{.*}}, 31 // CHECK-DAG: %{{.*}} = ashr i32 %{{.*}}, %[[Masked]] @@ -21,7 +21,7 @@ int64_t shl64(int64_t V, int64_t S) { return V << S; } -// CHECK-LABEL: define noundef i64 @_Z5shl64ll(i64 noundef %V, i64 noundef %S) #0 { +// CHECK-LABEL: define hidden noundef i64 @_Z5shl64ll(i64 noundef %V, i64 noundef %S) #0 { // CHECK-DAG: %[[Masked:.*]] = and i64 %{{.*}}, 63 // CHECK-DAG: %{{.*}} = shl i64 %{{.*}}, %[[Masked]] @@ -29,7 +29,7 @@ int64_t shr64(int64_t V, int64_t S) { return V >> S; } -// CHECK-LABEL: define noundef i64 @_Z5shr64ll(i64 noundef %V, i64 noundef %S) #0 { +// CHECK-LABEL: define hidden noundef i64 @_Z5shr64ll(i64 noundef %V, i64 noundef %S) #0 { // CHECK-DAG: %[[Masked:.*]] = and i64 %{{.*}}, 63 // CHECK-DAG: %{{.*}} = ashr i64 %{{.*}}, %[[Masked]] @@ -37,7 +37,7 @@ uint shlu32(uint V, uint S) { return V << S; } -// CHECK-LABEL: define noundef i32 @_Z6shlu32jj(i32 noundef %V, i32 noundef %S) #0 { +// CHECK-LABEL: define hidden noundef i32 @_Z6shlu32jj(i32 noundef %V, i32 noundef %S) #0 { // CHECK-DAG: %[[Masked:.*]] = and i32 %{{.*}}, 31 // CHECK-DAG: %{{.*}} = shl i32 %{{.*}}, %[[Masked]] @@ -45,7 +45,7 @@ uint shru32(uint V, uint S) { return V >> S; } -// CHECK-LABEL: define noundef i32 @_Z6shru32jj(i32 noundef %V, i32 noundef %S) #0 { +// CHECK-LABEL: define hidden noundef i32 @_Z6shru32jj(i32 noundef %V, i32 noundef %S) #0 { // CHECK-DAG: %[[Masked:.*]] = and i32 %{{.*}}, 31 // CHECK-DAG: %{{.*}} = lshr i32 %{{.*}}, %[[Masked]] @@ -53,7 +53,7 @@ uint64_t shlu64(uint64_t V, uint64_t S) { return V << S; } -// CHECK-LABEL: define noundef i64 @_Z6shlu64mm(i64 noundef %V, i64 noundef %S) #0 { +// CHECK-LABEL: define hidden noundef i64 @_Z6shlu64mm(i64 noundef %V, i64 noundef %S) #0 { // CHECK-DAG: %[[Masked:.*]] = and i64 %{{.*}}, 63 // CHECK-DAG: %{{.*}} = shl i64 %{{.*}}, %[[Masked]] @@ -61,6 +61,6 @@ uint64_t shru64(uint64_t V, uint64_t S) { return V >> S; } -// CHECK-LABEL: define noundef i64 @_Z6shru64mm(i64 noundef %V, i64 noundef %S) #0 { +// CHECK-LABEL: define hidden noundef i64 @_Z6shru64mm(i64 noundef %V, i64 noundef %S) #0 { // CHECK-DAG: %[[Masked:.*]] = and i64 %{{.*}}, 63 // CHECK-DAG: %{{.*}} = lshr i64 %{{.*}}, %[[Masked]] diff --git a/external/llvm-project/clang/test/CodeGenHLSL/this-assignment-overload.hlsl b/external/llvm-project/clang/test/CodeGenHLSL/this-assignment-overload.hlsl index a87eb0b38f60..a2df30703877 100644 --- a/external/llvm-project/clang/test/CodeGenHLSL/this-assignment-overload.hlsl +++ b/external/llvm-project/clang/test/CodeGenHLSL/this-assignment-overload.hlsl @@ -25,7 +25,7 @@ void main() { } // This test makes a probably safe assumption that HLSL 202x includes operator overloading for assignment operators. -// CHECK: define linkonce_odr noundef i32 @_ZN4Pair8getFirstEv(ptr noundef nonnull align 1 dereferenceable(8) %this) #0 align 2 { +// CHECK: define linkonce_odr hidden noundef i32 @_ZN4Pair8getFirstEv(ptr noundef nonnull align 1 dereferenceable(8) %this) #0 align 2 { // CHECK-NEXT:entry: // CHECK-NEXT:%this.addr = alloca ptr, align 4 // CHECK-NEXT:%Another = alloca %struct.Pair, align 1 @@ -42,7 +42,7 @@ void main() { // CHECK-NEXT:%0 = load i32, ptr %First2, align 1 // CHECK-NEXT:ret i32 %0 -// CHECK: define linkonce_odr noundef i32 @_ZN4Pair9getSecondEv(ptr noundef nonnull align 1 dereferenceable(8) %this) #0 align 2 { +// CHECK: define linkonce_odr hidden noundef i32 @_ZN4Pair9getSecondEv(ptr noundef nonnull align 1 dereferenceable(8) %this) #0 align 2 { // CHECK-NEXT:entry: // CHECK-NEXT:%this.addr = alloca ptr, align 4 // CHECK-NEXT:%agg.tmp = alloca %struct.Pair, align 1 diff --git a/external/llvm-project/clang/test/CodeGenHLSL/inline-spirv/SpirvType.alignment.hlsl b/external/llvm-project/clang/test/CodeGenHLSL/vk-features/SpirvType.alignment.hlsl similarity index 100% rename from external/llvm-project/clang/test/CodeGenHLSL/inline-spirv/SpirvType.alignment.hlsl rename to external/llvm-project/clang/test/CodeGenHLSL/vk-features/SpirvType.alignment.hlsl diff --git a/external/llvm-project/clang/test/CodeGenHLSL/inline-spirv/SpirvType.hlsl b/external/llvm-project/clang/test/CodeGenHLSL/vk-features/SpirvType.hlsl similarity index 87% rename from external/llvm-project/clang/test/CodeGenHLSL/inline-spirv/SpirvType.hlsl rename to external/llvm-project/clang/test/CodeGenHLSL/vk-features/SpirvType.hlsl index 5b58e436bbed..7149be0122f4 100644 --- a/external/llvm-project/clang/test/CodeGenHLSL/inline-spirv/SpirvType.hlsl +++ b/external/llvm-project/clang/test/CodeGenHLSL/vk-features/SpirvType.hlsl @@ -18,12 +18,12 @@ struct S { Int i; }; -// CHECK: define spir_func target("spirv.Type", target("spirv.Image", float, 5, 2, 0, 0, 2, 0), target("spirv.IntegralConstant", i64, 4), 28, 0, 0) @_Z14getArrayBufferu17spirv_type_28_0_0U5_TypeN4hlsl8RWBufferIfEEU6_ConstLm4E(target("spirv.Type", target("spirv.Image", float, 5, 2, 0, 0, 2, 0), target("spirv.IntegralConstant", i64, 4), 28, 0, 0) %v) #0 +// CHECK: define hidden spir_func target("spirv.Type", target("spirv.Image", float, 5, 2, 0, 0, 2, 0), target("spirv.IntegralConstant", i64, 4), 28, 0, 0) @_Z14getArrayBufferu17spirv_type_28_0_0U5_TypeN4hlsl8RWBufferIfEEU6_ConstLm4E(target("spirv.Type", target("spirv.Image", float, 5, 2, 0, 0, 2, 0), target("spirv.IntegralConstant", i64, 4), 28, 0, 0) %v) #0 ArrayBuffer<4> getArrayBuffer(ArrayBuffer<4> v) { return v; } -// CHECK: define spir_func target("spirv.Type", target("spirv.Literal", 32), target("spirv.Literal", 0), 21, 4, 32) @_Z6getIntu18spirv_type_21_4_32U4_LitLi32EU4_LitLi0E(target("spirv.Type", target("spirv.Literal", 32), target("spirv.Literal", 0), 21, 4, 32) %v) #0 +// CHECK: define hidden spir_func target("spirv.Type", target("spirv.Literal", 32), target("spirv.Literal", 0), 21, 4, 32) @_Z6getIntu18spirv_type_21_4_32U4_LitLi32EU4_LitLi0E(target("spirv.Type", target("spirv.Literal", 32), target("spirv.Literal", 0), 21, 4, 32) %v) #0 Int getInt(Int v) { return v; } diff --git a/external/llvm-project/clang/test/CodeGenHLSL/vk-features/vk.spec-constant.hlsl b/external/llvm-project/clang/test/CodeGenHLSL/vk-features/vk.spec-constant.hlsl new file mode 100644 index 000000000000..cbc1fa61eae2 --- /dev/null +++ b/external/llvm-project/clang/test/CodeGenHLSL/vk-features/vk.spec-constant.hlsl @@ -0,0 +1,210 @@ +// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --check-globals all --include-generated-funcs --version 5 +// RUN: %clang_cc1 -finclude-default-header -x hlsl -triple \ +// RUN: spirv-unknown-vulkan-compute %s -emit-llvm -disable-llvm-passes \ +// RUN: -o - | FileCheck %s + +[[vk::constant_id(1)]] +const bool bool_const = true; + +[[vk::constant_id(1)]] +const short short_const = 4; + +[[vk::constant_id(3)]] +const int int_const = 5; + +[[vk::constant_id(4)]] +const long long long_const = 8; + +[[vk::constant_id(5)]] +const unsigned short ushort_const = 10; + +[[vk::constant_id(6)]] +const unsigned int uint_const = 12; + +[[vk::constant_id(7)]] +const unsigned long long ulong_const = 25; + +[[vk::constant_id(8)]] +const half half_const = 40.4; + +[[vk::constant_id(8)]] +const float float_const = 50.5; + +[[vk::constant_id(9)]] +const double double_const = 100.2; + +enum E { + e0 = 10, + e1 = 20, + e2 = 30 +}; + +[[vk::constant_id(10)]] +const E enum_const = e2; + +[numthreads(1,1,1)] +void main() { + bool b = bool_const; + short s = short_const; + int i = int_const; + long long l = long_const; + unsigned short us = ushort_const; + unsigned int ui = uint_const; + unsigned long long ul = ulong_const; + half h = half_const; + float f = float_const; + double d = double_const; + E e = enum_const; +} +//. +// CHECK: @_ZL10bool_const = internal addrspace(10) global i32 0, align 4 +// CHECK: @_ZL11short_const = internal addrspace(10) global i16 0, align 2 +// CHECK: @_ZL9int_const = internal addrspace(10) global i32 0, align 4 +// CHECK: @_ZL10long_const = internal addrspace(10) global i64 0, align 8 +// CHECK: @_ZL12ushort_const = internal addrspace(10) global i16 0, align 2 +// CHECK: @_ZL10uint_const = internal addrspace(10) global i32 0, align 4 +// CHECK: @_ZL11ulong_const = internal addrspace(10) global i64 0, align 8 +// CHECK: @_ZL10half_const = internal addrspace(10) global float 0.000000e+00, align 4 +// CHECK: @_ZL11float_const = internal addrspace(10) global float 0.000000e+00, align 4 +// CHECK: @_ZL12double_const = internal addrspace(10) global double 0.000000e+00, align 8 +// CHECK: @_ZL10enum_const = internal addrspace(10) global i32 0, align 4 +//. +// CHECK-LABEL: define internal spir_func void @_Z4mainv( +// CHECK-SAME: ) #[[ATTR0:[0-9]+]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: [[TMP0:%.*]] = call token @llvm.experimental.convergence.entry() +// CHECK-NEXT: [[B:%.*]] = alloca i32, align 4 +// CHECK-NEXT: [[S:%.*]] = alloca i16, align 2 +// CHECK-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK-NEXT: [[L:%.*]] = alloca i64, align 8 +// CHECK-NEXT: [[US:%.*]] = alloca i16, align 2 +// CHECK-NEXT: [[UI:%.*]] = alloca i32, align 4 +// CHECK-NEXT: [[UL:%.*]] = alloca i64, align 8 +// CHECK-NEXT: [[H:%.*]] = alloca float, align 4 +// CHECK-NEXT: [[F:%.*]] = alloca float, align 4 +// CHECK-NEXT: [[D:%.*]] = alloca double, align 8 +// CHECK-NEXT: [[E:%.*]] = alloca i32, align 4 +// CHECK-NEXT: [[TMP1:%.*]] = load i32, ptr addrspace(10) @_ZL10bool_const, align 4 +// CHECK-NEXT: [[LOADEDV:%.*]] = trunc i32 [[TMP1]] to i1 +// CHECK-NEXT: [[STOREDV:%.*]] = zext i1 [[LOADEDV]] to i32 +// CHECK-NEXT: store i32 [[STOREDV]], ptr [[B]], align 4 +// CHECK-NEXT: [[TMP2:%.*]] = load i16, ptr addrspace(10) @_ZL11short_const, align 2 +// CHECK-NEXT: store i16 [[TMP2]], ptr [[S]], align 2 +// CHECK-NEXT: [[TMP3:%.*]] = load i32, ptr addrspace(10) @_ZL9int_const, align 4 +// CHECK-NEXT: store i32 [[TMP3]], ptr [[I]], align 4 +// CHECK-NEXT: [[TMP4:%.*]] = load i64, ptr addrspace(10) @_ZL10long_const, align 8 +// CHECK-NEXT: store i64 [[TMP4]], ptr [[L]], align 8 +// CHECK-NEXT: [[TMP5:%.*]] = load i16, ptr addrspace(10) @_ZL12ushort_const, align 2 +// CHECK-NEXT: store i16 [[TMP5]], ptr [[US]], align 2 +// CHECK-NEXT: [[TMP6:%.*]] = load i32, ptr addrspace(10) @_ZL10uint_const, align 4 +// CHECK-NEXT: store i32 [[TMP6]], ptr [[UI]], align 4 +// CHECK-NEXT: [[TMP7:%.*]] = load i64, ptr addrspace(10) @_ZL11ulong_const, align 8 +// CHECK-NEXT: store i64 [[TMP7]], ptr [[UL]], align 8 +// CHECK-NEXT: [[TMP8:%.*]] = load float, ptr addrspace(10) @_ZL10half_const, align 4 +// CHECK-NEXT: store float [[TMP8]], ptr [[H]], align 4 +// CHECK-NEXT: [[TMP9:%.*]] = load float, ptr addrspace(10) @_ZL11float_const, align 4 +// CHECK-NEXT: store float [[TMP9]], ptr [[F]], align 4 +// CHECK-NEXT: [[TMP10:%.*]] = load double, ptr addrspace(10) @_ZL12double_const, align 8 +// CHECK-NEXT: store double [[TMP10]], ptr [[D]], align 8 +// CHECK-NEXT: [[TMP11:%.*]] = load i32, ptr addrspace(10) @_ZL10enum_const, align 4 +// CHECK-NEXT: store i32 [[TMP11]], ptr [[E]], align 4 +// CHECK-NEXT: ret void +// +// CHECK-LABEL: define internal spir_func void @__cxx_global_var_init( +// CHECK-SAME: ) #[[ATTR3:[0-9]+]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: [[TMP0:%.*]] = call token @llvm.experimental.convergence.entry() +// CHECK-NEXT: [[TMP1:%.*]] = call i1 @_Z20__spirv_SpecConstantib(i32 1, i1 true) +// CHECK-NEXT: [[STOREDV:%.*]] = zext i1 [[TMP1]] to i32 +// CHECK-NEXT: store i32 [[STOREDV]], ptr addrspace(10) @_ZL10bool_const, align 4 +// CHECK-NEXT: ret void +// +// +// CHECK-LABEL: define internal spir_func void @__cxx_global_var_init.1( +// CHECK-SAME: ) #[[ATTR3]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: [[TMP0:%.*]] = call token @llvm.experimental.convergence.entry() +// CHECK-NEXT: [[TMP1:%.*]] = call i16 @_Z20__spirv_SpecConstantis(i32 1, i16 4) +// CHECK-NEXT: store i16 [[TMP1]], ptr addrspace(10) @_ZL11short_const, align 2 +// CHECK-NEXT: ret void +// +// +// CHECK-LABEL: define internal spir_func void @__cxx_global_var_init.2( +// CHECK-SAME: ) #[[ATTR3]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: [[TMP0:%.*]] = call token @llvm.experimental.convergence.entry() +// CHECK-NEXT: [[TMP1:%.*]] = call i32 @_Z20__spirv_SpecConstantii(i32 3, i32 5) +// CHECK-NEXT: store i32 [[TMP1]], ptr addrspace(10) @_ZL9int_const, align 4 +// CHECK-NEXT: ret void +// +// +// CHECK-LABEL: define internal spir_func void @__cxx_global_var_init.3( +// CHECK-SAME: ) #[[ATTR3]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: [[TMP0:%.*]] = call token @llvm.experimental.convergence.entry() +// CHECK-NEXT: [[TMP1:%.*]] = call i64 @_Z20__spirv_SpecConstantix(i32 4, i64 8) +// CHECK-NEXT: store i64 [[TMP1]], ptr addrspace(10) @_ZL10long_const, align 8 +// CHECK-NEXT: ret void +// +// +// CHECK-LABEL: define internal spir_func void @__cxx_global_var_init.4( +// CHECK-SAME: ) #[[ATTR3]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: [[TMP0:%.*]] = call token @llvm.experimental.convergence.entry() +// CHECK-NEXT: [[TMP1:%.*]] = call i16 @_Z20__spirv_SpecConstantit(i32 5, i16 10) +// CHECK-NEXT: store i16 [[TMP1]], ptr addrspace(10) @_ZL12ushort_const, align 2 +// CHECK-NEXT: ret void +// +// +// CHECK-LABEL: define internal spir_func void @__cxx_global_var_init.5( +// CHECK-SAME: ) #[[ATTR3]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: [[TMP0:%.*]] = call token @llvm.experimental.convergence.entry() +// CHECK-NEXT: [[TMP1:%.*]] = call i32 @_Z20__spirv_SpecConstantij(i32 6, i32 12) +// CHECK-NEXT: store i32 [[TMP1]], ptr addrspace(10) @_ZL10uint_const, align 4 +// CHECK-NEXT: ret void +// +// +// CHECK-LABEL: define internal spir_func void @__cxx_global_var_init.6( +// CHECK-SAME: ) #[[ATTR3]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: [[TMP0:%.*]] = call token @llvm.experimental.convergence.entry() +// CHECK-NEXT: [[TMP1:%.*]] = call i64 @_Z20__spirv_SpecConstantiy(i32 7, i64 25) +// CHECK-NEXT: store i64 [[TMP1]], ptr addrspace(10) @_ZL11ulong_const, align 8 +// CHECK-NEXT: ret void +// +// +// CHECK-LABEL: define internal spir_func void @__cxx_global_var_init.7( +// CHECK-SAME: ) #[[ATTR3]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: [[TMP0:%.*]] = call token @llvm.experimental.convergence.entry() +// CHECK-NEXT: [[TMP1:%.*]] = call reassoc nnan ninf nsz arcp afn float @_Z20__spirv_SpecConstantiDh(i32 8, float 0x4044333340000000) +// CHECK-NEXT: store float [[TMP1]], ptr addrspace(10) @_ZL10half_const, align 4 +// CHECK-NEXT: ret void +// +// +// CHECK-LABEL: define internal spir_func void @__cxx_global_var_init.8( +// CHECK-SAME: ) #[[ATTR3]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: [[TMP0:%.*]] = call token @llvm.experimental.convergence.entry() +// CHECK-NEXT: [[TMP1:%.*]] = call reassoc nnan ninf nsz arcp afn float @_Z20__spirv_SpecConstantif(i32 8, float 5.050000e+01) +// CHECK-NEXT: store float [[TMP1]], ptr addrspace(10) @_ZL11float_const, align 4 +// CHECK-NEXT: ret void +// +// +// CHECK-LABEL: define internal spir_func void @__cxx_global_var_init.9( +// CHECK-SAME: ) #[[ATTR3]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: [[TMP0:%.*]] = call token @llvm.experimental.convergence.entry() +// CHECK-NEXT: [[TMP1:%.*]] = call reassoc nnan ninf nsz arcp afn double @_Z20__spirv_SpecConstantid(i32 9, double 0x40590CCCC0000000) +// CHECK-NEXT: store double [[TMP1]], ptr addrspace(10) @_ZL12double_const, align 8 +// CHECK-NEXT: ret void +// +// +// CHECK-LABEL: define internal spir_func void @__cxx_global_var_init.10( +// CHECK-SAME: ) #[[ATTR3]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: [[TMP0:%.*]] = call token @llvm.experimental.convergence.entry() +// CHECK-NEXT: [[TMP1:%.*]] = call i32 @_Z20__spirv_SpecConstantii(i32 10, i32 30) +// CHECK-NEXT: store i32 [[TMP1]], ptr addrspace(10) @_ZL10enum_const, align 4 +// CHECK-NEXT: ret void diff --git a/external/llvm-project/clang/test/CodeGenHLSL/vk-input-builtin.hlsl b/external/llvm-project/clang/test/CodeGenHLSL/vk-input-builtin.hlsl index 1cc7963c0e28..157a1818c82f 100644 --- a/external/llvm-project/clang/test/CodeGenHLSL/vk-input-builtin.hlsl +++ b/external/llvm-project/clang/test/CodeGenHLSL/vk-input-builtin.hlsl @@ -3,7 +3,7 @@ [[vk::ext_builtin_input(/* WorkgroupId */ 26)]] static const uint3 groupid; -// CHECK: @_ZL7groupid = external local_unnamed_addr addrspace(7) externally_initialized constant <3 x i32>, align 16, !spirv.Decorations [[META0:![0-9]+]] +// CHECK: @_ZL7groupid = external hidden local_unnamed_addr addrspace(7) externally_initialized constant <3 x i32>, align 16, !spirv.Decorations [[META0:![0-9]+]] RWStructuredBuffer output : register(u1, space0); diff --git a/external/llvm-project/clang/test/CodeGenOpenCL/amdgcn-buffer-rsrc-type.cl b/external/llvm-project/clang/test/CodeGenOpenCL/amdgcn-buffer-rsrc-type.cl index 62fd20c4d141..f9d7968fc557 100644 --- a/external/llvm-project/clang/test/CodeGenOpenCL/amdgcn-buffer-rsrc-type.cl +++ b/external/llvm-project/clang/test/CodeGenOpenCL/amdgcn-buffer-rsrc-type.cl @@ -44,7 +44,7 @@ void consumeBufferPtr(__amdgpu_buffer_rsrc_t *p) { // CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr addrspace(5) [[A]], align 16, !tbaa [[TBAA8:![0-9]+]] // CHECK-NEXT: [[TOBOOL_NOT:%.*]] = icmp eq i32 [[TMP0]], 0 // CHECK-NEXT: [[TOBOOL_NOT_I:%.*]] = icmp eq ptr addrspace(5) [[A]], addrspacecast (ptr null to ptr addrspace(5)) -// CHECK-NEXT: [[OR_COND:%.*]] = or i1 [[TOBOOL_NOT_I]], [[TOBOOL_NOT]] +// CHECK-NEXT: [[OR_COND:%.*]] = select i1 [[TOBOOL_NOT]], i1 true, i1 [[TOBOOL_NOT_I]] // CHECK-NEXT: br i1 [[OR_COND]], label [[IF_END:%.*]], label [[IF_THEN_I:%.*]] // CHECK: if.then.i: // CHECK-NEXT: [[R:%.*]] = getelementptr inbounds nuw i8, ptr addrspace(5) [[A]], i32 16 diff --git a/external/llvm-project/clang/test/CodeGenOpenCL/amdgpu-features.cl b/external/llvm-project/clang/test/CodeGenOpenCL/amdgpu-features.cl index b94e1e76c7a2..730ed47f0b0c 100644 --- a/external/llvm-project/clang/test/CodeGenOpenCL/amdgpu-features.cl +++ b/external/llvm-project/clang/test/CodeGenOpenCL/amdgpu-features.cl @@ -52,6 +52,7 @@ // RUN: %clang_cc1 -triple amdgcn -target-cpu gfx1153 -emit-llvm -o - %s | FileCheck --check-prefix=GFX1153 %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 +// RUN: %clang_cc1 -triple amdgcn -target-cpu gfx1250 -emit-llvm -o - %s | FileCheck --check-prefix=GFX1250 %s // RUN: %clang_cc1 -triple amdgcn -target-cpu gfx1103 -target-feature +wavefrontsize64 -emit-llvm -o - %s | FileCheck --check-prefix=GFX1103-W64 %s @@ -107,6 +108,7 @@ // GFX1153: "target-features"="+16-bit-insts,+atomic-fadd-rtn-insts,+ci-insts,+dl-insts,+dot10-insts,+dot12-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-buffer-pk-add-bf16-inst,+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,+dot12-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-buffer-pk-add-bf16-inst,+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,+dot12-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" +// GFX1250: "target-features"="+16-bit-insts,+ashr-pk-insts,+atomic-buffer-global-pk-add-f16-insts,+atomic-buffer-pk-add-bf16-inst,+atomic-ds-pk-add-16-insts,+atomic-fadd-rtn-insts,+atomic-flat-pk-add-16-insts,+atomic-global-pk-add-bf16-inst,+bitop3-insts,+ci-insts,+dl-insts,+dot7-insts,+dot8-insts,+dpp,+fp8-conversion-insts,+gfx10-3-insts,+gfx10-insts,+gfx11-insts,+gfx12-insts,+gfx1250-insts,+gfx8-insts,+gfx9-insts,+permlane16-swap,+prng-inst,+setprio-inc-wg-inst,+wavefrontsize32" // GFX1103-W64: "target-features"="+16-bit-insts,+atomic-fadd-rtn-insts,+ci-insts,+dl-insts,+dot10-insts,+dot12-insts,+dot5-insts,+dot7-insts,+dot8-insts,+dot9-insts,+dpp,+gfx10-3-insts,+gfx10-insts,+gfx11-insts,+gfx8-insts,+gfx9-insts,+wavefrontsize64" diff --git a/external/llvm-project/clang/test/CodeGenOpenCL/as_type.cl b/external/llvm-project/clang/test/CodeGenOpenCL/as_type.cl index 2c6cdc3810b4..33e34b03a563 100644 --- a/external/llvm-project/clang/test/CodeGenOpenCL/as_type.cl +++ b/external/llvm-project/clang/test/CodeGenOpenCL/as_type.cl @@ -67,7 +67,7 @@ int3 f8(char16 x) { return __builtin_astype(x, int3); } -//CHECK: define{{.*}} spir_func noundef ptr addrspace(1) @addr_cast(ptr noundef readnone captures(ret: address, provenance) %[[x:.*]]) +//CHECK: define{{.*}} spir_func ptr addrspace(1) @addr_cast(ptr noundef readnone captures(ret: address, provenance) %[[x:.*]]) //CHECK: %[[cast:.*]] ={{.*}} addrspacecast ptr %[[x]] to ptr addrspace(1) //CHECK: ret ptr addrspace(1) %[[cast]] global int* addr_cast(int *x) { diff --git a/external/llvm-project/clang/test/CodeGenOpenCL/builtins-amdgcn-gfx1250.cl b/external/llvm-project/clang/test/CodeGenOpenCL/builtins-amdgcn-gfx1250.cl new file mode 100644 index 000000000000..3709b1ff52f3 --- /dev/null +++ b/external/llvm-project/clang/test/CodeGenOpenCL/builtins-amdgcn-gfx1250.cl @@ -0,0 +1,12 @@ +// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py +// RUN: %clang_cc1 -cl-std=CL2.0 -O0 -triple amdgcn-unknown-unknown -target-cpu gfx1250 -emit-llvm -o - %s | FileCheck %s +// REQUIRES: amdgpu-registered-target + +// CHECK-LABEL: @test_setprio_inc_wg( +// CHECK-NEXT: entry: +// CHECK-NEXT: call void @llvm.amdgcn.s.setprio.inc.wg(i16 10) +// CHECK-NEXT: ret void +// +void test_setprio_inc_wg() { + __builtin_amdgcn_s_setprio_inc_wg(10); +} diff --git a/external/llvm-project/clang/test/Driver/Inputs/basic_managarm_tree/lib/aarch64-managarm-mlibc/.keep b/external/llvm-project/clang/test/Driver/Inputs/basic_managarm_tree/lib/aarch64-managarm-mlibc/.keep new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/external/llvm-project/clang/test/Driver/Inputs/basic_managarm_tree/lib/riscv64-managarm-mlibc/.keep b/external/llvm-project/clang/test/Driver/Inputs/basic_managarm_tree/lib/riscv64-managarm-mlibc/.keep new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/external/llvm-project/clang/test/Driver/Inputs/basic_managarm_tree/lib/x86_64-managarm-mlibc/.keep b/external/llvm-project/clang/test/Driver/Inputs/basic_managarm_tree/lib/x86_64-managarm-mlibc/.keep new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/external/llvm-project/clang/test/Driver/Inputs/basic_managarm_tree/lib64/aarch64-managarm-mlibc/.keep b/external/llvm-project/clang/test/Driver/Inputs/basic_managarm_tree/lib64/aarch64-managarm-mlibc/.keep new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/external/llvm-project/clang/test/Driver/Inputs/basic_managarm_tree/lib64/riscv64-managarm-mlibc/.keep b/external/llvm-project/clang/test/Driver/Inputs/basic_managarm_tree/lib64/riscv64-managarm-mlibc/.keep new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/external/llvm-project/clang/test/Driver/Inputs/basic_managarm_tree/lib64/x86_64-managarm-mlibc/.keep b/external/llvm-project/clang/test/Driver/Inputs/basic_managarm_tree/lib64/x86_64-managarm-mlibc/.keep new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/external/llvm-project/clang/test/Driver/Inputs/basic_managarm_tree/usr/include/aarch64-managarm-mlibc/c++/10/.keep b/external/llvm-project/clang/test/Driver/Inputs/basic_managarm_tree/usr/include/aarch64-managarm-mlibc/c++/10/.keep new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/external/llvm-project/clang/test/Driver/Inputs/basic_managarm_tree/usr/include/c++/10/.keep b/external/llvm-project/clang/test/Driver/Inputs/basic_managarm_tree/usr/include/c++/10/.keep new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/external/llvm-project/clang/test/Driver/Inputs/basic_managarm_tree/usr/include/c++/v1/.keep b/external/llvm-project/clang/test/Driver/Inputs/basic_managarm_tree/usr/include/c++/v1/.keep new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/external/llvm-project/clang/test/Driver/Inputs/basic_managarm_tree/usr/include/riscv64-managarm-mlibc/c++/10/.keep b/external/llvm-project/clang/test/Driver/Inputs/basic_managarm_tree/usr/include/riscv64-managarm-mlibc/c++/10/.keep new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/external/llvm-project/clang/test/Driver/Inputs/basic_managarm_tree/usr/include/x86_64-managarm-mlibc/c++/10/.keep b/external/llvm-project/clang/test/Driver/Inputs/basic_managarm_tree/usr/include/x86_64-managarm-mlibc/c++/10/.keep new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/external/llvm-project/clang/test/Driver/Inputs/basic_managarm_tree/usr/lib/aarch64-managarm-mlibc/.keep b/external/llvm-project/clang/test/Driver/Inputs/basic_managarm_tree/usr/lib/aarch64-managarm-mlibc/.keep new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/external/llvm-project/clang/test/Driver/Inputs/basic_managarm_tree/usr/lib/gcc/aarch64-managarm-mlibc/10/crtbegin.o b/external/llvm-project/clang/test/Driver/Inputs/basic_managarm_tree/usr/lib/gcc/aarch64-managarm-mlibc/10/crtbegin.o new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/external/llvm-project/clang/test/Driver/Inputs/basic_managarm_tree/usr/lib/gcc/aarch64-managarm-mlibc/10/crtbeginS.o b/external/llvm-project/clang/test/Driver/Inputs/basic_managarm_tree/usr/lib/gcc/aarch64-managarm-mlibc/10/crtbeginS.o new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/external/llvm-project/clang/test/Driver/Inputs/basic_managarm_tree/usr/lib/gcc/aarch64-managarm-mlibc/10/crtbeginT.o b/external/llvm-project/clang/test/Driver/Inputs/basic_managarm_tree/usr/lib/gcc/aarch64-managarm-mlibc/10/crtbeginT.o new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/external/llvm-project/clang/test/Driver/Inputs/basic_managarm_tree/usr/lib/gcc/riscv64-managarm-mlibc/10/crtbegin.o b/external/llvm-project/clang/test/Driver/Inputs/basic_managarm_tree/usr/lib/gcc/riscv64-managarm-mlibc/10/crtbegin.o new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/external/llvm-project/clang/test/Driver/Inputs/basic_managarm_tree/usr/lib/gcc/riscv64-managarm-mlibc/10/crtbeginS.o b/external/llvm-project/clang/test/Driver/Inputs/basic_managarm_tree/usr/lib/gcc/riscv64-managarm-mlibc/10/crtbeginS.o new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/external/llvm-project/clang/test/Driver/Inputs/basic_managarm_tree/usr/lib/gcc/riscv64-managarm-mlibc/10/crtbeginT.o b/external/llvm-project/clang/test/Driver/Inputs/basic_managarm_tree/usr/lib/gcc/riscv64-managarm-mlibc/10/crtbeginT.o new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/external/llvm-project/clang/test/Driver/Inputs/basic_managarm_tree/usr/lib/gcc/x86_64-managarm-mlibc/10/crtbegin.o b/external/llvm-project/clang/test/Driver/Inputs/basic_managarm_tree/usr/lib/gcc/x86_64-managarm-mlibc/10/crtbegin.o new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/external/llvm-project/clang/test/Driver/Inputs/basic_managarm_tree/usr/lib/gcc/x86_64-managarm-mlibc/10/crtbeginS.o b/external/llvm-project/clang/test/Driver/Inputs/basic_managarm_tree/usr/lib/gcc/x86_64-managarm-mlibc/10/crtbeginS.o new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/external/llvm-project/clang/test/Driver/Inputs/basic_managarm_tree/usr/lib/gcc/x86_64-managarm-mlibc/10/crtbeginT.o b/external/llvm-project/clang/test/Driver/Inputs/basic_managarm_tree/usr/lib/gcc/x86_64-managarm-mlibc/10/crtbeginT.o new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/external/llvm-project/clang/test/Driver/Inputs/basic_managarm_tree/usr/lib/riscv64-managarm-mlibc/.keep b/external/llvm-project/clang/test/Driver/Inputs/basic_managarm_tree/usr/lib/riscv64-managarm-mlibc/.keep new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/external/llvm-project/clang/test/Driver/Inputs/basic_managarm_tree/usr/lib/x86_64-managarm-mlibc/.keep b/external/llvm-project/clang/test/Driver/Inputs/basic_managarm_tree/usr/lib/x86_64-managarm-mlibc/.keep new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/external/llvm-project/clang/test/Driver/Inputs/basic_managarm_tree/usr/lib64/.keep b/external/llvm-project/clang/test/Driver/Inputs/basic_managarm_tree/usr/lib64/.keep new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/external/llvm-project/clang/test/Driver/aix-shared-lib-tls-model-opt.c b/external/llvm-project/clang/test/Driver/aix-shared-lib-tls-model-opt.c index 7acf091f0a04..891caf4ed3fc 100644 --- a/external/llvm-project/clang/test/Driver/aix-shared-lib-tls-model-opt.c +++ b/external/llvm-project/clang/test/Driver/aix-shared-lib-tls-model-opt.c @@ -1,5 +1,5 @@ -// RUN: %clang -target powerpc64-unknown-aix -S -emit-llvm %s -o - | FileCheck --check-prefixes=CHECK-AIX,CHECK-AIX-OFF %s -// RUN: %clang -target powerpc-unknown-aix -S -emit-llvm %s -o - | FileCheck --check-prefixes=CHECK-AIX,CHECK-AIX-OFF %s +// RUN: %clang -target powerpc64-unknown-aix -S -emit-llvm %s -o - | FileCheck --check-prefix=CHECK-AIX %s +// RUN: %clang -target powerpc-unknown-aix -S -emit-llvm %s -o - | FileCheck --check-prefix=CHECK-AIX %s // RUN: %clang -target powerpc64le-unknown-linux-gnu -S -emit-llvm %s -o - | FileCheck --check-prefix=CHECK-LINUX %s // RUN: %clang -target powerpc64-unknown-linux-gnu -S -emit-llvm %s -o - | FileCheck --check-prefix=CHECK-LINUX %s @@ -19,9 +19,8 @@ int test(void) { // CHECK-AIX: test() #0 { // CHECK-AIX: attributes #0 = { -// CHECK-AIX-OFF-SAME: -aix-shared-lib-tls-model-opt // CHECK-AIX-ON-SAME: +aix-shared-lib-tls-model-opt -// CHECK-LINUX-NOT: {{[-+]aix-shared-lib-tls-model-opt}} +// CHECK-LINUX-NOT: {{[+]aix-shared-lib-tls-model-opt}} // CHECK-UNSUPPORTED-TARGET: option '-maix-shared-lib-tls-model-opt' cannot be specified on this target diff --git a/external/llvm-project/clang/test/Driver/aix-small-local-exec-dynamic-tls.c b/external/llvm-project/clang/test/Driver/aix-small-local-exec-dynamic-tls.c index 1a0619b58e89..6fc2b8efb4ae 100644 --- a/external/llvm-project/clang/test/Driver/aix-small-local-exec-dynamic-tls.c +++ b/external/llvm-project/clang/test/Driver/aix-small-local-exec-dynamic-tls.c @@ -1,37 +1,37 @@ -// RUN: %clang -target powerpc64-unknown-aix -S -emit-llvm %s -o - | FileCheck --check-prefix=CHECK-AIX-DEFAULT %s -// RUN: %clang -target powerpc-unknown-aix -S -emit-llvm %s -o - | FileCheck --check-prefix=CHECK-AIX-DEFAULT %s -// RUN: %clang -target powerpc64le-unknown-linux-gnu -S -emit-llvm %s -o - | FileCheck --check-prefix=CHECK-LINUX %s -// RUN: %clang -target powerpc64-unknown-linux-gnu -S -emit-llvm %s -o - | FileCheck --check-prefix=CHECK-LINUX %s +// RUN: %clang --target=powerpc64-unknown-aix -S -emit-llvm %s -o - | FileCheck --check-prefix=CHECK-DEFAULT %s +// RUN: %clang --target=powerpc-unknown-aix -S -emit-llvm %s -o - | FileCheck --check-prefix=CHECK-DEFAULT %s +// RUN: %clang --target=powerpc64le-unknown-linux-gnu -S -emit-llvm %s -o - | FileCheck --check-prefix=CHECK-DEFAULT %s +// RUN: %clang --target=powerpc64-unknown-linux-gnu -S -emit-llvm %s -o - | FileCheck --check-prefix=CHECK-DEFAULT %s -// RUN: %clang -target powerpc64-unknown-aix -maix-small-local-exec-tls -S -emit-llvm \ +// RUN: %clang --target=powerpc64-unknown-aix -maix-small-local-exec-tls -S -emit-llvm \ // RUN: %s -o - | FileCheck %s --check-prefix=CHECK-AIX_SMALL_LOCALEXEC_TLS -// RUN: %clang -target powerpc64-unknown-aix -maix-small-local-dynamic-tls -S -emit-llvm \ +// RUN: %clang --target=powerpc64-unknown-aix -maix-small-local-dynamic-tls -S -emit-llvm \ // RUN: %s -o - | FileCheck %s --check-prefix=CHECK-AIX_SMALL_LOCALDYNAMIC_TLS -// RUN: not %clang -target powerpc-unknown-aix -maix-small-local-exec-tls \ +// RUN: not %clang --target=powerpc-unknown-aix -maix-small-local-exec-tls \ // RUN: -fsyntax-only %s 2>&1 | FileCheck --check-prefix=CHECK-UNSUPPORTED-AIX32 %s -// RUN: not %clang -target powerpc64le-unknown-linux-gnu -maix-small-local-exec-tls \ +// RUN: not %clang --target=powerpc64le-unknown-linux-gnu -maix-small-local-exec-tls \ // RUN: -fsyntax-only %s 2>&1 | FileCheck --check-prefix=CHECK-UNSUPPORTED-LINUX %s -// RUN: not %clang -target powerpc64-unknown-linux-gnu -maix-small-local-exec-tls \ +// RUN: not %clang --target=powerpc64-unknown-linux-gnu -maix-small-local-exec-tls \ // RUN: -fsyntax-only %s 2>&1 | FileCheck --check-prefix=CHECK-UNSUPPORTED-LINUX %s -// RUN: not %clang -target powerpc64-unknown-aix -maix-small-local-exec-tls \ +// RUN: not %clang --target=powerpc64-unknown-aix -maix-small-local-exec-tls \ // RUN: -fsyntax-only -fno-data-sections %s 2>&1 | \ // RUN: FileCheck --check-prefix=CHECK-UNSUPPORTED-NO-DATASEC %s -// RUN: not %clang -target powerpc64-unknown-linux-gnu -maix-small-local-exec-tls \ +// RUN: not %clang --target=powerpc64-unknown-linux-gnu -maix-small-local-exec-tls \ // RUN: -fsyntax-only -fno-data-sections %s 2>&1 | \ // RUN: FileCheck --check-prefix=CHECK-UNSUPPORTED-NO-DATASEC %s -// RUN: not %clang -target powerpc-unknown-aix -maix-small-local-dynamic-tls \ +// RUN: not %clang --target=powerpc-unknown-aix -maix-small-local-dynamic-tls \ // RUN: -fsyntax-only %s 2>&1 | FileCheck --check-prefix=CHECK-UNSUPPORTED-AIX32 %s -// RUN: not %clang -target powerpc64le-unknown-linux-gnu -maix-small-local-dynamic-tls \ +// RUN: not %clang --target=powerpc64le-unknown-linux-gnu -maix-small-local-dynamic-tls \ // RUN: -fsyntax-only %s 2>&1 | FileCheck --check-prefix=CHECK-UNSUPPORTED-LINUX %s -// RUN: not %clang -target powerpc64-unknown-linux-gnu -maix-small-local-dynamic-tls \ +// RUN: not %clang --target=powerpc64-unknown-linux-gnu -maix-small-local-dynamic-tls \ // RUN: -fsyntax-only %s 2>&1 | FileCheck --check-prefix=CHECK-UNSUPPORTED-LINUX %s -// RUN: not %clang -target powerpc64-unknown-aix -maix-small-local-dynamic-tls \ +// RUN: not %clang --target=powerpc64-unknown-aix -maix-small-local-dynamic-tls \ // RUN: -fsyntax-only -fno-data-sections %s 2>&1 | \ // RUN: FileCheck --check-prefix=CHECK-UNSUPPORTED-NO-DATASEC %s -// RUN: not %clang -target powerpc64-unknown-linux-gnu -maix-small-local-dynamic-tls \ +// RUN: not %clang --target=powerpc64-unknown-linux-gnu -maix-small-local-dynamic-tls \ // RUN: -fsyntax-only -fno-data-sections %s 2>&1 | \ // RUN: FileCheck --check-prefix=CHECK-UNSUPPORTED-NO-DATASEC %s @@ -39,10 +39,9 @@ int test(void) { return 0; } -// CHECK-AIX-DEFAULT: test() #0 { -// CHECK-AIX-DEFAULT: attributes #0 = { -// CHECK-AIX-DEFAULT-SAME: {{-aix-small-local-exec-tls,.*-aix-small-local-dynamic-tls|-aix-small-local-dynamic-tls,.*-aix-small-local-exec-tls}} -// CHECK-LINUX-NOT: {{[-+]aix-small-local-exec-tls,.*[-+]aix-small-local-dynamic-tls|[-+]aix-small-local-dynamic-tls,.*[-+]aix-small-local-exec-tls}} +// CHECK-DEFAULT: test() #0 { +// CHECK-DEFAULT: attributes #0 = { +// CHECK-DEFAULT-NOT: {{[-+]aix-small-local-exec-tls,.*[-+]aix-small-local-dynamic-tls|[-+]aix-small-local-dynamic-tls,.*[-+]aix-small-local-exec-tls}} // CHECK-UNSUPPORTED-AIX32: option '-maix-small-local-[exec|dynamic]-tls' cannot be specified on this target // CHECK-UNSUPPORTED-LINUX: option '-maix-small-local-[exec|dynamic]-tls' cannot be specified on this target diff --git a/external/llvm-project/clang/test/Driver/amdgpu-macros.cl b/external/llvm-project/clang/test/Driver/amdgpu-macros.cl index 35dc190761ca..a60593f2ab9e 100644 --- a/external/llvm-project/clang/test/Driver/amdgpu-macros.cl +++ b/external/llvm-project/clang/test/Driver/amdgpu-macros.cl @@ -130,6 +130,7 @@ // RUN: %clang -E -dM -target amdgcn -mcpu=gfx1153 %s 2>&1 | FileCheck --check-prefixes=ARCH-GCN,FAST_FMAF %s -DWAVEFRONT_SIZE=32 -DCPU=gfx1153 -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 +// RUN: %clang -E -dM -target amdgcn -mcpu=gfx1250 %s 2>&1 | FileCheck --check-prefixes=ARCH-GCN,FAST_FMAF %s -DWAVEFRONT_SIZE=32 -DCPU=gfx1250 -DFAMILY=GFX12 // RUN: %clang -E -dM -target amdgcn -mcpu=gfx9-generic %s 2>&1 | FileCheck --check-prefixes=ARCH-GCN,FAST_FMAF %s -DWAVEFRONT_SIZE=64 -DCPU=gfx9_generic -DFAMILY=GFX9 // RUN: %clang -E -dM -target amdgcn -mcpu=gfx9-4-generic %s 2>&1 | FileCheck --check-prefixes=ARCH-GCN,FAST_FMAF %s -DWAVEFRONT_SIZE=64 -DCPU=gfx9_4_generic -DFAMILY=GFX9 @@ -177,13 +178,19 @@ // RUN: %clang -E -dM -target amdgcn -mcpu=gfx906 -mcumode \ // RUN: %s 2>&1 | FileCheck --check-prefix=CUMODE-ON %s // RUN: %clang -E -dM -target amdgcn -mcpu=gfx906 -mno-cumode \ -// RUN: %s 2>&1 | FileCheck --check-prefixes=CUMODE-ON,WARN-CUMODE %s +// RUN: %s 2>&1 | FileCheck -DMCPU=gfx906 --check-prefixes=CUMODE-ON,WARN-CUMODE %s // RUN: %clang -E -dM -target amdgcn -mcpu=gfx1030 \ // RUN: %s 2>&1 | FileCheck --check-prefix=CUMODE-OFF %s // RUN: %clang -E -dM -target amdgcn -mcpu=gfx1030 -mcumode \ // RUN: %s 2>&1 | FileCheck --check-prefix=CUMODE-ON %s // RUN: %clang -E -dM -target amdgcn -mcpu=gfx1030 -mno-cumode \ // RUN: %s 2>&1 | FileCheck --check-prefix=CUMODE-OFF %s -// WARN-CUMODE-DAG: warning: ignoring '-mno-cumode' option as it is not currently supported for processor 'gfx906' [-Woption-ignored] +// RUN: %clang -E -dM -target amdgcn -mcpu=gfx1250 \ +// RUN: %s 2>&1 | FileCheck --check-prefix=CUMODE-ON %s +// RUN: %clang -E -dM -target amdgcn -mcpu=gfx1250 -mcumode \ +// RUN: %s 2>&1 | FileCheck --check-prefix=CUMODE-ON %s +// RUN: %clang -E -dM -target amdgcn -mcpu=gfx1250 -mno-cumode \ +// RUN: %s 2>&1 | FileCheck -DMCPU=gfx1250 --check-prefixes=CUMODE-ON,WARN-CUMODE %s +// WARN-CUMODE-DAG: warning: ignoring '-mno-cumode' option as it is not currently supported for processor '[[MCPU]]' [-Woption-ignored] // CUMODE-ON-DAG: #define __AMDGCN_CUMODE__ 1 // CUMODE-OFF-DAG: #define __AMDGCN_CUMODE__ 0 diff --git a/external/llvm-project/clang/test/Driver/amdgpu-mcpu.cl b/external/llvm-project/clang/test/Driver/amdgpu-mcpu.cl index ad5fd8ebaa6a..6d302e4c59ad 100644 --- a/external/llvm-project/clang/test/Driver/amdgpu-mcpu.cl +++ b/external/llvm-project/clang/test/Driver/amdgpu-mcpu.cl @@ -115,6 +115,7 @@ // RUN: %clang -### -target amdgcn -mcpu=gfx1153 %s 2>&1 | FileCheck --check-prefix=GFX1153 %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 +// RUN: %clang -### -target amdgcn -mcpu=gfx1250 %s 2>&1 | FileCheck --check-prefix=GFX1250 %s // RUN: %clang -### -target amdgcn -mcpu=gfx9-generic %s 2>&1 | FileCheck --check-prefix=GFX9_GENERIC %s // RUN: %clang -### -target amdgcn -mcpu=gfx9-4-generic %s 2>&1 | FileCheck --check-prefix=GFX9_4_GENERIC %s @@ -169,6 +170,7 @@ // GFX1153: "-target-cpu" "gfx1153" // GFX1200: "-target-cpu" "gfx1200" // GFX1201: "-target-cpu" "gfx1201" +// GFX1250: "-target-cpu" "gfx1250" // GFX9_GENERIC: "-target-cpu" "gfx9-generic" // GFX9_4_GENERIC: "-target-cpu" "gfx9-4-generic" diff --git a/external/llvm-project/clang/test/Driver/android-link.cpp b/external/llvm-project/clang/test/Driver/android-link.cpp index ab7dae540558..b103263cdd3f 100644 --- a/external/llvm-project/clang/test/Driver/android-link.cpp +++ b/external/llvm-project/clang/test/Driver/android-link.cpp @@ -16,6 +16,16 @@ // RUN: FileCheck -check-prefix=CORTEX-A57 < %t %s // RUN: %clang --target=aarch64-none-linux-android \ +// RUN: -mno-fix-cortex-a53-843419 \ +// RUN: -### -v %s 2> %t +// RUN: FileCheck -check-prefix=OVERRIDDEN < %t %s +// +// RUN: %clang -target aarch64-none-linux-android \ +// RUN: -mno-fix-cortex-a53-843419 -mfix-cortex-a53-843419 \ +// RUN: -### -v %s 2> %t +// RUN: FileCheck -check-prefix=OVERRIDDEN2 < %t %s +// +// RUN: %clang -target aarch64-none-linux-android \ // RUN: -### -v %s 2> %t // RUN: FileCheck -check-prefix=MAX-PAGE-SIZE-16KB < %t %s @@ -31,6 +41,8 @@ // GENERIC-ARM: --fix-cortex-a53-843419 // CORTEX-A53: --fix-cortex-a53-843419 // CORTEX-A57-NOT: --fix-cortex-a53-843419 +// OVERRIDDEN-NOT: --fix-cortex-a53-843419 +// OVERRIDDEN2: --fix-cortex-a53-843419 // MAX-PAGE-SIZE-4KB: "-z" "max-page-size=4096" // MAX-PAGE-SIZE-16KB: "-z" "max-page-size=16384" // NO-MAX-PAGE-SIZE-16KB-NOT: "-z" "max-page-size=16384" diff --git a/external/llvm-project/clang/test/Driver/cl-options.c b/external/llvm-project/clang/test/Driver/cl-options.c index 0535285862b9..eb079895a0a8 100644 --- a/external/llvm-project/clang/test/Driver/cl-options.c +++ b/external/llvm-project/clang/test/Driver/cl-options.c @@ -821,7 +821,11 @@ // ARM64EC_OVERRIDE: warning: /arm64EC has been overridden by specified target: x86_64-pc-windows-msvc; option ignored // RUN: %clang_cl /d2epilogunwind /c -### -- %s 2>&1 | FileCheck %s --check-prefix=EPILOGUNWIND -// EPILOGUNWIND: -fwinx64-eh-unwindv2 +// EPILOGUNWIND: -fwinx64-eh-unwindv2=best-effort + +// RUN: %clang_cl /d2epilogunwindrequirev2 /c -### -- %s 2>&1 | FileCheck %s --check-prefix=EPILOGUNWINDREQUIREV2 +// RUN: %clang_cl /d2epilogunwindrequirev2 /d2epilogunwind /c -### -- %s 2>&1 | FileCheck %s --check-prefix=EPILOGUNWINDREQUIREV2 +// EPILOGUNWINDREQUIREV2: -fwinx64-eh-unwindv2=require // RUN: %clang_cl /funcoverride:override_me1 /funcoverride:override_me2 /c -### -- %s 2>&1 | FileCheck %s --check-prefix=FUNCOVERRIDE // FUNCOVERRIDE: -loader-replaceable-function=override_me1 diff --git a/external/llvm-project/clang/test/Driver/extend-variable-liveness.c b/external/llvm-project/clang/test/Driver/extend-variable-liveness.c index bbfb2ece6f29..99a5409cecce 100644 --- a/external/llvm-project/clang/test/Driver/extend-variable-liveness.c +++ b/external/llvm-project/clang/test/Driver/extend-variable-liveness.c @@ -1,7 +1,8 @@ // Tests that -fextend-variable-liveness and its aliases are correctly passed -// by the driver. +// by the driver, and are set by default at -Og. // RUN: %clang -### -c %s 2>&1 | FileCheck %s --check-prefixes=CHECK,DEFAULT +// RUN: %clang -### -Og -c %s 2>&1 | FileCheck %s --check-prefixes=CHECK,ALL // RUN: %clang -fextend-variable-liveness=none -### -c %s 2>&1 | FileCheck %s --check-prefixes=CHECK,NONE // RUN: %clang -fextend-variable-liveness=this -### -c %s 2>&1 | FileCheck %s --check-prefixes=CHECK,THIS // RUN: %clang -fextend-variable-liveness=all -### -c %s 2>&1 | FileCheck %s --check-prefixes=CHECK,ALL diff --git a/external/llvm-project/clang/test/Driver/fveclib.c b/external/llvm-project/clang/test/Driver/fveclib.c index 5420555c36a2..c57e9aa7a3cc 100644 --- a/external/llvm-project/clang/test/Driver/fveclib.c +++ b/external/llvm-project/clang/test/Driver/fveclib.c @@ -1,6 +1,7 @@ // RUN: %clang -### -c -fveclib=none %s 2>&1 | FileCheck --check-prefix=CHECK-NOLIB %s // RUN: %clang -### -c -fveclib=Accelerate %s 2>&1 | FileCheck --check-prefix=CHECK-ACCELERATE %s // RUN: %clang -### -c --target=x86_64-unknown-linux-gnu -fveclib=libmvec %s 2>&1 | FileCheck --check-prefix=CHECK-libmvec %s +// RUN: %clang -### -c --target=aarch64-linux-gnu -fveclib=libmvec %s 2>&1 | FileCheck --check-prefix=CHECK-LIBMVEC-AARCH64 %s // RUN: %clang -### -c --target=x86_64-unknown-linux-gnu -fveclib=AMDLIBM %s 2>&1 | FileCheck --check-prefix=CHECK-AMDLIBM %s // RUN: %clang -### -c -fveclib=MASSV %s 2>&1 | FileCheck --check-prefix=CHECK-MASSV %s // RUN: %clang -### -c -fveclib=Darwin_libsystem_m %s 2>&1 | FileCheck --check-prefix=CHECK-DARWIN_LIBSYSTEM_M %s @@ -12,6 +13,7 @@ // CHECK-NOLIB: "-fveclib=none" // CHECK-ACCELERATE: "-fveclib=Accelerate" // CHECK-libmvec: "-fveclib=libmvec" +// CHECK-LIBMVEC-AARCH64: "-fveclib=libmvec" // CHECK-AMDLIBM: "-fveclib=AMDLIBM" // CHECK-MASSV: "-fveclib=MASSV" // CHECK-DARWIN_LIBSYSTEM_M: "-fveclib=Darwin_libsystem_m" @@ -23,7 +25,6 @@ // RUN: not %clang --target=x86 -c -fveclib=SLEEF %s 2>&1 | FileCheck --check-prefix=CHECK-ERROR %s // RUN: not %clang --target=x86 -c -fveclib=ArmPL %s 2>&1 | FileCheck --check-prefix=CHECK-ERROR %s -// RUN: not %clang --target=aarch64 -c -fveclib=libmvec %s 2>&1 | FileCheck --check-prefix=CHECK-ERROR %s // RUN: not %clang --target=aarch64 -c -fveclib=SVML %s 2>&1 | FileCheck --check-prefix=CHECK-ERROR %s // RUN: not %clang --target=aarch64 -c -fveclib=AMDLIBM %s 2>&1 | FileCheck --check-prefix=CHECK-ERROR %s // CHECK-ERROR: unsupported option {{.*}} for target @@ -43,6 +44,9 @@ // RUN: %clang -### --target=x86_64-unknown-linux-gnu -fveclib=libmvec -flto %s 2>&1 | FileCheck --check-prefix=CHECK-LTO-LIBMVEC %s // CHECK-LTO-LIBMVEC: "-plugin-opt=-vector-library=LIBMVEC" +// RUN: %clang -### --target=aarch64-linux-gnu -fveclib=libmvec -flto %s 2>&1 | FileCheck --check-prefix=CHECK-LTO-LIBMVEC-AARCH64 %s +// CHECK-LTO-LIBMVEC-AARCH64: "-plugin-opt=-vector-library=LIBMVEC" + // RUN: %clang -### --target=x86_64-unknown-linux-gnu -fveclib=AMDLIBM -flto %s 2>&1 | FileCheck --check-prefix=CHECK-LTO-AMDLIBM %s // CHECK-LTO-AMDLIBM: "-plugin-opt=-vector-library=AMDLIBM" @@ -68,6 +72,10 @@ // CHECK-ERRNO-LIBMVEC: "-fveclib=libmvec" // CHECK-ERRNO-LIBMVEC-SAME: "-fmath-errno" +// RUN: %clang -### --target=aarch64-linux-gnu -fveclib=libmvec %s 2>&1 | FileCheck --check-prefix=CHECK-ERRNO-LIBMVEC-AARCH64 %s +// CHECK-ERRNO-LIBMVEC-AARCH64: "-fveclib=libmvec" +// CHECK-ERRNO-LIBMVEC-AARCH64-SAME: "-fmath-errno" + // RUN: %clang -### --target=x86_64-unknown-linux-gnu -fveclib=AMDLIBM %s 2>&1 | FileCheck --check-prefix=CHECK-ERRNO-AMDLIBM %s // CHECK-ERRNO-AMDLIBM: "-fveclib=AMDLIBM" // CHECK-ERRNO-AMDLIBM-SAME: "-fmath-errno" diff --git a/external/llvm-project/clang/test/Driver/hip-include-path.hip b/external/llvm-project/clang/test/Driver/hip-include-path.hip index 5eeee2f5ce0d..3c7384ab9835 100644 --- a/external/llvm-project/clang/test/Driver/hip-include-path.hip +++ b/external/llvm-project/clang/test/Driver/hip-include-path.hip @@ -12,6 +12,10 @@ // RUN: -std=c++11 --rocm-path=%S/Inputs/rocm -nogpuinc -nogpulib %s 2>&1 \ // RUN: | FileCheck -check-prefixes=COMMON,CLANG,NOHIP %s +// RUN: %clang -c -### --target=x86_64-unknown-linux-gnu --cuda-gpu-arch=gfx900 \ +// RUN: -std=c++11 --rocm-path=%S/Inputs/rocm --no-offload-inc -nogpulib --offload-inc %s 2>&1 \ +// RUN: | FileCheck -check-prefixes=COMMON,CLANG,HIP %s + // COMMON-LABEL: "{{[^"]*}}clang{{[^"]*}}" "-cc1" // CLANG-SAME: "-internal-isystem" "{{[^"]*}}/lib{{[^"]*}}/clang/{{[^"]*}}/include/cuda_wrappers" // NOCLANG-NOT: "{{[^"]*}}/lib{{[^"]*}}/clang/{{[^"]*}}/include/cuda_wrappers" diff --git a/external/llvm-project/clang/test/Driver/hip-runtime-libs-linux.hip b/external/llvm-project/clang/test/Driver/hip-runtime-libs-linux.hip index a4cd2733114b..eda87d0aa4b6 100644 --- a/external/llvm-project/clang/test/Driver/hip-runtime-libs-linux.hip +++ b/external/llvm-project/clang/test/Driver/hip-runtime-libs-linux.hip @@ -20,6 +20,11 @@ // RUN: --rocm-path=%S/Inputs/rocm %t.o -frtlib-add-rpath 2>&1 \ // RUN: | FileCheck -check-prefixes=ROCM-RPATH %s +// Test that a canonical HIP runtime path is passed to the -rpath flag +// RUN: %clang -### --hip-link --target=x86_64-linux-gnu \ +// RUN: --rocm-path=%S/Inputs/rocm/./bin/../include/../ %t.o -frtlib-add-rpath 2>&1 \ +// RUN: | FileCheck -check-prefixes=ROCM-RPATH-CANONICAL %s + // Test detecting latest /opt/rocm-{release} directory. // RUN: rm -rf %t && mkdir -p %t/opt // RUN: cp -r %S/Inputs/rocm %t/opt/rocm-3.9.0-1234 @@ -55,6 +60,7 @@ // ROCM-PATH: "-L[[HIPRT:.*/Inputs/rocm/lib]]" "-lamdhip64" // ROCM-RPATH: "-L[[HIPRT:.*/Inputs/rocm/lib]]" "-rpath" "[[HIPRT]]" "-lamdhip64" +// ROCM-RPATH-CANONICAL: "-rpath" "{{.*/rocm/lib}}" "-lamdhip64" // ROCM-REL: "-L[[HIPRT:.*/opt/rocm-3.10.0/lib]]" "-lamdhip64" // NOHIPRT-NOT: "-L{{.*/Inputs/rocm/lib}}" // NOHIPRT-NOT: "-rpath" "{{.*/Inputs/rocm/lib}}" diff --git a/external/llvm-project/clang/test/Driver/hip-thinlto.hip b/external/llvm-project/clang/test/Driver/hip-thinlto.hip index 4227cd3f2e9f..bcb7d4e6cb52 100644 --- a/external/llvm-project/clang/test/Driver/hip-thinlto.hip +++ b/external/llvm-project/clang/test/Driver/hip-thinlto.hip @@ -3,6 +3,7 @@ // CHECK: -plugin-opt=thinlto // CHECK-SAME: -plugin-opt=-force-import-all // CHECK-SAME: -plugin-opt=-avail-extern-to-local +// CHECK-SAME: -plugin-opt=-avail-extern-gv-in-addrspace-to-local=3 int main(int, char *[]) { return 0; } diff --git a/external/llvm-project/clang/test/Driver/ignored-pch.cpp b/external/llvm-project/clang/test/Driver/ignored-pch.cpp new file mode 100644 index 000000000000..a3597dc0fe0d --- /dev/null +++ b/external/llvm-project/clang/test/Driver/ignored-pch.cpp @@ -0,0 +1,19 @@ +// RUN: rm -rf %t +// RUN: mkdir -p %t + +// Create PCH without -ignore-pch. +// RUN: %clang -x c++-header %S/Inputs/pchfile.h -### 2>&1 | FileCheck %s -check-prefix=CHECK-EMIT-PCH +// RUN: %clang -x c++-header %S/Inputs/pchfile.h -o %t/pchfile.h.pch +// RUN: %clang %s -include-pch %t/pchfile.h.pch -### 2>&1 | FileCheck %s -check-prefix=CHECK-INCLUDE-PCH +// RUN: %clang %s -emit-ast -include-pch %t/pchfile.h.pch -### 2>&1 | FileCheck %s -check-prefixes=CHECK-EMIT-PCH,CHECK-INCLUDE-PCH + + +// Create PCH with -ignore-pch. +// RUN: %clang -x c++-header -ignore-pch %S/Inputs/pchfile.h -### 2>&1 | FileCheck %s -check-prefix=CHECK-IGNORE-PCH +// RUN: %clang %s -ignore-pch -include-pch %t/pchfile.h.pch -### 2>&1 | FileCheck %s -check-prefix=CHECK-IGNORE-PCH +// RUN: %clang %s -ignore-pch -emit-ast -include-pch %t/pchfile.h.pch -### 2>&1 | FileCheck %s -check-prefix=CHECK-IGNORE-PCH + +// CHECK-EMIT-PCH: -emit-pch +// CHECK-INCLUDE-PCH: -include-pch +// CHECK-IGNORE-PCH-NOT: -emit-pch +// CHECK-IGNORE-PCH-NOT: -include-pch diff --git a/external/llvm-project/clang/test/Driver/managarm.cpp b/external/llvm-project/clang/test/Driver/managarm.cpp new file mode 100644 index 000000000000..9c3f2d4d722a --- /dev/null +++ b/external/llvm-project/clang/test/Driver/managarm.cpp @@ -0,0 +1,267 @@ +// UNSUPPORTED: system-windows + +// RUN: %clang -### %s --target=x86_64-unknown-managarm-mlibc --sysroot=%S/Inputs/basic_managarm_tree \ +// RUN: --stdlib=platform 2>&1 | FileCheck --check-prefix=CHECK-X86-64 %s +// CHECK-X86-64: "-cc1" +// CHECK-X86-64-SAME: "-isysroot" "[[SYSROOT:[^"]+]]" +// CHECK-X86-64-SAME: {{^}} "-internal-isystem" "[[SYSROOT]]/usr/lib/gcc/x86_64-managarm-mlibc/10/../../../../include/c++/10" +// CHECK-X86-64-SAME: {{^}} "-internal-isystem" "[[SYSROOT]]/usr/lib/gcc/x86_64-managarm-mlibc/10/../../../../include/x86_64-managarm-mlibc/c++/10" +// CHECK-X86-64-SAME: {{^}} "-internal-isystem" "[[SYSROOT]]/usr/lib/gcc/x86_64-managarm-mlibc/10/../../../../include/c++/10/backward" +// CHECK-X86-64-SAME: {{^}} "-internal-isystem" "[[SYSROOT]]/usr/local/include" +// CHECK-X86-64-SAME: "-internal-externc-isystem" +// CHECK-X86-64-SAME: {{^}} "[[SYSROOT]]/usr/include/x86_64-managarm-mlibc" +// CHECK-X86-64-SAME: {{^}} "-internal-externc-isystem" "[[SYSROOT]]/include" +// CHECK-X86-64-SAME: {{^}} "-internal-externc-isystem" "[[SYSROOT]]/usr/include" +// CHECK-X86-64: "{{.*}}ld" "--sysroot=[[SYSROOT:[^"]+]]" +// CHECK-X86-64-SAME: "-dynamic-linker" "/lib/x86_64-managarm/ld.so" +// CHECK-X86-64-SAME: "{{.*}}/usr/lib/gcc/x86_64-managarm-mlibc/10/crtbegin.o" +// CHECK-X86-64-SAME: "-L +// CHECK-X86-64-SAME: {{^}}[[SYSROOT]]/usr/lib/gcc/x86_64-managarm-mlibc/10" +// CHECK-X86-64-SAME: {{^}} "-L[[SYSROOT]]/usr/lib/gcc/x86_64-managarm-mlibc/10/../../../../lib64" +// CHECK-X86-64-SAME: {{^}} "-L[[SYSROOT]]/lib/x86_64-managarm-mlibc" +// CHECK-X86-64-SAME: {{^}} "-L[[SYSROOT]]/lib/../lib64" +// CHECK-X86-64-SAME: {{^}} "-L[[SYSROOT]]/usr/lib/x86_64-managarm-mlibc" +// CHECK-X86-64-SAME: {{^}} "-L[[SYSROOT]]/usr/lib64" +// CHECK-X86-64-SAME: {{^}} "-L[[SYSROOT]]/lib" +// CHECK-X86-64-SAME: {{^}} "-L[[SYSROOT]]/usr/lib" + +// RUN: %clang -### %s --target=x86_64-unknown-managarm-mlibc --sysroot=%S/Inputs/basic_managarm_tree \ +// RUN: --stdlib=libc++ --rtlib=compiler-rt --unwindlib=libunwind 2>&1 | FileCheck --check-prefix=CHECK-X86-64-LIBS %s +// CHECK-X86-64-LIBS: "-cc1" +// CHECK-X86-64-LIBS-SAME: "-isysroot" "[[SYSROOT:[^"]+]]" +// CHECK-X86-64-LIBS-SAME: {{^}} "-internal-isystem" "[[SYSROOT:[^"]+]]/include/c++/v1" +// CHECK-X86-64-LIBS-SAME: {{^}} "-internal-isystem" "[[SYSROOT:[^"]+]]/usr/local/include" +// CHECK-X86-64-LIBS-SAME: "-internal-externc-isystem" +// CHECK-X86-64-LIBS-SAME: {{^}} "[[SYSROOT]]/usr/include/x86_64-managarm-mlibc" +// CHECK-X86-64-LIBS-SAME: {{^}} "-internal-externc-isystem" "[[SYSROOT]]/include" +// CHECK-X86-64-LIBS-SAME: {{^}} "-internal-externc-isystem" "[[SYSROOT]]/usr/include" +// CHECK-X86-64-LIBS: "{{.*}}ld" "--sysroot=[[SYSROOT:[^"]+]]" +// CHECK-X86-64-LIBS-SAME: "-dynamic-linker" "/lib/x86_64-managarm/ld.so" +// CHECK-X86-64-LIBS-SAME: "{{.*}}/usr/lib/gcc/x86_64-managarm-mlibc/10/crtbegin.o" +// CHECK-X86-64-LIBS-SAME: "-L +// CHECK-X86-64-LIBS-SAME: {{^}}[[SYSROOT]]/usr/lib/gcc/x86_64-managarm-mlibc/10" +// CHECK-X86-64-LIBS-SAME: {{^}} "-L[[SYSROOT]]/usr/lib/gcc/x86_64-managarm-mlibc/10/../../../../lib64" +// CHECK-X86-64-LIBS-SAME: {{^}} "-L[[SYSROOT]]/lib/x86_64-managarm-mlibc" +// CHECK-X86-64-LIBS-SAME: {{^}} "-L[[SYSROOT]]/lib/../lib64" +// CHECK-X86-64-LIBS-SAME: {{^}} "-L[[SYSROOT]]/usr/lib/x86_64-managarm-mlibc" +// CHECK-X86-64-LIBS-SAME: {{^}} "-L[[SYSROOT]]/usr/lib64" +// CHECK-X86-64-LIBS-SAME: {{^}} "-L[[SYSROOT]]/lib" +// CHECK-X86-64-LIBS-SAME: {{^}} "-L[[SYSROOT]]/usr/lib" + +// RUN: %clang -### %s --target=x86_64-unknown-managarm-mlibc --sysroot=%S/Inputs/basic_managarm_tree \ +// RUN: --stdlib=platform -static 2>&1 | FileCheck --check-prefix=CHECK-X86-64-STATIC %s +// CHECK-X86-64-STATIC: "-cc1" +// CHECK-X86-64-STATIC-SAME: "-static-define" +// CHECK-X86-64-STATIC-SAME: "-isysroot" "[[SYSROOT:[^"]+]]" +// CHECK-X86-64-STATIC-SAME: {{^}} "-internal-isystem" "[[SYSROOT]]/usr/lib/gcc/x86_64-managarm-mlibc/10/../../../../include/c++/10" +// CHECK-X86-64-STATIC-SAME: {{^}} "-internal-isystem" "[[SYSROOT]]/usr/lib/gcc/x86_64-managarm-mlibc/10/../../../../include/x86_64-managarm-mlibc/c++/10" +// CHECK-X86-64-STATIC-SAME: {{^}} "-internal-isystem" "[[SYSROOT]]/usr/lib/gcc/x86_64-managarm-mlibc/10/../../../../include/c++/10/backward" +// CHECK-X86-64-STATIC-SAME: {{^}} "-internal-isystem" "[[SYSROOT]]/usr/local/include" +// CHECK-X86-64-STATIC-SAME: "-internal-externc-isystem" +// CHECK-X86-64-STATIC-SAME: {{^}} "[[SYSROOT]]/usr/include/x86_64-managarm-mlibc" +// CHECK-X86-64-STATIC-SAME: {{^}} "-internal-externc-isystem" "[[SYSROOT]]/include" +// CHECK-X86-64-STATIC-SAME: {{^}} "-internal-externc-isystem" "[[SYSROOT]]/usr/include" +// CHECK-X86-64-STATIC: "{{.*}}ld" "--sysroot=[[SYSROOT:[^"]+]]" +// CHECK-X86-64-STATIC-SAME: "-static" +// CHECK-X86-64-STATIC-SAME: "{{.*}}/usr/lib/gcc/x86_64-managarm-mlibc/10/crtbeginT.o" +// CHECK-X86-64-STATIC-SAME: "-L +// CHECK-X86-64-STATIC-SAME: {{^}}[[SYSROOT]]/usr/lib/gcc/x86_64-managarm-mlibc/10" +// CHECK-X86-64-STATIC-SAME: {{^}} "-L[[SYSROOT]]/usr/lib/gcc/x86_64-managarm-mlibc/10/../../../../lib64" +// CHECK-X86-64-STATIC-SAME: {{^}} "-L[[SYSROOT]]/lib/x86_64-managarm-mlibc" +// CHECK-X86-64-STATIC-SAME: {{^}} "-L[[SYSROOT]]/lib/../lib64" +// CHECK-X86-64-STATIC-SAME: {{^}} "-L[[SYSROOT]]/usr/lib/x86_64-managarm-mlibc" +// CHECK-X86-64-STATIC-SAME: {{^}} "-L[[SYSROOT]]/usr/lib64" +// CHECK-X86-64-STATIC-SAME: {{^}} "-L[[SYSROOT]]/lib" +// CHECK-X86-64-STATIC-SAME: {{^}} "-L[[SYSROOT]]/usr/lib" + +// RUN: %clang -### %s --target=x86_64-unknown-managarm-mlibc --sysroot=%S/Inputs/basic_managarm_tree \ +// RUN: -shared 2>&1 | FileCheck --check-prefix=CHECK-X86-64-SHARED %s +// CHECK-X86-64-SHARED: "{{.*}}ld" "--sysroot=[[SYSROOT:[^"]+]]" +// CHECK-X86-64-SHARED-SAME: "{{.*}}/usr/lib/gcc/x86_64-managarm-mlibc/10/crtbeginS.o" +// CHECK-X86-64-SHARED-SAME: "-L +// CHECK-X86-64-SHARED-SAME: {{^}}[[SYSROOT]]/usr/lib/gcc/x86_64-managarm-mlibc/10" +// CHECK-X86-64-SHARED-SAME: {{^}} "-L[[SYSROOT]]/usr/lib/gcc/x86_64-managarm-mlibc/10/../../../../lib64" +// CHECK-X86-64-SHARED-SAME: {{^}} "-L[[SYSROOT]]/lib/x86_64-managarm-mlibc" +// CHECK-X86-64-SHARED-SAME: {{^}} "-L[[SYSROOT]]/lib/../lib64" +// CHECK-X86-64-SHARED-SAME: {{^}} "-L[[SYSROOT]]/usr/lib/x86_64-managarm-mlibc" +// CHECK-X86-64-SHARED-SAME: {{^}} "-L[[SYSROOT]]/usr/lib64" +// CHECK-X86-64-SHARED-SAME: {{^}} "-L[[SYSROOT]]/lib" +// CHECK-X86-64-SHARED-SAME: {{^}} "-L[[SYSROOT]]/usr/lib" + +// RUN: %clang -### %s --target=aarch64-unknown-managarm-mlibc --sysroot=%S/Inputs/basic_managarm_tree \ +// RUN: --stdlib=platform 2>&1 | FileCheck --check-prefix=CHECK-AARCH64 %s +// CHECK-AARCH64: "-cc1" +// CHECK-AARCH64-SAME: "-isysroot" "[[SYSROOT:[^"]+]]" +// CHECK-AARCH64-SAME: {{^}} "-internal-isystem" "[[SYSROOT]]/usr/lib/gcc/aarch64-managarm-mlibc/10/../../../../include/c++/10" +// CHECK-AARCH64-SAME: {{^}} "-internal-isystem" "[[SYSROOT]]/usr/lib/gcc/aarch64-managarm-mlibc/10/../../../../include/aarch64-managarm-mlibc/c++/10" +// CHECK-AARCH64-SAME: {{^}} "-internal-isystem" "[[SYSROOT]]/usr/lib/gcc/aarch64-managarm-mlibc/10/../../../../include/c++/10/backward" +// CHECK-AARCH64-SAME: {{^}} "-internal-isystem" "[[SYSROOT]]/usr/local/include" +// CHECK-AARCH64-SAME: "-internal-externc-isystem" +// CHECK-AARCH64-SAME: {{^}} "[[SYSROOT]]/usr/include/aarch64-managarm-mlibc" +// CHECK-AARCH64-SAME: {{^}} "-internal-externc-isystem" "[[SYSROOT]]/include" +// CHECK-AARCH64-SAME: {{^}} "-internal-externc-isystem" "[[SYSROOT]]/usr/include" +// CHECK-AARCH64: "{{.*}}ld" "--sysroot=[[SYSROOT:[^"]+]]" +// CHECK-AARCH64-SAME: "-m" "aarch64managarm" +// CHECK-AARCH64-SAME: {{^}} "-dynamic-linker" "/lib/aarch64-managarm/ld.so" +// CHECK-AARCH64-SAME: "{{.*}}/usr/lib/gcc/aarch64-managarm-mlibc/10/crtbegin.o" +// CHECK-AARCH64-SAME: {{^}} "-L +// CHECK-AARCH64-SAME: {{^}}[[SYSROOT]]/usr/lib/gcc/aarch64-managarm-mlibc/10" +// CHECK-AARCH64-SAME: {{^}} "-L[[SYSROOT]]/usr/lib/gcc/aarch64-managarm-mlibc/10/../../../../lib64" +// CHECK-AARCH64-SAME: {{^}} "-L[[SYSROOT]]/lib/aarch64-managarm-mlibc" +// CHECK-AARCH64-SAME: {{^}} "-L[[SYSROOT]]/lib/../lib64" +// CHECK-AARCH64-SAME: {{^}} "-L[[SYSROOT]]/usr/lib/aarch64-managarm-mlibc" +// CHECK-AARCH64-SAME: {{^}} "-L[[SYSROOT]]/usr/lib64" +// CHECK-AARCH64-SAME: {{^}} "-L[[SYSROOT]]/lib" +// CHECK-AARCH64-SAME: {{^}} "-L[[SYSROOT]]/usr/lib" + +// RUN: %clang -### %s --target=aarch64-unknown-managarm-mlibc --sysroot=%S/Inputs/basic_managarm_tree \ +// RUN: --stdlib=libc++ --rtlib=compiler-rt --unwindlib=libunwind 2>&1 | FileCheck --check-prefix=CHECK-AARCH64-LIBS %s +// CHECK-AARCH64-LIBS: "-cc1" +// CHECK-AARCH64-LIBS-SAME: "-isysroot" "[[SYSROOT:[^"]+]]" +// CHECK-AARCH64-LIBS-SAME: {{^}} "-internal-isystem" "[[SYSROOT:[^"]+]]/include/c++/v1" +// CHECK-AARCH64-LIBS-SAME: {{^}} "-internal-isystem" "[[SYSROOT:[^"]+]]/usr/local/include" +// CHECK-AARCH64-LIBS-SAME: "-internal-externc-isystem" +// CHECK-AARCH64-LIBS-SAME: {{^}} "[[SYSROOT]]/usr/include/aarch64-managarm-mlibc" +// CHECK-AARCH64-LIBS-SAME: {{^}} "-internal-externc-isystem" "[[SYSROOT]]/include" +// CHECK-AARCH64-LIBS-SAME: {{^}} "-internal-externc-isystem" "[[SYSROOT]]/usr/include" +// CHECK-AARCH64-LIBS: "{{.*}}ld" "--sysroot=[[SYSROOT:[^"]+]]" +// CHECK-AARCH64-LIBS-SAME: "-m" "aarch64managarm" +// CHECK-AARCH64-LIBS-SAME: {{^}} "-dynamic-linker" "/lib/aarch64-managarm/ld.so" +// CHECK-AARCH64-LIBS-SAME: "{{.*}}/usr/lib/gcc/aarch64-managarm-mlibc/10/crtbegin.o" +// CHECK-AARCH64-LIBS-SAME: {{^}} "-L +// CHECK-AARCH64-LIBS-SAME: {{^}}[[SYSROOT]]/usr/lib/gcc/aarch64-managarm-mlibc/10" +// CHECK-AARCH64-LIBS-SAME: {{^}} "-L[[SYSROOT]]/usr/lib/gcc/aarch64-managarm-mlibc/10/../../../../lib64" +// CHECK-AARCH64-LIBS-SAME: {{^}} "-L[[SYSROOT]]/lib/aarch64-managarm-mlibc" +// CHECK-AARCH64-LIBS-SAME: {{^}} "-L[[SYSROOT]]/lib/../lib64" +// CHECK-AARCH64-LIBS-SAME: {{^}} "-L[[SYSROOT]]/usr/lib/aarch64-managarm-mlibc" +// CHECK-AARCH64-LIBS-SAME: {{^}} "-L[[SYSROOT]]/usr/lib64" +// CHECK-AARCH64-LIBS-SAME: {{^}} "-L[[SYSROOT]]/lib" +// CHECK-AARCH64-LIBS-SAME: {{^}} "-L[[SYSROOT]]/usr/lib" + +// RUN: %clang -### %s --target=aarch64-unknown-managarm-mlibc --sysroot=%S/Inputs/basic_managarm_tree \ +// RUN: --stdlib=platform -static 2>&1 | FileCheck --check-prefix=CHECK-AARCH64-STATIC %s +// CHECK-AARCH64-STATIC: "-cc1" +// CHECK-AARCH64-STATIC-SAME: "-static-define" +// CHECK-AARCH64-STATIC-SAME: "-isysroot" "[[SYSROOT:[^"]+]]" +// CHECK-AARCH64-STATIC-SAME: {{^}} "-internal-isystem" "[[SYSROOT]]/usr/lib/gcc/aarch64-managarm-mlibc/10/../../../../include/c++/10" +// CHECK-AARCH64-STATIC-SAME: {{^}} "-internal-isystem" "[[SYSROOT]]/usr/lib/gcc/aarch64-managarm-mlibc/10/../../../../include/aarch64-managarm-mlibc/c++/10" +// CHECK-AARCH64-STATIC-SAME: {{^}} "-internal-isystem" "[[SYSROOT]]/usr/lib/gcc/aarch64-managarm-mlibc/10/../../../../include/c++/10/backward" +// CHECK-AARCH64-STATIC-SAME: {{^}} "-internal-isystem" "[[SYSROOT]]/usr/local/include" +// CHECK-AARCH64-STATIC-SAME: "-internal-externc-isystem" +// CHECK-AARCH64-STATIC-SAME: {{^}} "[[SYSROOT]]/usr/include/aarch64-managarm-mlibc" +// CHECK-AARCH64-STATIC-SAME: {{^}} "-internal-externc-isystem" "[[SYSROOT]]/include" +// CHECK-AARCH64-STATIC-SAME: {{^}} "-internal-externc-isystem" "[[SYSROOT]]/usr/include" +// CHECK-AARCH64-STATIC: "{{.*}}ld" "--sysroot=[[SYSROOT:[^"]+]]" +// CHECK-AARCH64-STATIC-SAME: "-m" "aarch64managarm" +// CHECK-AARCH64-STATIC-SAME: {{^}} "-static" +// CHECK-AARCH64-STATIC-SAME: "{{.*}}/usr/lib/gcc/aarch64-managarm-mlibc/10/crtbeginT.o" +// CHECK-AARCH64-STATIC-SAME: {{^}} "-L +// CHECK-AARCH64-STATIC-SAME: {{^}}[[SYSROOT]]/usr/lib/gcc/aarch64-managarm-mlibc/10" +// CHECK-AARCH64-STATIC-SAME: {{^}} "-L[[SYSROOT]]/usr/lib/gcc/aarch64-managarm-mlibc/10/../../../../lib64" +// CHECK-AARCH64-STATIC-SAME: {{^}} "-L[[SYSROOT]]/lib/aarch64-managarm-mlibc" +// CHECK-AARCH64-STATIC-SAME: {{^}} "-L[[SYSROOT]]/lib/../lib64" +// CHECK-AARCH64-STATIC-SAME: {{^}} "-L[[SYSROOT]]/usr/lib/aarch64-managarm-mlibc" +// CHECK-AARCH64-STATIC-SAME: {{^}} "-L[[SYSROOT]]/usr/lib64" +// CHECK-AARCH64-STATIC-SAME: {{^}} "-L[[SYSROOT]]/lib" +// CHECK-AARCH64-STATIC-SAME: {{^}} "-L[[SYSROOT]]/usr/lib" + +// RUN: %clang -### %s --target=aarch64-unknown-managarm-mlibc --sysroot=%S/Inputs/basic_managarm_tree \ +// RUN: -shared 2>&1 | FileCheck --check-prefix=CHECK-AARCH64-SHARED %s +// CHECK-AARCH64-SHARED: "{{.*}}ld" "--sysroot=[[SYSROOT:[^"]+]]" +// CHECK-AARCH64-SHARED-SAME: "-m" "aarch64managarm" +// CHECK-AARCH64-SHARED-SAME: {{^}} "{{.*}}/usr/lib/gcc/aarch64-managarm-mlibc/10/crtbeginS.o" +// CHECK-AARCH64-SHARED-SAME: {{^}} "-L +// CHECK-AARCH64-SHARED-SAME: {{^}}[[SYSROOT]]/usr/lib/gcc/aarch64-managarm-mlibc/10" +// CHECK-AARCH64-SHARED-SAME: {{^}} "-L[[SYSROOT]]/usr/lib/gcc/aarch64-managarm-mlibc/10/../../../../lib64" +// CHECK-AARCH64-SHARED-SAME: {{^}} "-L[[SYSROOT]]/lib/aarch64-managarm-mlibc" +// CHECK-AARCH64-SHARED-SAME: {{^}} "-L[[SYSROOT]]/lib/../lib64" +// CHECK-AARCH64-SHARED-SAME: {{^}} "-L[[SYSROOT]]/usr/lib/aarch64-managarm-mlibc" +// CHECK-AARCH64-SHARED-SAME: {{^}} "-L[[SYSROOT]]/usr/lib64" +// CHECK-AARCH64-SHARED-SAME: {{^}} "-L[[SYSROOT]]/lib" +// CHECK-AARCH64-SHARED-SAME: {{^}} "-L[[SYSROOT]]/usr/lib" + +// RUN: %clang -### %s --target=riscv64-unknown-managarm-mlibc --sysroot=%S/Inputs/basic_managarm_tree \ +// RUN: --stdlib=platform 2>&1 | FileCheck --check-prefix=CHECK-RISCV64 %s +// CHECK-RISCV64: "-cc1" +// CHECK-RISCV64-SAME: "-isysroot" "[[SYSROOT:[^"]+]]" +// CHECK-RISCV64-SAME: {{^}} "-internal-isystem" "[[SYSROOT]]/usr/lib/gcc/riscv64-managarm-mlibc/10/../../../../include/c++/10" +// CHECK-RISCV64-SAME: {{^}} "-internal-isystem" "[[SYSROOT]]/usr/lib/gcc/riscv64-managarm-mlibc/10/../../../../include/riscv64-managarm-mlibc/c++/10" +// CHECK-RISCV64-SAME: {{^}} "-internal-isystem" "[[SYSROOT]]/usr/lib/gcc/riscv64-managarm-mlibc/10/../../../../include/c++/10/backward" +// CHECK-RISCV64-SAME: {{^}} "-internal-isystem" "[[SYSROOT]]/usr/local/include" +// CHECK-RISCV64-SAME: "-internal-externc-isystem" +// CHECK-RISCV64-SAME: {{^}} "[[SYSROOT]]/usr/include/riscv64-managarm-mlibc" +// CHECK-RISCV64-SAME: {{^}} "-internal-externc-isystem" "[[SYSROOT]]/include" +// CHECK-RISCV64-SAME: {{^}} "-internal-externc-isystem" "[[SYSROOT]]/usr/include" +// CHECK-RISCV64: "{{.*}}ld" "--sysroot=[[SYSROOT:[^"]+]]" +// CHECK-RISCV64-SAME: "{{.*}}/usr/lib/gcc/riscv64-managarm-mlibc/10/crtbegin.o" +// CHECK-RISCV64-SAME: "-L +// CHECK-RISCV64-SAME: {{^}}[[SYSROOT]]/usr/lib/gcc/riscv64-managarm-mlibc/10" +// CHECK-RISCV64-SAME: {{^}} "-L[[SYSROOT]]/usr/lib/gcc/riscv64-managarm-mlibc/10/../../../../lib64" +// CHECK-RISCV64-SAME: {{^}} "-L[[SYSROOT]]/lib/riscv64-managarm-mlibc" +// CHECK-RISCV64-SAME: {{^}} "-L[[SYSROOT]]/lib/../lib64" +// CHECK-RISCV64-SAME: {{^}} "-L[[SYSROOT]]/usr/lib/riscv64-managarm-mlibc" +// CHECK-RISCV64-SAME: {{^}} "-L[[SYSROOT]]/usr/lib64" +// CHECK-RISCV64-SAME: {{^}} "-L[[SYSROOT]]/lib" +// CHECK-RISCV64-SAME: {{^}} "-L[[SYSROOT]]/usr/lib" + +// RUN: %clang -### %s --target=riscv64-unknown-managarm-mlibc --sysroot=%S/Inputs/basic_managarm_tree \ +// RUN: --stdlib=libc++ --rtlib=compiler-rt --unwindlib=libunwind 2>&1 | FileCheck --check-prefix=CHECK-RISCV64-LIBS %s +// CHECK-RISCV64-LIBS: "-cc1" +// CHECK-RISCV64-LIBS-SAME: "-isysroot" "[[SYSROOT:[^"]+]]" +// CHECK-RISCV64-LIBS-SAME: {{^}} "-internal-isystem" "[[SYSROOT:[^"]+]]/include/c++/v1" +// CHECK-RISCV64-LIBS-SAME: {{^}} "-internal-isystem" "[[SYSROOT:[^"]+]]/usr/local/include" +// CHECK-RISCV64-LIBS-SAME: "-internal-externc-isystem" +// CHECK-RISCV64-LIBS-SAME: {{^}} "[[SYSROOT]]/usr/include/riscv64-managarm-mlibc" +// CHECK-RISCV64-LIBS-SAME: {{^}} "-internal-externc-isystem" "[[SYSROOT]]/include" +// CHECK-RISCV64-LIBS-SAME: {{^}} "-internal-externc-isystem" "[[SYSROOT]]/usr/include" +// CHECK-RISCV64-LIBS: "{{.*}}ld" "--sysroot=[[SYSROOT:[^"]+]]" +// CHECK-RISCV64-LIBS-SAME: "{{.*}}/usr/lib/gcc/riscv64-managarm-mlibc/10/crtbegin.o" +// CHECK-RISCV64-LIBS-SAME: "-L +// CHECK-RISCV64-LIBS-SAME: {{^}}[[SYSROOT]]/usr/lib/gcc/riscv64-managarm-mlibc/10" +// CHECK-RISCV64-LIBS-SAME: {{^}} "-L[[SYSROOT]]/usr/lib/gcc/riscv64-managarm-mlibc/10/../../../../lib64" +// CHECK-RISCV64-LIBS-SAME: {{^}} "-L[[SYSROOT]]/lib/riscv64-managarm-mlibc" +// CHECK-RISCV64-LIBS-SAME: {{^}} "-L[[SYSROOT]]/lib/../lib64" +// CHECK-RISCV64-LIBS-SAME: {{^}} "-L[[SYSROOT]]/usr/lib/riscv64-managarm-mlibc" +// CHECK-RISCV64-LIBS-SAME: {{^}} "-L[[SYSROOT]]/usr/lib64" +// CHECK-RISCV64-LIBS-SAME: {{^}} "-L[[SYSROOT]]/lib" +// CHECK-RISCV64-LIBS-SAME: {{^}} "-L[[SYSROOT]]/usr/lib" + +// RUN: %clang -### %s --target=riscv64-unknown-managarm-mlibc --sysroot=%S/Inputs/basic_managarm_tree \ +// RUN: --stdlib=platform -static 2>&1 | FileCheck --check-prefix=CHECK-RISCV64-STATIC %s +// CHECK-RISCV64-STATIC: "-cc1" +// CHECK-RISCV64-STATIC-SAME: "-static-define" +// CHECK-RISCV64-STATIC-SAME: "-isysroot" "[[SYSROOT:[^"]+]]" +// CHECK-RISCV64-STATIC-SAME: {{^}} "-internal-isystem" "[[SYSROOT]]/usr/lib/gcc/riscv64-managarm-mlibc/10/../../../../include/c++/10" +// CHECK-RISCV64-STATIC-SAME: {{^}} "-internal-isystem" "[[SYSROOT]]/usr/lib/gcc/riscv64-managarm-mlibc/10/../../../../include/riscv64-managarm-mlibc/c++/10" +// CHECK-RISCV64-STATIC-SAME: {{^}} "-internal-isystem" "[[SYSROOT]]/usr/lib/gcc/riscv64-managarm-mlibc/10/../../../../include/c++/10/backward" +// CHECK-RISCV64-STATIC-SAME: {{^}} "-internal-isystem" "[[SYSROOT]]/usr/local/include" +// CHECK-RISCV64-STATIC-SAME: "-internal-externc-isystem" +// CHECK-RISCV64-STATIC-SAME: {{^}} "[[SYSROOT]]/usr/include/riscv64-managarm-mlibc" +// CHECK-RISCV64-STATIC-SAME: {{^}} "-internal-externc-isystem" "[[SYSROOT]]/include" +// CHECK-RISCV64-STATIC-SAME: {{^}} "-internal-externc-isystem" "[[SYSROOT]]/usr/include" +// CHECK-RISCV64-STATIC: "{{.*}}ld" "--sysroot=[[SYSROOT:[^"]+]]" +// CHECK-RISCV64-STATIC-SAME: "-static" +// CHECK-RISCV64-STATIC-SAME: "{{.*}}/usr/lib/gcc/riscv64-managarm-mlibc/10/crtbeginT.o" +// CHECK-RISCV64-STATIC-SAME: "-L +// CHECK-RISCV64-STATIC-SAME: {{^}}[[SYSROOT]]/usr/lib/gcc/riscv64-managarm-mlibc/10" +// CHECK-RISCV64-STATIC-SAME: {{^}} "-L[[SYSROOT]]/usr/lib/gcc/riscv64-managarm-mlibc/10/../../../../lib64" +// CHECK-RISCV64-STATIC-SAME: {{^}} "-L[[SYSROOT]]/lib/riscv64-managarm-mlibc" +// CHECK-RISCV64-STATIC-SAME: {{^}} "-L[[SYSROOT]]/lib/../lib64" +// CHECK-RISCV64-STATIC-SAME: {{^}} "-L[[SYSROOT]]/usr/lib/riscv64-managarm-mlibc" +// CHECK-RISCV64-STATIC-SAME: {{^}} "-L[[SYSROOT]]/usr/lib64" +// CHECK-RISCV64-STATIC-SAME: {{^}} "-L[[SYSROOT]]/lib" +// CHECK-RISCV64-STATIC-SAME: {{^}} "-L[[SYSROOT]]/usr/lib" + +// RUN: %clang -### %s --target=riscv64-unknown-managarm-mlibc --sysroot=%S/Inputs/basic_managarm_tree \ +// RUN: -shared 2>&1 | FileCheck --check-prefix=CHECK-RISCV64-SHARED %s +// CHECK-RISCV64-SHARED: "{{.*}}ld" "--sysroot=[[SYSROOT:[^"]+]]" +// CHECK-RISCV64-SHARED-SAME: "{{.*}}/usr/lib/gcc/riscv64-managarm-mlibc/10/crtbeginS.o" +// CHECK-RISCV64-SHARED-SAME: "-L +// CHECK-RISCV64-SHARED-SAME: {{^}}[[SYSROOT]]/usr/lib/gcc/riscv64-managarm-mlibc/10" +// CHECK-RISCV64-SHARED-SAME: {{^}} "-L[[SYSROOT]]/usr/lib/gcc/riscv64-managarm-mlibc/10/../../../../lib64" +// CHECK-RISCV64-SHARED-SAME: {{^}} "-L[[SYSROOT]]/lib/riscv64-managarm-mlibc" +// CHECK-RISCV64-SHARED-SAME: {{^}} "-L[[SYSROOT]]/lib/../lib64" +// CHECK-RISCV64-SHARED-SAME: {{^}} "-L[[SYSROOT]]/usr/lib/riscv64-managarm-mlibc" +// CHECK-RISCV64-SHARED-SAME: {{^}} "-L[[SYSROOT]]/usr/lib64" +// CHECK-RISCV64-SHARED-SAME: {{^}} "-L[[SYSROOT]]/lib" +// CHECK-RISCV64-SHARED-SAME: {{^}} "-L[[SYSROOT]]/usr/lib" diff --git a/external/llvm-project/clang/test/Driver/modules.cpp b/external/llvm-project/clang/test/Driver/modules.cpp index b0d1f2280d25..088a73230f81 100644 --- a/external/llvm-project/clang/test/Driver/modules.cpp +++ b/external/llvm-project/clang/test/Driver/modules.cpp @@ -1,43 +1,48 @@ // RUN: rm -rf %t // RUN: mkdir %t +// RUN: split-file %s %t // Check compiling a module interface to a .pcm file. // -// RUN: %clang -std=c++2a -x c++-module --precompile %s -o %t/module.pcm -v 2>&1 | FileCheck %s --check-prefix=CHECK-PRECOMPILE -// RUN: %clang -std=gnu++2a -x c++-module --precompile %s -o %t/module-gnu.pcm -v 2>&1 | FileCheck %s --check-prefix=CHECK-PRECOMPILE +// RUN: %clang -std=c++2a -x c++-module --precompile %t/foo.cpp -o %t/foo.pcm -v 2>&1 | FileCheck %s --check-prefix=CHECK-PRECOMPILE +// RUN: %clang -std=gnu++2a -x c++-module --precompile %t/foo.cpp -o %t/foo-gnu.pcm -v 2>&1 | FileCheck %s --check-prefix=CHECK-PRECOMPILE // // CHECK-PRECOMPILE: -cc1 {{.*}} -emit-module-interface // CHECK-PRECOMPILE-SAME: -o {{.*}}.pcm // CHECK-PRECOMPILE-SAME: -x c++ -// CHECK-PRECOMPILE-SAME: modules.cpp +// CHECK-PRECOMPILE-SAME: foo.cpp // Check compiling a .pcm file to a .o file. // -// RUN: %clang -std=c++2a %t/module.pcm -S -o %t/module.pcm.o -v 2>&1 | FileCheck %s --check-prefix=CHECK-COMPILE +// RUN: %clang -std=c++2a %t/foo.pcm -S -o %t/foo.pcm.o -v 2>&1 | FileCheck %s --check-prefix=CHECK-COMPILE // // CHECK-COMPILE: -cc1 {{.*}} {{-emit-obj|-S}} -// CHECK-COMPILE-SAME: -o {{.*}}module{{2*}}.pcm.o +// CHECK-COMPILE-SAME: -o {{.*}}foo{{2*}}.pcm.o // CHECK-COMPILE-SAME: -x pcm // CHECK-COMPILE-SAME: {{.*}}.pcm // Check use of a .pcm file in another compilation. // -// RUN: %clang -std=c++2a -fmodule-file=%t/module.pcm -Dexport= %s -S -o %t/module.o -v 2>&1 | FileCheck %s --check-prefix=CHECK-USE -// RUN: %clang -std=c++20 -fmodule-file=%t/module.pcm -Dexport= %s -S -o %t/module.o -v 2>&1 | FileCheck %s --check-prefix=CHECK-USE -// RUN: %clang -std=gnu++20 -fmodule-file=%t/module-gnu.pcm -Dexport= %s -S -o %t/module.o -v 2>&1 | FileCheck %s --check-prefix=CHECK-USE +// RUN: %clang -std=c++2a -fmodule-file=foo=%t/foo.pcm %t/foo_impl.cpp -S -o %t/module.o -v 2>&1 | FileCheck %s --check-prefix=CHECK-USE +// RUN: %clang -std=c++20 -fmodule-file=foo=%t/foo.pcm %t/foo_impl.cpp -S -o %t/module.o -v 2>&1 | FileCheck %s --check-prefix=CHECK-USE +// RUN: %clang -std=gnu++20 -fmodule-file=foo=%t/foo-gnu.pcm %t/foo_impl.cpp -S -o %t/module.o -v 2>&1 | FileCheck %s --check-prefix=CHECK-USE // // CHECK-USE: -cc1 {{.*}} {{-emit-obj|-S}} -// CHECK-USE-SAME: -fmodule-file={{.*}}.pcm +// CHECK-USE-SAME: -fmodule-file=foo={{.*}}.pcm // CHECK-USE-SAME: -o {{.*}}.{{o|s}}{{"?}} {{.*}}-x c++ -// CHECK-USE-SAME: modules.cpp +// CHECK-USE-SAME: foo_impl.cpp // Check combining precompile and compile steps works. // -// RUN: %clang -std=c++2a -x c++-module %s -S -o %t/module2.pcm.o -v 2>&1 | FileCheck %s --check-prefix=CHECK-PRECOMPILE --check-prefix=CHECK-COMPILE +// RUN: %clang -std=c++2a -x c++-module %t/foo.cpp -S -o %t/foo2.pcm.o -v 2>&1 | FileCheck %s --check-prefix=CHECK-PRECOMPILE --check-prefix=CHECK-COMPILE // Check that .cppm is treated as a module implicitly. // -// RUN: cp %s %t/module.cppm -// RUN: %clang -std=c++2a --precompile %t/module.cppm -o %t/module.pcm -v 2>&1 | FileCheck %s --check-prefix=CHECK-PRECOMPILE +// RUN: cp %t/foo.cpp %t/foo.cppm +// RUN: %clang -std=c++2a --precompile %t/foo.cppm -o %t/foo.pcm -v 2>&1 | FileCheck %s --check-prefix=CHECK-PRECOMPILE +//--- foo.cpp export module foo; + +//--- foo_impl.cpp +module foo; diff --git a/external/llvm-project/clang/test/Driver/openmp-offload-gpu.c b/external/llvm-project/clang/test/Driver/openmp-offload-gpu.c index 71c2d8522388..fb62ded7cf54 100644 --- a/external/llvm-project/clang/test/Driver/openmp-offload-gpu.c +++ b/external/llvm-project/clang/test/Driver/openmp-offload-gpu.c @@ -392,6 +392,7 @@ // THINLTO-GFX906: --device-compiler=amdgcn-amd-amdhsa=-flto=thin // THINLTO-GFX906-SAME: --device-linker=amdgcn-amd-amdhsa=-plugin-opt=-force-import-all // THINLTO-GFX906-SAME: --device-linker=amdgcn-amd-amdhsa=-plugin-opt=-avail-extern-to-local +// THINLTO-GFX906-SAME: --device-linker=amdgcn-amd-amdhsa=-plugin-opt=-avail-extern-gv-in-addrspace-to-local=3 // THINLTO-GFX906-SAME: --device-linker=amdgcn-amd-amdhsa=-plugin-opt=-amdgpu-internalize-symbols // // RUN: %clang -### --target=x86_64-unknown-linux-gnu -fopenmp=libomp \ diff --git a/external/llvm-project/clang/test/Driver/ppc-crbits.cpp b/external/llvm-project/clang/test/Driver/ppc-crbits.cpp index 3ed56308cb52..62893d3d0e87 100644 --- a/external/llvm-project/clang/test/Driver/ppc-crbits.cpp +++ b/external/llvm-project/clang/test/Driver/ppc-crbits.cpp @@ -64,8 +64,6 @@ // RUN: %clang -target powerpc64le-unknown-linux-gnu -mcpu=pwr8 -mno-crbits \ // RUN: -emit-llvm -S %s -o - | FileCheck %s --check-prefix=HAS-NOCRBITS -// RUN: %clang -target powerpc64le-unknown-linux-gnu -mcpu=pwr7 -emit-llvm \ -// RUN: -S %s -o - | FileCheck %s --check-prefix=HAS-NOCRBITS // RUN: %clang -target powerpc64le-unknown-linux-gnu -mcpu=pwr7 -mcrbits \ // RUN: -emit-llvm -S %s -o - | FileCheck %s --check-prefix=HAS-CRBITS // RUN: %clang -target powerpc64le-unknown-linux-gnu -mcpu=pwr7 -mno-crbits \ @@ -92,8 +90,6 @@ // RUN: %clang -target powerpc-ibm-aix -mcpu=pwr8 -mno-crbits \ // RUN: -emit-llvm -S %s -o - | FileCheck %s --check-prefix=HAS-NOCRBITS -// RUN: %clang -target powerpc-ibm-aix -mcpu=pwr7 -emit-llvm \ -// RUN: -S %s -o - | FileCheck %s --check-prefix=HAS-NOCRBITS // RUN: %clang -target powerpc-ibm-aix -mcpu=pwr7 -mcrbits \ // RUN: -emit-llvm -S %s -o - | FileCheck %s --check-prefix=HAS-CRBITS // RUN: %clang -target powerpc-ibm-aix -mcpu=pwr7 -mno-crbits \ diff --git a/external/llvm-project/clang/test/Driver/ppc-isa-features.cpp b/external/llvm-project/clang/test/Driver/ppc-isa-features.cpp index 92c5bc82f72b..35dbfbcdf569 100644 --- a/external/llvm-project/clang/test/Driver/ppc-isa-features.cpp +++ b/external/llvm-project/clang/test/Driver/ppc-isa-features.cpp @@ -5,20 +5,20 @@ // RUN: %clang -target powerpc64-unknown-aix -mcpu=pwr9 -S -emit-llvm %s -o - | FileCheck %s -check-prefix=CHECK-PWR9 // RUN: %clang -target powerpc-unknown-aix -mcpu=pwr10 -S -emit-llvm %s -o - | FileCheck %s -check-prefix=CHECK-PWR10 -// CHECK-PWR6: -isa-v206-instructions -// CHECK-PWR6: -isa-v207-instructions -// CHECK-PWR6: -isa-v30-instructions +// CHECK-PWR6-NOT: isa-v206-instructions +// CHECK-PWR6-NOT: isa-v207-instructions +// CHECK-PWR6-NOT: isa-v30-instructions -// CHECK-A2: +isa-v206-instructions -// CHECK-A2: -isa-v207-instructions -// CHECK-A2: -isa-v30-instructions +// CHECK-A2: +isa-v206-instructions +// CHECK-A2-NOT: isa-v207-instructions +// CHECK-A2-NOT: isa-v30-instructions -// CHECK-PWR7: +isa-v206-instructions -// CHECK-PWR7: -isa-v207-instructions -// CHECK-PWR7: -isa-v30-instructions +// CHECK-PWR7: +isa-v206-instructions +// CHECK-PWR7-NOT: isa-v207-instructions +// CHECK-PWR7-NOT: isa-v30-instructions -// CHECK-PWR8: +isa-v207-instructions -// CHECK-PWR8: -isa-v30-instructions +// CHECK-PWR8: +isa-v207-instructions +// CHECK-PWR8-NOT: isa-v30-instructions // CHECK-PWR9: +isa-v207-instructions // CHECK-PWR9: +isa-v30-instructions diff --git a/external/llvm-project/clang/test/Driver/print-enabled-extensions/riscv-andes-a25.c b/external/llvm-project/clang/test/Driver/print-enabled-extensions/riscv-andes-a25.c index d8b3848d8452..cfb4d0ed58d1 100644 --- a/external/llvm-project/clang/test/Driver/print-enabled-extensions/riscv-andes-a25.c +++ b/external/llvm-project/clang/test/Driver/print-enabled-extensions/riscv-andes-a25.c @@ -10,7 +10,6 @@ // CHECK-NEXT: f 2.2 'F' (Single-Precision Floating-Point) // CHECK-NEXT: d 2.2 'D' (Double-Precision Floating-Point) // CHECK-NEXT: c 2.0 'C' (Compressed Instructions) -// CHECK-NEXT: b 1.0 'B' (the collection of the Zba, Zbb, Zbs extensions) // CHECK-NEXT: zicsr 2.0 'Zicsr' (CSRs) // CHECK-NEXT: zifencei 2.0 'Zifencei' (fence.i) // CHECK-NEXT: zmmul 1.0 'Zmmul' (Integer Multiplication) @@ -19,12 +18,8 @@ // CHECK-NEXT: zca 1.0 'Zca' (part of the C extension, excluding compressed floating point loads/stores) // CHECK-NEXT: zcd 1.0 'Zcd' (Compressed Double-Precision Floating-Point Instructions) // CHECK-NEXT: zcf 1.0 'Zcf' (Compressed Single-Precision Floating-Point Instructions) -// CHECK-NEXT: zba 1.0 'Zba' (Address Generation Instructions) -// CHECK-NEXT: zbb 1.0 'Zbb' (Basic Bit-Manipulation) -// CHECK-NEXT: zbc 1.0 'Zbc' (Carry-Less Multiplication) -// CHECK-NEXT: zbs 1.0 'Zbs' (Single-Bit Instructions) // CHECK-NEXT: xandesperf 5.0 'XAndesPerf' (Andes Performance Extension) // CHECK-EMPTY: // CHECK-NEXT: Experimental extensions // CHECK-EMPTY: -// CHECK-NEXT: ISA String: rv32i2p1_m2p0_a2p1_f2p2_d2p2_c2p0_b1p0_zicsr2p0_zifencei2p0_zmmul1p0_zaamo1p0_zalrsc1p0_zca1p0_zcd1p0_zcf1p0_zba1p0_zbb1p0_zbc1p0_zbs1p0_xandesperf5p0 +// CHECK-NEXT: ISA String: rv32i2p1_m2p0_a2p1_f2p2_d2p2_c2p0_zicsr2p0_zifencei2p0_zmmul1p0_zaamo1p0_zalrsc1p0_zca1p0_zcd1p0_zcf1p0_xandesperf5p0 diff --git a/external/llvm-project/clang/test/Driver/print-enabled-extensions/riscv-andes-a45.c b/external/llvm-project/clang/test/Driver/print-enabled-extensions/riscv-andes-a45.c index a0a1c3591140..3c3c554dffc5 100644 --- a/external/llvm-project/clang/test/Driver/print-enabled-extensions/riscv-andes-a45.c +++ b/external/llvm-project/clang/test/Driver/print-enabled-extensions/riscv-andes-a45.c @@ -10,7 +10,6 @@ // CHECK-NEXT: f 2.2 'F' (Single-Precision Floating-Point) // CHECK-NEXT: d 2.2 'D' (Double-Precision Floating-Point) // CHECK-NEXT: c 2.0 'C' (Compressed Instructions) -// CHECK-NEXT: b 1.0 'B' (the collection of the Zba, Zbb, Zbs extensions) // CHECK-NEXT: zicsr 2.0 'Zicsr' (CSRs) // CHECK-NEXT: zifencei 2.0 'Zifencei' (fence.i) // CHECK-NEXT: zmmul 1.0 'Zmmul' (Integer Multiplication) @@ -19,11 +18,8 @@ // CHECK-NEXT: zca 1.0 'Zca' (part of the C extension, excluding compressed floating point loads/stores) // CHECK-NEXT: zcd 1.0 'Zcd' (Compressed Double-Precision Floating-Point Instructions) // CHECK-NEXT: zcf 1.0 'Zcf' (Compressed Single-Precision Floating-Point Instructions) -// CHECK-NEXT: zba 1.0 'Zba' (Address Generation Instructions) -// CHECK-NEXT: zbb 1.0 'Zbb' (Basic Bit-Manipulation) -// CHECK-NEXT: zbs 1.0 'Zbs' (Single-Bit Instructions) // CHECK-NEXT: xandesperf 5.0 'XAndesPerf' (Andes Performance Extension) // CHECK-EMPTY: // CHECK-NEXT: Experimental extensions // CHECK-EMPTY: -// CHECK-NEXT: ISA String: rv32i2p1_m2p0_a2p1_f2p2_d2p2_c2p0_b1p0_zicsr2p0_zifencei2p0_zmmul1p0_zaamo1p0_zalrsc1p0_zca1p0_zcd1p0_zcf1p0_zba1p0_zbb1p0_zbs1p0_xandesperf5p0 +// CHECK-NEXT: ISA String: rv32i2p1_m2p0_a2p1_f2p2_d2p2_c2p0_zicsr2p0_zifencei2p0_zmmul1p0_zaamo1p0_zalrsc1p0_zca1p0_zcd1p0_zcf1p0_xandesperf5p0 diff --git a/external/llvm-project/clang/test/Driver/print-enabled-extensions/riscv-andes-ax25.c b/external/llvm-project/clang/test/Driver/print-enabled-extensions/riscv-andes-ax25.c index 3f933ecd8ac8..70100a0a8df1 100644 --- a/external/llvm-project/clang/test/Driver/print-enabled-extensions/riscv-andes-ax25.c +++ b/external/llvm-project/clang/test/Driver/print-enabled-extensions/riscv-andes-ax25.c @@ -10,7 +10,6 @@ // CHECK-NEXT: f 2.2 'F' (Single-Precision Floating-Point) // CHECK-NEXT: d 2.2 'D' (Double-Precision Floating-Point) // CHECK-NEXT: c 2.0 'C' (Compressed Instructions) -// CHECK-NEXT: b 1.0 'B' (the collection of the Zba, Zbb, Zbs extensions) // CHECK-NEXT: zicsr 2.0 'Zicsr' (CSRs) // CHECK-NEXT: zifencei 2.0 'Zifencei' (fence.i) // CHECK-NEXT: zmmul 1.0 'Zmmul' (Integer Multiplication) @@ -18,12 +17,8 @@ // CHECK-NEXT: zalrsc 1.0 'Zalrsc' (Load-Reserved/Store-Conditional) // CHECK-NEXT: zca 1.0 'Zca' (part of the C extension, excluding compressed floating point loads/stores) // CHECK-NEXT: zcd 1.0 'Zcd' (Compressed Double-Precision Floating-Point Instructions) -// CHECK-NEXT: zba 1.0 'Zba' (Address Generation Instructions) -// CHECK-NEXT: zbb 1.0 'Zbb' (Basic Bit-Manipulation) -// CHECK-NEXT: zbc 1.0 'Zbc' (Carry-Less Multiplication) -// CHECK-NEXT: zbs 1.0 'Zbs' (Single-Bit Instructions) // CHECK-NEXT: xandesperf 5.0 'XAndesPerf' (Andes Performance Extension) // CHECK-EMPTY: // CHECK-NEXT: Experimental extensions // CHECK-EMPTY: -// CHECK-NEXT: ISA String: rv64i2p1_m2p0_a2p1_f2p2_d2p2_c2p0_b1p0_zicsr2p0_zifencei2p0_zmmul1p0_zaamo1p0_zalrsc1p0_zca1p0_zcd1p0_zba1p0_zbb1p0_zbc1p0_zbs1p0_xandesperf5p0 +// CHECK-NEXT: ISA String: rv64i2p1_m2p0_a2p1_f2p2_d2p2_c2p0_zicsr2p0_zifencei2p0_zmmul1p0_zaamo1p0_zalrsc1p0_zca1p0_zcd1p0_xandesperf5p0 diff --git a/external/llvm-project/clang/test/Driver/print-enabled-extensions/riscv-andes-ax45.c b/external/llvm-project/clang/test/Driver/print-enabled-extensions/riscv-andes-ax45.c index 6460d701411b..d2b1a32e321e 100644 --- a/external/llvm-project/clang/test/Driver/print-enabled-extensions/riscv-andes-ax45.c +++ b/external/llvm-project/clang/test/Driver/print-enabled-extensions/riscv-andes-ax45.c @@ -10,7 +10,6 @@ // CHECK-NEXT: f 2.2 'F' (Single-Precision Floating-Point) // CHECK-NEXT: d 2.2 'D' (Double-Precision Floating-Point) // CHECK-NEXT: c 2.0 'C' (Compressed Instructions) -// CHECK-NEXT: b 1.0 'B' (the collection of the Zba, Zbb, Zbs extensions) // CHECK-NEXT: zicsr 2.0 'Zicsr' (CSRs) // CHECK-NEXT: zifencei 2.0 'Zifencei' (fence.i) // CHECK-NEXT: zmmul 1.0 'Zmmul' (Integer Multiplication) @@ -18,11 +17,8 @@ // CHECK-NEXT: zalrsc 1.0 'Zalrsc' (Load-Reserved/Store-Conditional) // CHECK-NEXT: zca 1.0 'Zca' (part of the C extension, excluding compressed floating point loads/stores) // CHECK-NEXT: zcd 1.0 'Zcd' (Compressed Double-Precision Floating-Point Instructions) -// CHECK-NEXT: zba 1.0 'Zba' (Address Generation Instructions) -// CHECK-NEXT: zbb 1.0 'Zbb' (Basic Bit-Manipulation) -// CHECK-NEXT: zbs 1.0 'Zbs' (Single-Bit Instructions) // CHECK-NEXT: xandesperf 5.0 'XAndesPerf' (Andes Performance Extension) // CHECK-EMPTY: // CHECK-NEXT: Experimental extensions // CHECK-EMPTY: -// CHECK-NEXT: ISA String: rv64i2p1_m2p0_a2p1_f2p2_d2p2_c2p0_b1p0_zicsr2p0_zifencei2p0_zmmul1p0_zaamo1p0_zalrsc1p0_zca1p0_zcd1p0_zba1p0_zbb1p0_zbs1p0_xandesperf5p0 +// CHECK-NEXT: ISA String: rv64i2p1_m2p0_a2p1_f2p2_d2p2_c2p0_zicsr2p0_zifencei2p0_zmmul1p0_zaamo1p0_zalrsc1p0_zca1p0_zcd1p0_xandesperf5p0 diff --git a/external/llvm-project/clang/test/Driver/print-enabled-extensions/riscv-andes-ax45mpv.c b/external/llvm-project/clang/test/Driver/print-enabled-extensions/riscv-andes-ax45mpv.c new file mode 100644 index 000000000000..bab35b117f57 --- /dev/null +++ b/external/llvm-project/clang/test/Driver/print-enabled-extensions/riscv-andes-ax45mpv.c @@ -0,0 +1,33 @@ +// RUN: %clang --target=riscv64 -mcpu=andes-ax45mpv --print-enabled-extensions | FileCheck %s +// REQUIRES: riscv-registered-target + +// CHECK: Extensions enabled for the given RISC-V target +// CHECK-EMPTY: +// CHECK-NEXT: Name Version Description +// CHECK-NEXT: i 2.1 'I' (Base Integer Instruction Set) +// CHECK-NEXT: m 2.0 'M' (Integer Multiplication and Division) +// CHECK-NEXT: a 2.1 'A' (Atomic Instructions) +// CHECK-NEXT: f 2.2 'F' (Single-Precision Floating-Point) +// CHECK-NEXT: d 2.2 'D' (Double-Precision Floating-Point) +// CHECK-NEXT: c 2.0 'C' (Compressed Instructions) +// CHECK-NEXT: v 1.0 'V' (Vector Extension for Application Processors) +// CHECK-NEXT: zicsr 2.0 'Zicsr' (CSRs) +// CHECK-NEXT: zifencei 2.0 'Zifencei' (fence.i) +// CHECK-NEXT: zmmul 1.0 'Zmmul' (Integer Multiplication) +// CHECK-NEXT: zaamo 1.0 'Zaamo' (Atomic Memory Operations) +// CHECK-NEXT: zalrsc 1.0 'Zalrsc' (Load-Reserved/Store-Conditional) +// CHECK-NEXT: zca 1.0 'Zca' (part of the C extension, excluding compressed floating point loads/stores) +// CHECK-NEXT: zcd 1.0 'Zcd' (Compressed Double-Precision Floating-Point Instructions) +// CHECK-NEXT: zve32f 1.0 'Zve32f' (Vector Extensions for Embedded Processors with maximal 32 EEW and F extension) +// CHECK-NEXT: zve32x 1.0 'Zve32x' (Vector Extensions for Embedded Processors with maximal 32 EEW) +// CHECK-NEXT: zve64d 1.0 'Zve64d' (Vector Extensions for Embedded Processors with maximal 64 EEW, F and D extension) +// CHECK-NEXT: zve64f 1.0 'Zve64f' (Vector Extensions for Embedded Processors with maximal 64 EEW and F extension) +// CHECK-NEXT: zve64x 1.0 'Zve64x' (Vector Extensions for Embedded Processors with maximal 64 EEW) +// CHECK-NEXT: zvl128b 1.0 'Zvl128b' (Minimum Vector Length 128) +// CHECK-NEXT: zvl32b 1.0 'Zvl32b' (Minimum Vector Length 32) +// CHECK-NEXT: zvl64b 1.0 'Zvl64b' (Minimum Vector Length 64) +// CHECK-NEXT: xandesperf 5.0 'XAndesPerf' (Andes Performance Extension) +// CHECK-EMPTY: +// CHECK-NEXT: Experimental extensions +// CHECK-EMPTY: +// CHECK-NEXT: ISA String: rv64i2p1_m2p0_a2p1_f2p2_d2p2_c2p0_v1p0_zicsr2p0_zifencei2p0_zmmul1p0_zaamo1p0_zalrsc1p0_zca1p0_zcd1p0_zve32f1p0_zve32x1p0_zve64d1p0_zve64f1p0_zve64x1p0_zvl128b1p0_zvl32b1p0_zvl64b1p0_xandesperf5p0 diff --git a/external/llvm-project/clang/test/Driver/print-enabled-extensions/riscv-andes-n45.c b/external/llvm-project/clang/test/Driver/print-enabled-extensions/riscv-andes-n45.c index 4d9c514b756e..1a2c30bfc7a2 100644 --- a/external/llvm-project/clang/test/Driver/print-enabled-extensions/riscv-andes-n45.c +++ b/external/llvm-project/clang/test/Driver/print-enabled-extensions/riscv-andes-n45.c @@ -10,7 +10,6 @@ // CHECK-NEXT: f 2.2 'F' (Single-Precision Floating-Point) // CHECK-NEXT: d 2.2 'D' (Double-Precision Floating-Point) // CHECK-NEXT: c 2.0 'C' (Compressed Instructions) -// CHECK-NEXT: b 1.0 'B' (the collection of the Zba, Zbb, Zbs extensions) // CHECK-NEXT: zicsr 2.0 'Zicsr' (CSRs) // CHECK-NEXT: zifencei 2.0 'Zifencei' (fence.i) // CHECK-NEXT: zmmul 1.0 'Zmmul' (Integer Multiplication) @@ -19,11 +18,8 @@ // CHECK-NEXT: zca 1.0 'Zca' (part of the C extension, excluding compressed floating point loads/stores) // CHECK-NEXT: zcd 1.0 'Zcd' (Compressed Double-Precision Floating-Point Instructions) // CHECK-NEXT: zcf 1.0 'Zcf' (Compressed Single-Precision Floating-Point Instructions) -// CHECK-NEXT: zba 1.0 'Zba' (Address Generation Instructions) -// CHECK-NEXT: zbb 1.0 'Zbb' (Basic Bit-Manipulation) -// CHECK-NEXT: zbs 1.0 'Zbs' (Single-Bit Instructions) // CHECK-NEXT: xandesperf 5.0 'XAndesPerf' (Andes Performance Extension) // CHECK-EMPTY: // CHECK-NEXT: Experimental extensions // CHECK-EMPTY: -// CHECK-NEXT: ISA String: rv32i2p1_m2p0_a2p1_f2p2_d2p2_c2p0_b1p0_zicsr2p0_zifencei2p0_zmmul1p0_zaamo1p0_zalrsc1p0_zca1p0_zcd1p0_zcf1p0_zba1p0_zbb1p0_zbs1p0_xandesperf5p0 +// CHECK-NEXT: ISA String: rv32i2p1_m2p0_a2p1_f2p2_d2p2_c2p0_zicsr2p0_zifencei2p0_zmmul1p0_zaamo1p0_zalrsc1p0_zca1p0_zcd1p0_zcf1p0_xandesperf5p0 diff --git a/external/llvm-project/clang/test/Driver/print-enabled-extensions/riscv-andes-nx45.c b/external/llvm-project/clang/test/Driver/print-enabled-extensions/riscv-andes-nx45.c index 5eaada3f9e16..50c38da3bd03 100644 --- a/external/llvm-project/clang/test/Driver/print-enabled-extensions/riscv-andes-nx45.c +++ b/external/llvm-project/clang/test/Driver/print-enabled-extensions/riscv-andes-nx45.c @@ -10,7 +10,6 @@ // CHECK-NEXT: f 2.2 'F' (Single-Precision Floating-Point) // CHECK-NEXT: d 2.2 'D' (Double-Precision Floating-Point) // CHECK-NEXT: c 2.0 'C' (Compressed Instructions) -// CHECK-NEXT: b 1.0 'B' (the collection of the Zba, Zbb, Zbs extensions) // CHECK-NEXT: zicsr 2.0 'Zicsr' (CSRs) // CHECK-NEXT: zifencei 2.0 'Zifencei' (fence.i) // CHECK-NEXT: zmmul 1.0 'Zmmul' (Integer Multiplication) @@ -18,11 +17,8 @@ // CHECK-NEXT: zalrsc 1.0 'Zalrsc' (Load-Reserved/Store-Conditional) // CHECK-NEXT: zca 1.0 'Zca' (part of the C extension, excluding compressed floating point loads/stores) // CHECK-NEXT: zcd 1.0 'Zcd' (Compressed Double-Precision Floating-Point Instructions) -// CHECK-NEXT: zba 1.0 'Zba' (Address Generation Instructions) -// CHECK-NEXT: zbb 1.0 'Zbb' (Basic Bit-Manipulation) -// CHECK-NEXT: zbs 1.0 'Zbs' (Single-Bit Instructions) // CHECK-NEXT: xandesperf 5.0 'XAndesPerf' (Andes Performance Extension) // CHECK-EMPTY: // CHECK-NEXT: Experimental extensions // CHECK-EMPTY: -// CHECK-NEXT: ISA String: rv64i2p1_m2p0_a2p1_f2p2_d2p2_c2p0_b1p0_zicsr2p0_zifencei2p0_zmmul1p0_zaamo1p0_zalrsc1p0_zca1p0_zcd1p0_zba1p0_zbb1p0_zbs1p0_xandesperf5p0 +// CHECK-NEXT: ISA String: rv64i2p1_m2p0_a2p1_f2p2_d2p2_c2p0_zicsr2p0_zifencei2p0_zmmul1p0_zaamo1p0_zalrsc1p0_zca1p0_zcd1p0_xandesperf5p0 diff --git a/external/llvm-project/clang/test/Driver/print-supported-extensions-riscv.c b/external/llvm-project/clang/test/Driver/print-supported-extensions-riscv.c index 95464f06378e..5008c2b7f789 100644 --- a/external/llvm-project/clang/test/Driver/print-supported-extensions-riscv.c +++ b/external/llvm-project/clang/test/Driver/print-supported-extensions-riscv.c @@ -159,6 +159,7 @@ // CHECK-NEXT: svpbmt 1.0 'Svpbmt' (Page-Based Memory Types) // CHECK-NEXT: svvptc 1.0 'Svvptc' (Obviating Memory-Management Instructions after Marking PTEs Valid) // CHECK-NEXT: xandesperf 5.0 'XAndesPerf' (Andes Performance Extension) +// CHECK-NEXT: xandesvbfhcvt 5.0 'XAndesVBFHCvt' (Andes Vector BFLOAT16 Conversion Extension) // CHECK-NEXT: xandesvdot 5.0 'XAndesVDot' (Andes Vector Dot Product Extension) // CHECK-NEXT: xandesvpackfph 5.0 'XAndesVPackFPH' (Andes Vector Packed FP16 Extension) // CHECK-NEXT: xcvalu 1.0 'XCValu' (CORE-V ALU Operations) @@ -213,7 +214,7 @@ // CHECK-NEXT: smctr 1.0 'Smctr' (Control Transfer Records Machine Level) // CHECK-NEXT: ssctr 1.0 'Ssctr' (Control Transfer Records Supervisor Level) // CHECK-NEXT: svukte 0.3 'Svukte' (Address-Independent Latency of User-Mode Faults to Supervisor Addresses) -// CHECK-NEXT: xqccmp 0.1 'Xqccmp' (Qualcomm 16-bit Push/Pop and Double Moves) +// CHECK-NEXT: xqccmp 0.3 'Xqccmp' (Qualcomm 16-bit Push/Pop and Double Moves) // CHECK-NEXT: xqcia 0.7 'Xqcia' (Qualcomm uC Arithmetic Extension) // CHECK-NEXT: xqciac 0.3 'Xqciac' (Qualcomm uC Load-Store Address Calculation Extension) // CHECK-NEXT: xqcibi 0.2 'Xqcibi' (Qualcomm uC Branch Immediate Extension) @@ -221,14 +222,14 @@ // CHECK-NEXT: xqcicli 0.3 'Xqcicli' (Qualcomm uC Conditional Load Immediate Extension) // CHECK-NEXT: xqcicm 0.2 'Xqcicm' (Qualcomm uC Conditional Move Extension) // CHECK-NEXT: xqcics 0.2 'Xqcics' (Qualcomm uC Conditional Select Extension) -// CHECK-NEXT: xqcicsr 0.3 'Xqcicsr' (Qualcomm uC CSR Extension) -// CHECK-NEXT: xqciint 0.7 'Xqciint' (Qualcomm uC Interrupts Extension) +// CHECK-NEXT: xqcicsr 0.4 'Xqcicsr' (Qualcomm uC CSR Extension) +// CHECK-NEXT: xqciint 0.10 'Xqciint' (Qualcomm uC Interrupts Extension) // CHECK-NEXT: xqciio 0.1 'Xqciio' (Qualcomm uC External Input Output Extension) // CHECK-NEXT: xqcilb 0.2 'Xqcilb' (Qualcomm uC Long Branch Extension) // CHECK-NEXT: xqcili 0.2 'Xqcili' (Qualcomm uC Load Large Immediate Extension) // CHECK-NEXT: xqcilia 0.2 'Xqcilia' (Qualcomm uC Large Immediate Arithmetic Extension) // CHECK-NEXT: xqcilo 0.3 'Xqcilo' (Qualcomm uC Large Offset Load Store Extension) -// CHECK-NEXT: xqcilsm 0.5 'Xqcilsm' (Qualcomm uC Load Store Multiple Extension) +// CHECK-NEXT: xqcilsm 0.6 'Xqcilsm' (Qualcomm uC Load Store Multiple Extension) // CHECK-NEXT: xqcisim 0.2 'Xqcisim' (Qualcomm uC Simulation Hint Extension) // CHECK-NEXT: xqcisls 0.2 'Xqcisls' (Qualcomm uC Scaled Load Store Extension) // CHECK-NEXT: xqcisync 0.3 'Xqcisync' (Qualcomm uC Sync Delay Extension) diff --git a/external/llvm-project/clang/test/Driver/riscv-cpus.c b/external/llvm-project/clang/test/Driver/riscv-cpus.c index 7605a3056d43..3736e76ed06d 100644 --- a/external/llvm-project/clang/test/Driver/riscv-cpus.c +++ b/external/llvm-project/clang/test/Driver/riscv-cpus.c @@ -751,3 +751,11 @@ // RUN: %clang --target=riscv64 -### -c %s 2>&1 -mtune=andes-ax45 | FileCheck -check-prefix=MTUNE-ANDES-AX45 %s // MTUNE-ANDES-AX45: "-tune-cpu" "andes-ax45" + +// RUN: %clang --target=riscv64 -### -c %s 2>&1 -mcpu=andes-ax45mpv | FileCheck -check-prefix=MCPU-ANDES-AX45MPV %s +// COM: The list of extensions are tested in `test/Driver/print-enabled-extensions/riscv-andes-ax45mpv.c` +// MCPU-ANDES-AX45MPV: "-target-cpu" "andes-ax45mpv" +// MCPU-ANDES-AX45MPV-SAME: "-target-abi" "lp64d" + +// RUN: %clang --target=riscv64 -### -c %s 2>&1 -mtune=andes-ax45mpv | FileCheck -check-prefix=MTUNE-ANDES-AX45MPV %s +// MTUNE-ANDES-AX45MPV: "-tune-cpu" "andes-ax45mpv" diff --git a/external/llvm-project/clang/test/Driver/spirv-amd-toolchain.c b/external/llvm-project/clang/test/Driver/spirv-amd-toolchain.c new file mode 100644 index 000000000000..c9417400a937 --- /dev/null +++ b/external/llvm-project/clang/test/Driver/spirv-amd-toolchain.c @@ -0,0 +1,19 @@ +// RUN: %clang -### -ccc-print-phases --target=spirv64-amd-amdhsa %s 2>&1 \ +// RUN: | FileCheck %s --check-prefix=PHASES +// PHASES: 0: input, "[[INPUT:.+]]", c +// PHASES: 1: preprocessor, {0}, cpp-output +// PHASES: 2: compiler, {1}, ir +// PHASES: 3: backend, {2}, assembler +// PHASES: 4: assembler, {3}, object +// PHASES: 5: linker, {4}, image + +// RUN: %clang -### -ccc-print-bindings --target=spirv64-amd-amdhsa %s 2>&1 \ +// RUN: | FileCheck %s --check-prefix=BINDINGS +// BINDINGS: # "spirv64-amd-amdhsa" - "clang", inputs: ["[[INPUT:.+]]"], output: "[[OUTPUT:.+]]" +// BINDINGS: # "spirv64-amd-amdhsa" - "AMDGCN::Linker", inputs: ["[[OUTPUT]]"], output: "a.out" + +// RUN: %clang -### --target=spirv64-amd-amdhsa %s -nogpulib -nogpuinc 2>&1 \ +// RUN: | FileCheck %s --check-prefix=INVOCATION +// INVOCATION: "-cc1" "-triple" "spirv64-amd-amdhsa" {{.*}} "-o" "[[OUTPUT:.+]]" "-x" "c" +// INVOCATION: "{{.*}}llvm-link" "-o" "a.out" "[[OUTPUT]]" +// INVOCATION: "{{.*}}llvm-spirv" "--spirv-max-version=1.6" "--spirv-ext=+all" "--spirv-allow-unknown-intrinsics" "--spirv-lower-const-expr" "--spirv-preserve-auxdata" "--spirv-debug-info-version=nonsemantic-shader-200" "a.out" "-o" "a.out" diff --git a/external/llvm-project/clang/test/ExtractAPI/methods.cpp b/external/llvm-project/clang/test/ExtractAPI/methods.cpp index 67f04b4d33db..180c2f92b277 100644 --- a/external/llvm-project/clang/test/ExtractAPI/methods.cpp +++ b/external/llvm-project/clang/test/ExtractAPI/methods.cpp @@ -45,11 +45,19 @@ class Foo { // GETCOUNT-NEXT: ] // RUN: FileCheck %s --input-file %t/output.symbols.json --check-prefix SETL - void setLength(int length) noexcept; + virtual void setLength(int length) noexcept; // SETL: "!testRelLabel": "memberOf $ c:@S@Foo@F@setLength#I# $ c:@S@Foo" // SETL-LABEL: "!testLabel": "c:@S@Foo@F@setLength#I#" // SETL: "declarationFragments": [ // SETL-NEXT: { + // SETL-NEXT: "kind": "keyword", + // SETL-NEXT: "spelling": "virtual" + // SETL-NEXT: }, + // SETL-NEXT: { + // SETL-NEXT: "kind": "text", + // SETL-NEXT: "spelling": " " + // SETL-NEXT: }, + // SETL-NEXT: { // SETL-NEXT: "kind": "typeIdentifier", // SETL-NEXT: "preciseIdentifier": "c:v", // SETL-NEXT: "spelling": "void" diff --git a/external/llvm-project/clang/test/ExtractAPI/objc_instancetype.m b/external/llvm-project/clang/test/ExtractAPI/objc_instancetype.m index 071ebe440918..dbd47a1f746f 100644 --- a/external/llvm-project/clang/test/ExtractAPI/objc_instancetype.m +++ b/external/llvm-project/clang/test/ExtractAPI/objc_instancetype.m @@ -157,6 +157,10 @@ - (id) reset; }, "names": { "navigator": [ + { + "kind": "text", + "spelling": "- " + }, { "kind": "identifier", "spelling": "init" @@ -228,6 +232,10 @@ - (id) reset; }, "names": { "navigator": [ + { + "kind": "text", + "spelling": "- " + }, { "kind": "identifier", "spelling": "reset" diff --git a/external/llvm-project/clang/test/Misc/loop-opt-setup.c b/external/llvm-project/clang/test/Misc/loop-opt-setup.c index 01643e6073b5..c1c620e52200 100644 --- a/external/llvm-project/clang/test/Misc/loop-opt-setup.c +++ b/external/llvm-project/clang/test/Misc/loop-opt-setup.c @@ -15,7 +15,7 @@ int foo(void) { // CHECK-NOT: br i1 void Helper(void) { - const int *nodes[5]; + const int *nodes[5] = {0}; int num_active = 5; while (num_active) diff --git a/external/llvm-project/clang/test/Misc/target-invalid-cpu-note/amdgcn.c b/external/llvm-project/clang/test/Misc/target-invalid-cpu-note/amdgcn.c index 9ef44b2bb403..352658b6fb38 100644 --- a/external/llvm-project/clang/test/Misc/target-invalid-cpu-note/amdgcn.c +++ b/external/llvm-project/clang/test/Misc/target-invalid-cpu-note/amdgcn.c @@ -68,6 +68,7 @@ // CHECK-SAME: {{^}}, gfx1153 // CHECK-SAME: {{^}}, gfx1200 // CHECK-SAME: {{^}}, gfx1201 +// CHECK-SAME: {{^}}, gfx1250 // CHECK-SAME: {{^}}, gfx9-generic // CHECK-SAME: {{^}}, gfx10-1-generic // CHECK-SAME: {{^}}, gfx10-3-generic diff --git a/external/llvm-project/clang/test/Misc/target-invalid-cpu-note/nvptx.c b/external/llvm-project/clang/test/Misc/target-invalid-cpu-note/nvptx.c index 6675a1ecc34b..b5209ffc5f0a 100644 --- a/external/llvm-project/clang/test/Misc/target-invalid-cpu-note/nvptx.c +++ b/external/llvm-project/clang/test/Misc/target-invalid-cpu-note/nvptx.c @@ -83,5 +83,6 @@ // CHECK-SAME: {{^}}, gfx12-generic // CHECK-SAME: {{^}}, gfx1200 // CHECK-SAME: {{^}}, gfx1201 +// CHECK-SAME: {{^}}, gfx1250 // CHECK-SAME: {{^}}, amdgcnspirv // CHECK-SAME: {{$}} diff --git a/external/llvm-project/clang/test/Misc/target-invalid-cpu-note/riscv.c b/external/llvm-project/clang/test/Misc/target-invalid-cpu-note/riscv.c index d736695b4883..5d6cda0044a9 100644 --- a/external/llvm-project/clang/test/Misc/target-invalid-cpu-note/riscv.c +++ b/external/llvm-project/clang/test/Misc/target-invalid-cpu-note/riscv.c @@ -29,6 +29,7 @@ // RISCV64-NEXT: note: valid target CPU values are: // RISCV64-SAME: {{^}} andes-ax25 // RISCV64-SAME: {{^}}, andes-ax45 +// RISCV64-SAME: {{^}}, andes-ax45mpv // RISCV64-SAME: {{^}}, andes-nx45 // RISCV64-SAME: {{^}}, generic-rv64 // RISCV64-SAME: {{^}}, mips-p8700 @@ -89,6 +90,7 @@ // TUNE-RISCV64-NEXT: note: valid target CPU values are: // TUNE-RISCV64-SAME: {{^}} andes-ax25 // TUNE-RISCV64-SAME: {{^}}, andes-ax45 +// TUNE-RISCV64-SAME: {{^}}, andes-ax45mpv // TUNE-RISCV64-SAME: {{^}}, andes-nx45 // TUNE-RISCV64-SAME: {{^}}, generic-rv64 // TUNE-RISCV64-SAME: {{^}}, mips-p8700 diff --git a/external/llvm-project/clang/test/Modules/include-after-imports-enums.cppm b/external/llvm-project/clang/test/Modules/include-after-imports-enums.cppm new file mode 100644 index 000000000000..00affd98e299 --- /dev/null +++ b/external/llvm-project/clang/test/Modules/include-after-imports-enums.cppm @@ -0,0 +1,25 @@ +// RUN: rm -rf %t +// RUN: mkdir -p %t +// RUN: split-file %s %t +// +// RUN: %clang_cc1 -std=c++20 %t/M.cppm -emit-module-interface -o %t/M.pcm +// RUN: %clang_cc1 -std=c++20 %t/use.cpp -fprebuilt-module-path=%t -verify -fsyntax-only +// +// RUN: %clang_cc1 -std=c++20 %t/M.cppm -emit-reduced-module-interface -o %t/M.pcm +// RUN: %clang_cc1 -std=c++20 %t/use.cpp -fprebuilt-module-path=%t -verify -fsyntax-only + +//--- enum.h +enum E { Value }; + +//--- M.cppm +module; +#include "enum.h" +export module M; +auto e = Value; + +//--- use.cpp +// expected-no-diagnostics +import M; +#include "enum.h" + +auto e = Value; diff --git a/external/llvm-project/clang/test/Modules/named-modules-adl-3.cppm b/external/llvm-project/clang/test/Modules/named-modules-adl-3.cppm index d70946fa068b..a3644b45a534 100644 --- a/external/llvm-project/clang/test/Modules/named-modules-adl-3.cppm +++ b/external/llvm-project/clang/test/Modules/named-modules-adl-3.cppm @@ -58,6 +58,7 @@ void b(T x) { } //--- c.cppm +module; #ifdef EXPORT_OPERATOR // expected-no-diagnostics #endif diff --git a/external/llvm-project/clang/test/Modules/pr131058.cppm b/external/llvm-project/clang/test/Modules/pr131058.cppm new file mode 100644 index 000000000000..c5a626103373 --- /dev/null +++ b/external/llvm-project/clang/test/Modules/pr131058.cppm @@ -0,0 +1,85 @@ +// RUN: rm -rf %t +// RUN: mkdir -p %t +// RUN: split-file %s %t +// +// RUN: %clang_cc1 -std=c++20 %t/M.cppm -emit-module-interface -o %t/M.pcm +// RUN: %clang_cc1 -std=c++20 %t/use.cpp -fsyntax-only -verify -fprebuilt-module-path=%t + +// RUN: %clang_cc1 -std=c++20 %t/M.cppm -emit-reduced-module-interface -o %t/M.pcm +// RUN: %clang_cc1 -std=c++20 %t/use.cpp -fsyntax-only -verify -fprebuilt-module-path=%t + +// RUN: %clang_cc1 -std=c++20 %t/M0.cppm -emit-module-interface -o %t/M.pcm +// RUN: %clang_cc1 -std=c++20 %t/use.cpp -fsyntax-only -verify -fprebuilt-module-path=%t -DMODULE_LOCAL +// RUN: %clang_cc1 -std=c++20 %t/M0.cpp -fsyntax-only -verify -fprebuilt-module-path=%t + +// RUN: %clang_cc1 -std=c++20 %t/M0.cppm -emit-reduced-module-interface -o %t/M.pcm +// RUN: %clang_cc1 -std=c++20 %t/use.cpp -fsyntax-only -verify -fprebuilt-module-path=%t -DMODULE_LOCAL +// RUN: %clang_cc1 -std=c++20 %t/M0.cpp -fsyntax-only -verify -fprebuilt-module-path=%t + +// RUN: %clang_cc1 -std=c++20 %t/M2.cppm -emit-module-interface -o %t/M.pcm +// RUN: %clang_cc1 -std=c++20 %t/use.cpp -fsyntax-only -verify -fprebuilt-module-path=%t + +// RUN: %clang_cc1 -std=c++20 %t/M2.cppm -emit-reduced-module-interface -o %t/M.pcm +// RUN: %clang_cc1 -std=c++20 %t/use.cpp -fsyntax-only -verify -fprebuilt-module-path=%t + +// RUN: %clang_cc1 -std=c++20 %t/M3.cppm -emit-reduced-module-interface -o %t/M.pcm +// RUN: %clang_cc1 -std=c++20 %t/use2.cpp -fsyntax-only -verify -fprebuilt-module-path=%t + +//--- enum.h +enum { SomeName, }; + +//--- M.cppm +module; +#include "enum.h" +export module M; +export auto e = SomeName; + +//--- M0.cppm +export module M; +enum { SomeName, }; +export auto e = SomeName; + +//--- M0.cpp +// expected-no-diagnostics +module M; +auto a = SomeName; + +//--- use.cpp +import M; +auto a = SomeName; // expected-error {{use of undeclared identifier 'SomeName'}} +auto b = decltype(e)::SomeName; + +//--- enum1.h +extern "C++" { +enum { SomeName, }; +} + +//--- M2.cppm +module; +#include "enum1.h" +export module M; +export auto e = SomeName; + +//--- enums.h +namespace nn { +enum E { Value }; +enum E2 { VisibleEnum }; +enum AlwaysVisibleEnums { UnconditionallyVisible }; +} + +//--- M3.cppm +module; +#include "enums.h" +export module M; +export namespace nn { + using nn::E2::VisibleEnum; + using nn::AlwaysVisibleEnums; +} +auto e1 = nn::Value; +auto e2 = nn::VisibleEnum; + +//--- use2.cpp +import M; +auto e = nn::Value1; // expected-error {{no member named 'Value1' in namespace 'nn'}} +auto e2 = nn::VisibleEnum; +auto e3 = nn::UnconditionallyVisible; diff --git a/external/llvm-project/clang/test/Modules/pr144230.cppm b/external/llvm-project/clang/test/Modules/pr144230.cppm new file mode 100644 index 000000000000..7de9fc6461ab --- /dev/null +++ b/external/llvm-project/clang/test/Modules/pr144230.cppm @@ -0,0 +1,26 @@ +// RUN: rm -rf %t +// RUN: mkdir -p %t +// RUN: split-file %s %t + +// RUN: %clang_cc1 -std=c++20 %t/A.cppm -emit-module-interface -o %t/A.pcm +// RUN: %clang_cc1 -std=c++20 %t/P.cppm -emit-module-interface -o %t/M-P.pcm -fprebuilt-module-path=%t +// RUN: %clang_cc1 -std=c++20 %t/M.cppm -emit-module-interface -o %t/M.pcm -fprebuilt-module-path=%t +// RUN: %clang_cc1 -std=c++20 %t/M.cpp -fprebuilt-module-path=%t -fsyntax-only -verify + +//--- A.cppm +export module A; +export using T = int; + +//--- P.cppm +export module M:P; +import A; + +//--- M.cppm +export module M; +export import :P; + +//--- M.cpp +// expected-no-diagnostics +module M; + +T x; diff --git a/external/llvm-project/clang/test/Modules/preferred_name_header_unit.cpp b/external/llvm-project/clang/test/Modules/preferred_name_header_unit.cpp new file mode 100644 index 000000000000..b1f1e3579f31 --- /dev/null +++ b/external/llvm-project/clang/test/Modules/preferred_name_header_unit.cpp @@ -0,0 +1,64 @@ +// RUN: rm -fR %t +// RUN: split-file %s %t +// RUN: cd %t +// RUN: %clang_cc1 -verify -w -std=c++20 -fmodule-name=h1.h -emit-header-unit -xc++-user-header h1.h -o h1.pcm +// RUN: %clang_cc1 -verify -w -std=c++20 -fmodule-map-file=module.modulemap -fmodule-file=h1.h=h1.pcm main.cpp -o main.o + +//--- module.modulemap +module "h1.h" { + header "h1.h" + export * +} + +//--- h0.h +// expected-no-diagnostics +#pragma once +namespace std { + +template class basic_string; + +namespace pmr { +using string = basic_string; +} + +template +class __attribute__((__preferred_name__(pmr::string))) basic_string; + +template class basic_string_view {}; + +template class basic_string { + typedef _CharT value_type; + typedef _Allocator allocator_type; + struct __rep; +public: + template + basic_string(_Tp) {} + basic_string operator+=(value_type); +}; + +namespace filesystem { +class path { + typedef char value_type; + value_type preferred_separator; + typedef basic_string string_type; + typedef basic_string_view __string_view; + template void append(_Source) { + __pn_ += preferred_separator; + } + void __root_directory() { append(string_type(__string_view{})); } + string_type __pn_; +}; +} // namespace filesystem +} // namespace std + +//--- h1.h +// expected-no-diagnostics +#pragma once + +#include "h0.h" + +//--- main.cpp +// expected-no-diagnostics +#include "h0.h" + +import "h1.h"; diff --git a/external/llvm-project/clang/test/Modules/reserved-names-1.cppm b/external/llvm-project/clang/test/Modules/reserved-names-1.cppm index e780f1e35b3b..35b264bcb573 100644 --- a/external/llvm-project/clang/test/Modules/reserved-names-1.cppm +++ b/external/llvm-project/clang/test/Modules/reserved-names-1.cppm @@ -88,12 +88,14 @@ export module module; // expected-error {{'module' is an invalid name for a modu export module import; // expected-error {{'import' is an invalid name for a module}} //--- _Test.cppm +module; #ifdef NODIAGNOSTICS // expected-no-diagnostics #endif export module _Test; // loud-warning {{'_Test' is a reserved name for a module}} //--- __test.cppm +module; #ifdef NODIAGNOSTICS // expected-no-diagnostics #endif @@ -101,6 +103,7 @@ export module __test; // loud-warning {{'__test' is a reserved name for a module export int a = 43; //--- te__st.cppm +module; #ifdef NODIAGNOSTICS // expected-no-diagnostics #endif @@ -108,6 +111,7 @@ export module te__st; // loud-warning {{'te__st' is a reserved name for a module export int a = 43; //--- std.cppm +module; #ifdef NODIAGNOSTICS // expected-no-diagnostics #endif @@ -116,36 +120,42 @@ export module std; // loud-warning {{'std' is a reserved name for a module}} export int a = 43; //--- std.foo.cppm +module; #ifdef NODIAGNOSTICS // expected-no-diagnostics #endif export module std.foo;// loud-warning {{'std' is a reserved name for a module}} //--- std0.cppm +module; #ifdef NODIAGNOSTICS // expected-no-diagnostics #endif export module std0; // loud-warning {{'std0' is a reserved name for a module}} //--- std1000000.cppm +module; #ifdef NODIAGNOSTICS // expected-no-diagnostics #endif export module std1000000; // loud-warning {{'std1000000' is a reserved name for a module}} //--- should_diag._Test.cppm +module; #ifdef NODIAGNOSTICS // expected-no-diagnostics #endif export module should_diag._Test; // loud-warning {{'_Test' is a reserved name for a module}} //--- system-module.cppm +module; // expected-error {{missing 'module' declaration at end of global module fragment introduced here}} // Show that being in a system header doesn't save you from diagnostics about // use of an invalid module-name identifier. # 34 "reserved-names-1.cpp" 1 3 export module module; // expected-error {{'module' is an invalid name for a module}} //--- system._Test.import.cppm +module; // expected-error {{missing 'module' declaration at end of global module fragment introduced here}} # 34 "reserved-names-1.cpp" 1 3 export module _Test.import; // expected-error {{'import' is an invalid name for a module}} diff --git a/external/llvm-project/clang/test/Modules/reserved-names-system-header-1.cpp b/external/llvm-project/clang/test/Modules/reserved-names-system-header-1.cpp index 2db4c08add1d..fa869483980f 100644 --- a/external/llvm-project/clang/test/Modules/reserved-names-system-header-1.cpp +++ b/external/llvm-project/clang/test/Modules/reserved-names-system-header-1.cpp @@ -1,6 +1,7 @@ // RUN: %clang_cc1 -std=c++20 -fsyntax-only -verify %s // expected-no-diagnostics +module; // Show that we suppress the reserved identifier diagnostic in a system header. # 100 "file.cpp" 1 3 // Enter a system header export module std; diff --git a/external/llvm-project/clang/test/Modules/reserved-names-system-header-2.cpp b/external/llvm-project/clang/test/Modules/reserved-names-system-header-2.cpp index 2087f487721c..d429e58dc171 100644 --- a/external/llvm-project/clang/test/Modules/reserved-names-system-header-2.cpp +++ b/external/llvm-project/clang/test/Modules/reserved-names-system-header-2.cpp @@ -1,6 +1,7 @@ // RUN: %clang_cc1 -std=c++20 -fsyntax-only -verify %s // expected-no-diagnostics +module; // Show that we suppress the reserved identifier diagnostic in a system header. # 100 "file.cpp" 1 3 // Enter a system header export module __test; diff --git a/external/llvm-project/clang/test/Modules/var-init-side-effects.cpp b/external/llvm-project/clang/test/Modules/var-init-side-effects.cpp new file mode 100644 index 000000000000..438a9eb20427 --- /dev/null +++ b/external/llvm-project/clang/test/Modules/var-init-side-effects.cpp @@ -0,0 +1,37 @@ +// Tests referencing variable with initializer containing side effect across module boundary +// +// RUN: rm -rf %t +// RUN: mkdir -p %t +// RUN: split-file %s %t + +// RUN: %clang_cc1 -std=c++20 -emit-module-interface %t/Foo.cppm \ +// RUN: -o %t/Foo.pcm + +// RUN: %clang_cc1 -std=c++20 -emit-module-interface \ +// RUN: -fmodule-file=Foo=%t/Foo.pcm \ +// RUN: %t/Bar.cppm \ +// RUN: -o %t/Bar.pcm + +// RUN: %clang_cc1 -std=c++20 -emit-obj \ +// RUN: -main-file-name Bar.cppm \ +// RUN: -fmodule-file=Foo=%t/Foo.pcm \ +// RUN: -x pcm %t/Bar.pcm \ +// RUN: -o %t/Bar.o + +//--- Foo.cppm +export module Foo; + +export { +class S {}; + +inline S s = S{}; +} + +//--- Bar.cppm +export module Bar; +import Foo; + +S bar() { + return s; +} + diff --git a/external/llvm-project/clang/test/Options/enable_16bit_types_validation_spirv.hlsl b/external/llvm-project/clang/test/Options/enable_16bit_types_validation_spirv.hlsl index aad8836db106..f37d00503fe5 100644 --- a/external/llvm-project/clang/test/Options/enable_16bit_types_validation_spirv.hlsl +++ b/external/llvm-project/clang/test/Options/enable_16bit_types_validation_spirv.hlsl @@ -4,7 +4,7 @@ // SPIRV: error: '-fnative-half-type' option requires target HLSL Version >= 2018, but HLSL Version is 'hlsl2016' // valid: "spirv-unknown-vulkan-library" -// valid: define spir_func void @{{.*main.*}}() #0 { +// valid: define hidden spir_func void @{{.*main.*}}() #0 { [numthreads(1,1,1)] void main() diff --git a/external/llvm-project/clang/test/PCH/Inputs/ignored-pch.h b/external/llvm-project/clang/test/PCH/Inputs/ignored-pch.h new file mode 100644 index 000000000000..56047037c331 --- /dev/null +++ b/external/llvm-project/clang/test/PCH/Inputs/ignored-pch.h @@ -0,0 +1,6 @@ +#ifndef IGNORED_PCH_H +#define IGNORED_PCH_H +inline int f() { + return 42; +} +#endif // IGNORED_PCH_H diff --git a/external/llvm-project/clang/test/PCH/ignored-pch.c b/external/llvm-project/clang/test/PCH/ignored-pch.c new file mode 100644 index 000000000000..c6ef3fe74cee --- /dev/null +++ b/external/llvm-project/clang/test/PCH/ignored-pch.c @@ -0,0 +1,109 @@ +// RUN: rm -rf %t.pch %t.ll +// RUN: %clang -x c-header %S/Inputs/ignored-pch.h -o %t.pch +// RUN: %clang -S -emit-llvm %s -include-pch %t.pch -o %t.ll +// RUN: ls %t.pch +// RUN: ls %t.ll + +// RUN: rm -rf %t.pch %t.ll +// RUN: %clang -x c-header %S/Inputs/ignored-pch.h -o %t.pch +// RUN: %clang %s -emit-ast -include-pch %t.pch -o %t.ll +// RUN: ls %t.pch +// RUN: ls %t.ll + +// Check that -ignore-pch causes -emit-pch and -include-pch options to be ignored. +// RUN: rm -rf %t.pch %t.ll +// RUN: %clang -x c-header %S/Inputs/ignored-pch.h -ignore-pch -o %t.pch +// RUN: %clang -S -emit-llvm %s -include-pch %t.pch -ignore-pch -o %t.ll +// RUN: not ls %t.pch +// RUN: ls %t.ll + +// RUN: rm -rf %t.pch %t.ll +// RUN: %clang -emit-ast %s -include-pch %t.pch -ignore-pch -o %t.ll +// RUN: not ls %t.ll + +// Check that -ignore-pch works for multiple PCH related options. +// Test with -building-pch-with-obj. +// RUN: rm -rf %t.pch %t.ll +// RUN: %clang -x c-header %S/Inputs/ignored-pch.h -ignore-pch -Xclang -building-pch-with-obj -o %t.pch +// RUN: %clang -S -emit-llvm %s -include-pch %t.pch -ignore-pch -Xclang -building-pch-with-obj -o %t.ll +// RUN: not ls %t.pch +// RUN: ls %t.ll + +// Test with -fallow-pch-with-compiler-errors. +// RUN: rm -rf %t.pch %t.ll +// RUN: %clang -x c-header %S/Inputs/ignored-pch.h -ignore-pch -Xclang -fallow-pch-with-compiler-errors -o %t.pch +// RUN: %clang -S -emit-llvm %s -include-pch %t.pch -ignore-pch -Xclang -fallow-pch-with-compiler-errors -o %t.ll +// RUN: not ls %t.pch +// RUN: ls %t.ll + +// Test with -fallow-pch-with-different-modules-cache-path. +// RUN: rm -rf %t.pch %t.ll +// RUN: %clang -x c-header %S/Inputs/ignored-pch.h -ignore-pch -Xclang -fallow-pch-with-different-modules-cache-path -o %t.pch +// RUN: %clang -S -emit-llvm %s -ignore-pch -include-pch %t.pch -Xclang -fallow-pch-with-different-modules-cache-path -o %t.ll +// RUN: not ls %t.pch +// RUN: ls %t.ll + +// Test with -fpch-codegen. +// RUN: rm -rf %t.pch %t.ll +// RUN: %clang -x c-header %S/Inputs/ignored-pch.h -ignore-pch -fpch-codegen -o %t.pch +// RUN: %clang -S -emit-llvm %s -include-pch %t.pch -ignore-pch -fpch-codegen -o %t.ll +// RUN: not ls %t.pch +// RUN: ls %t.ll + +// Test with -fpch-debuginfo. +// RUN: rm -rf %t.pch %t.ll +// RUN: %clang -x c-header %S/Inputs/ignored-pch.h -ignore-pch -fpch-debuginfo -o %t.pch +// RUN: %clang -S -emit-llvm %s -include-pch %t.pch -ignore-pch -fpch-debuginfo -o %t.ll +// RUN: not ls %t.pch +// RUN: ls %t.ll + +// Test with -fpch-instantiate-templates. +// RUN: rm -rf %t.pch %t.ll +// RUN: %clang -x c-header %S/Inputs/ignored-pch.h -ignore-pch -fpch-instantiate-templates -o %t.pch +// RUN: %clang -S -emit-llvm %s -include-pch %t.pch -ignore-pch -fpch-instantiate-templates -o %t.ll +// RUN: not ls %t.pch +// RUN: ls %t.ll + +// Test with -fno-pch-timestamp. +// RUN: rm -rf %t.pch %t.ll +// RUN: %clang -x c-header %S/Inputs/ignored-pch.h -ignore-pch -Xclang -fno-pch-timestamp -o %t.pch +// RUN: %clang -S -emit-llvm %s -include-pch %t.pch -ignore-pch -Xclang -fno-pch-timestamp -o %t.ll +// RUN: not ls %t.pch +// RUN: ls %t.ll + +// Test with -fno-validate-pch. +// RUN: rm -rf %t.pch %t.ll +// RUN: %clang -x c-header %S/Inputs/ignored-pch.h -ignore-pch -Xclang -fno-validate-pch -o %t.pch +// RUN: %clang -S -emit-llvm %s -include-pch %t.pch -ignore-pch -Xclang -fno-validate-pch -o %t.ll +// RUN: not ls %t.pch +// RUN: ls %t.ll + +// Test with -relocatable-pch. +// RUN: rm -rf %t.pch %t.ll +// RUN: %clang -x c-header %S/Inputs/ignored-pch.h -ignore-pch -relocatable-pch -o %t.pch +// RUN: %clang -S -emit-llvm %s -include-pch %t.pch -ignore-pch -relocatable-pch -o %t.ll +// RUN: not ls %t.pch +// RUN: ls %t.ll + +// Test with -pch-through-hdrstop-create/-pch-through-hdrstop-use +// RUN: rm -rf %t.pch %t.ll +// RUN: %clang -x c-header %S/Inputs/ignored-pch.h -ignore-pch -Xclang -pch-through-hdrstop-create -o %t.pch +// RUN: %clang -S -emit-llvm %s -include-pch %t.pch -ignore-pch -Xclang -pch-through-hdrstop-use -o %t.ll +// RUN: not ls %t.pch +// RUN: ls %t.ll + + +// Test with AST dump output: +// RUN: rm -rf %t.pch %t.ll +// RUN: %clang -x c-header %S/Inputs/ignored-pch.h -o %t.pch +// RUN: %clang %s -include-pch %t.pch -Xclang -ast-dump-all -c | FileCheck --check-prefix=CHECK-AST-PCH %s +// RUN: %clang %s -include-pch %t.pch -ignore-pch -Xclang -ast-dump-all -c | FileCheck --check-prefix=CHECK-AST %s + +// CHECK-AST-PCH: +// CHECK-AST-NOT: + +#pragma hdrstop +#include "Inputs/ignored-pch.h" +int main() { + return f(); +} diff --git a/external/llvm-project/clang/test/Preprocessor/init.c b/external/llvm-project/clang/test/Preprocessor/init.c index 031a6c1a755b..bed39dc3e34d 100644 --- a/external/llvm-project/clang/test/Preprocessor/init.c +++ b/external/llvm-project/clang/test/Preprocessor/init.c @@ -1622,6 +1622,11 @@ // RUN: %clang_cc1 -x c -std=c99 -E -dM -ffreestanding -triple=amd64-unknown-openbsd < /dev/null | FileCheck -match-full-lines -check-prefix OPENBSD-STDC-N %s // OPENBSD-STDC-N-NOT:#define __STDC_NO_THREADS__ 1 // +// RUN: %clang_cc1 -triple=aarch64-unknown-managarm-mlibc -E -dM < /dev/null | FileCheck -match-full-lines -check-prefix MANAGARM %s +// RUN: %clang_cc1 -triple=riscv64-unknown-managarm-mlibc -E -dM < /dev/null | FileCheck -match-full-lines -check-prefix MANAGARM %s +// RUN: %clang_cc1 -triple=x86_64-unknown-managarm-mlibc -E -dM < /dev/null | FileCheck -match-full-lines -check-prefix MANAGARM %s +// MANAGARM: #define __managarm__ 1 + // RUN: %clang_cc1 -E -dM -ffreestanding -triple=xcore-none-none < /dev/null | FileCheck -match-full-lines -check-prefix XCORE %s // XCORE:#define __BYTE_ORDER__ __ORDER_LITTLE_ENDIAN__ // XCORE:#define __LITTLE_ENDIAN__ 1 diff --git a/external/llvm-project/clang/test/Preprocessor/predefined-arch-macros.c b/external/llvm-project/clang/test/Preprocessor/predefined-arch-macros.c index 0570477fce57..86d51820ae5b 100644 --- a/external/llvm-project/clang/test/Preprocessor/predefined-arch-macros.c +++ b/external/llvm-project/clang/test/Preprocessor/predefined-arch-macros.c @@ -2091,6 +2091,9 @@ // RUN: %clang -march=meteorlake -m32 -E -dM %s -o - 2>&1 \ // RUN: -target i386-unknown-linux \ // RUN: | FileCheck -match-full-lines %s -check-prefix=CHECK_ADL_M32 +// RUN: %clang -march=gracemont -m32 -E -dM %s -o - 2>&1 \ +// RUN: -target i386-unknown-linux \ +// RUN: | FileCheck -match-full-lines %s -check-prefix=CHECK_ADL_M32 // CHECK_ADL_M32: #define __ADX__ 1 // CHECK_ADL_M32: #define __AES__ 1 // CHECK_ADL_M32: #define __AVX2__ 1 @@ -2099,7 +2102,7 @@ // CHECK_ADL_M32: #define __AVX__ 1 // CHECK_ADL_M32: #define __BMI2__ 1 // CHECK_ADL_M32: #define __BMI__ 1 -// CHECK_ADL_M32: #define __CLDEMOTE__ 1 +// CHECK_ADL_M32-NOT: #define __CLDEMOTE__ 1 // CHECK_ADL_M32: #define __CLFLUSHOPT__ 1 // CHECK_ADL_M32: #define __CLWB__ 1 // CHECK_ADL_M32: #define __F16C__ 1 @@ -2159,6 +2162,9 @@ // RUN: %clang -march=meteorlake -m64 -E -dM %s -o - 2>&1 \ // RUN: -target i386-unknown-linux \ // RUN: | FileCheck -match-full-lines %s -check-prefix=CHECK_ADL_M64 +// RUN: %clang -march=gracemont -m64 -E -dM %s -o - 2>&1 \ +// RUN: -target i386-unknown-linux \ +// RUN: | FileCheck -match-full-lines %s -check-prefix=CHECK_ADL_M64 // CHECK_ADL_M64: #define __ADX__ 1 // CHECK_ADL_M64: #define __AES__ 1 // CHECK_ADL_M64: #define __AVX2__ 1 @@ -2167,7 +2173,7 @@ // CHECK_ADL_M64: #define __AVX__ 1 // CHECK_ADL_M64: #define __BMI2__ 1 // CHECK_ADL_M64: #define __BMI__ 1 -// CHECK_ADL_M64: #define __CLDEMOTE__ 1 +// CHECK_ADL_M64-NOT: #define __CLDEMOTE__ 1 // CHECK_ADL_M64: #define __CLFLUSHOPT__ 1 // CHECK_ADL_M64: #define __CLWB__ 1 // CHECK_ADL_M64: #define __F16C__ 1 @@ -2550,191 +2556,211 @@ // RUN: %clang -march=sierraforest -m32 -E -dM %s -o - 2>&1 \ // RUN: --target=i386 \ -// RUN: | FileCheck -match-full-lines %s -check-prefix=CHECK_SRF_M32 +// RUN: | FileCheck -match-full-lines %s -check-prefixes=CHECK_ARL_M32,CHECK_SRF_M32 // RUN: %clang -march=grandridge -m32 -E -dM %s -o - 2>&1 \ // RUN: --target=i386 \ -// RUN: | FileCheck -match-full-lines %s -check-prefixes=CHECK_SRF_M32 +// RUN: | FileCheck -match-full-lines %s -check-prefixes=CHECK_ARL_M32,CHECK_SRF_M32 // RUN: %clang -march=arrowlake -m32 -E -dM %s -o - 2>&1 \ // RUN: -target i386-unknown-linux \ -// RUN: | FileCheck -match-full-lines %s -check-prefix=CHECK_SRF_M32 +// RUN: | FileCheck -match-full-lines %s -check-prefix=CHECK_ARL_M32 // RUN: %clang -march=arrowlake-s -m32 -E -dM %s -o - 2>&1 \ // RUN: -target i386-unknown-linux \ -// RUN: | FileCheck -match-full-lines %s -check-prefixes=CHECK_SRF_M32,CHECK_ARLS_M32 +// RUN: | FileCheck -match-full-lines %s -check-prefixes=CHECK_ARL_M32,CHECK_ARLS_M32 // RUN: %clang -march=lunarlake -m32 -E -dM %s -o - 2>&1 \ // RUN: -target i386-unknown-linux \ -// RUN: | FileCheck -match-full-lines %s -check-prefixes=CHECK_SRF_M32,CHECK_ARLS_M32 +// RUN: | FileCheck -match-full-lines %s -check-prefixes=CHECK_ARL_M32,CHECK_ARLS_M32 // RUN: %clang -march=pantherlake -m32 -E -dM %s -o - 2>&1 \ // RUN: -target i386-unknown-linux \ -// RUN: | FileCheck -match-full-lines %s -check-prefixes=CHECK_SRF_M32,CHECK_ARLS_M32,CHECK_PTL_M32 +// RUN: | FileCheck -match-full-lines %s -check-prefixes=CHECK_ARL_M32,CHECK_ARLS_M32,CHECK_PTL_M32 // RUN: %clang -march=clearwaterforest -m32 -E -dM %s -o - 2>&1 \ // RUN: -target i386-unknown-linux \ // RUN: | FileCheck -match-full-lines %s -check-prefixes=CHECK_SRF_M32,CHECK_ARLS_M32,CHECK_PTL_M32,CHECK_CWF_M32 -// CHECK_SRF_M32: #define __ADX__ 1 -// CHECK_SRF_M32: #define __AES__ 1 -// CHECK_SRF_M32: #define __AVX2__ 1 -// CHECK_SRF_M32-NOT: AVX512 -// CHECK_SRF_M32: #define __AVXIFMA__ 1 -// CHECK_SRF_M32: #define __AVXVNNIINT8__ 1 -// CHECK_SRF_M32: #define __AVXVNNI__ 1 -// CHECK_SRF_M32: #define __AVX__ 1 -// CHECK_SRF_M32: #define __BMI2__ 1 -// CHECK_SRF_M32: #define __BMI__ 1 +// CHECK_ARL_M32: #define __ADX__ 1 +// CHECK_ARL_M32: #define __AES__ 1 +// CHECK_ARL_M32: #define __AVX2__ 1 +// CHECK_ARL_M32-NOT: AVX512 +// CHECK_ARL_M32: #define __AVXIFMA__ 1 +// CHECK_ARL_M32: #define __AVXNECONVERT__ 1 +// CHECK_ARL_M32-NOT: #define __AVXVNNIINT16__ 1 +// CHECK_ARLS_M32: #define __AVXVNNIINT16__ 1 +// CHECK_ARL_M32: #define __AVXVNNIINT8__ 1 +// CHECK_ARL_M32: #define __AVXVNNI__ 1 +// CHECK_ARL_M32: #define __AVX__ 1 +// CHECK_ARL_M32: #define __BMI2__ 1 +// CHECK_ARL_M32: #define __BMI__ 1 +// CHECK_ARLS_M32-NOT: __CLDEMOTE__ // CHECK_SRF_M32: #define __CLDEMOTE__ 1 -// CHECK_SRF_M32: #define __CLFLUSHOPT__ 1 -// CHECK_SRF_M32: #define __CLWB__ 1 -// CHECK_SRF_M32: #define __CMPCCXADD__ 1 -// CHECK_SRF_M32: #define __ENQCMD__ 1 -// CHECK_SRF_M32: #define __F16C__ 1 -// CHECK_SRF_M32: #define __FMA__ 1 -// CHECK_SRF_M32: #define __FSGSBASE__ 1 -// CHECK_SRF_M32: #define __FXSR__ 1 -// CHECK_SRF_M32: #define __GFNI__ 1 -// CHECK_SRF_M32: #define __HRESET__ 1 -// CHECK_SRF_M32: #define __INVPCID__ 1 -// CHECK_SRF_M32: #define __KL__ 1 -// CHECK_SRF_M32: #define __LZCNT__ 1 -// CHECK_SRF_M32: #define __MMX__ 1 -// CHECK_SRF_M32: #define __MOVBE__ 1 -// CHECK_SRF_M32: #define __MOVDIR64B__ 1 -// CHECK_SRF_M32: #define __MOVDIRI__ 1 -// CHECK_SRF_M32: #define __PCLMUL__ 1 -// CHECK_SRF_M32: #define __PCONFIG__ 1 -// CHECK_SRF_M32: #define __PKU__ 1 -// CHECK_SRF_M32: #define __POPCNT__ 1 -// CHECK_SRF_M32-NOT: #define __PREFETCHI__ 1 +// CHECK_ARL_M32: #define __CLFLUSHOPT__ 1 +// CHECK_ARL_M32: #define __CLWB__ 1 +// CHECK_ARL_M32: #define __CMPCCXADD__ 1 +// CHECK_ARL_M32: #define __ENQCMD__ 1 +// CHECK_ARL_M32: #define __F16C__ 1 +// CHECK_ARL_M32: #define __FMA__ 1 +// CHECK_ARL_M32: #define __FSGSBASE__ 1 +// CHECK_ARL_M32: #define __FXSR__ 1 +// CHECK_ARL_M32: #define __GFNI__ 1 +// CHECK_ARL_M32: #define __HRESET__ 1 +// CHECK_ARL_M32: #define __INVPCID__ 1 +// CHECK_ARL_M32: #define __KL__ 1 +// CHECK_ARL_M32: #define __LZCNT__ 1 +// CHECK_ARL_M32: #define __MMX__ 1 +// CHECK_ARL_M32: #define __MOVBE__ 1 +// CHECK_ARL_M32: #define __MOVDIR64B__ 1 +// CHECK_ARL_M32: #define __MOVDIRI__ 1 +// CHECK_ARL_M32: #define __PCLMUL__ 1 +// CHECK_ARL_M32: #define __PCONFIG__ 1 +// CHECK_ARL_M32: #define __PKU__ 1 +// CHECK_ARL_M32: #define __POPCNT__ 1 +// CHECK_ARL_M32-NOT: #define __PREFETCHI__ 1 // CHECK_ARLS_M32-NOT: #define __PREFETCHI__ 1 // CHECK_PTL_M32: #define __PREFETCHI__ 1 -// CHECK_SRF_M32: #define __PRFCHW__ 1 -// CHECK_SRF_M32: #define __PTWRITE__ 1 -// CHECK_SRF_M32-NOT: #define __RAOINT__ 1 -// CHECK_SRF_M32: #define __RDPID__ 1 -// CHECK_SRF_M32: #define __RDRND__ 1 -// CHECK_SRF_M32: #define __RDSEED__ 1 -// CHECK_SRF_M32: #define __SERIALIZE__ 1 -// CHECK_SRF_M32: #define __SGX__ 1 -// CHECK_SRF_M32: #define __SHA__ 1 -// CHECK_SRF_M32: #define __SHSTK__ 1 -// CHECK_SRF_M32: #define __SSE2__ 1 -// CHECK_SRF_M32: #define __SSE3__ 1 -// CHECK_SRF_M32: #define __SSE4_1__ 1 -// CHECK_SRF_M32: #define __SSE4_2__ 1 -// CHECK_SRF_M32: #define __SSE_MATH__ 1 -// CHECK_SRF_M32: #define __SSE__ 1 -// CHECK_SRF_M32: #define __SSSE3__ 1 -// CHECK_SRF_M32: #define __UINTR__ 1 -// CHECK_SRF_M32-NOT: #define __USERMSR__ 1 +// CHECK_ARL_M32: #define __PRFCHW__ 1 +// CHECK_ARL_M32: #define __PTWRITE__ 1 +// CHECK_ARL_M32-NOT: #define __RAOINT__ 1 +// CHECK_ARL_M32: #define __RDPID__ 1 +// CHECK_ARL_M32: #define __RDRND__ 1 +// CHECK_ARL_M32: #define __RDSEED__ 1 +// CHECK_ARL_M32: #define __SERIALIZE__ 1 +// CHECK_ARL_M32: #define __SGX__ 1 +// CHECK_ARL_M32-NOT: #define __SHA512__ 1 +// CHECK_ARLS_M32: #define __SHA512__ 1 +// CHECK_ARL_M32: #define __SHA__ 1 +// CHECK_ARL_M32: #define __SHSTK__ 1 +// CHECK_ARL_M32-NOT: #define __SM3__ 1 +// CHECK_ARLS_M32: #define __SM3__ 1 +// CHECK_ARL_M32-NOT: #define __SM4__ 1 +// CHECK_ARLS_M32: #define __SM4__ 1 +// CHECK_ARL_M32: #define __SSE2__ 1 +// CHECK_ARL_M32: #define __SSE3__ 1 +// CHECK_ARL_M32: #define __SSE4_1__ 1 +// CHECK_ARL_M32: #define __SSE4_2__ 1 +// CHECK_ARL_M32: #define __SSE_MATH__ 1 +// CHECK_ARL_M32: #define __SSE__ 1 +// CHECK_ARL_M32: #define __SSSE3__ 1 +// CHECK_ARL_M32: #define __UINTR__ 1 +// CHECK_ARL_M32-NOT: #define __USERMSR__ 1 // CHECK_ARLS_M32-NOT: #define __USERMSR__ 1 // CHECK_PTL_M32-NOT: #define __USERMSR__ 1 // CHECK_CWF_M32: #define __USERMSR__ 1 -// CHECK_SRF_M32: #define __VAES__ 1 -// CHECK_SRF_M32: #define __VPCLMULQDQ__ 1 -// CHECK_SRF_M32: #define __WAITPKG__ 1 -// CHECK_SRF_M32: #define __WIDEKL__ 1 -// CHECK_SRF_M32: #define __XSAVEC__ 1 -// CHECK_SRF_M32: #define __XSAVEOPT__ 1 -// CHECK_SRF_M32: #define __XSAVES__ 1 -// CHECK_SRF_M32: #define __XSAVE__ 1 -// CHECK_SRF_M32: #define __corei7 1 -// CHECK_SRF_M32: #define __corei7__ 1 -// CHECK_SRF_M32: #define __i386 1 -// CHECK_SRF_M32: #define __i386__ 1 -// CHECK_SRF_M32: #define __tune_corei7__ 1 -// CHECK_SRF_M32: #define i386 1 +// CHECK_ARL_M32: #define __VAES__ 1 +// CHECK_ARL_M32: #define __VPCLMULQDQ__ 1 +// CHECK_ARL_M32: #define __WAITPKG__ 1 +// CHECK_ARL_M32: #define __WIDEKL__ 1 +// CHECK_ARL_M32: #define __XSAVEC__ 1 +// CHECK_ARL_M32: #define __XSAVEOPT__ 1 +// CHECK_ARL_M32: #define __XSAVES__ 1 +// CHECK_ARL_M32: #define __XSAVE__ 1 +// CHECK_ARL_M32: #define __corei7 1 +// CHECK_ARL_M32: #define __corei7__ 1 +// CHECK_ARL_M32: #define __i386 1 +// CHECK_ARL_M32: #define __i386__ 1 +// CHECK_ARL_M32: #define __tune_corei7__ 1 +// CHECK_ARL_M32: #define i386 1 // RUN: %clang -march=sierraforest -m64 -E -dM %s -o - 2>&1 \ // RUN: --target=i386 \ -// RUN: | FileCheck -match-full-lines %s -check-prefix=CHECK_SRF_M64 +// RUN: | FileCheck -match-full-lines %s -check-prefixes=CHECK_ARL_M64,CHECK_SRF_M64 // RUN: %clang -march=grandridge -m64 -E -dM %s -o - 2>&1 \ // RUN: --target=i386 \ -// RUN: | FileCheck -match-full-lines %s -check-prefixes=CHECK_SRF_M64 +// RUN: | FileCheck -match-full-lines %s -check-prefixes=CHECK_ARL_M64,CHECK_SRF_M64 // RUN: %clang -march=arrowlake -m64 -E -dM %s -o - 2>&1 \ // RUN: -target i386-unknown-linux \ -// RUN: | FileCheck -match-full-lines %s -check-prefix=CHECK_SRF_M64 +// RUN: | FileCheck -match-full-lines %s -check-prefix=CHECK_ARL_M64 // RUN: %clang -march=arrowlake-s -m64 -E -dM %s -o - 2>&1 \ // RUN: -target i386-unknown-linux \ -// RUN: | FileCheck -match-full-lines %s -check-prefixes=CHECK_SRF_M64,CHECK_ARLS_M64 +// RUN: | FileCheck -match-full-lines %s -check-prefixes=CHECK_ARL_M64,CHECK_ARLS_M64 // RUN: %clang -march=lunarlake -m64 -E -dM %s -o - 2>&1 \ // RUN: -target i386-unknown-linux \ -// RUN: | FileCheck -match-full-lines %s -check-prefixes=CHECK_SRF_M64,CHECK_ARLS_M64 +// RUN: | FileCheck -match-full-lines %s -check-prefixes=CHECK_ARL_M64,CHECK_ARLS_M64 // RUN: %clang -march=pantherlake -m64 -E -dM %s -o - 2>&1 \ // RUN: -target i386-unknown-linux \ -// RUN: | FileCheck -match-full-lines %s -check-prefixes=CHECK_SRF_M64,CHECK_ARLS_M64,CHECK_PTL_M64 +// RUN: | FileCheck -match-full-lines %s -check-prefixes=CHECK_ARL_M64,CHECK_ARLS_M64,CHECK_PTL_M64 // RUN: %clang -march=clearwaterforest -m64 -E -dM %s -o - 2>&1 \ // RUN: -target i386-unknown-linux \ -// RUN: | FileCheck -match-full-lines %s -check-prefixes=CHECK_SRF_M64,CHECK_ARLS_M64,CHECK_PTL_M64,CHECK_CWF_M64 -// CHECK_SRF_M64: #define __ADX__ 1 -// CHECK_SRF_M64: #define __AES__ 1 -// CHECK_SRF_M64: #define __AVX2__ 1 -// CHECK_SRF_M64-NOT: AVX512 -// CHECK_SRF_M64: #define __AVXIFMA__ 1 -// CHECK_SRF_M64: #define __AVXVNNIINT8__ 1 -// CHECK_SRF_M64: #define __AVXVNNI__ 1 -// CHECK_SRF_M64: #define __AVX__ 1 -// CHECK_SRF_M64: #define __BMI2__ 1 -// CHECK_SRF_M64: #define __BMI__ 1 +// RUN: | FileCheck -match-full-lines %s -check-prefixes=CHECK_ARL_M64,CHECK_SRF_M64,CHECK_ARLS_M64,CHECK_PTL_M64,CHECK_CWF_M64 +// CHECK_ARL_M64: #define __ADX__ 1 +// CHECK_ARL_M64: #define __AES__ 1 +// CHECK_ARL_M64: #define __AVX2__ 1 +// CHECK_ARL_M64-NOT: AVX512 +// CHECK_ARL_M64: #define __AVXIFMA__ 1 +// CHECK_ARL_M64: #define __AVXNECONVERT__ 1 +// CHECK_ARL_M64-NOT: #define __AVXVNNIINT16__ 1 +// CHECK_ARLS_M64: #define __AVXVNNIINT16__ 1 +// CHECK_ARL_M64: #define __AVXVNNIINT8__ 1 +// CHECK_ARL_M64: #define __AVXVNNI__ 1 +// CHECK_ARL_M64: #define __AVX__ 1 +// CHECK_ARL_M64: #define __BMI2__ 1 +// CHECK_ARL_M64: #define __BMI__ 1 +// CHECK_ARLS_M64-NOT: __CLDEMOTE__ // CHECK_SRF_M64: #define __CLDEMOTE__ 1 -// CHECK_SRF_M64: #define __CLFLUSHOPT__ 1 -// CHECK_SRF_M64: #define __CLWB__ 1 -// CHECK_SRF_M64: #define __CMPCCXADD__ 1 -// CHECK_SRF_M64: #define __ENQCMD__ 1 -// CHECK_SRF_M64: #define __F16C__ 1 -// CHECK_SRF_M64: #define __FMA__ 1 -// CHECK_SRF_M64: #define __FSGSBASE__ 1 -// CHECK_SRF_M64: #define __FXSR__ 1 -// CHECK_SRF_M64: #define __GFNI__ 1 -// CHECK_SRF_M64: #define __HRESET__ 1 -// CHECK_SRF_M64: #define __INVPCID__ 1 -// CHECK_SRF_M64: #define __KL__ 1 -// CHECK_SRF_M64: #define __LZCNT__ 1 -// CHECK_SRF_M64: #define __MMX__ 1 -// CHECK_SRF_M64: #define __MOVBE__ 1 -// CHECK_SRF_M64: #define __MOVDIR64B__ 1 -// CHECK_SRF_M64: #define __MOVDIRI__ 1 -// CHECK_SRF_M64: #define __PCLMUL__ 1 -// CHECK_SRF_M64: #define __PCONFIG__ 1 -// CHECK_SRF_M64: #define __PKU__ 1 -// CHECK_SRF_M64: #define __POPCNT__ 1 -// CHECK_SRF_M64-NOT: #define __PREFETCHI__ 1 +// CHECK_ARL_M64: #define __CLFLUSHOPT__ 1 +// CHECK_ARL_M64: #define __CLWB__ 1 +// CHECK_ARL_M64: #define __CMPCCXADD__ 1 +// CHECK_ARL_M64: #define __ENQCMD__ 1 +// CHECK_ARL_M64: #define __F16C__ 1 +// CHECK_ARL_M64: #define __FMA__ 1 +// CHECK_ARL_M64: #define __FSGSBASE__ 1 +// CHECK_ARL_M64: #define __FXSR__ 1 +// CHECK_ARL_M64: #define __GFNI__ 1 +// CHECK_ARL_M64: #define __HRESET__ 1 +// CHECK_ARL_M64: #define __INVPCID__ 1 +// CHECK_ARL_M64: #define __KL__ 1 +// CHECK_ARL_M64: #define __LZCNT__ 1 +// CHECK_ARL_M64: #define __MMX__ 1 +// CHECK_ARL_M64: #define __MOVBE__ 1 +// CHECK_ARL_M64: #define __MOVDIR64B__ 1 +// CHECK_ARL_M64: #define __MOVDIRI__ 1 +// CHECK_ARL_M64: #define __PCLMUL__ 1 +// CHECK_ARL_M64: #define __PCONFIG__ 1 +// CHECK_ARL_M64: #define __PKU__ 1 +// CHECK_ARL_M64: #define __POPCNT__ 1 +// CHECK_ARL_M64-NOT: #define __PREFETCHI__ 1 // CHECK_ARLS_M64-NOT: #define __PREFETCHI__ 1 // CHECK_PTL_M64: #define __PREFETCHI__ 1 -// CHECK_SRF_M64: #define __PRFCHW__ 1 -// CHECK_SRF_M64: #define __PTWRITE__ 1 -// CHECK_SRF_M64-NOT: #define __RAOINT__ 1 -// CHECK_SRF_M64: #define __RDPID__ 1 -// CHECK_SRF_M64: #define __RDRND__ 1 -// CHECK_SRF_M64: #define __RDSEED__ 1 -// CHECK_SRF_M64: #define __SERIALIZE__ 1 -// CHECK_SRF_M64: #define __SGX__ 1 -// CHECK_SRF_M64: #define __SHA__ 1 -// CHECK_SRF_M64: #define __SHSTK__ 1 -// CHECK_SRF_M64: #define __SSE2_MATH__ 1 -// CHECK_SRF_M64: #define __SSE2__ 1 -// CHECK_SRF_M64: #define __SSE3__ 1 -// CHECK_SRF_M64: #define __SSE4_1__ 1 -// CHECK_SRF_M64: #define __SSE4_2__ 1 -// CHECK_SRF_M64: #define __SSE_MATH__ 1 -// CHECK_SRF_M64: #define __SSE__ 1 -// CHECK_SRF_M64: #define __SSSE3__ 1 -// CHECK_SRF_M64: #define __UINTR__ 1 -// CHECK_SRF_M64-NOT: #define __USERMSR__ 1 +// CHECK_ARL_M64: #define __PRFCHW__ 1 +// CHECK_ARL_M64: #define __PTWRITE__ 1 +// CHECK_ARL_M64-NOT: #define __RAOINT__ 1 +// CHECK_ARL_M64: #define __RDPID__ 1 +// CHECK_ARL_M64: #define __RDRND__ 1 +// CHECK_ARL_M64: #define __RDSEED__ 1 +// CHECK_ARL_M64: #define __SERIALIZE__ 1 +// CHECK_ARL_M64: #define __SGX__ 1 +// CHECK_ARL_M64-NOT: #define __SHA512__ 1 +// CHECK_ARLS_M64: #define __SHA512__ 1 +// CHECK_ARL_M64: #define __SHA__ 1 +// CHECK_ARL_M64: #define __SHSTK__ 1 +// CHECK_ARL_M64-NOT: #define __SM3__ 1 +// CHECK_ARLS_M64: #define __SM3__ 1 +// CHECK_ARL_M64-NOT: #define __SM4__ 1 +// CHECK_ARLS_M64: #define __SM4__ 1 +// CHECK_ARL_M64: #define __SSE2_MATH__ 1 +// CHECK_ARL_M64: #define __SSE2__ 1 +// CHECK_ARL_M64: #define __SSE3__ 1 +// CHECK_ARL_M64: #define __SSE4_1__ 1 +// CHECK_ARL_M64: #define __SSE4_2__ 1 +// CHECK_ARL_M64: #define __SSE_MATH__ 1 +// CHECK_ARL_M64: #define __SSE__ 1 +// CHECK_ARL_M64: #define __SSSE3__ 1 +// CHECK_ARL_M64: #define __UINTR__ 1 +// CHECK_ARL_M64-NOT: #define __USERMSR__ 1 // CHECK_ARLS_M64-NOT: #define __USERMSR__ 1 // CHECK_PTL_M64-NOT: #define __USERMSR__ 1 // CHECK_CWF_M64: #define __USERMSR__ 1 -// CHECK_SRF_M64: #define __VAES__ 1 -// CHECK_SRF_M64: #define __VPCLMULQDQ__ 1 -// CHECK_SRF_M64: #define __WAITPKG__ 1 -// CHECK_SRF_M64: #define __WIDEKL__ 1 -// CHECK_SRF_M64: #define __XSAVEC__ 1 -// CHECK_SRF_M64: #define __XSAVEOPT__ 1 -// CHECK_SRF_M64: #define __XSAVES__ 1 -// CHECK_SRF_M64: #define __XSAVE__ 1 -// CHECK_SRF_M64: #define __amd64 1 -// CHECK_SRF_M64: #define __amd64__ 1 -// CHECK_SRF_M64: #define __corei7 1 -// CHECK_SRF_M64: #define __corei7__ 1 -// CHECK_SRF_M64: #define __tune_corei7__ 1 -// CHECK_SRF_M64: #define __x86_64 1 -// CHECK_SRF_M64: #define __x86_64__ 1 +// CHECK_ARL_M64: #define __VAES__ 1 +// CHECK_ARL_M64: #define __VPCLMULQDQ__ 1 +// CHECK_ARL_M64: #define __WAITPKG__ 1 +// CHECK_ARL_M64: #define __WIDEKL__ 1 +// CHECK_ARL_M64: #define __XSAVEC__ 1 +// CHECK_ARL_M64: #define __XSAVEOPT__ 1 +// CHECK_ARL_M64: #define __XSAVES__ 1 +// CHECK_ARL_M64: #define __XSAVE__ 1 +// CHECK_ARL_M64: #define __amd64 1 +// CHECK_ARL_M64: #define __amd64__ 1 +// CHECK_ARL_M64: #define __corei7 1 +// CHECK_ARL_M64: #define __corei7__ 1 +// CHECK_ARL_M64: #define __tune_corei7__ 1 +// CHECK_ARL_M64: #define __x86_64 1 +// CHECK_ARL_M64: #define __x86_64__ 1 // RUN: %clang -march=geode -m32 -E -dM %s -o - 2>&1 \ // RUN: -target i386-unknown-linux \ diff --git a/external/llvm-project/clang/test/Preprocessor/predefined-macros-no-warnings.c b/external/llvm-project/clang/test/Preprocessor/predefined-macros-no-warnings.c index 4e3e29ccfa8a..fe27ed8814ee 100644 --- a/external/llvm-project/clang/test/Preprocessor/predefined-macros-no-warnings.c +++ b/external/llvm-project/clang/test/Preprocessor/predefined-macros-no-warnings.c @@ -14,6 +14,7 @@ // RUN: %clang_cc1 %s -Eonly -Wsystem-headers -Werror -triple aarch64-fuchsia // RUN: %clang_cc1 %s -Eonly -Wsystem-headers -Werror -triple aarch64-linux // RUN: %clang_cc1 %s -Eonly -Wsystem-headers -Werror -triple aarch64-linux-openhos +// RUN: %clang_cc1 %s -Eonly -Wsystem-headers -Werror -triple aarch64-managarm // RUN: %clang_cc1 %s -Eonly -Wsystem-headers -Werror -triple aarch64-netbsd // RUN: %clang_cc1 %s -Eonly -Wsystem-headers -Werror -triple aarch64-openbsd // RUN: %clang_cc1 %s -Eonly -Wsystem-headers -Werror -triple aarch64-win32-gnu @@ -108,6 +109,7 @@ // RUN: %clang_cc1 %s -Eonly -Wsystem-headers -Werror -triple riscv64-fuchsia // RUN: %clang_cc1 %s -Eonly -Wsystem-headers -Werror -triple riscv64-linux // RUN: %clang_cc1 %s -Eonly -Wsystem-headers -Werror -triple riscv64-linux-openhos +// RUN: %clang_cc1 %s -Eonly -Wsystem-headers -Werror -triple riscv64-managarm // RUN: %clang_cc1 %s -Eonly -Wsystem-headers -Werror -triple sparc // RUN: %clang_cc1 %s -Eonly -Wsystem-headers -Werror -triple sparc-linux // RUN: %clang_cc1 %s -Eonly -Wsystem-headers -Werror -triple sparc-solaris @@ -167,6 +169,7 @@ // RUN: %clang_cc1 %s -Eonly -Wsystem-headers -Werror -triple x86_64-nacl // RUN: %clang_cc1 %s -Eonly -Wsystem-headers -Werror -triple x86_64-ps4 // RUN: %clang_cc1 %s -Eonly -Wsystem-headers -Werror -triple x86_64-ps5 +// RUN: %clang_cc1 %s -Eonly -Wsystem-headers -Werror -triple x86_64-managarm // RUN: %clang_cc1 %s -Eonly -Wsystem-headers -Werror -triple spir // RUN: %clang_cc1 %s -Eonly -Wsystem-headers -Werror -triple spir64 // RUN: %clang_cc1 %s -Eonly -Wsystem-headers -Werror -triple spirv32 diff --git a/external/llvm-project/clang/test/Preprocessor/riscv-target-features-andes.c b/external/llvm-project/clang/test/Preprocessor/riscv-target-features-andes.c index 3cd9b0435413..c66d4427b5cf 100644 --- a/external/llvm-project/clang/test/Preprocessor/riscv-target-features-andes.c +++ b/external/llvm-project/clang/test/Preprocessor/riscv-target-features-andes.c @@ -15,6 +15,14 @@ // RUN: -o - | FileCheck --check-prefix=CHECK-XANDESPERF %s // CHECK-XANDESPERF: __riscv_xandesperf 5000000{{$}} +// RUN: %clang --target=riscv32 \ +// RUN: -march=rv32i_xandesvbfhcvt -E -dM %s \ +// RUN: -o - | FileCheck --check-prefix=CHECK-XANDESVBFHCVT %s +// RUN: %clang --target=riscv64 \ +// RUN: -march=rv64i_xandesvbfhcvt -E -dM %s \ +// RUN: -o - | FileCheck --check-prefix=CHECK-XANDESVBFHCVT %s +// CHECK-XANDESVBFHCVT: __riscv_xandesvbfhcvt 5000000{{$}} + // RUN: %clang --target=riscv32 \ // RUN: -march=rv32i_xandesvpackfph -E -dM %s \ // RUN: -o - | FileCheck --check-prefix=CHECK-XANDESVPACKFPH %s diff --git a/external/llvm-project/clang/test/Sema/gh87867.c b/external/llvm-project/clang/test/Sema/gh87867.c new file mode 100644 index 000000000000..0568c734424c --- /dev/null +++ b/external/llvm-project/clang/test/Sema/gh87867.c @@ -0,0 +1,33 @@ +// RUN: %clang_cc1 -fsyntax-only -verify -std=c23 %s + +// Compound literal doesn't need a constant expression inside a initializer-list if it is already inside a function +// see: https://github.com/llvm/llvm-project/issues/87867 +int foo(int *a, int b) { + return 0; +} + +int x; +struct{int t;} a = (struct { + typeof(foo(&(struct { int t; }){.t = x}.t, 0)) t; // expected-error {{initializer element is not a compile-time constant}} +}){0}; + +void inside_a_func(){ + int x; + (void)(struct { + typeof(foo(&(struct { int t; }){.t = x}.t, 0)) t; + }){0}; +} + +// see: https://github.com/llvm/llvm-project/issues/143613 +#define bitcast(type, value) \ + (((union{ typeof(value) src; type dst; }){ (value) }).dst) + +double placeholder = 10.0; +double bar = bitcast(double, placeholder); // expected-error {{initializer element is not a compile-time constant}} + +int main(void) +{ + int foo = 4; + foo = bitcast(int, bitcast(double, foo)); + return 0; +} diff --git a/external/llvm-project/clang/test/Sema/ppc-dmf-types.c b/external/llvm-project/clang/test/Sema/ppc-dmf-types.c new file mode 100644 index 000000000000..b3da72df2508 --- /dev/null +++ b/external/llvm-project/clang/test/Sema/ppc-dmf-types.c @@ -0,0 +1,103 @@ +// RUN: %clang_cc1 -triple powerpc64le-unknown-unknown -fsyntax-only \ +// RUN: -target-cpu future %s -verify +// RUN: %clang_cc1 -triple powerpc64-unknown-unknown -fsyntax-only \ +// RUN: -target-cpu future %s -verify + +// The use of PPC MMA types is strongly restricted. Non-pointer MMA variables +// can only be declared in functions and a limited number of operations are +// supported on these types. This test case checks that invalid uses of MMA +// types are correctly prevented. + +// vector dmr + +// typedef +typedef __dmr1024 dmr_t; + +// function argument +void testDmrArg1(__dmr1024 vdmr, int *ptr) { // expected-error {{invalid use of PPC MMA type}} + __dmr1024 *vdmrp = (__dmr1024 *)ptr; + *vdmrp = vdmr; +} + +void testDmrArg2(const __dmr1024 vdmr, int *ptr) { // expected-error {{invalid use of PPC MMA type}} + __dmr1024 *vdmrp = (__dmr1024 *)ptr; + *vdmrp = vdmr; +} + +void testDmrArg3(const dmr_t vdmr, int *ptr) { // expected-error {{invalid use of PPC MMA type}} + __dmr1024 *vdmrp = (__dmr1024 *)ptr; + *vdmrp = vdmr; +} + +// function return +__dmr1024 testDmrRet1(int *ptr) { // expected-error {{invalid use of PPC MMA type}} + __dmr1024 *vdmrp = (__dmr1024 *)ptr; + return *vdmrp; // expected-error {{invalid use of PPC MMA type}} +} + +const dmr_t testDmrRet4(int *ptr) { // expected-error {{invalid use of PPC MMA type}} + __dmr1024 *vdmrp = (__dmr1024 *)ptr; + return *vdmrp; // expected-error {{invalid use of PPC MMA type}} +} + +// global +__dmr1024 globalvdmr; // expected-error {{invalid use of PPC MMA type}} +const __dmr1024 globalvdmr2; // expected-error {{invalid use of PPC MMA type}} +__dmr1024 *globalvdmrp; +const __dmr1024 *const globalvdmrp2; +dmr_t globalvdmr_t; // expected-error {{invalid use of PPC MMA type}} + +// struct field +struct TestDmrStruct { + int a; + float b; + __dmr1024 c; // expected-error {{invalid use of PPC MMA type}} + __dmr1024 *vq; +}; + +// operators +int testDmrOperators1(int *ptr) { + __dmr1024 *vdmrp = (__dmr1024 *)ptr; + __dmr1024 vdmr1 = *(vdmrp + 0); + __dmr1024 vdmr2 = *(vdmrp + 1); + __dmr1024 vdmr3 = *(vdmrp + 2); + if (vdmr1) // expected-error {{statement requires expression of scalar type ('__dmr1024' invalid)}} + *(vdmrp + 10) = vdmr1; + if (!vdmr2) // expected-error {{invalid argument type '__dmr1024' to unary expression}} + *(vdmrp + 11) = vdmr3; + int c1 = vdmr1 && vdmr2; // expected-error {{invalid operands to binary expression ('__dmr1024' and '__dmr1024')}} + int c2 = vdmr2 == vdmr3; // expected-error {{invalid operands to binary expression ('__dmr1024' and '__dmr1024')}} + int c3 = vdmr2 < vdmr1; // expected-error {{invalid operands to binary expression ('__dmr1024' and '__dmr1024')}} + return c1 || c2 || c3; +} + +void testDmrOperators2(int *ptr) { + __dmr1024 *vdmrp = (__dmr1024 *)ptr; + __dmr1024 vdmr1 = *(vdmrp + 0); + __dmr1024 vdmr2 = *(vdmrp + 1); + __dmr1024 vdmr3 = *(vdmrp + 2); + vdmr1 = -vdmr1; // expected-error {{invalid argument type '__dmr1024' to unary expression}} + vdmr2 = vdmr1 + vdmr3; // expected-error {{invalid operands to binary expression ('__dmr1024' and '__dmr1024')}} + vdmr2 = vdmr2 * vdmr3; // expected-error {{invalid operands to binary expression ('__dmr1024' and '__dmr1024')}} + vdmr3 = vdmr3 | vdmr3; // expected-error {{invalid operands to binary expression ('__dmr1024' and '__dmr1024')}} + vdmr3 = vdmr3 << 2; // expected-error {{invalid operands to binary expression ('__dmr1024' and 'int')}} + *(vdmrp + 10) = vdmr1; + *(vdmrp + 11) = vdmr2; + *(vdmrp + 12) = vdmr3; +} + +vector unsigned char testDmrOperators3(int *ptr) { + __dmr1024 *vdmrp = (__dmr1024 *)ptr; + __dmr1024 vdmr1 = *(vdmrp + 0); + __dmr1024 vdmr2 = *(vdmrp + 1); + __dmr1024 vdmr3 = *(vdmrp + 2); + vdmr1 ? *(vdmrp + 10) = vdmr2 : *(vdmrp + 11) = vdmr3; // expected-error {{used type '__dmr1024' where arithmetic or pointer type is required}} + vdmr2 = vdmr3; + return vdmr2[1]; // expected-error {{subscripted value is not an array, pointer, or vector}} +} + +void testDmrOperators4(int v, void *ptr) { + __dmr1024 *vdmrp = (__dmr1024 *)ptr; + __dmr1024 vdmr1 = (__dmr1024)v; // expected-error {{used type '__dmr1024' where arithmetic or pointer type is required}} + __dmr1024 vdmr2 = (__dmr1024)vdmrp; // expected-error {{used type '__dmr1024' where arithmetic or pointer type is required}} +} diff --git a/external/llvm-project/clang/test/SemaCXX/builtin-is-constant-evaluated.cpp b/external/llvm-project/clang/test/SemaCXX/builtin-is-constant-evaluated.cpp index c775fe71069d..66981acf87a8 100644 --- a/external/llvm-project/clang/test/SemaCXX/builtin-is-constant-evaluated.cpp +++ b/external/llvm-project/clang/test/SemaCXX/builtin-is-constant-evaluated.cpp @@ -154,3 +154,17 @@ namespace narrowing { // expected-note {{insert an explicit cast to silence this issue}} } } + +struct GH99680 { + static const int x1 = 1/(1-__builtin_is_constant_evaluated()); // expected-error {{in-class initializer for static data member is not a constant expression}} \ + // expected-note {{division by zero}} + static const int x2 = __builtin_is_constant_evaluated(); + static_assert(x2 == 1); + static const float x3 = 1/(1-__builtin_is_constant_evaluated()); // expected-error {{in-class initializer for static data member of type 'const float' requires 'constexpr' specifier}} \ + // expected-note {{add 'constexpr'}} \ + // expected-error {{in-class initializer for static data member is not a constant expression}} \ + // expected-note {{division by zero}} + static const float x4 = __builtin_is_constant_evaluated(); // expected-error {{in-class initializer for static data member of type 'const float' requires 'constexpr' specifier}} \ + // expected-note {{add 'constexpr'}} + static_assert(fold(x4 == 1)); +}; diff --git a/external/llvm-project/clang/test/SemaCXX/class.cpp b/external/llvm-project/clang/test/SemaCXX/class.cpp index 2f59544e7f36..f1e02d5158aa 100644 --- a/external/llvm-project/clang/test/SemaCXX/class.cpp +++ b/external/llvm-project/clang/test/SemaCXX/class.cpp @@ -1,5 +1,5 @@ // RUN: %clang_cc1 -fsyntax-only -verify=expected,cxx11 -Wc++11-compat %s -// RUN: %clang_cc1 -fsyntax-only -verify -Wc++11-compat %s -std=c++98 +// RUN: %clang_cc1 -fsyntax-only -verify=expected,cxx98 -Wc++11-compat %s -std=c++98 class C { public: auto int errx; // expected-error {{storage class specified for a member declaration}} @@ -32,7 +32,7 @@ class C { int : 1, : 2; typedef int E : 1; // expected-error {{typedef member 'E' cannot be a bit-field}} static int sb : 1; // expected-error {{static member 'sb' cannot be a bit-field}} - static int vs; + static int vs; // cxx11-note {{declared here}} typedef int func(); func tm; @@ -48,20 +48,28 @@ class C { #endif static int si = 0; // expected-error {{non-const static data member must be initialized out of line}} static const NestedC ci = 0; // expected-error {{static data member of type 'const NestedC' must be initialized out of line}} - static const int nci = vs; // expected-error {{in-class initializer for static data member is not a constant expression}} + static const int nci = vs; // expected-error {{in-class initializer for static data member is not a constant expression}} \ + // cxx11-note {{read of non-const variable 'vs' is not allowed in a constant expression}} \ + // cxx98-note {{subexpression not valid in a constant expression}} static const int vi = 0; static const volatile int cvi = 0; // ok, illegal in C++11 #if __cplusplus >= 201103L // expected-error@-2 {{static const volatile data member must be initialized out of line}} #endif static const E evi = 0; - static const int overflow = 1000000*1000000; // cxx11-error {{in-class initializer for static data member is not a constant expression}} - // expected-warning@-1 {{overflow in expression}} - static const int overflow_shift = 1<<32; // cxx11-error {{in-class initializer for static data member is not a constant expression}} - static const int overflow_shift2 = 1>>32; // cxx11-error {{in-class initializer for static data member is not a constant expression}} - static const int overflow_shift3 = 1<<-1; // cxx11-error {{in-class initializer for static data member is not a constant expression}} - static const int overflow_shift4 = 1<<-1; // cxx11-error {{in-class initializer for static data member is not a constant expression}} - static const int overflow_shift5 = -1<<1; // cxx11-error {{in-class initializer for static data member is not a constant expression}} + static const int overflow = 1000000*1000000; // cxx11-error {{in-class initializer for static data member is not a constant expression}} \ + // cxx11-note {{value 1000000000000 is outside the range of representable values of type 'int'}} \ + // expected-warning {{overflow in expression}} + static const int overflow_shift = 1<<32; // cxx11-error {{in-class initializer for static data member is not a constant expression}} \ + // cxx11-note {{shift count 32 >= width of type 'int' (32 bits)}} + static const int overflow_shift2 = 1>>32; // cxx11-error {{in-class initializer for static data member is not a constant expression}}\ + // cxx11-note {{shift count 32 >= width of type 'int' (32 bits)}} + static const int overflow_shift3 = 1<<-1; // cxx11-error {{in-class initializer for static data member is not a constant expression}} \ + // cxx11-note {{negative shift count -1}} + static const int overflow_shift4 = 1<<-1; // cxx11-error {{in-class initializer for static data member is not a constant expression}} \ + // cxx11-note {{negative shift count -1}} + static const int overflow_shift5 = -1<<1; // cxx11-error {{in-class initializer for static data member is not a constant expression}} \ + // cxx11-note {{left shift of negative value -1}} void m() { sx = 0; diff --git a/external/llvm-project/clang/test/SemaCXX/cxx0x-class.cpp b/external/llvm-project/clang/test/SemaCXX/cxx0x-class.cpp index a612a5c07e6e..4b54221cceff 100644 --- a/external/llvm-project/clang/test/SemaCXX/cxx0x-class.cpp +++ b/external/llvm-project/clang/test/SemaCXX/cxx0x-class.cpp @@ -1,6 +1,6 @@ // RUN: %clang_cc1 -Wno-uninitialized -fsyntax-only -verify -std=c++11 -Wno-error=static-float-init %s -int vs = 0; +int vs = 0; // expected-note {{declared here}} class C { public: @@ -11,17 +11,20 @@ class C { int i = 0; static int si = 0; // expected-error {{non-const static data member must be initialized out of line}} static const NestedC ci = 0; // expected-error {{static data member of type 'const NestedC' must be initialized out of line}} - static const int nci = vs; // expected-error {{in-class initializer for static data member is not a constant expression}} + static const int nci = vs; // expected-error {{in-class initializer for static data member is not a constant expression}} \ + // expected-note {{read of non-const variable 'vs' is not allowed in a constant expression}} static const int vi = 0; static const volatile int cvi = 0; // expected-error {{static const volatile data member must be initialized out of line}} }; namespace rdar8367341 { - float foo(); // expected-note {{here}} + float foo(); // expected-note 2 {{here}} struct A { static const float x = 5.0f; // expected-warning {{requires 'constexpr'}} expected-note {{add 'constexpr'}} - static const float y = foo(); // expected-warning {{requires 'constexpr'}} expected-note {{add 'constexpr'}} + static const float y = foo(); // expected-warning {{requires 'constexpr'}} expected-note {{add 'constexpr'}} \ + // expected-error {{in-class initializer for static data member is not a constant expression}} \ + // expected-note {{non-constexpr function 'foo' cannot be used in a constant expression}} static constexpr float x2 = 5.0f; static constexpr float y2 = foo(); // expected-error {{must be initialized by a constant expression}} expected-note {{non-constexpr function 'foo'}} }; diff --git a/external/llvm-project/clang/test/SemaCXX/cxx2a-consteval.cpp b/external/llvm-project/clang/test/SemaCXX/cxx2a-consteval.cpp index d9932e4dd824..1474c48cda3c 100644 --- a/external/llvm-project/clang/test/SemaCXX/cxx2a-consteval.cpp +++ b/external/llvm-project/clang/test/SemaCXX/cxx2a-consteval.cpp @@ -1154,20 +1154,20 @@ namespace GH65985 { int consteval operator""_foo(unsigned long long V) { return 0; } -int consteval operator""_bar(unsigned long long V); // expected-note 3{{here}} +int consteval operator""_bar(unsigned long long V); // expected-note 4 {{here}} int consteval f() { return 0; } -int consteval g(); // expected-note {{here}} +int consteval g(); // expected-note 2 {{here}} struct C { static const int a = 1_foo; static constexpr int b = 1_foo; static const int c = 1_bar; // expected-error {{call to consteval function 'GH65985::operator""_bar' is not a constant expression}} \ - // expected-note {{undefined function 'operator""_bar' cannot be used in a constant expression}} \ + // expected-note 2 {{undefined function 'operator""_bar' cannot be used in a constant expression}} \ // expected-error {{in-class initializer for static data member is not a constant expression}} // FIXME: remove duplicate diagnostics @@ -1179,7 +1179,7 @@ struct C { static const int e = f(); static const int f = g(); // expected-error {{call to consteval function 'GH65985::g' is not a constant expression}} \ // expected-error {{in-class initializer for static data member is not a constant expression}} \ - // expected-note {{undefined function 'g' cannot be used in a constant expression}} + // expected-note 2 {{undefined function 'g' cannot be used in a constant expression}} }; } diff --git a/external/llvm-project/clang/test/SemaCXX/exception-spec.cpp b/external/llvm-project/clang/test/SemaCXX/exception-spec.cpp index 6ad19aab397b..31c691b28da4 100644 --- a/external/llvm-project/clang/test/SemaCXX/exception-spec.cpp +++ b/external/llvm-project/clang/test/SemaCXX/exception-spec.cpp @@ -52,3 +52,24 @@ namespace AssignmentOp { D2 &operator=(const D2&); // expected-error {{more lax}} }; } + +namespace OverloadedFunctions { + +template +void f(T&) noexcept; + +template +void f(T (&arr)[N]) noexcept(noexcept(f(*arr))); + +template +inline void f(T&) noexcept {} + +template +inline void f(T (&arr)[N]) noexcept(noexcept(f(*arr))) {} + +void g() { + int x[1]; + f(x); +} + +} diff --git a/external/llvm-project/clang/test/SemaCXX/modules.cppm b/external/llvm-project/clang/test/SemaCXX/modules.cppm index 41204be76eaf..5d0d6da44a2e 100644 --- a/external/llvm-project/clang/test/SemaCXX/modules.cppm +++ b/external/llvm-project/clang/test/SemaCXX/modules.cppm @@ -1,19 +1,20 @@ -// RUN: %clang_cc1 -std=c++20 -emit-module-interface %s -o %t.0.pcm -verify -DTEST=0 -// RUN: %clang_cc1 -std=c++20 -emit-module-interface %s -o %t.1.pcm -verify -DTEST=1 -// RUN: %clang_cc1 -std=c++20 -emit-module-interface %s -fmodule-file=foo=%t.0.pcm -o %t.2.pcm -verify -DTEST=2 -// RUN: %clang_cc1 -std=c++20 -emit-module-interface %s -fmodule-file=foo=%t.0.pcm -o %t.3.pcm -verify -Dfoo=bar -DTEST=3 +// RUN: rm -rf %t +// RUN: mkdir -p %t +// RUN: split-file %s %t -#if TEST == 0 || TEST == 2 -// expected-no-diagnostics -#endif +// RUN: %clang_cc1 -std=c++20 -emit-module-interface %t/test0.cpp -o %t/test0.pcm -verify +// RUN: %clang_cc1 -std=c++20 -emit-module-interface %t/test1.cpp -o %t/test1.pcm -verify +// RUN: %clang_cc1 -std=c++20 -emit-module-interface %t/test2.cpp -fmodule-file=foo=%t/test0.pcm -o %t/test2.pcm -verify +// RUN: %clang_cc1 -std=c++20 -emit-module-interface %t/test3.cpp -fmodule-file=foo=%t/test0.pcm -o %t/test3.pcm -verify +//--- test0.cpp +// expected-no-diagnostics export module foo; static int m; int n; -#if TEST == 0 export { int a; int b; @@ -27,33 +28,18 @@ export void f() {} export struct T { } t; -#elif TEST == 3 -int use_a = a; // expected-error {{use of undeclared identifier 'a'}} -#undef foo -import foo; // expected-error {{imports must immediately follow the module declaration}} - -export {} -export { - ; // No diagnostic after P2615R1 DR -} -export { - static_assert(true); // No diagnostic after P2615R1 DR -} +//--- test1.cpp +export module foo; -int use_b = b; // expected-error{{use of undeclared identifier 'b'}} -int use_n = n; // FIXME: this should not be visible, because it is not exported +static int m; -extern int n; -static_assert(&n != p); // expected-error{{use of undeclared identifier 'p'}} -#endif +int n; -#if TEST == 1 struct S { export int n; // expected-error {{expected member name or ';'}} export static int n; // expected-error {{expected member name or ';'}} }; -#endif // FIXME: Exports of declarations without external linkage are disallowed. // Exports of declarations with non-external-linkage types are disallowed. @@ -61,7 +47,6 @@ struct S { // Cannot export within another export. This isn't precisely covered by the // language rules right now, but (per personal correspondence between zygoloid // and gdr) is the intent. -#if TEST == 1 export { // expected-note {{export block begins here}} extern "C++" { namespace NestedExport { @@ -71,4 +56,36 @@ export { // expected-note {{export block begins here}} } // namespace NestedExport } } -#endif + +//--- test2.cpp +// expected-no-diagnostics +export module foo; + +static int m; + +int n; + +//--- test3.cpp +export module bar; + +static int m; + +int n; + +int use_a = a; // expected-error {{use of undeclared identifier 'a'}} + +import foo; // expected-error {{imports must immediately follow the module declaration}} + +export {} +export { + ; // No diagnostic after P2615R1 DR +} +export { + static_assert(true); // No diagnostic after P2615R1 DR +} + +int use_b = b; // expected-error{{use of undeclared identifier 'b'}} +int use_n = n; // FIXME: this should not be visible, because it is not exported + +extern int n; +static_assert(&n != p); // expected-error{{use of undeclared identifier 'p'}} diff --git a/external/llvm-project/clang/test/SemaCXX/type-aware-new-delete-transparent-contexts.cpp b/external/llvm-project/clang/test/SemaCXX/type-aware-new-delete-transparent-contexts.cpp index 7c0b967a3c03..30fea464a8dc 100644 --- a/external/llvm-project/clang/test/SemaCXX/type-aware-new-delete-transparent-contexts.cpp +++ b/external/llvm-project/clang/test/SemaCXX/type-aware-new-delete-transparent-contexts.cpp @@ -1,12 +1,22 @@ -// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++26 -fexceptions -DTRANSPARENT_DECL=0 -// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++26 -fexceptions -DTRANSPARENT_DECL=1 -// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++26 -fexceptions -DTRANSPARENT_DECL=2 +// RUN: rm -rf %t +// RUN: mkdir %t +// RUN: split-file %s %t +// RUN: %clang_cc1 -fsyntax-only -verify %t/testing.cpp -std=c++26 -fexceptions -DTRANSPARENT_DECL=0 +// RUN: %clang_cc1 -fsyntax-only -verify %t/testing.cpp -std=c++26 -fexceptions -DTRANSPARENT_DECL=1 +// RUN: %clang_cc1 -fsyntax-only -verify %t/module_testing.cppm -std=c++26 -fexceptions -DTRANSPARENT_DECL=2 + +//--- module_testing.cppm // expected-no-diagnostics -#if TRANSPARENT_DECL==2 export module Testing; -#endif +#include "testing.inc" + +//--- testing.cpp +// expected-no-diagnostics +#include "testing.inc" + +//--- testing.inc namespace std { template struct type_identity {}; using size_t = __SIZE_TYPE__; diff --git a/external/llvm-project/clang/test/SemaHLSL/RootSignature-resource-ranges-err.hlsl b/external/llvm-project/clang/test/SemaHLSL/RootSignature-resource-ranges-err.hlsl new file mode 100644 index 000000000000..e5152e72d480 --- /dev/null +++ b/external/llvm-project/clang/test/SemaHLSL/RootSignature-resource-ranges-err.hlsl @@ -0,0 +1,21 @@ +// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.3-library -x hlsl -o - %s -verify + +// expected-error@+1 {{resource ranges b[42;42] and b[42;42] overlap within space = 0 and visibility = All}} +[RootSignature("CBV(b42), CBV(b42)")] +void bad_root_signature_0() {} + +// expected-error@+1 {{resource ranges t[0;0] and t[0;0] overlap within space = 3 and visibility = All}} +[RootSignature("SRV(t0, space = 3), SRV(t0, space = 3)")] +void bad_root_signature_1() {} + +// expected-error@+1 {{resource ranges u[0;0] and u[0;0] overlap within space = 0 and visibility = Pixel}} +[RootSignature("UAV(u0, visibility = SHADER_VISIBILITY_PIXEL), UAV(u0, visibility = SHADER_VISIBILITY_PIXEL)")] +void bad_root_signature_2() {} + +// expected-error@+1 {{resource ranges u[0;0] and u[0;0] overlap within space = 0 and visibility = Pixel}} +[RootSignature("UAV(u0, visibility = SHADER_VISIBILITY_ALL), UAV(u0, visibility = SHADER_VISIBILITY_PIXEL)")] +void bad_root_signature_3() {} + +// expected-error@+1 {{resource ranges u[0;0] and u[0;0] overlap within space = 0 and visibility = Pixel}} +[RootSignature("UAV(u0, visibility = SHADER_VISIBILITY_PIXEL), UAV(u0, visibility = SHADER_VISIBILITY_ALL)")] +void bad_root_signature_4() {} diff --git a/external/llvm-project/clang/test/SemaHLSL/RootSignature-resource-ranges.hlsl b/external/llvm-project/clang/test/SemaHLSL/RootSignature-resource-ranges.hlsl new file mode 100644 index 000000000000..5778fb2ae4eb --- /dev/null +++ b/external/llvm-project/clang/test/SemaHLSL/RootSignature-resource-ranges.hlsl @@ -0,0 +1,15 @@ +// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.3-library -x hlsl -o - %s -verify + +// expected-no-diagnostics + +[RootSignature("CBV(b0), CBV(b1)")] +void valid_root_signature_0() {} + +[RootSignature("CBV(b0, visibility = SHADER_VISIBILITY_DOMAIN), CBV(b0, visibility = SHADER_VISIBILITY_PIXEL)")] +void valid_root_signature_1() {} + +[RootSignature("CBV(b0, space = 1), CBV(b0, space = 2)")] +void valid_root_signature_2() {} + +[RootSignature("CBV(b0), SRV(t0)")] +void valid_root_signature_3() {} diff --git a/external/llvm-project/clang/test/SemaHLSL/num_threads.hlsl b/external/llvm-project/clang/test/SemaHLSL/num_threads.hlsl index b5f9ad6c33cd..96200312bbf6 100644 --- a/external/llvm-project/clang/test/SemaHLSL/num_threads.hlsl +++ b/external/llvm-project/clang/test/SemaHLSL/num_threads.hlsl @@ -10,6 +10,8 @@ // RUN: %clang_cc1 -triple dxil-pc-shadermodel5.0-compute -x hlsl -ast-dump -o - %s -DFAIL -verify // RUN: %clang_cc1 -triple dxil-pc-shadermodel4.0-compute -x hlsl -ast-dump -o - %s -DFAIL -verify +// RUN: %clang_cc1 -triple spirv-pc-vulkan1.3-compute -x hlsl -ast-dump -o - %s | FileCheck %s --check-prefixes=CHECK,CHECK-SPIRV + #if __SHADER_TARGET_STAGE == __SHADER_STAGE_COMPUTE || __SHADER_TARGET_STAGE == __SHADER_STAGE_MESH || __SHADER_TARGET_STAGE == __SHADER_STAGE_AMPLIFICATION || __SHADER_TARGET_STAGE == __SHADER_STAGE_LIBRARY #ifdef FAIL @@ -88,24 +90,30 @@ int entry() { // Because these two attributes match, they should both appear in the AST [numthreads(2,2,1)] -// CHECK: HLSLNumThreadsAttr 0x{{[0-9a-fA-F]+}} 2 2 1 +// CHECK: HLSLNumThreadsAttr 0x{{[0-9a-fA-F]+}} 2 2 1 int secondFn(); [numthreads(2,2,1)] -// CHECK: HLSLNumThreadsAttr 0x{{[0-9a-fA-F]+}} 2 2 1 +// CHECK: HLSLNumThreadsAttr 0x{{[0-9a-fA-F]+}} 2 2 1 int secondFn() { return 1; } [numthreads(4,2,1)] -// CHECK: HLSLNumThreadsAttr 0x{{[0-9a-fA-F]+}} 4 2 1 +// CHECK: HLSLNumThreadsAttr 0x{{[0-9a-fA-F]+}} 4 2 1 int onlyOnForwardDecl(); -// CHECK: HLSLNumThreadsAttr 0x{{[0-9a-fA-F]+}} Inherited 4 2 1 +// CHECK: HLSLNumThreadsAttr 0x{{[0-9a-fA-F]+}} Inherited 4 2 1 int onlyOnForwardDecl() { return 1; } +#ifdef __spirv__ +[numthreads(4,2,128)] +// CHECK-SPIRV: HLSLNumThreadsAttr 0x{{[0-9a-fA-F]+}} 4 2 128 +int largeZ(); +#endif + #else // Vertex and Pixel only beyond here // expected-error-re@+1 {{attribute 'numthreads' is unsupported in '{{[A-Za-z]+}}' shaders, requires one of the following: compute, amplification, mesh}} [numthreads(1,1,1)] diff --git a/external/llvm-project/clang/test/SemaHLSL/vk.spec-constant.error.hlsl b/external/llvm-project/clang/test/SemaHLSL/vk.spec-constant.error.hlsl new file mode 100644 index 000000000000..24873d272a54 --- /dev/null +++ b/external/llvm-project/clang/test/SemaHLSL/vk.spec-constant.error.hlsl @@ -0,0 +1,37 @@ +// RUN: %clang_cc1 -finclude-default-header -triple spirv-pc-vulkan1.3-compute -verify %s +// RUN: %clang_cc1 -finclude-default-header -triple dxil-pc-shadermodel6.8-compute -verify %s + +#ifndef __spirv__ +// expected-warning@+2{{'constant_id' attribute ignored}} +#endif +[[vk::constant_id(0)]] +const bool sc0 = true; + +#ifdef __spirv__ +// expected-error@+2{{variable with 'vk::constant_id' attribute must be a const int/float/enum/bool and be initialized with a literal}} +[[vk::constant_id(1)]] +const bool sc1 = sc0; // error + +// expected-warning@+1{{'constant_id' attribute only applies to external global variables}} +[[vk::constant_id(2)]] +static const bool sc2 = false; // error + +// expected-error@+2{{variable with 'vk::constant_id' attribute must be a const int/float/enum/bool and be initialized with a literal}} +[[vk::constant_id(3)]] +const bool sc3; // error + +// expected-error@+2{{variable with 'vk::constant_id' attribute must be a const int/float/enum/bool and be initialized with a literal}} +[[vk::constant_id(4)]] +bool sc4 = false; // error + +// expected-error@+2{{variable with 'vk::constant_id' attribute must be a const int/float/enum/bool and be initialized with a literal}} +[[vk::constant_id(5)]] +const int2 sc5 = {0,0}; // error + +[numthreads(1,1,1)] +void main() { + // expected-warning@+1{{'constant_id' attribute only applies to external global variables}} + [[vk::constant_id(6)]] + const bool sc6 = false; // error +} +#endif diff --git a/external/llvm-project/clang/test/SemaObjCXX/arc-type-conversion.mm b/external/llvm-project/clang/test/SemaObjCXX/arc-type-conversion.mm index 64cfd02ec18c..0d281bf3e5c4 100644 --- a/external/llvm-project/clang/test/SemaObjCXX/arc-type-conversion.mm +++ b/external/llvm-project/clang/test/SemaObjCXX/arc-type-conversion.mm @@ -1,5 +1,8 @@ // RUN: %clang_cc1 -fobjc-runtime-has-weak -fsyntax-only -fobjc-arc -verify -fblocks %s +@class NSString; +typedef unsigned __INTPTR_TYPE__ uintptr_t; + void * cvt(id arg) // expected-note{{candidate function not viable: cannot convert argument of incomplete type 'void *' to '__strong id'}} { void* voidp_val; @@ -72,6 +75,24 @@ void test_reinterpret_cast(__strong id *sip, __weak id *wip, (void)reinterpret_cast<__weak id *>(cwip); // expected-error{{reinterpret_cast from '__weak id const *' to '__weak id *' casts away qualifiers}} (void)reinterpret_cast<__weak id *>(csip); // expected-error{{reinterpret_cast from '__strong id const *' to '__weak id *' casts away qualifiers}} (void)reinterpret_cast<__strong id *>(cwip); // expected-error{{reinterpret_cast from '__weak id const *' to '__strong id *' casts away qualifiers}} + + auto *ul = reinterpret_cast(sip); + (void)reinterpret_cast<__strong id *>(ul); + auto *wp = reinterpret_cast<__weak NSString *>(sip); + (void)reinterpret_cast<__strong id *>(wp); + (void)reinterpret_cast(csip); // expected-error {{reinterpret_cast from '__strong id const *' to 'unsigned long *' casts away qualifiers}} + (void)reinterpret_cast(csip); + const unsigned long *cul = nullptr; + (void)reinterpret_cast<__strong id *>(cul); // expected-error {{reinterpret_cast from 'const unsigned long *' to '__strong id *' casts away qualifiers}} + (void)reinterpret_cast(cul); + volatile __strong id *vsip = nullptr; + (void)reinterpret_cast(vsip); // expected-error {{reinterpret_cast from '__strong id volatile *' to 'unsigned long *' casts away qualifiers}} + (void)reinterpret_cast(vsip); + volatile unsigned long *vul = nullptr; + (void)reinterpret_cast<__strong id *>(vul); // expected-error {{reinterpret_cast from 'volatile unsigned long *' to '__strong id *' casts away qualifiers}} + (void)reinterpret_cast(vul); + auto uip = reinterpret_cast(sip); + (void)reinterpret_cast<__strong id *>(uip); // expected-error {{to '__strong id *' is disallowed with ARC}} } void test_cstyle_cast(__strong id *sip, __weak id *wip, @@ -194,8 +215,6 @@ void from_void(void *vp) { typedef void (^Block_strong)() __strong; typedef void (^Block_autoreleasing)() __autoreleasing; -@class NSString; - void ownership_transfer_in_cast(void *vp, Block *pblk) { __strong NSString **sip2 = static_cast(static_cast<__strong id *>(vp)); __strong NSString **&si2pref = static_cast(sip2); diff --git a/external/llvm-project/clang/test/SemaOpenCL/builtins-amdgcn-error-gfx1250-param.cl b/external/llvm-project/clang/test/SemaOpenCL/builtins-amdgcn-error-gfx1250-param.cl new file mode 100644 index 000000000000..b69fcb5f445b --- /dev/null +++ b/external/llvm-project/clang/test/SemaOpenCL/builtins-amdgcn-error-gfx1250-param.cl @@ -0,0 +1,6 @@ +// REQUIRES: amdgpu-registered-target +// RUN: %clang_cc1 -triple amdgcn-- -target-cpu gfx1250 -verify -S -o - %s + +void test_setprio_inc_wg(short a) { + __builtin_amdgcn_s_setprio_inc_wg(a); // expected-error {{'__builtin_amdgcn_s_setprio_inc_wg' must be a constant integer}} +} diff --git a/external/llvm-project/clang/test/SemaOpenCL/builtins-amdgcn-error-gfx1250.cl b/external/llvm-project/clang/test/SemaOpenCL/builtins-amdgcn-error-gfx1250.cl new file mode 100644 index 000000000000..c5440ed1a75a --- /dev/null +++ b/external/llvm-project/clang/test/SemaOpenCL/builtins-amdgcn-error-gfx1250.cl @@ -0,0 +1,6 @@ +// REQUIRES: amdgpu-registered-target +// RUN: %clang_cc1 -triple amdgcn-- -target-cpu gfx1200 -verify -S -o - %s + +void test() { + __builtin_amdgcn_s_setprio_inc_wg(1); // expected-error {{'__builtin_amdgcn_s_setprio_inc_wg' needs target feature setprio-inc-wg-inst}} +} diff --git a/external/llvm-project/clang/test/SemaTemplate/concepts-out-of-line-def.cpp b/external/llvm-project/clang/test/SemaTemplate/concepts-out-of-line-def.cpp index e5d00491d3fb..bf505dec0ca1 100644 --- a/external/llvm-project/clang/test/SemaTemplate/concepts-out-of-line-def.cpp +++ b/external/llvm-project/clang/test/SemaTemplate/concepts-out-of-line-def.cpp @@ -853,3 +853,18 @@ template requires C auto TplClass::buggy() -> void {} } + +namespace GH139476 { + +namespace moo { + template + constexpr bool baa = true; + + template requires baa + void caw(); +} + +template requires moo::baa +void moo::caw() {} + +} diff --git a/external/llvm-project/clang/test/SemaTemplate/instantiate-static-var.cpp b/external/llvm-project/clang/test/SemaTemplate/instantiate-static-var.cpp index 63d8366b617c..6602670af901 100644 --- a/external/llvm-project/clang/test/SemaTemplate/instantiate-static-var.cpp +++ b/external/llvm-project/clang/test/SemaTemplate/instantiate-static-var.cpp @@ -1,11 +1,13 @@ -// RUN: %clang_cc1 -fsyntax-only -verify %s -// RUN: %clang_cc1 -fsyntax-only -verify -std=c++98 %s -// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s +// RUN: %clang_cc1 -fsyntax-only -verify=expected,cxx11 %s +// RUN: %clang_cc1 -fsyntax-only -verify=expected,cxx98 -std=c++98 %s +// RUN: %clang_cc1 -fsyntax-only -verify=expected,cxx11 -std=c++11 %s template class X { public: - static const T value = 10 / Divisor; // expected-error{{in-class initializer for static data member is not a constant expression}} + static const T value = 10 / Divisor; // expected-error{{in-class initializer for static data member is not a constant expression}} \ + // cxx11-note {{division by zero}} \ + // cxx98-note {{subexpression not valid}} }; int array1[X::value == 5? 1 : -1]; diff --git a/external/llvm-project/clang/tools/clang-linker-wrapper/ClangLinkerWrapper.cpp b/external/llvm-project/clang/tools/clang-linker-wrapper/ClangLinkerWrapper.cpp index b8f45925d2a4..7a56431e3ff8 100644 --- a/external/llvm-project/clang/tools/clang-linker-wrapper/ClangLinkerWrapper.cpp +++ b/external/llvm-project/clang/tools/clang-linker-wrapper/ClangLinkerWrapper.cpp @@ -268,7 +268,8 @@ Expected findProgram(StringRef Name, ArrayRef Paths) { bool linkerSupportsLTO(const ArgList &Args) { llvm::Triple Triple(Args.getLastArgValue(OPT_triple_EQ)); return Triple.isNVPTX() || Triple.isAMDGPU() || - Args.getLastArgValue(OPT_linker_path_EQ).ends_with("lld"); + (!Triple.isGPU() && + Args.getLastArgValue(OPT_linker_path_EQ).ends_with("lld")); } /// Returns the hashed value for a constant string. diff --git a/external/llvm-project/clang/tools/clang-nvlink-wrapper/ClangNVLinkWrapper.cpp b/external/llvm-project/clang/tools/clang-nvlink-wrapper/ClangNVLinkWrapper.cpp index faf73a7c2f19..4b63971214f8 100644 --- a/external/llvm-project/clang/tools/clang-nvlink-wrapper/ClangNVLinkWrapper.cpp +++ b/external/llvm-project/clang/tools/clang-nvlink-wrapper/ClangNVLinkWrapper.cpp @@ -341,11 +341,16 @@ Expected> createLTO(const ArgList &Args) { Conf.CPU = Args.getLastArgValue(OPT_arch); Conf.Options = codegen::InitTargetOptionsFromCodeGenFlags(Triple); - Conf.RemarksFilename = RemarksFilename; - Conf.RemarksPasses = RemarksPasses; - Conf.RemarksWithHotness = RemarksWithHotness; + Conf.RemarksFilename = + Args.getLastArgValue(OPT_opt_remarks_filename, RemarksFilename); + Conf.RemarksPasses = + Args.getLastArgValue(OPT_opt_remarks_filter, RemarksPasses); + Conf.RemarksFormat = + Args.getLastArgValue(OPT_opt_remarks_format, RemarksFormat); + + Conf.RemarksWithHotness = + Args.hasArg(OPT_opt_remarks_with_hotness) || RemarksWithHotness; Conf.RemarksHotnessThreshold = RemarksHotnessThreshold; - Conf.RemarksFormat = RemarksFormat; Conf.MAttrs = llvm::codegen::getMAttrs(); std::optional CGOptLevelOrNone = diff --git a/external/llvm-project/clang/tools/clang-nvlink-wrapper/NVLinkOpts.td b/external/llvm-project/clang/tools/clang-nvlink-wrapper/NVLinkOpts.td index 6de1a25c14f8..7af35bf5989e 100644 --- a/external/llvm-project/clang/tools/clang-nvlink-wrapper/NVLinkOpts.td +++ b/external/llvm-project/clang/tools/clang-nvlink-wrapper/NVLinkOpts.td @@ -72,6 +72,16 @@ def : Joined<["--", "-"], "plugin-opt=emit-llvm">, Flags<[WrapperOnlyOption]>, Alias; def : Joined<["--", "-"], "plugin-opt=emit-asm">, Flags<[WrapperOnlyOption]>, Alias; + +def opt_remarks_filename : Joined<["--", "-"], "plugin-opt=opt-remarks-filename=">, + Flags<[WrapperOnlyOption]>, HelpText<"YAML output file for optimization remarks">; +def opt_remarks_format : Joined<["--", "-"], "plugin-opt=opt-remarks-format=">, + Flags<[WrapperOnlyOption]>, HelpText<"The format used for serializing remarks (default: YAML)">; +def opt_remarks_filter : Joined<["--", "-"], "plugin-opt=opt-remarks-filter=">, + Flags<[WrapperOnlyOption]>, HelpText<"Regex for the passes that need to be serialized to the output file">; +def opt_remarks_with_hotness : Flag<["--", "-"], "plugin-opt=opt-remarks-with-hotness">, + Flags<[WrapperOnlyOption]>, HelpText<"Include hotness information in the optimization remarks file">; + def plugin_opt : Joined<["--", "-"], "plugin-opt=">, Flags<[WrapperOnlyOption]>, HelpText<"Options passed to LLVM, not including the Clang invocation. Use " "'--plugin-opt=--help' for a list of options.">; diff --git a/external/llvm-project/clang/tools/clang-scan-deps/ClangScanDeps.cpp b/external/llvm-project/clang/tools/clang-scan-deps/ClangScanDeps.cpp index 921ba7aadd67..ce0770a51d65 100644 --- a/external/llvm-project/clang/tools/clang-scan-deps/ClangScanDeps.cpp +++ b/external/llvm-project/clang/tools/clang-scan-deps/ClangScanDeps.cpp @@ -85,6 +85,7 @@ static ScanningOutputFormat Format = ScanningOutputFormat::Make; static ScanningOptimizations OptimizeArgs; static std::string ModuleFilesDir; static bool EagerLoadModules; +static bool CacheNegativeStats = true; static unsigned NumThreads = 0; static std::string CompilationDB; static std::optional ModuleName; @@ -191,6 +192,8 @@ static void ParseArgs(int argc, char **argv) { EagerLoadModules = Args.hasArg(OPT_eager_load_pcm); + CacheNegativeStats = !Args.hasArg(OPT_no_cache_negative_stats); + if (const llvm::opt::Arg *A = Args.getLastArg(OPT_j)) { StringRef S{A->getValue()}; if (!llvm::to_integer(S, NumThreads, 0)) { @@ -1080,8 +1083,9 @@ int clang_scan_deps_main(int argc, char **argv, const llvm::ToolContext &) { }); }; - DependencyScanningService Service(ScanMode, Format, OptimizeArgs, - EagerLoadModules, /*TraceVFS=*/Verbose); + DependencyScanningService Service( + ScanMode, Format, OptimizeArgs, EagerLoadModules, /*TraceVFS=*/Verbose, + llvm::sys::toTimeT(std::chrono::system_clock::now()), CacheNegativeStats); llvm::Timer T; T.startTimer(); diff --git a/external/llvm-project/clang/tools/clang-scan-deps/Opts.td b/external/llvm-project/clang/tools/clang-scan-deps/Opts.td index 9cccbb3aaf0c..582ae60851e1 100644 --- a/external/llvm-project/clang/tools/clang-scan-deps/Opts.td +++ b/external/llvm-project/clang/tools/clang-scan-deps/Opts.td @@ -22,6 +22,7 @@ defm module_files_dir : Eq<"module-files-dir", def optimize_args_EQ : CommaJoined<["-", "--"], "optimize-args=">, HelpText<"Which command-line arguments of modules to optimize">; def eager_load_pcm : F<"eager-load-pcm", "Load PCM files eagerly (instead of lazily on import)">; +def no_cache_negative_stats : F<"no-cache-negative-stats", "Don't cache stat failures">; def j : Arg<"j", "Number of worker threads to use (default: use all concurrent threads)">; diff --git a/external/llvm-project/clang/unittests/Lex/LexerTest.cpp b/external/llvm-project/clang/unittests/Lex/LexerTest.cpp index 381755d4d1b6..33c8abbec35a 100644 --- a/external/llvm-project/clang/unittests/Lex/LexerTest.cpp +++ b/external/llvm-project/clang/unittests/Lex/LexerTest.cpp @@ -49,7 +49,8 @@ class LexerTest : public ::testing::Test { } std::unique_ptr CreatePP(StringRef Source, - TrivialModuleLoader &ModLoader) { + TrivialModuleLoader &ModLoader, + StringRef PreDefines = {}) { std::unique_ptr Buf = llvm::MemoryBuffer::getMemBuffer(Source); SourceMgr.setMainFileID(SourceMgr.createFileID(std::move(Buf))); @@ -61,6 +62,8 @@ class LexerTest : public ::testing::Test { PPOpts, Diags, LangOpts, SourceMgr, HeaderInfo, ModLoader, /*IILookup =*/nullptr, /*OwnsHeaderSearch =*/false); + if (!PreDefines.empty()) + PP->setPredefines(PreDefines.str()); PP->Initialize(*Target); PP->EnterMainSourceFile(); return PP; @@ -769,4 +772,46 @@ TEST(LexerPreambleTest, PreambleBounds) { } } +TEST_F(LexerTest, CheckFirstPPToken) { + { + TrivialModuleLoader ModLoader; + auto PP = CreatePP("// This is a comment\n" + "int a;", + ModLoader); + Token Tok; + PP->Lex(Tok); + EXPECT_TRUE(Tok.is(tok::kw_int)); + EXPECT_TRUE(PP->hasSeenMainFileFirstPPToken()); + EXPECT_TRUE(PP->getMainFileFirstPPToken().isFirstPPToken()); + EXPECT_TRUE(PP->getMainFileFirstPPToken().is(tok::kw_int)); + } + { + TrivialModuleLoader ModLoader; + auto PP = CreatePP("// This is a comment\n" + "#define FOO int\n" + "FOO a;", + ModLoader); + Token Tok; + PP->Lex(Tok); + EXPECT_TRUE(Tok.is(tok::kw_int)); + EXPECT_TRUE(PP->hasSeenMainFileFirstPPToken()); + EXPECT_TRUE(PP->getMainFileFirstPPToken().isFirstPPToken()); + EXPECT_TRUE(PP->getMainFileFirstPPToken().is(tok::hash)); + } + + { + TrivialModuleLoader ModLoader; + auto PP = CreatePP("// This is a comment\n" + "FOO a;", + ModLoader, "#define FOO int\n"); + Token Tok; + PP->Lex(Tok); + EXPECT_TRUE(Tok.is(tok::kw_int)); + EXPECT_TRUE(PP->hasSeenMainFileFirstPPToken()); + EXPECT_TRUE(PP->getMainFileFirstPPToken().isFirstPPToken()); + EXPECT_TRUE(PP->getMainFileFirstPPToken().is(tok::identifier)); + EXPECT_TRUE( + PP->getMainFileFirstPPToken().getIdentifierInfo()->isStr("FOO")); + } +} } // anonymous namespace diff --git a/external/llvm-project/clang/unittests/Parse/CMakeLists.txt b/external/llvm-project/clang/unittests/Parse/CMakeLists.txt index 6859efed294c..2ed43a83b878 100644 --- a/external/llvm-project/clang/unittests/Parse/CMakeLists.txt +++ b/external/llvm-project/clang/unittests/Parse/CMakeLists.txt @@ -11,5 +11,6 @@ add_clang_unittest(ParseTests LLVMTestingSupport clangTesting LLVM_COMPONENTS + FrontendHLSL Support ) diff --git a/external/llvm-project/clang/unittests/Tooling/DependencyScanning/DependencyScannerTest.cpp b/external/llvm-project/clang/unittests/Tooling/DependencyScanning/DependencyScannerTest.cpp index 683d9070b1dc..d194b2877ad8 100644 --- a/external/llvm-project/clang/unittests/Tooling/DependencyScanning/DependencyScannerTest.cpp +++ b/external/llvm-project/clang/unittests/Tooling/DependencyScanning/DependencyScannerTest.cpp @@ -384,3 +384,55 @@ TEST(DependencyScanner, ScanDepsWithDiagConsumer) { EXPECT_TRUE(DiagConsumer.Finished); } } + +TEST(DependencyScanner, NoNegativeCache) { + StringRef CWD = "/root"; + + auto VFS = new llvm::vfs::InMemoryFileSystem(); + VFS->setCurrentWorkingDirectory(CWD); + auto Sept = llvm::sys::path::get_separator(); + std::string HeaderPath = + std::string(llvm::formatv("{0}root{0}header.h", Sept)); + std::string Test0Path = + std::string(llvm::formatv("{0}root{0}test0.cpp", Sept)); + std::string Test1Path = + std::string(llvm::formatv("{0}root{0}test1.cpp", Sept)); + + VFS->addFile(Test0Path, 0, + llvm::MemoryBuffer::getMemBuffer( + "#if __has_include(\"header.h\")\n#endif")); + VFS->addFile(Test1Path, 0, + llvm::MemoryBuffer::getMemBuffer("#include \"header.h\"")); + + DependencyScanningService Service( + ScanningMode::DependencyDirectivesScan, ScanningOutputFormat::Make, + ScanningOptimizations::All, false, false, + llvm::sys::toTimeT(std::chrono::system_clock::now()), false); + DependencyScanningTool ScanTool(Service, VFS); + + std::vector CommandLine0 = {"clang", + "-target", + "x86_64-apple-macosx10.7", + "-c", + "test0.cpp", + "-o" + "test0.cpp.o"}; + std::vector CommandLine1 = {"clang", + "-target", + "x86_64-apple-macosx10.7", + "-c", + "test1.cpp", + "-o" + "test1.cpp.o"}; + + std::string Result; + ASSERT_THAT_ERROR( + ScanTool.getDependencyFile(CommandLine0, CWD).moveInto(Result), + llvm::Succeeded()); + + VFS->addFile(HeaderPath, 0, llvm::MemoryBuffer::getMemBuffer("")); + + ASSERT_THAT_ERROR( + ScanTool.getDependencyFile(CommandLine1, CWD).moveInto(Result), + llvm::Succeeded()); +} diff --git a/external/llvm-project/clang/unittests/Tooling/DependencyScanning/DependencyScanningFilesystemTest.cpp b/external/llvm-project/clang/unittests/Tooling/DependencyScanning/DependencyScanningFilesystemTest.cpp index 7420743c97a2..a68ea72d3816 100644 --- a/external/llvm-project/clang/unittests/Tooling/DependencyScanning/DependencyScanningFilesystemTest.cpp +++ b/external/llvm-project/clang/unittests/Tooling/DependencyScanning/DependencyScanningFilesystemTest.cpp @@ -7,6 +7,7 @@ //===----------------------------------------------------------------------===// #include "clang/Tooling/DependencyScanning/DependencyScanningFilesystem.h" +#include "clang/Tooling/DependencyScanning/DependencyScanningService.h" #include "llvm/ADT/SmallString.h" #include "llvm/Support/VirtualFileSystem.h" #include "gtest/gtest.h" @@ -19,9 +20,10 @@ TEST(DependencyScanningWorkerFilesystem, CacheStatusFailures) { auto InstrumentingFS = llvm::makeIntrusiveRefCnt(InMemoryFS); - DependencyScanningFilesystemSharedCache SharedCache; - DependencyScanningWorkerFilesystem DepFS(SharedCache, InstrumentingFS); - DependencyScanningWorkerFilesystem DepFS2(SharedCache, InstrumentingFS); + DependencyScanningService Service(ScanningMode::DependencyDirectivesScan, + ScanningOutputFormat::Make); + DependencyScanningWorkerFilesystem DepFS(Service, InstrumentingFS); + DependencyScanningWorkerFilesystem DepFS2(Service, InstrumentingFS); DepFS.status("/foo.c"); EXPECT_EQ(InstrumentingFS->NumStatusCalls, 1u); @@ -45,9 +47,10 @@ TEST(DependencyScanningFilesystem, CacheGetRealPath) { auto InstrumentingFS = llvm::makeIntrusiveRefCnt(InMemoryFS); - DependencyScanningFilesystemSharedCache SharedCache; - DependencyScanningWorkerFilesystem DepFS(SharedCache, InstrumentingFS); - DependencyScanningWorkerFilesystem DepFS2(SharedCache, InstrumentingFS); + DependencyScanningService Service(ScanningMode::DependencyDirectivesScan, + ScanningOutputFormat::Make); + DependencyScanningWorkerFilesystem DepFS(Service, InstrumentingFS); + DependencyScanningWorkerFilesystem DepFS2(Service, InstrumentingFS); { llvm::SmallString<128> Result; @@ -80,8 +83,9 @@ TEST(DependencyScanningFilesystem, RealPathAndStatusInvariants) { InMemoryFS->addFile("/foo.c", 0, llvm::MemoryBuffer::getMemBuffer("")); InMemoryFS->addFile("/bar.c", 0, llvm::MemoryBuffer::getMemBuffer("")); - DependencyScanningFilesystemSharedCache SharedCache; - DependencyScanningWorkerFilesystem DepFS(SharedCache, InMemoryFS); + DependencyScanningService Service(ScanningMode::DependencyDirectivesScan, + ScanningOutputFormat::Make); + DependencyScanningWorkerFilesystem DepFS(Service, InMemoryFS); // Success. { @@ -133,8 +137,9 @@ TEST(DependencyScanningFilesystem, CacheStatOnExists) { InMemoryFS->setCurrentWorkingDirectory("/"); InMemoryFS->addFile("/foo", 0, llvm::MemoryBuffer::getMemBuffer("")); InMemoryFS->addFile("/bar", 0, llvm::MemoryBuffer::getMemBuffer("")); - DependencyScanningFilesystemSharedCache SharedCache; - DependencyScanningWorkerFilesystem DepFS(SharedCache, InstrumentingFS); + DependencyScanningService Service(ScanningMode::DependencyDirectivesScan, + ScanningOutputFormat::Make); + DependencyScanningWorkerFilesystem DepFS(Service, InstrumentingFS); DepFS.status("/foo"); DepFS.status("/foo"); @@ -156,8 +161,9 @@ TEST(DependencyScanningFilesystem, CacheStatFailures) { auto InstrumentingFS = llvm::makeIntrusiveRefCnt(InMemoryFS); - DependencyScanningFilesystemSharedCache SharedCache; - DependencyScanningWorkerFilesystem DepFS(SharedCache, InstrumentingFS); + DependencyScanningService Service(ScanningMode::DependencyDirectivesScan, + ScanningOutputFormat::Make); + DependencyScanningWorkerFilesystem DepFS(Service, InstrumentingFS); DepFS.status("/dir"); DepFS.status("/dir"); @@ -183,8 +189,9 @@ TEST(DependencyScanningFilesystem, DiagnoseStaleStatFailures) { auto InMemoryFS = llvm::makeIntrusiveRefCnt(); InMemoryFS->setCurrentWorkingDirectory("/"); - DependencyScanningFilesystemSharedCache SharedCache; - DependencyScanningWorkerFilesystem DepFS(SharedCache, InMemoryFS); + DependencyScanningService Service(ScanningMode::DependencyDirectivesScan, + ScanningOutputFormat::Make); + DependencyScanningWorkerFilesystem DepFS(Service, InMemoryFS); bool Path1Exists = DepFS.exists("/path1.suffix"); EXPECT_EQ(Path1Exists, false); @@ -197,7 +204,7 @@ TEST(DependencyScanningFilesystem, DiagnoseStaleStatFailures) { EXPECT_EQ(Path1Exists, false); std::vector InvalidPaths = - SharedCache.getInvalidNegativeStatCachedPaths(*InMemoryFS); + Service.getSharedCache().getInvalidNegativeStatCachedPaths(*InMemoryFS); EXPECT_EQ(InvalidPaths.size(), 1u); ASSERT_STREQ("/path1.suffix", InvalidPaths[0].str().c_str()); diff --git a/external/llvm-project/clang/utils/TableGen/ClangAttrEmitter.cpp b/external/llvm-project/clang/utils/TableGen/ClangAttrEmitter.cpp index f892626a447e..dfeb6b1b1ec1 100644 --- a/external/llvm-project/clang/utils/TableGen/ClangAttrEmitter.cpp +++ b/external/llvm-project/clang/utils/TableGen/ClangAttrEmitter.cpp @@ -5482,14 +5482,12 @@ void EmitTestPragmaAttributeSupportedAttributes(const RecordKeeper &Records, } const Record *SubjectObj = I.second->getValueAsDef("Subjects"); OS << " ("; - bool PrintComma = false; + ListSeparator LS; for (const auto &Subject : enumerate(SubjectObj->getValueAsListOfDefs("Subjects"))) { if (!isSupportedPragmaClangAttributeSubject(*Subject.value())) continue; - if (PrintComma) - OS << ", "; - PrintComma = true; + OS << LS; PragmaClangAttributeSupport::RuleOrAggregateRuleSet &RuleSet = Support.SubjectsToRules.find(Subject.value())->getSecond(); if (RuleSet.isRule()) { diff --git a/external/llvm-project/clang/utils/TableGen/ClangDiagnosticsEmitter.cpp b/external/llvm-project/clang/utils/TableGen/ClangDiagnosticsEmitter.cpp index bfc60f485cd3..b28cb2c09ac5 100644 --- a/external/llvm-project/clang/utils/TableGen/ClangDiagnosticsEmitter.cpp +++ b/external/llvm-project/clang/utils/TableGen/ClangDiagnosticsEmitter.cpp @@ -2225,13 +2225,10 @@ void clang::EmitClangDiagDocs(const RecordKeeper &Records, raw_ostream &OS) { else OS << "Also controls "; - bool First = true; sort(GroupInfo.SubGroups); - for (StringRef Name : GroupInfo.SubGroups) { - if (!First) OS << ", "; - OS << "`" << (IsRemarkGroup ? "-R" : "-W") << Name << "`_"; - First = false; - } + ListSeparator LS; + for (StringRef Name : GroupInfo.SubGroups) + OS << LS << "`" << (IsRemarkGroup ? "-R" : "-W") << Name << "`_"; OS << ".\n\n"; } diff --git a/external/llvm-project/clang/www/cxx_status.html b/external/llvm-project/clang/www/cxx_status.html index dff57689e84b..a70e65e35d5e 100755 --- a/external/llvm-project/clang/www/cxx_status.html +++ b/external/llvm-project/clang/www/cxx_status.html @@ -292,6 +292,48 @@

C++2c implementation status

P1967R14 No + + + Reflection + P2996R13 + No + + + P3394R4 + No + + + P3293R3 + No + + + P3491R3 + No + + + P3096R12 + No + + + Attaching main to the global module + P3618R0 (DR) + No + + + Expansion Statements + P1306R5 + No + + + constexpr virtual inheritance + P3533R2 + No + + + Preprocessing is never undefined + P2843R3 + No + diff --git a/external/llvm-project/compiler-rt/lib/builtins/CMakeLists.txt b/external/llvm-project/compiler-rt/lib/builtins/CMakeLists.txt index 680b00097ca9..856d9f5c7899 100644 --- a/external/llvm-project/compiler-rt/lib/builtins/CMakeLists.txt +++ b/external/llvm-project/compiler-rt/lib/builtins/CMakeLists.txt @@ -883,7 +883,11 @@ else () if(COMPILER_RT_DISABLE_AARCH64_FMV) list(APPEND BUILTIN_DEFS DISABLE_AARCH64_FMV) elseif(COMPILER_RT_BAREMETAL_BUILD) - list(APPEND BUILTIN_DEFS ENABLE_BAREMETAL_AARCH64_FMV) + foreach (arch ${BUILTIN_SUPPORTED_ARCH}) + if("${arch}" MATCHES "arm64|aarch64") + list(APPEND BUILTIN_DEFS ENABLE_BAREMETAL_AARCH64_FMV) + endif() + endforeach () endif() append_list_if(COMPILER_RT_HAS_ASM_LSE HAS_ASM_LSE BUILTIN_DEFS) diff --git a/external/llvm-project/compiler-rt/lib/builtins/cpu_model/riscv.c b/external/llvm-project/compiler-rt/lib/builtins/cpu_model/riscv.c index 16d55fcfffe7..c02f6e9961ca 100644 --- a/external/llvm-project/compiler-rt/lib/builtins/cpu_model/riscv.c +++ b/external/llvm-project/compiler-rt/lib/builtins/cpu_model/riscv.c @@ -40,6 +40,8 @@ struct { #define I_BITMASK (1ULL << 8) #define M_GROUPID 0 #define M_BITMASK (1ULL << 12) +#define Q_GROUPID 0 +#define Q_BITMASK (1ULL << 16) #define V_GROUPID 0 #define V_BITMASK (1ULL << 21) #define ZACAS_GROUPID 0 diff --git a/external/llvm-project/compiler-rt/lib/fuzzer/tests/CMakeLists.txt b/external/llvm-project/compiler-rt/lib/fuzzer/tests/CMakeLists.txt index adfae3d63e64..c5885ccccd20 100644 --- a/external/llvm-project/compiler-rt/lib/fuzzer/tests/CMakeLists.txt +++ b/external/llvm-project/compiler-rt/lib/fuzzer/tests/CMakeLists.txt @@ -35,6 +35,27 @@ if(CMAKE_SYSTEM_NAME STREQUAL "Linux" AND COMPILER_RT_LIBCXXABI_PATH) list(APPEND LIBFUZZER_UNITTEST_CFLAGS -nostdinc++ -fno-exceptions) list(APPEND LIBFUZZER_UNITTEST_LINK_FLAGS -nostdlib++ -fno-exceptions) + + # When we use -nostdlib++, we remove the default C++ runtime which normally + # provides the stack unwinding symbols (like __aeabi_unwind_cpp_pr0). + # We must now manually find and link a suitable unwinder library. + set(FUZZER_UNWINDER_LIBS) + if(COMPILER_RT_USE_LLVM_UNWINDER) + # Prefer LLVM's own libunwind. + list(APPEND FUZZER_UNWINDER_LIBS ${COMPILER_RT_UNWINDER_LINK_LIBS}) + elseif(COMPILER_RT_HAS_GCC_S_LIB) + # As a fallback, use the shared libgcc_s library. + list(APPEND FUZZER_UNWINDER_LIBS -lgcc_s) + elseif(COMPILER_RT_HAS_GCC_LIB) + # As a final fallback, use the static libgcc library. + list(APPEND FUZZER_UNWINDER_LIBS -lgcc) + elseif(NOT COMPILER_RT_USE_BUILTINS_LIBRARY) + # If no unwinder is found and we aren't using the builtins library + message(FATAL_ERROR "Fuzzer tests require a suitable unwinder, but none was found.") + endif() + # Add the detected unwinder library to our link flags. + list(APPEND LIBFUZZER_UNITTEST_LINK_FLAGS ${FUZZER_UNWINDER_LIBS}) + endif() if ("-fvisibility=hidden" IN_LIST LIBFUZZER_CFLAGS) diff --git a/external/llvm-project/compiler-rt/lib/lsan/lsan_allocator.cpp b/external/llvm-project/compiler-rt/lib/lsan/lsan_allocator.cpp index 493bf5f9efc5..a436d9c07ac6 100644 --- a/external/llvm-project/compiler-rt/lib/lsan/lsan_allocator.cpp +++ b/external/llvm-project/compiler-rt/lib/lsan/lsan_allocator.cpp @@ -220,6 +220,10 @@ void lsan_free(void *p) { Deallocate(p); } +void lsan_free_sized(void *p, uptr) { Deallocate(p); } + +void lsan_free_aligned_sized(void *p, uptr, uptr) { Deallocate(p); } + void *lsan_realloc(void *p, uptr size, const StackTrace &stack) { return SetErrnoOnNull(Reallocate(stack, p, size, 1)); } diff --git a/external/llvm-project/compiler-rt/lib/lsan/lsan_allocator.h b/external/llvm-project/compiler-rt/lib/lsan/lsan_allocator.h index 5eed0cbdb309..2342f11fb5d0 100644 --- a/external/llvm-project/compiler-rt/lib/lsan/lsan_allocator.h +++ b/external/llvm-project/compiler-rt/lib/lsan/lsan_allocator.h @@ -127,6 +127,8 @@ void *lsan_aligned_alloc(uptr alignment, uptr size, const StackTrace &stack); void *lsan_memalign(uptr alignment, uptr size, const StackTrace &stack); void *lsan_malloc(uptr size, const StackTrace &stack); void lsan_free(void *p); +void lsan_free_sized(void *p, uptr size); +void lsan_free_aligned_sized(void *p, uptr alignment, uptr size); void *lsan_realloc(void *p, uptr size, const StackTrace &stack); void *lsan_reallocarray(void *p, uptr nmemb, uptr size, const StackTrace &stack); diff --git a/external/llvm-project/compiler-rt/lib/lsan/lsan_interceptors.cpp b/external/llvm-project/compiler-rt/lib/lsan/lsan_interceptors.cpp index a8252cddacf2..f9f83f6c0cc4 100644 --- a/external/llvm-project/compiler-rt/lib/lsan/lsan_interceptors.cpp +++ b/external/llvm-project/compiler-rt/lib/lsan/lsan_interceptors.cpp @@ -84,6 +84,35 @@ INTERCEPTOR(void, free, void *p) { lsan_free(p); } +# if SANITIZER_INTERCEPT_FREE_SIZED +INTERCEPTOR(void, free_sized, void *p, uptr size) { + if (UNLIKELY(!p)) + return; + if (DlsymAlloc::PointerIsMine(p)) + return DlsymAlloc::Free(p); + ENSURE_LSAN_INITED; + lsan_free_sized(p, size); +} +# define LSAN_MAYBE_INTERCEPT_FREE_SIZED INTERCEPT_FUNCTION(free_sized) +# else +# define LSAN_MAYBE_INTERCEPT_FREE_SIZED +# endif + +# if SANITIZER_INTERCEPT_FREE_ALIGNED_SIZED +INTERCEPTOR(void, free_aligned_sized, void *p, uptr alignment, uptr size) { + if (UNLIKELY(!p)) + return; + if (DlsymAlloc::PointerIsMine(p)) + return DlsymAlloc::Free(p); + ENSURE_LSAN_INITED; + lsan_free_aligned_sized(p, alignment, size); +} +# define LSAN_MAYBE_INTERCEPT_FREE_ALIGNED_SIZED \ + INTERCEPT_FUNCTION(free_aligned_sized) +# else +# define LSAN_MAYBE_INTERCEPT_FREE_ALIGNED_SIZED +# endif + INTERCEPTOR(void*, calloc, uptr nmemb, uptr size) { if (DlsymAlloc::Use()) return DlsymAlloc::Callocate(nmemb, size); @@ -117,6 +146,9 @@ INTERCEPTOR(void*, valloc, uptr size) { GET_STACK_TRACE_MALLOC; return lsan_valloc(size, stack); } +#else +# define LSAN_MAYBE_INTERCEPT_FREE_SIZED +# define LSAN_MAYBE_INTERCEPT_FREE_ALIGNED_SIZED #endif // !SANITIZER_APPLE #if SANITIZER_INTERCEPT_MEMALIGN @@ -547,6 +579,8 @@ void InitializeInterceptors() { INTERCEPT_FUNCTION(malloc); INTERCEPT_FUNCTION(free); + LSAN_MAYBE_INTERCEPT_FREE_SIZED; + LSAN_MAYBE_INTERCEPT_FREE_ALIGNED_SIZED; LSAN_MAYBE_INTERCEPT_CFREE; INTERCEPT_FUNCTION(calloc); INTERCEPT_FUNCTION(realloc); diff --git a/external/llvm-project/compiler-rt/lib/lsan/lsan_malloc_mac.cpp b/external/llvm-project/compiler-rt/lib/lsan/lsan_malloc_mac.cpp index 525c30272ccc..8a16c053da23 100644 --- a/external/llvm-project/compiler-rt/lib/lsan/lsan_malloc_mac.cpp +++ b/external/llvm-project/compiler-rt/lib/lsan/lsan_malloc_mac.cpp @@ -44,16 +44,19 @@ using namespace __lsan; void *p = lsan_valloc(size, stack) #define COMMON_MALLOC_FREE(ptr) \ lsan_free(ptr) -#define COMMON_MALLOC_SIZE(ptr) \ - uptr size = lsan_mz_size(ptr) -#define COMMON_MALLOC_FILL_STATS(zone, stats) -#define COMMON_MALLOC_REPORT_UNKNOWN_REALLOC(ptr, zone_ptr, zone_name) \ - (void)zone_name; \ - Report("mz_realloc(%p) -- attempting to realloc unallocated memory.\n", ptr); -#define COMMON_MALLOC_NAMESPACE __lsan -#define COMMON_MALLOC_HAS_ZONE_ENUMERATOR 0 -#define COMMON_MALLOC_HAS_EXTRA_INTROSPECTION_INIT 0 +# define COMMON_MALLOC_FREE_SIZED(ptr, size) lsan_free_sized(ptr, size) +# define COMMON_MALLOC_FREE_ALIGNED_SIZED(ptr, alignment, size) \ + lsan_free_aligned_sized(ptr, alignment, size) +# define COMMON_MALLOC_SIZE(ptr) uptr size = lsan_mz_size(ptr) +# define COMMON_MALLOC_FILL_STATS(zone, stats) +# define COMMON_MALLOC_REPORT_UNKNOWN_REALLOC(ptr, zone_ptr, zone_name) \ + (void)zone_name; \ + Report("mz_realloc(%p) -- attempting to realloc unallocated memory.\n", \ + ptr); +# define COMMON_MALLOC_NAMESPACE __lsan +# define COMMON_MALLOC_HAS_ZONE_ENUMERATOR 0 +# define COMMON_MALLOC_HAS_EXTRA_INTROSPECTION_INIT 0 -#include "sanitizer_common/sanitizer_malloc_mac.inc" +# include "sanitizer_common/sanitizer_malloc_mac.inc" #endif // SANITIZER_APPLE diff --git a/external/llvm-project/compiler-rt/lib/msan/msan_interceptors.cpp b/external/llvm-project/compiler-rt/lib/msan/msan_interceptors.cpp index 76255cdb742a..bc28434d1d49 100644 --- a/external/llvm-project/compiler-rt/lib/msan/msan_interceptors.cpp +++ b/external/llvm-project/compiler-rt/lib/msan/msan_interceptors.cpp @@ -34,6 +34,7 @@ #include "sanitizer_common/sanitizer_glibc_version.h" #include "sanitizer_common/sanitizer_libc.h" #include "sanitizer_common/sanitizer_linux.h" +#include "sanitizer_common/sanitizer_platform_interceptors.h" #include "sanitizer_common/sanitizer_platform_limits_netbsd.h" #include "sanitizer_common/sanitizer_platform_limits_posix.h" #include "sanitizer_common/sanitizer_stackdepot.h" @@ -215,6 +216,35 @@ INTERCEPTOR(void, free, void *ptr) { MsanDeallocate(&stack, ptr); } +#if SANITIZER_INTERCEPT_FREE_SIZED +INTERCEPTOR(void, free_sized, void *ptr, uptr size) { + if (UNLIKELY(!ptr)) + return; + if (DlsymAlloc::PointerIsMine(ptr)) + return DlsymAlloc::Free(ptr); + GET_MALLOC_STACK_TRACE; + MsanDeallocate(&stack, ptr); +} +# define MSAN_MAYBE_INTERCEPT_FREE_SIZED INTERCEPT_FUNCTION(free_sized) +#else +# define MSAN_MAYBE_INTERCEPT_FREE_SIZED +#endif + +#if SANITIZER_INTERCEPT_FREE_ALIGNED_SIZED +INTERCEPTOR(void, free_aligned_sized, void *ptr, uptr alignment, uptr size) { + if (UNLIKELY(!ptr)) + return; + if (DlsymAlloc::PointerIsMine(ptr)) + return DlsymAlloc::Free(ptr); + GET_MALLOC_STACK_TRACE; + MsanDeallocate(&stack, ptr); +} +# define MSAN_MAYBE_INTERCEPT_FREE_ALIGNED_SIZED \ + INTERCEPT_FUNCTION(free_aligned_sized) +#else +# define MSAN_MAYBE_INTERCEPT_FREE_ALIGNED_SIZED +#endif + #if !SANITIZER_FREEBSD && !SANITIZER_NETBSD INTERCEPTOR(void, cfree, void *ptr) { if (UNLIKELY(!ptr)) @@ -1127,7 +1157,7 @@ static void SignalAction(int signo, void *si, void *uc) { SignalHandlerScope signal_handler_scope; ScopedThreadLocalStateBackup stlsb; UnpoisonParam(3); - __msan_unpoison(si, sizeof(__sanitizer_sigaction)); + __msan_unpoison(si, sizeof(__sanitizer_siginfo)); __msan_unpoison(uc, ucontext_t_sz(uc)); typedef void (*sigaction_cb)(int, void *, void *); @@ -1775,6 +1805,8 @@ void InitializeInterceptors() { INTERCEPT_FUNCTION(realloc); INTERCEPT_FUNCTION(reallocarray); INTERCEPT_FUNCTION(free); + MSAN_MAYBE_INTERCEPT_FREE_SIZED; + MSAN_MAYBE_INTERCEPT_FREE_ALIGNED_SIZED; MSAN_MAYBE_INTERCEPT_CFREE; MSAN_MAYBE_INTERCEPT_MALLOC_USABLE_SIZE; MSAN_MAYBE_INTERCEPT_MALLINFO; diff --git a/external/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_common.h b/external/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_common.h index a90cf7c05e39..93c197f5efaa 100644 --- a/external/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_common.h +++ b/external/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_common.h @@ -166,7 +166,7 @@ uptr FindAvailableMemoryRange(uptr size, uptr alignment, uptr left_padding, // Used to check if we can map shadow memory to a fixed location. bool MemoryRangeIsAvailable(uptr range_start, uptr range_end); -// Releases memory pages entirely within the [beg, end] address range. Noop if +// Releases memory pages entirely within the [beg, end) address range. Noop if // the provided range does not contain at least one entire page. void ReleaseMemoryPagesToOS(uptr beg, uptr end); void IncreaseTotalMmap(uptr size); diff --git a/external/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_linux.h b/external/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_linux.h index 6959f785990f..05b7d2e28a61 100644 --- a/external/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_linux.h +++ b/external/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_linux.h @@ -130,7 +130,7 @@ bool LibraryNameIs(const char *full_name, const char *base_name); // Call cb for each region mapped by map. void ForEachMappedRegion(link_map *map, void (*cb)(const void *, uptr)); -// Releases memory pages entirely within the [beg, end] address range. +// Releases memory pages entirely within the [beg, end) address range. // The pages no longer count toward RSS; reads are guaranteed to return 0. // Requires (but does not verify!) that pages are MAP_PRIVATE. inline void ReleaseMemoryPagesToOSAndZeroFill(uptr beg, uptr end) { diff --git a/external/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_malloc_mac.inc b/external/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_malloc_mac.inc index 6343eb284afb..be27584f2053 100644 --- a/external/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_malloc_mac.inc +++ b/external/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_malloc_mac.inc @@ -144,6 +144,22 @@ INTERCEPTOR(void, free, void *ptr) { COMMON_MALLOC_FREE(ptr); } +#if SANITIZER_INTERCEPT_FREE_SIZED && defined(COMMON_MALLOC_FREE_SIZED) +INTERCEPTOR(void, free_sized, void *ptr, size_t size) { + COMMON_MALLOC_ENTER(); + COMMON_MALLOC_FREE_SIZED(ptr, size); +} +#endif + +#if SANITIZER_INTERCEPT_FREE_ALIGNED_SIZED && \ + defined(COMMON_MALLOC_FREE_ALIGNED_SIZED) +INTERCEPTOR(void, free_aligned_sized, void *ptr, size_t alignment, + size_t size) { + COMMON_MALLOC_ENTER(); + COMMON_MALLOC_FREE_ALIGNED_SIZED(ptr, alignment, size); +} +#endif + INTERCEPTOR(void *, realloc, void *ptr, size_t size) { COMMON_MALLOC_ENTER(); COMMON_MALLOC_REALLOC(ptr, size); diff --git a/external/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_platform.h b/external/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_platform.h index 9f5f41cd8551..4c8d9a9b86be 100644 --- a/external/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_platform.h +++ b/external/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_platform.h @@ -14,7 +14,8 @@ #if !defined(__linux__) && !defined(__FreeBSD__) && !defined(__NetBSD__) && \ !defined(__APPLE__) && !defined(_WIN32) && !defined(__Fuchsia__) && \ - !(defined(__sun__) && defined(__svr4__)) && !defined(__HAIKU__) + !(defined(__sun__) && defined(__svr4__)) && !defined(__HAIKU__) && \ + !defined(__wasi__) # error "This operating system is not supported" #endif @@ -61,6 +62,12 @@ # define SANITIZER_HAIKU 0 #endif +#if defined(__wasi__) +# define SANITIZER_WASI 1 +#else +# define SANITIZER_WASI 0 +#endif + // - SANITIZER_APPLE: all Apple code // - TARGET_OS_OSX: macOS // - SANITIZER_IOS: devices (iOS and iOS-like) diff --git a/external/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_platform_interceptors.h b/external/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_platform_interceptors.h index ccc808b60ca7..29987decdff4 100644 --- a/external/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_platform_interceptors.h +++ b/external/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_platform_interceptors.h @@ -663,6 +663,17 @@ SANITIZER_WEAK_IMPORT void *aligned_alloc(__sanitizer::usize __alignment, #define SANITIZER_INTERCEPT_GETSERVBYNAME_R SI_GLIBC #define SANITIZER_INTERCEPT_GETSERVBYPORT_R SI_GLIBC +// Until free_sized and free_aligned_sized are more generally available, +// we can only unconditionally intercept on ELF-based platforms where it +// is okay to have undefined weak symbols. +#ifdef __ELF__ +# define SANITIZER_INTERCEPT_FREE_SIZED 1 +# define SANITIZER_INTERCEPT_FREE_ALIGNED_SIZED 1 +#else +# define SANITIZER_INTERCEPT_FREE_SIZED 0 +# define SANITIZER_INTERCEPT_FREE_ALIGNED_SIZED 0 +#endif + // This macro gives a way for downstream users to override the above // interceptor macros irrespective of the platform they are on. They have // to do two things: diff --git a/external/llvm-project/compiler-rt/lib/scudo/standalone/chunk.h b/external/llvm-project/compiler-rt/lib/scudo/standalone/chunk.h index a1b8e723d4cb..9da2dc57e71a 100644 --- a/external/llvm-project/compiler-rt/lib/scudo/standalone/chunk.h +++ b/external/llvm-project/compiler-rt/lib/scudo/standalone/chunk.h @@ -125,7 +125,7 @@ inline void loadHeader(u32 Cookie, const void *Ptr, *NewUnpackedHeader = bit_cast(NewPackedHeader); if (UNLIKELY(NewUnpackedHeader->Checksum != computeHeaderChecksum(Cookie, Ptr, NewUnpackedHeader))) - reportHeaderCorruption(NewUnpackedHeader, const_cast(Ptr)); + reportHeaderCorruption(NewUnpackedHeader, Ptr); } inline bool isValid(u32 Cookie, const void *Ptr, diff --git a/external/llvm-project/compiler-rt/lib/scudo/standalone/combined.h b/external/llvm-project/compiler-rt/lib/scudo/standalone/combined.h index 43655642843c..87acdec2a3ba 100644 --- a/external/llvm-project/compiler-rt/lib/scudo/standalone/combined.h +++ b/external/llvm-project/compiler-rt/lib/scudo/standalone/combined.h @@ -775,7 +775,7 @@ class Allocator { // Getting the alloc size of a chunk only makes sense if it's allocated. if (UNLIKELY(Header.State != Chunk::State::Allocated)) - reportInvalidChunkState(AllocatorAction::Sizing, const_cast(Ptr)); + reportInvalidChunkState(AllocatorAction::Sizing, Ptr); return getSize(Ptr, &Header); } diff --git a/external/llvm-project/compiler-rt/lib/scudo/standalone/report.cpp b/external/llvm-project/compiler-rt/lib/scudo/standalone/report.cpp index 14a4066d3720..b97a74b078c2 100644 --- a/external/llvm-project/compiler-rt/lib/scudo/standalone/report.cpp +++ b/external/llvm-project/compiler-rt/lib/scudo/standalone/report.cpp @@ -66,17 +66,16 @@ void NORETURN reportInvalidFlag(const char *FlagType, const char *Value) { // The checksum of a chunk header is invalid. This could be caused by an // {over,under}write of the header, a pointer that is not an actual chunk. -void NORETURN reportHeaderCorruption(void *Header, void *Ptr) { +void NORETURN reportHeaderCorruption(void *Header, const void *Ptr) { ScopedErrorReport Report; Report.append("corrupted chunk header at address %p", Ptr); if (*static_cast(Header) == 0U) { // Header all zero, which could indicate that this might be a pointer that // has been double freed but the memory has been released to the kernel. Report.append(": chunk header is zero and might indicate memory corruption " - "or a double free\n", - Ptr); + "or a double free\n"); } else { - Report.append(": most likely due to memory corruption\n", Ptr); + Report.append(": most likely due to memory corruption\n"); } } @@ -131,13 +130,13 @@ static const char *stringifyAction(AllocatorAction Action) { // The chunk is not in a state congruent with the operation we want to perform. // This is usually the case with a double-free, a realloc of a freed pointer. -void NORETURN reportInvalidChunkState(AllocatorAction Action, void *Ptr) { +void NORETURN reportInvalidChunkState(AllocatorAction Action, const void *Ptr) { ScopedErrorReport Report; Report.append("invalid chunk state when %s address %p\n", stringifyAction(Action), Ptr); } -void NORETURN reportMisalignedPointer(AllocatorAction Action, void *Ptr) { +void NORETURN reportMisalignedPointer(AllocatorAction Action, const void *Ptr) { ScopedErrorReport Report; Report.append("misaligned pointer when %s address %p\n", stringifyAction(Action), Ptr); @@ -145,7 +144,7 @@ void NORETURN reportMisalignedPointer(AllocatorAction Action, void *Ptr) { // The deallocation function used is at odds with the one used to allocate the // chunk (eg: new[]/delete or malloc/delete, and so on). -void NORETURN reportDeallocTypeMismatch(AllocatorAction Action, void *Ptr, +void NORETURN reportDeallocTypeMismatch(AllocatorAction Action, const void *Ptr, u8 TypeA, u8 TypeB) { ScopedErrorReport Report; Report.append("allocation type mismatch when %s address %p (%d vs %d)\n", @@ -154,7 +153,7 @@ void NORETURN reportDeallocTypeMismatch(AllocatorAction Action, void *Ptr, // The size specified to the delete operator does not match the one that was // passed to new when allocating the chunk. -void NORETURN reportDeleteSizeMismatch(void *Ptr, uptr Size, +void NORETURN reportDeleteSizeMismatch(const void *Ptr, uptr Size, uptr ExpectedSize) { ScopedErrorReport Report; Report.append( diff --git a/external/llvm-project/compiler-rt/lib/scudo/standalone/report.h b/external/llvm-project/compiler-rt/lib/scudo/standalone/report.h index c0214b51560e..c397dd3fc9c6 100644 --- a/external/llvm-project/compiler-rt/lib/scudo/standalone/report.h +++ b/external/llvm-project/compiler-rt/lib/scudo/standalone/report.h @@ -24,7 +24,7 @@ void NORETURN reportRawError(const char *Message); void NORETURN reportInvalidFlag(const char *FlagType, const char *Value); // Chunk header related errors. -void NORETURN reportHeaderCorruption(void *Header, void *Ptr); +void NORETURN reportHeaderCorruption(void *Header, const void *Ptr); // Sanity checks related error. void NORETURN reportSanityCheckError(const char *Field); @@ -41,11 +41,12 @@ enum class AllocatorAction : u8 { Reallocating, Sizing, }; -void NORETURN reportInvalidChunkState(AllocatorAction Action, void *Ptr); -void NORETURN reportMisalignedPointer(AllocatorAction Action, void *Ptr); -void NORETURN reportDeallocTypeMismatch(AllocatorAction Action, void *Ptr, +void NORETURN reportInvalidChunkState(AllocatorAction Action, const void *Ptr); +void NORETURN reportMisalignedPointer(AllocatorAction Action, const void *Ptr); +void NORETURN reportDeallocTypeMismatch(AllocatorAction Action, const void *Ptr, u8 TypeA, u8 TypeB); -void NORETURN reportDeleteSizeMismatch(void *Ptr, uptr Size, uptr ExpectedSize); +void NORETURN reportDeleteSizeMismatch(const void *Ptr, uptr Size, + uptr ExpectedSize); // C wrappers errors. void NORETURN reportAlignmentNotPowerOfTwo(uptr Alignment); diff --git a/external/llvm-project/compiler-rt/lib/tsan/rtl/tsan_platform.h b/external/llvm-project/compiler-rt/lib/tsan/rtl/tsan_platform.h index 354f6da6a64a..ada594bc11fc 100644 --- a/external/llvm-project/compiler-rt/lib/tsan/rtl/tsan_platform.h +++ b/external/llvm-project/compiler-rt/lib/tsan/rtl/tsan_platform.h @@ -931,7 +931,7 @@ bool IsAppMem(uptr mem) { return SelectMapping(mem); } struct IsShadowMemImpl { template static bool Apply(uptr mem) { - return mem >= Mapping::kShadowBeg && mem <= Mapping::kShadowEnd; + return mem >= Mapping::kShadowBeg && mem < Mapping::kShadowEnd; } }; @@ -943,7 +943,7 @@ bool IsShadowMem(RawShadow *p) { struct IsMetaMemImpl { template static bool Apply(uptr mem) { - return mem >= Mapping::kMetaShadowBeg && mem <= Mapping::kMetaShadowEnd; + return mem >= Mapping::kMetaShadowBeg && mem < Mapping::kMetaShadowEnd; } }; diff --git a/external/llvm-project/compiler-rt/lib/tsan/rtl/tsan_rtl.cpp b/external/llvm-project/compiler-rt/lib/tsan/rtl/tsan_rtl.cpp index d8be21284b93..981f37b89e78 100644 --- a/external/llvm-project/compiler-rt/lib/tsan/rtl/tsan_rtl.cpp +++ b/external/llvm-project/compiler-rt/lib/tsan/rtl/tsan_rtl.cpp @@ -624,6 +624,7 @@ void MapShadow(uptr addr, uptr size) { static uptr mapped_meta_end = 0; uptr meta_begin = (uptr)MemToMeta(addr); uptr meta_end = (uptr)MemToMeta(addr + size); + // Windows wants 64K alignment. meta_begin = RoundDownTo(meta_begin, 64 << 10); meta_end = RoundUpTo(meta_end, 64 << 10); if (!data_mapped) { @@ -634,9 +635,6 @@ void MapShadow(uptr addr, uptr size) { Die(); } else { // Mapping continuous heap. - // Windows wants 64K alignment. - meta_begin = RoundDownTo(meta_begin, 64 << 10); - meta_end = RoundUpTo(meta_end, 64 << 10); CHECK_GT(meta_end, mapped_meta_end); if (meta_begin < mapped_meta_end) meta_begin = mapped_meta_end; diff --git a/external/llvm-project/compiler-rt/lib/tsan/rtl/tsan_rtl_access.cpp b/external/llvm-project/compiler-rt/lib/tsan/rtl/tsan_rtl_access.cpp index cf07686d968d..bd8deefefa1b 100644 --- a/external/llvm-project/compiler-rt/lib/tsan/rtl/tsan_rtl_access.cpp +++ b/external/llvm-project/compiler-rt/lib/tsan/rtl/tsan_rtl_access.cpp @@ -523,9 +523,9 @@ ALWAYS_INLINE USED void UnalignedMemoryAccess(ThreadState* thr, uptr pc, } void ShadowSet(RawShadow* p, RawShadow* end, RawShadow v) { - DCHECK_LE(p, end); + DCHECK_LT(p, end); DCHECK(IsShadowMem(p)); - DCHECK(IsShadowMem(end)); + DCHECK(IsShadowMem(end - 1)); UNUSED const uptr kAlign = kShadowCnt * kShadowSize; DCHECK_EQ(reinterpret_cast(p) % kAlign, 0); DCHECK_EQ(reinterpret_cast(end) % kAlign, 0); @@ -569,6 +569,7 @@ static void MemoryRangeSet(uptr addr, uptr size, RawShadow val) { RawShadow* mid1 = Min(end, reinterpret_cast(RoundUp( reinterpret_cast(begin) + kPageSize / 2, kPageSize))); + // begin must < mid1 ShadowSet(begin, mid1, val); // Reset middle part. RawShadow* mid2 = RoundDown(end, kPageSize); @@ -577,7 +578,10 @@ static void MemoryRangeSet(uptr addr, uptr size, RawShadow val) { Die(); } // Set the ending. - ShadowSet(mid2, end, val); + if (mid2 < end) + ShadowSet(mid2, end, val); + else + DCHECK_EQ(mid2, end); } void MemoryResetRange(ThreadState* thr, uptr pc, uptr addr, uptr size) { @@ -669,7 +673,7 @@ void MemoryAccessRangeT(ThreadState* thr, uptr pc, uptr addr, uptr size) { RawShadow* shadow_mem = MemToShadow(addr); DPrintf2("#%d: MemoryAccessRange: @%p %p size=%d is_read=%d\n", thr->tid, (void*)pc, (void*)addr, (int)size, is_read); - + DCHECK_NE(size, 0); #if SANITIZER_DEBUG if (!IsAppMem(addr)) { Printf("Access to non app mem start: %p\n", (void*)addr); diff --git a/external/llvm-project/compiler-rt/lib/tsan/rtl/tsan_sync.cpp b/external/llvm-project/compiler-rt/lib/tsan/rtl/tsan_sync.cpp index 09d41780d188..97335bc8ecf7 100644 --- a/external/llvm-project/compiler-rt/lib/tsan/rtl/tsan_sync.cpp +++ b/external/llvm-project/compiler-rt/lib/tsan/rtl/tsan_sync.cpp @@ -247,11 +247,14 @@ void MetaMap::MoveMemory(uptr src, uptr dst, uptr sz) { CHECK_NE(src, dst); CHECK_NE(sz, 0); uptr diff = dst - src; - u32 *src_meta = MemToMeta(src); - u32 *dst_meta = MemToMeta(dst); - u32 *src_meta_end = MemToMeta(src + sz); - uptr inc = 1; - if (dst > src) { + u32 *src_meta, *dst_meta, *src_meta_end; + uptr inc; + if (dst < src) { + src_meta = MemToMeta(src); + dst_meta = MemToMeta(dst); + src_meta_end = MemToMeta(src + sz); + inc = 1; + } else { src_meta = MemToMeta(src + sz) - 1; dst_meta = MemToMeta(dst + sz) - 1; src_meta_end = MemToMeta(src) - 1; diff --git a/external/llvm-project/compiler-rt/test/fuzzer/uncaught-exception.test b/external/llvm-project/compiler-rt/test/fuzzer/uncaught-exception.test index b055c88f6d90..d1b98cfb7c74 100644 --- a/external/llvm-project/compiler-rt/test/fuzzer/uncaught-exception.test +++ b/external/llvm-project/compiler-rt/test/fuzzer/uncaught-exception.test @@ -4,7 +4,10 @@ REQUIRES: windows RUN: %cpp_compiler %S/UncaughtException.cpp -o %t-UncaughtException -RUN: not %run %t-UncaughtException 2>&1 | FileCheck %s +# Clang will fail the test with 'deadly signal', but other compilers may fail with different error messages. +# For example, msvc fails with 'uncaught C++ exception'. So the error we check depends on the compiler target. +RUN: not %run %t-UncaughtException 2>&1 | FileCheck %s --check-prefixes=CHECK-CRASH,%if target={{.*-windows-msvc.*}} %{CHECK-MSVC%} %else %{CHECK-ERROR%} -CHECK: ERROR: libFuzzer: deadly signal -CHECK: Test unit written to ./crash +CHECK-ERROR: ERROR: libFuzzer: deadly signal +CHECK-MSVC: ERROR: libFuzzer: uncaught C++ exception +CHECK-CRASH: Test unit written to ./crash diff --git a/external/llvm-project/compiler-rt/test/profile/Posix/gcov-file-change-line.cpp b/external/llvm-project/compiler-rt/test/profile/Posix/gcov-file-change-line.cpp new file mode 100644 index 000000000000..a750befb47e5 --- /dev/null +++ b/external/llvm-project/compiler-rt/test/profile/Posix/gcov-file-change-line.cpp @@ -0,0 +1,15 @@ +// RUN: rm -rf %t && split-file %s %t && cd %t +// RUN: %clangxx --coverage main.cpp -o t +// RUN: %run ./t +// RUN: llvm-cov gcov -t t-main. | FileCheck %s + +//--- main.cpp +#include + +int main(int argc, char *argv[]) { // CHECK: 2: [[#]]:int main + puts(""); // CHECK-NEXT: 2: [[#]]: +#line 3 + puts(""); // line 3 + return 0; // line 4 +} +// CHECK-NOT: {{^ +[0-9]+:}} diff --git a/external/llvm-project/compiler-rt/test/profile/Posix/gcov-file-change.cpp b/external/llvm-project/compiler-rt/test/profile/Posix/gcov-file-change.cpp index 9d3bc79591f2..0cef1c3512f8 100644 --- a/external/llvm-project/compiler-rt/test/profile/Posix/gcov-file-change.cpp +++ b/external/llvm-project/compiler-rt/test/profile/Posix/gcov-file-change.cpp @@ -16,8 +16,8 @@ inline auto *const inl_var_main = // CHECK: 1: [[#]]:inline auto void foo(int x) { // CHECK-NEXT: 1: [[#]]: if (x) { // CHECK-NEXT: 1: [[#]]: #include "a.inc" - } -} + } // CHECK: 1: [[#]]: +} // CHECK-NEXT: 1: [[#]]: // CHECK-NOT: {{^ +[0-9]+:}} int main(int argc, char *argv[]) { // CHECK: 1: [[#]]:int main @@ -32,10 +32,8 @@ int main(int argc, char *argv[]) { // CHECK: 1: [[#]]:int main //--- a.h /// Apple targets doesn't enable -mconstructor-aliases by default and the count may be 4. struct A { A() { } }; // CHECK: {{[24]}}: [[#]]:struct A -inline auto *const inl_var_a = - new A; -/// TODO a.inc:1 should have line execution. -// CHECK-NOT: {{^ +[0-9]+:}} +inline auto *const inl_var_a = // CHECK-NEXT: 1: [[#]]: + new A; // CHECK-NEXT: 1: [[#]]: //--- a.inc -puts(""); +puts(""); // CHECK: 1: [[#]]:puts diff --git a/external/llvm-project/compiler-rt/test/sanitizer_common/TestCases/Linux/free_aligned_sized.c b/external/llvm-project/compiler-rt/test/sanitizer_common/TestCases/Linux/free_aligned_sized.c new file mode 100644 index 000000000000..7710c6236819 --- /dev/null +++ b/external/llvm-project/compiler-rt/test/sanitizer_common/TestCases/Linux/free_aligned_sized.c @@ -0,0 +1,13 @@ +// RUN: %clang -std=c23 -O0 %s -o %t && %run %t +// UNSUPPORTED: asan, hwasan, rtsan, tsan, ubsan + +#include +#include + +extern void free_aligned_sized(void *p, size_t alignment, size_t size); + +int main() { + volatile void *p = aligned_alloc(128, 1024); + free_aligned_sized((void *)p, 128, 1024); + return 0; +} diff --git a/external/llvm-project/compiler-rt/test/sanitizer_common/TestCases/Linux/free_sized.c b/external/llvm-project/compiler-rt/test/sanitizer_common/TestCases/Linux/free_sized.c new file mode 100644 index 000000000000..9eac562fecb0 --- /dev/null +++ b/external/llvm-project/compiler-rt/test/sanitizer_common/TestCases/Linux/free_sized.c @@ -0,0 +1,15 @@ +// RUN: %clang -std=c23 -O0 %s -o %t && %run %t +// UNSUPPORTED: asan, hwasan, rtsan, tsan, ubsan + +#include +#include + +extern void *aligned_alloc(size_t alignment, size_t size); + +extern void free_sized(void *p, size_t size); + +int main() { + volatile void *p = malloc(64); + free_sized((void *)p, 64); + return 0; +} diff --git a/external/llvm-project/flang-rt/include/flang-rt/runtime/environment.h b/external/llvm-project/flang-rt/include/flang-rt/runtime/environment.h index 16258b3bbba9..e579f6012ce8 100644 --- a/external/llvm-project/flang-rt/include/flang-rt/runtime/environment.h +++ b/external/llvm-project/flang-rt/include/flang-rt/runtime/environment.h @@ -64,6 +64,9 @@ struct ExecutionEnvironment { bool defaultUTF8{false}; // DEFAULT_UTF8 bool checkPointerDeallocation{true}; // FORT_CHECK_POINTER_DEALLOCATION + enum InternalDebugging { WorkQueue = 1 }; + int internalDebugging{0}; // FLANG_RT_DEBUG + // CUDA related variables std::size_t cudaStackLimit{0}; // ACC_OFFLOAD_STACK_SIZE bool cudaDeviceIsManaged{false}; // NV_CUDAFOR_DEVICE_IS_MANAGED diff --git a/external/llvm-project/flang-rt/include/flang-rt/runtime/stat.h b/external/llvm-project/flang-rt/include/flang-rt/runtime/stat.h index 070d0bf8673f..dc372de53506 100644 --- a/external/llvm-project/flang-rt/include/flang-rt/runtime/stat.h +++ b/external/llvm-project/flang-rt/include/flang-rt/runtime/stat.h @@ -24,7 +24,7 @@ class Terminator; enum Stat { StatOk = 0, // required to be zero by Fortran - // Interoperable STAT= codes + // Interoperable STAT= codes (>= 11) StatBaseNull = CFI_ERROR_BASE_ADDR_NULL, StatBaseNotNull = CFI_ERROR_BASE_ADDR_NOT_NULL, StatInvalidElemLen = CFI_INVALID_ELEM_LEN, @@ -36,7 +36,7 @@ enum Stat { StatMemAllocation = CFI_ERROR_MEM_ALLOCATION, StatOutOfBounds = CFI_ERROR_OUT_OF_BOUNDS, - // Standard STAT= values + // Standard STAT= values (>= 101) StatFailedImage = FORTRAN_RUNTIME_STAT_FAILED_IMAGE, StatLocked = FORTRAN_RUNTIME_STAT_LOCKED, StatLockedOtherImage = FORTRAN_RUNTIME_STAT_LOCKED_OTHER_IMAGE, @@ -49,10 +49,14 @@ enum Stat { // Additional "processor-defined" STAT= values StatInvalidArgumentNumber = FORTRAN_RUNTIME_STAT_INVALID_ARG_NUMBER, StatMissingArgument = FORTRAN_RUNTIME_STAT_MISSING_ARG, - StatValueTooShort = FORTRAN_RUNTIME_STAT_VALUE_TOO_SHORT, + StatValueTooShort = FORTRAN_RUNTIME_STAT_VALUE_TOO_SHORT, // -1 StatMoveAllocSameAllocatable = FORTRAN_RUNTIME_STAT_MOVE_ALLOC_SAME_ALLOCATABLE, StatBadPointerDeallocation = FORTRAN_RUNTIME_STAT_BAD_POINTER_DEALLOCATION, + + // Dummy status for work queue continuation, declared here to perhaps + // avoid collisions + StatContinue = 201 }; RT_API_ATTRS const char *StatErrorString(int); diff --git a/external/llvm-project/flang-rt/include/flang-rt/runtime/type-info.h b/external/llvm-project/flang-rt/include/flang-rt/runtime/type-info.h index 5e79efde164f..80301a313282 100644 --- a/external/llvm-project/flang-rt/include/flang-rt/runtime/type-info.h +++ b/external/llvm-project/flang-rt/include/flang-rt/runtime/type-info.h @@ -154,12 +154,17 @@ class SpecialBinding { RT_API_ATTRS bool IsArgDescriptor(int zeroBasedArg) const { return (isArgDescriptorSet_ >> zeroBasedArg) & 1; } - RT_API_ATTRS bool isTypeBound() const { return isTypeBound_; } + RT_API_ATTRS bool IsTypeBound() const { return isTypeBound_ != 0; } RT_API_ATTRS bool IsArgContiguous(int zeroBasedArg) const { return (isArgContiguousSet_ >> zeroBasedArg) & 1; } - template RT_API_ATTRS PROC GetProc() const { - return reinterpret_cast(proc_); + template + RT_API_ATTRS PROC GetProc(const Binding *bindings = nullptr) const { + if (bindings && isTypeBound_ > 0) { + return reinterpret_cast(bindings[isTypeBound_ - 1].proc); + } else { + return reinterpret_cast(proc_); + } } FILE *Dump(FILE *) const; @@ -193,6 +198,8 @@ class SpecialBinding { // When false, the defined I/O subroutine must have been // called via a generic interface, not a generic TBP. std::uint8_t isArgDescriptorSet_{0}; + // When a special binding is type-bound, this is its binding's index (plus 1, + // so that 0 signifies that it's not type-bound). std::uint8_t isTypeBound_{0}; // True when a FINAL subroutine has a dummy argument that is an array that // is CONTIGUOUS or neither assumed-rank nor assumed-shape. @@ -240,6 +247,7 @@ class DerivedType { RT_API_ATTRS bool noFinalizationNeeded() const { return noFinalizationNeeded_; } + RT_API_ATTRS bool noDefinedAssignment() const { return noDefinedAssignment_; } RT_API_ATTRS std::size_t LenParameters() const { return lenParameterKind().Elements(); @@ -322,6 +330,7 @@ class DerivedType { bool noInitializationNeeded_{false}; bool noDestructionNeeded_{false}; bool noFinalizationNeeded_{false}; + bool noDefinedAssignment_{false}; }; } // namespace Fortran::runtime::typeInfo diff --git a/external/llvm-project/flang-rt/include/flang-rt/runtime/work-queue.h b/external/llvm-project/flang-rt/include/flang-rt/runtime/work-queue.h new file mode 100644 index 000000000000..0daa7bc4d338 --- /dev/null +++ b/external/llvm-project/flang-rt/include/flang-rt/runtime/work-queue.h @@ -0,0 +1,555 @@ +//===-- include/flang-rt/runtime/work-queue.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 +// +//===----------------------------------------------------------------------===// + +// Internal runtime utilities for work queues that replace the use of recursion +// for better GPU device support. +// +// A work queue comprises a list of tickets. Each ticket class has a Begin() +// member function, which is called once, and a Continue() member function +// that can be called zero or more times. A ticket's execution terminates +// when either of these member functions returns a status other than +// StatContinue. When that status is not StatOk, then the whole queue +// is shut down. +// +// By returning StatContinue from its Continue() member function, +// a ticket suspends its execution so that any nested tickets that it +// may have created can be run to completion. It is the reponsibility +// of each ticket class to maintain resumption information in its state +// and manage its own progress. Most ticket classes inherit from +// class ComponentsOverElements, which implements an outer loop over all +// components of a derived type, and an inner loop over all elements +// of a descriptor, possibly with multiple phases of execution per element. +// +// Tickets are created by WorkQueue::Begin...() member functions. +// There is one of these for each "top level" recursive function in the +// Fortran runtime support library that has been restructured into this +// ticket framework. +// +// When the work queue is running tickets, it always selects the last ticket +// on the list for execution -- "work stack" might have been a more accurate +// name for this framework. This ticket may, while doing its job, create +// new tickets, and since those are pushed after the active one, the first +// such nested ticket will be the next one executed to completion -- i.e., +// the order of nested WorkQueue::Begin...() calls is respected. +// Note that a ticket's Continue() member function won't be called again +// until all nested tickets have run to completion and it is once again +// the last ticket on the queue. +// +// Example for an assignment to a derived type: +// 1. Assign() is called, and its work queue is created. It calls +// WorkQueue::BeginAssign() and then WorkQueue::Run(). +// 2. Run calls AssignTicket::Begin(), which pushes a tickets via +// BeginFinalize() and returns StatContinue. +// 3. FinalizeTicket::Begin() and FinalizeTicket::Continue() are called +// until one of them returns StatOk, which ends the finalization ticket. +// 4. AssignTicket::Continue() is then called; it creates a DerivedAssignTicket +// and then returns StatOk, which ends the ticket. +// 5. At this point, only one ticket remains. DerivedAssignTicket::Begin() +// and ::Continue() are called until they are done (not StatContinue). +// Along the way, it may create nested AssignTickets for components, +// and suspend itself so that they may each run to completion. + +#ifndef FLANG_RT_RUNTIME_WORK_QUEUE_H_ +#define FLANG_RT_RUNTIME_WORK_QUEUE_H_ + +#include "flang-rt/runtime/connection.h" +#include "flang-rt/runtime/descriptor.h" +#include "flang-rt/runtime/stat.h" +#include "flang-rt/runtime/type-info.h" +#include "flang/Common/api-attrs.h" +#include "flang/Runtime/freestanding-tools.h" +#include + +namespace Fortran::runtime::io { +class IoStatementState; +struct NonTbpDefinedIoTable; +} // namespace Fortran::runtime::io + +namespace Fortran::runtime { +class Terminator; +class WorkQueue; + +// Ticket worker base classes + +template class ImmediateTicketRunner { +public: + RT_API_ATTRS explicit ImmediateTicketRunner(TICKET &ticket) + : ticket_{ticket} {} + RT_API_ATTRS int Run(WorkQueue &workQueue) { + int status{ticket_.Begin(workQueue)}; + while (status == StatContinue) { + status = ticket_.Continue(workQueue); + } + return status; + } + +private: + TICKET &ticket_; +}; + +// Base class for ticket workers that operate elementwise over descriptors +class Elementwise { +public: + RT_API_ATTRS Elementwise( + const Descriptor &instance, const Descriptor *from = nullptr) + : instance_{instance}, from_{from} { + instance_.GetLowerBounds(subscripts_); + if (from_) { + from_->GetLowerBounds(fromSubscripts_); + } + } + RT_API_ATTRS bool IsComplete() const { return elementAt_ >= elements_; } + RT_API_ATTRS void Advance() { + ++elementAt_; + instance_.IncrementSubscripts(subscripts_); + if (from_) { + from_->IncrementSubscripts(fromSubscripts_); + } + } + RT_API_ATTRS void SkipToEnd() { elementAt_ = elements_; } + RT_API_ATTRS void Reset() { + elementAt_ = 0; + instance_.GetLowerBounds(subscripts_); + if (from_) { + from_->GetLowerBounds(fromSubscripts_); + } + } + +protected: + const Descriptor &instance_, *from_{nullptr}; + std::size_t elements_{instance_.Elements()}; + std::size_t elementAt_{0}; + SubscriptValue subscripts_[common::maxRank]; + SubscriptValue fromSubscripts_[common::maxRank]; +}; + +// Base class for ticket workers that operate over derived type components. +class Componentwise { +public: + RT_API_ATTRS Componentwise(const typeInfo::DerivedType &); + RT_API_ATTRS bool IsComplete() const { return componentAt_ >= components_; } + RT_API_ATTRS void Advance() { + ++componentAt_; + GetComponent(); + } + RT_API_ATTRS void SkipToEnd() { + component_ = nullptr; + componentAt_ = components_; + } + RT_API_ATTRS void Reset() { + component_ = nullptr; + componentAt_ = 0; + GetComponent(); + } + RT_API_ATTRS void GetComponent(); + +protected: + const typeInfo::DerivedType &derived_; + std::size_t components_{0}, componentAt_{0}; + const typeInfo::Component *component_{nullptr}; + StaticDescriptor componentDescriptor_; +}; + +// Base class for ticket workers that operate over derived type components +// in an outer loop, and elements in an inner loop. +class ComponentsOverElements : public Componentwise, public Elementwise { +public: + RT_API_ATTRS ComponentsOverElements(const Descriptor &instance, + const typeInfo::DerivedType &derived, const Descriptor *from = nullptr) + : Componentwise{derived}, Elementwise{instance, from} { + if (Elementwise::IsComplete()) { + Componentwise::SkipToEnd(); + } + } + RT_API_ATTRS bool IsComplete() const { return Componentwise::IsComplete(); } + RT_API_ATTRS void Advance() { + SkipToNextElement(); + if (Elementwise::IsComplete()) { + Elementwise::Reset(); + Componentwise::Advance(); + } + } + RT_API_ATTRS void SkipToNextElement() { + phase_ = 0; + Elementwise::Advance(); + } + RT_API_ATTRS void SkipToNextComponent() { + phase_ = 0; + Elementwise::Reset(); + Componentwise::Advance(); + } + RT_API_ATTRS void Reset() { + phase_ = 0; + Elementwise::Reset(); + Componentwise::Reset(); + } + +protected: + int phase_{0}; +}; + +// Base class for ticket workers that operate over elements in an outer loop, +// type components in an inner loop. +class ElementsOverComponents : public Elementwise, public Componentwise { +public: + RT_API_ATTRS ElementsOverComponents(const Descriptor &instance, + const typeInfo::DerivedType &derived, const Descriptor *from = nullptr) + : Elementwise{instance, from}, Componentwise{derived} { + if (Componentwise::IsComplete()) { + Elementwise::SkipToEnd(); + } + } + RT_API_ATTRS bool IsComplete() const { return Elementwise::IsComplete(); } + RT_API_ATTRS void Advance() { + SkipToNextComponent(); + if (Componentwise::IsComplete()) { + Componentwise::Reset(); + Elementwise::Advance(); + } + } + RT_API_ATTRS void SkipToNextComponent() { + phase_ = 0; + Componentwise::Advance(); + } + RT_API_ATTRS void SkipToNextElement() { + phase_ = 0; + Componentwise::Reset(); + Elementwise::Advance(); + } + +protected: + int phase_{0}; +}; + +// Ticket worker classes + +// Implements derived type instance initialization +class InitializeTicket : public ImmediateTicketRunner, + private ComponentsOverElements { +public: + RT_API_ATTRS InitializeTicket( + const Descriptor &instance, const typeInfo::DerivedType &derived) + : ImmediateTicketRunner{*this}, + ComponentsOverElements{instance, derived} {} + RT_API_ATTRS int Begin(WorkQueue &); + RT_API_ATTRS int Continue(WorkQueue &); +}; + +// Initializes one derived type instance from the value of another +class InitializeCloneTicket + : public ImmediateTicketRunner, + private ComponentsOverElements { +public: + RT_API_ATTRS InitializeCloneTicket(const Descriptor &clone, + const Descriptor &original, const typeInfo::DerivedType &derived, + bool hasStat, const Descriptor *errMsg) + : ImmediateTicketRunner{*this}, + ComponentsOverElements{original, derived}, clone_{clone}, + hasStat_{hasStat}, errMsg_{errMsg} {} + RT_API_ATTRS int Begin(WorkQueue &) { return StatContinue; } + RT_API_ATTRS int Continue(WorkQueue &); + +private: + const Descriptor &clone_; + bool hasStat_{false}; + const Descriptor *errMsg_{nullptr}; + StaticDescriptor cloneComponentDescriptor_; +}; + +// Implements derived type instance finalization +class FinalizeTicket : public ImmediateTicketRunner, + private ComponentsOverElements { +public: + RT_API_ATTRS FinalizeTicket( + const Descriptor &instance, const typeInfo::DerivedType &derived) + : ImmediateTicketRunner{*this}, + ComponentsOverElements{instance, derived} {} + RT_API_ATTRS int Begin(WorkQueue &); + RT_API_ATTRS int Continue(WorkQueue &); + +private: + const typeInfo::DerivedType *finalizableParentType_{nullptr}; +}; + +// Implements derived type instance destruction +class DestroyTicket : public ImmediateTicketRunner, + private ComponentsOverElements { +public: + RT_API_ATTRS DestroyTicket(const Descriptor &instance, + const typeInfo::DerivedType &derived, bool finalize) + : ImmediateTicketRunner{*this}, + ComponentsOverElements{instance, derived}, finalize_{finalize} {} + RT_API_ATTRS int Begin(WorkQueue &); + RT_API_ATTRS int Continue(WorkQueue &); + +private: + bool finalize_{false}; +}; + +// Implements general intrinsic assignment +class AssignTicket : public ImmediateTicketRunner { +public: + RT_API_ATTRS AssignTicket(Descriptor &to, const Descriptor &from, int flags, + MemmoveFct memmoveFct, const typeInfo::DerivedType *declaredType) + : ImmediateTicketRunner{*this}, to_{to}, from_{&from}, + flags_{flags}, memmoveFct_{memmoveFct}, declaredType_{declaredType} {} + RT_API_ATTRS int Begin(WorkQueue &); + RT_API_ATTRS int Continue(WorkQueue &); + +private: + RT_API_ATTRS bool IsSimpleMemmove() const { + return !toDerived_ && to_.rank() == from_->rank() && to_.IsContiguous() && + from_->IsContiguous() && to_.ElementBytes() == from_->ElementBytes(); + } + RT_API_ATTRS Descriptor &GetTempDescriptor(); + + Descriptor &to_; + const Descriptor *from_{nullptr}; + int flags_{0}; // enum AssignFlags + MemmoveFct memmoveFct_{nullptr}; + StaticDescriptor tempDescriptor_; + const typeInfo::DerivedType *declaredType_{nullptr}; + const typeInfo::DerivedType *toDerived_{nullptr}; + Descriptor *toDeallocate_{nullptr}; + bool persist_{false}; + bool done_{false}; +}; + +// Implements derived type intrinsic assignment. +template +class DerivedAssignTicket + : public ImmediateTicketRunner>, + private std::conditional_t { +public: + using Base = std::conditional_t; + RT_API_ATTRS DerivedAssignTicket(const Descriptor &to, const Descriptor &from, + const typeInfo::DerivedType &derived, int flags, MemmoveFct memmoveFct, + Descriptor *deallocateAfter) + : ImmediateTicketRunner{*this}, + Base{to, derived, &from}, flags_{flags}, memmoveFct_{memmoveFct}, + deallocateAfter_{deallocateAfter} {} + RT_API_ATTRS int Begin(WorkQueue &); + RT_API_ATTRS int Continue(WorkQueue &); + +private: + static constexpr bool isComponentwise_{IS_COMPONENTWISE}; + bool toIsContiguous_{this->instance_.IsContiguous()}; + bool fromIsContiguous_{this->from_->IsContiguous()}; + int flags_{0}; + MemmoveFct memmoveFct_{nullptr}; + Descriptor *deallocateAfter_{nullptr}; + StaticDescriptor fromComponentDescriptor_; +}; + +namespace io::descr { + +template +class DescriptorIoTicket + : public ImmediateTicketRunner>, + private Elementwise { +public: + RT_API_ATTRS DescriptorIoTicket(io::IoStatementState &io, + const Descriptor &descriptor, const io::NonTbpDefinedIoTable *table, + bool &anyIoTookPlace) + : ImmediateTicketRunner(*this), + Elementwise{descriptor}, io_{io}, table_{table}, + anyIoTookPlace_{anyIoTookPlace} {} + RT_API_ATTRS int Begin(WorkQueue &); + RT_API_ATTRS int Continue(WorkQueue &); + RT_API_ATTRS bool &anyIoTookPlace() { return anyIoTookPlace_; } + +private: + io::IoStatementState &io_; + const io::NonTbpDefinedIoTable *table_{nullptr}; + bool &anyIoTookPlace_; + common::optional nonTbpSpecial_; + const typeInfo::DerivedType *derived_{nullptr}; + const typeInfo::SpecialBinding *special_{nullptr}; + StaticDescriptor elementDescriptor_; +}; + +template +class DerivedIoTicket : public ImmediateTicketRunner>, + private ElementsOverComponents { +public: + RT_API_ATTRS DerivedIoTicket(io::IoStatementState &io, + const Descriptor &descriptor, const typeInfo::DerivedType &derived, + const io::NonTbpDefinedIoTable *table, bool &anyIoTookPlace) + : ImmediateTicketRunner(*this), + ElementsOverComponents{descriptor, derived}, io_{io}, table_{table}, + anyIoTookPlace_{anyIoTookPlace} {} + RT_API_ATTRS int Begin(WorkQueue &) { return StatContinue; } + RT_API_ATTRS int Continue(WorkQueue &); + +private: + io::IoStatementState &io_; + const io::NonTbpDefinedIoTable *table_{nullptr}; + bool &anyIoTookPlace_; +}; + +} // namespace io::descr + +struct NullTicket { + RT_API_ATTRS int Begin(WorkQueue &) const { return StatOk; } + RT_API_ATTRS int Continue(WorkQueue &) const { return StatOk; } +}; + +struct Ticket { + RT_API_ATTRS int Continue(WorkQueue &); + bool begun{false}; + std::variant, + DerivedAssignTicket, + io::descr::DescriptorIoTicket, + io::descr::DescriptorIoTicket, + io::descr::DerivedIoTicket, + io::descr::DerivedIoTicket> + u; +}; + +class WorkQueue { +public: + RT_API_ATTRS explicit WorkQueue(Terminator &terminator) + : terminator_{terminator} { + for (int j{1}; j < numStatic_; ++j) { + static_[j].previous = &static_[j - 1]; + static_[j - 1].next = &static_[j]; + } + } + RT_API_ATTRS ~WorkQueue(); + RT_API_ATTRS Terminator &terminator() { return terminator_; }; + + // APIs for particular tasks. These can return StatOk if the work is + // completed immediately. + RT_API_ATTRS int BeginInitialize( + const Descriptor &descriptor, const typeInfo::DerivedType &derived) { + if (runTicketsImmediately_) { + return InitializeTicket{descriptor, derived}.Run(*this); + } else { + StartTicket().u.emplace(descriptor, derived); + return StatContinue; + } + } + RT_API_ATTRS int BeginInitializeClone(const Descriptor &clone, + const Descriptor &original, const typeInfo::DerivedType &derived, + bool hasStat, const Descriptor *errMsg) { + if (runTicketsImmediately_) { + return InitializeCloneTicket{clone, original, derived, hasStat, errMsg} + .Run(*this); + } else { + StartTicket().u.emplace( + clone, original, derived, hasStat, errMsg); + return StatContinue; + } + } + RT_API_ATTRS int BeginFinalize( + const Descriptor &descriptor, const typeInfo::DerivedType &derived) { + if (runTicketsImmediately_) { + return FinalizeTicket{descriptor, derived}.Run(*this); + } else { + StartTicket().u.emplace(descriptor, derived); + return StatContinue; + } + } + RT_API_ATTRS int BeginDestroy(const Descriptor &descriptor, + const typeInfo::DerivedType &derived, bool finalize) { + if (runTicketsImmediately_) { + return DestroyTicket{descriptor, derived, finalize}.Run(*this); + } else { + StartTicket().u.emplace(descriptor, derived, finalize); + return StatContinue; + } + } + RT_API_ATTRS int BeginAssign(Descriptor &to, const Descriptor &from, + int flags, MemmoveFct memmoveFct, + const typeInfo::DerivedType *declaredType) { + if (runTicketsImmediately_) { + return AssignTicket{to, from, flags, memmoveFct, declaredType}.Run(*this); + } else { + StartTicket().u.emplace( + to, from, flags, memmoveFct, declaredType); + return StatContinue; + } + } + template + RT_API_ATTRS int BeginDerivedAssign(Descriptor &to, const Descriptor &from, + const typeInfo::DerivedType &derived, int flags, MemmoveFct memmoveFct, + Descriptor *deallocateAfter) { + if (runTicketsImmediately_) { + return DerivedAssignTicket{ + to, from, derived, flags, memmoveFct, deallocateAfter} + .Run(*this); + } else { + StartTicket().u.emplace>( + to, from, derived, flags, memmoveFct, deallocateAfter); + return StatContinue; + } + } + template + RT_API_ATTRS int BeginDescriptorIo(io::IoStatementState &io, + const Descriptor &descriptor, const io::NonTbpDefinedIoTable *table, + bool &anyIoTookPlace) { + if (runTicketsImmediately_) { + return io::descr::DescriptorIoTicket{ + io, descriptor, table, anyIoTookPlace} + .Run(*this); + } else { + StartTicket().u.emplace>( + io, descriptor, table, anyIoTookPlace); + return StatContinue; + } + } + template + RT_API_ATTRS int BeginDerivedIo(io::IoStatementState &io, + const Descriptor &descriptor, const typeInfo::DerivedType &derived, + const io::NonTbpDefinedIoTable *table, bool &anyIoTookPlace) { + if (runTicketsImmediately_) { + return io::descr::DerivedIoTicket{ + io, descriptor, derived, table, anyIoTookPlace} + .Run(*this); + } else { + StartTicket().u.emplace>( + io, descriptor, derived, table, anyIoTookPlace); + return StatContinue; + } + } + + RT_API_ATTRS int Run(); + +private: +#if RT_DEVICE_COMPILATION + // Always use the work queue on a GPU device to avoid recursion. + static constexpr bool runTicketsImmediately_{false}; +#else + // Avoid the work queue overhead on the host, unless it needs + // debugging, which is so much easier there. + static constexpr bool runTicketsImmediately_{true}; +#endif + + // Most uses of the work queue won't go very deep. + static constexpr int numStatic_{2}; + + struct TicketList { + bool isStatic{true}; + Ticket ticket; + TicketList *previous{nullptr}, *next{nullptr}; + }; + + RT_API_ATTRS Ticket &StartTicket(); + RT_API_ATTRS void Stop(); + + Terminator &terminator_; + TicketList *first_{nullptr}, *last_{nullptr}, *insertAfter_{nullptr}; + TicketList static_[numStatic_]; + TicketList *firstFree_{static_}; +}; + +} // namespace Fortran::runtime +#endif // FLANG_RT_RUNTIME_WORK_QUEUE_H_ diff --git a/external/llvm-project/flang-rt/lib/runtime/CMakeLists.txt b/external/llvm-project/flang-rt/lib/runtime/CMakeLists.txt index a3f63b431564..332c0872e065 100644 --- a/external/llvm-project/flang-rt/lib/runtime/CMakeLists.txt +++ b/external/llvm-project/flang-rt/lib/runtime/CMakeLists.txt @@ -68,6 +68,7 @@ set(supported_sources type-info.cpp unit.cpp utf.cpp + work-queue.cpp ) # List of source not used for GPU offloading. @@ -131,6 +132,7 @@ set(gpu_sources type-code.cpp type-info.cpp utf.cpp + work-queue.cpp complex-powi.cpp reduce.cpp reduction.cpp diff --git a/external/llvm-project/flang-rt/lib/runtime/allocatable.cpp b/external/llvm-project/flang-rt/lib/runtime/allocatable.cpp index ef18da6ea078..f724f0a20884 100644 --- a/external/llvm-project/flang-rt/lib/runtime/allocatable.cpp +++ b/external/llvm-project/flang-rt/lib/runtime/allocatable.cpp @@ -165,6 +165,26 @@ int RTDEF(AllocatableAllocateSource)(Descriptor &alloc, alloc, /*asyncObject=*/nullptr, hasStat, errMsg, sourceFile, sourceLine)}; if (stat == StatOk) { Terminator terminator{sourceFile, sourceLine}; + if (alloc.rank() != source.rank() && source.rank() != 0) { + terminator.Crash("ALLOCATE object has rank %d while SOURCE= has rank %d", + alloc.rank(), source.rank()); + } + if (int rank{source.rank()}; rank > 0) { + SubscriptValue allocExtent[maxRank], sourceExtent[maxRank]; + alloc.GetShape(allocExtent); + source.GetShape(sourceExtent); + for (int j{0}; j < rank; ++j) { + if (allocExtent[j] != sourceExtent[j]) { + if (!hasStat) { + terminator.Crash("ALLOCATE object has extent %jd on dimension %d, " + "but SOURCE= has extent %jd", + static_cast(allocExtent[j]), j + 1, + static_cast(sourceExtent[j])); + } + return StatInvalidExtent; + } + } + } DoFromSourceAssign(alloc, source, terminator); } return stat; diff --git a/external/llvm-project/flang-rt/lib/runtime/assign.cpp b/external/llvm-project/flang-rt/lib/runtime/assign.cpp index b5dc84b884b3..f936a4192a33 100644 --- a/external/llvm-project/flang-rt/lib/runtime/assign.cpp +++ b/external/llvm-project/flang-rt/lib/runtime/assign.cpp @@ -14,6 +14,7 @@ #include "flang-rt/runtime/terminator.h" #include "flang-rt/runtime/tools.h" #include "flang-rt/runtime/type-info.h" +#include "flang-rt/runtime/work-queue.h" namespace Fortran::runtime { @@ -62,11 +63,24 @@ static inline RT_API_ATTRS bool MustDeallocateLHS( // Distinct shape? Deallocate int rank{to.rank()}; for (int j{0}; j < rank; ++j) { - if (to.GetDimension(j).Extent() != from.GetDimension(j).Extent()) { + const auto &toDim{to.GetDimension(j)}; + const auto &fromDim{from.GetDimension(j)}; + if (toDim.Extent() != fromDim.Extent()) { + return true; + } + if ((flags & UpdateLHSBounds) && + toDim.LowerBound() != fromDim.LowerBound()) { return true; } } } + // Not reallocating; may have to update bounds + if (flags & UpdateLHSBounds) { + int rank{to.rank()}; + for (int j{0}; j < rank; ++j) { + to.GetDimension(j).SetLowerBound(from.GetDimension(j).LowerBound()); + } + } return false; } @@ -102,11 +116,7 @@ static RT_API_ATTRS int AllocateAssignmentLHS( toDim.SetByteStride(stride); stride *= toDim.Extent(); } - int result{ReturnError(terminator, to.Allocate(kNoAsyncObject))}; - if (result == StatOk && derived && !derived->noInitializationNeeded()) { - result = ReturnError(terminator, Initialize(to, *derived, terminator)); - } - return result; + return ReturnError(terminator, to.Allocate(kNoAsyncObject)); } // least <= 0, most >= 0 @@ -169,24 +179,27 @@ static RT_API_ATTRS bool MayAlias(const Descriptor &x, const Descriptor &y) { } static RT_API_ATTRS void DoScalarDefinedAssignment(const Descriptor &to, - const Descriptor &from, const typeInfo::SpecialBinding &special) { + const Descriptor &from, const typeInfo::DerivedType &derived, + const typeInfo::SpecialBinding &special) { bool toIsDesc{special.IsArgDescriptor(0)}; bool fromIsDesc{special.IsArgDescriptor(1)}; + const auto *bindings{ + derived.binding().OffsetElement()}; if (toIsDesc) { if (fromIsDesc) { - auto *p{ - special.GetProc()}; + auto *p{special.GetProc( + bindings)}; p(to, from); } else { - auto *p{special.GetProc()}; + auto *p{special.GetProc(bindings)}; p(to, from.raw().base_addr); } } else { if (fromIsDesc) { - auto *p{special.GetProc()}; + auto *p{special.GetProc(bindings)}; p(to.raw().base_addr, from); } else { - auto *p{special.GetProc()}; + auto *p{special.GetProc(bindings)}; p(to.raw().base_addr, from.raw().base_addr); } } @@ -208,7 +221,7 @@ static RT_API_ATTRS void DoElementalDefinedAssignment(const Descriptor &to, to.IncrementSubscripts(toAt), from.IncrementSubscripts(fromAt)) { toElementDesc.set_base_addr(to.Element(toAt)); fromElementDesc.set_base_addr(from.Element(fromAt)); - DoScalarDefinedAssignment(toElementDesc, fromElementDesc, special); + DoScalarDefinedAssignment(toElementDesc, fromElementDesc, derived, special); } } @@ -231,6 +244,8 @@ static RT_API_ATTRS void BlankPadCharacterAssignment(Descriptor &to, } } +RT_OFFLOAD_API_GROUP_BEGIN + // Common implementation of assignments, both intrinsic assignments and // those cases of polymorphic user-defined ASSIGNMENT(=) TBPs that could not // be resolved in semantics. Most assignment statements do not need any @@ -244,275 +259,461 @@ static RT_API_ATTRS void BlankPadCharacterAssignment(Descriptor &to, // dealing with array constructors. RT_API_ATTRS void Assign(Descriptor &to, const Descriptor &from, Terminator &terminator, int flags, MemmoveFct memmoveFct) { - bool mustDeallocateLHS{(flags & DeallocateLHS) || - MustDeallocateLHS(to, from, terminator, flags)}; - DescriptorAddendum *toAddendum{to.Addendum()}; - const typeInfo::DerivedType *toDerived{ - toAddendum ? toAddendum->derivedType() : nullptr}; - if (toDerived && (flags & NeedFinalization) && - toDerived->noFinalizationNeeded()) { - flags &= ~NeedFinalization; - } - std::size_t toElementBytes{to.ElementBytes()}; - std::size_t fromElementBytes{from.ElementBytes()}; - // The following lambda definition violates the conding style, - // but cuda-11.8 nvcc hits an internal error with the brace initialization. - auto isSimpleMemmove = [&]() { - return !toDerived && to.rank() == from.rank() && to.IsContiguous() && - from.IsContiguous() && toElementBytes == fromElementBytes; - }; - StaticDescriptor deferredDeallocStatDesc; - Descriptor *deferDeallocation{nullptr}; - if (MayAlias(to, from)) { + WorkQueue workQueue{terminator}; + if (workQueue.BeginAssign(to, from, flags, memmoveFct, nullptr) == + StatContinue) { + workQueue.Run(); + } +} + +RT_API_ATTRS int AssignTicket::Begin(WorkQueue &workQueue) { + bool mustDeallocateLHS{(flags_ & DeallocateLHS) || + MustDeallocateLHS(to_, *from_, workQueue.terminator(), flags_)}; + DescriptorAddendum *toAddendum{to_.Addendum()}; + toDerived_ = toAddendum ? toAddendum->derivedType() : nullptr; + if (toDerived_ && (flags_ & NeedFinalization) && + toDerived_->noFinalizationNeeded()) { + flags_ &= ~NeedFinalization; + } + if (MayAlias(to_, *from_)) { if (mustDeallocateLHS) { - deferDeallocation = &deferredDeallocStatDesc.descriptor(); - Fortran::runtime::memcpy( - reinterpret_cast(deferDeallocation), &to, to.SizeInBytes()); - to.set_base_addr(nullptr); - } else if (!isSimpleMemmove()) { + // Convert the LHS into a temporary, then make it look deallocated. + toDeallocate_ = &tempDescriptor_.descriptor(); + persist_ = true; // tempDescriptor_ state must outlive child tickets + std::memcpy( + reinterpret_cast(toDeallocate_), &to_, to_.SizeInBytes()); + to_.set_base_addr(nullptr); + if (toDerived_ && (flags_ & NeedFinalization)) { + if (int status{workQueue.BeginFinalize(*toDeallocate_, *toDerived_)}; + status != StatOk && status != StatContinue) { + return status; + } + flags_ &= ~NeedFinalization; + } + } else if (!IsSimpleMemmove()) { // Handle LHS/RHS aliasing by copying RHS into a temp, then // recursively assigning from that temp. - auto descBytes{from.SizeInBytes()}; - StaticDescriptor staticDesc; - Descriptor &newFrom{staticDesc.descriptor()}; - Fortran::runtime::memcpy(reinterpret_cast(&newFrom), &from, descBytes); + auto descBytes{from_->SizeInBytes()}; + Descriptor &newFrom{tempDescriptor_.descriptor()}; + persist_ = true; // tempDescriptor_ state must outlive child tickets + std::memcpy(reinterpret_cast(&newFrom), from_, descBytes); // Pretend the temporary descriptor is for an ALLOCATABLE // entity, otherwise, the Deallocate() below will not // free the descriptor memory. newFrom.raw().attribute = CFI_attribute_allocatable; - auto stat{ReturnError(terminator, newFrom.Allocate(kNoAsyncObject))}; - if (stat == StatOk) { - if (HasDynamicComponent(from)) { - // If 'from' has allocatable/automatic component, we cannot - // just make a shallow copy of the descriptor member. - // This will still leave data overlap in 'to' and 'newFrom'. - // For example: - // type t - // character, allocatable :: c(:) - // end type t - // type(t) :: x(3) - // x(2:3) = x(1:2) - // We have to make a deep copy into 'newFrom' in this case. - RTNAME(AssignTemporary) - (newFrom, from, terminator.sourceFileName(), terminator.sourceLine()); - } else { - ShallowCopy(newFrom, from, true, from.IsContiguous()); + if (int stat{ReturnError( + workQueue.terminator(), newFrom.Allocate(kNoAsyncObject))}; + stat != StatOk) { + return stat; + } + if (HasDynamicComponent(*from_)) { + // If 'from' has allocatable/automatic component, we cannot + // just make a shallow copy of the descriptor member. + // This will still leave data overlap in 'to' and 'newFrom'. + // For example: + // type t + // character, allocatable :: c(:) + // end type t + // type(t) :: x(3) + // x(2:3) = x(1:2) + // We have to make a deep copy into 'newFrom' in this case. + if (const DescriptorAddendum *addendum{newFrom.Addendum()}) { + if (const auto *derived{addendum->derivedType()}) { + if (!derived->noInitializationNeeded()) { + if (int status{workQueue.BeginInitialize(newFrom, *derived)}; + status != StatOk && status != StatContinue) { + return status; + } + } + } } - Assign(to, newFrom, terminator, - flags & - (NeedFinalization | ComponentCanBeDefinedAssignment | - ExplicitLengthCharacterLHS | CanBeDefinedAssignment)); - newFrom.Deallocate(); + static constexpr int nestedFlags{MaybeReallocate | PolymorphicLHS}; + if (int status{workQueue.BeginAssign( + newFrom, *from_, nestedFlags, memmoveFct_, nullptr)}; + status != StatOk && status != StatContinue) { + return status; + } + } else { + ShallowCopy(newFrom, *from_, true, from_->IsContiguous()); } - return; + from_ = &newFrom; // this is why from_ has to be a pointer + flags_ &= NeedFinalization | ComponentCanBeDefinedAssignment | + ExplicitLengthCharacterLHS | CanBeDefinedAssignment; + toDeallocate_ = &newFrom; } } - if (to.IsAllocatable()) { + if (to_.IsAllocatable()) { if (mustDeallocateLHS) { - if (deferDeallocation) { - if ((flags & NeedFinalization) && toDerived) { - Finalize(*deferDeallocation, *toDerived, &terminator); - flags &= ~NeedFinalization; - } - } else { - to.Destroy((flags & NeedFinalization) != 0, /*destroyPointers=*/false, - &terminator); - flags &= ~NeedFinalization; + if (!toDeallocate_ && to_.IsAllocated()) { + toDeallocate_ = &to_; + } + } else if (to_.rank() != from_->rank() && !to_.IsAllocated()) { + workQueue.terminator().Crash("Assign: mismatched ranks (%d != %d) in " + "assignment to unallocated allocatable", + to_.rank(), from_->rank()); + } + } else if (!to_.IsAllocated()) { + workQueue.terminator().Crash( + "Assign: left-hand side variable is neither allocated nor allocatable"); + } + if (toDerived_ && to_.IsAllocated()) { + // Schedule finalization or destruction of the LHS. + if (flags_ & NeedFinalization) { + if (int status{workQueue.BeginFinalize(to_, *toDerived_)}; + status != StatOk && status != StatContinue) { + return status; + } + } else if (!toDerived_->noDestructionNeeded()) { + if (int status{ + workQueue.BeginDestroy(to_, *toDerived_, /*finalize=*/false)}; + status != StatOk && status != StatContinue) { + return status; } - } else if (to.rank() != from.rank() && !to.IsAllocated()) { - terminator.Crash("Assign: mismatched ranks (%d != %d) in assignment to " - "unallocated allocatable", - to.rank(), from.rank()); } - if (!to.IsAllocated()) { - if (AllocateAssignmentLHS(to, from, terminator, flags) != StatOk) { - return; + } + return StatContinue; +} + +RT_API_ATTRS int AssignTicket::Continue(WorkQueue &workQueue) { + if (done_) { + // All child tickets are complete; can release this ticket's state. + if (toDeallocate_) { + toDeallocate_->Deallocate(); + } + return StatOk; + } + // All necessary finalization or destruction that was initiated by Begin() + // has been completed. Deallocation may be pending, and if it's for the LHS, + // do it now so that the LHS gets reallocated. + if (toDeallocate_ == &to_) { + toDeallocate_ = nullptr; + to_.Deallocate(); + } + // Allocate the LHS if needed + if (!to_.IsAllocated()) { + if (int stat{ + AllocateAssignmentLHS(to_, *from_, workQueue.terminator(), flags_)}; + stat != StatOk) { + return stat; + } + const auto *addendum{to_.Addendum()}; + toDerived_ = addendum ? addendum->derivedType() : nullptr; + if (toDerived_) { + if (!toDerived_->noInitializationNeeded()) { + if (int status{workQueue.BeginInitialize(to_, *toDerived_)}; + status != StatOk) { + return status; + } } - flags &= ~NeedFinalization; - toElementBytes = to.ElementBytes(); // may have changed - toDerived = toAddendum ? toAddendum->derivedType() : nullptr; } } - if (toDerived && (flags & CanBeDefinedAssignment)) { - // Check for a user-defined assignment type-bound procedure; - // see 10.2.1.4-5. A user-defined assignment TBP defines all of - // the semantics, including allocatable (re)allocation and any - // finalization. - // - // Note that the aliasing and LHS (re)allocation handling above - // needs to run even with CanBeDefinedAssignment flag, when - // the Assign() is invoked recursively for component-per-component - // assignments. - if (to.rank() == 0) { - if (const auto *special{toDerived->FindSpecialBinding( + // Check for a user-defined assignment type-bound procedure; + // see 10.2.1.4-5. + // Note that the aliasing and LHS (re)allocation handling above + // needs to run even with CanBeDefinedAssignment flag, since + // Assign() can be invoked recursively for component-wise assignments. + // The declared type (if known) must be used for generic resolution + // of ASSIGNMENT(=) to a binding, but that binding can be overridden. + if (declaredType_ && (flags_ & CanBeDefinedAssignment)) { + if (to_.rank() == 0) { + if (const auto *special{declaredType_->FindSpecialBinding( typeInfo::SpecialBinding::Which::ScalarAssignment)}) { - return DoScalarDefinedAssignment(to, from, *special); + DoScalarDefinedAssignment(to_, *from_, *toDerived_, *special); + done_ = true; + return StatContinue; } } - if (const auto *special{toDerived->FindSpecialBinding( + if (const auto *special{declaredType_->FindSpecialBinding( typeInfo::SpecialBinding::Which::ElementalAssignment)}) { - return DoElementalDefinedAssignment(to, from, *toDerived, *special); + DoElementalDefinedAssignment(to_, *from_, *toDerived_, *special); + done_ = true; + return StatContinue; } } - SubscriptValue toAt[maxRank]; - to.GetLowerBounds(toAt); - // Scalar expansion of the RHS is implied by using the same empty - // subscript values on each (seemingly) elemental reference into - // "from". - SubscriptValue fromAt[maxRank]; - from.GetLowerBounds(fromAt); - std::size_t toElements{to.Elements()}; - if (from.rank() > 0 && toElements != from.Elements()) { - terminator.Crash("Assign: mismatching element counts in array assignment " - "(to %zd, from %zd)", - toElements, from.Elements()); + // Intrinsic assignment + std::size_t toElements{to_.Elements()}; + if (from_->rank() > 0 && toElements != from_->Elements()) { + workQueue.terminator().Crash("Assign: mismatching element counts in array " + "assignment (to %zd, from %zd)", + toElements, from_->Elements()); } - if (to.type() != from.type()) { - terminator.Crash("Assign: mismatching types (to code %d != from code %d)", - to.type().raw(), from.type().raw()); + if (to_.type() != from_->type()) { + workQueue.terminator().Crash( + "Assign: mismatching types (to code %d != from code %d)", + to_.type().raw(), from_->type().raw()); } - if (toElementBytes > fromElementBytes && !to.type().IsCharacter()) { - terminator.Crash("Assign: mismatching non-character element sizes (to %zd " - "bytes != from %zd bytes)", + std::size_t toElementBytes{to_.ElementBytes()}; + std::size_t fromElementBytes{from_->ElementBytes()}; + if (toElementBytes > fromElementBytes && !to_.type().IsCharacter()) { + workQueue.terminator().Crash("Assign: mismatching non-character element " + "sizes (to %zd bytes != from %zd bytes)", toElementBytes, fromElementBytes); } - if (const typeInfo::DerivedType * - updatedToDerived{toAddendum ? toAddendum->derivedType() : nullptr}) { - // Derived type intrinsic assignment, which is componentwise and elementwise - // for all components, including parent components (10.2.1.2-3). - // The target is first finalized if still necessary (7.5.6.3(1)) - if (flags & NeedFinalization) { - Finalize(to, *updatedToDerived, &terminator); - } else if (updatedToDerived && !updatedToDerived->noDestructionNeeded()) { - Destroy(to, /*finalize=*/false, *updatedToDerived, &terminator); - } - // Copy the data components (incl. the parent) first. - const Descriptor &componentDesc{updatedToDerived->component()}; - std::size_t numComponents{componentDesc.Elements()}; - for (std::size_t j{0}; j < toElements; - ++j, to.IncrementSubscripts(toAt), from.IncrementSubscripts(fromAt)) { - for (std::size_t k{0}; k < numComponents; ++k) { - const auto &comp{ - *componentDesc.ZeroBasedIndexedElement( - k)}; // TODO: exploit contiguity here - // Use PolymorphicLHS for components so that the right things happen - // when the components are polymorphic; when they're not, they're both - // not, and their declared types will match. - int nestedFlags{MaybeReallocate | PolymorphicLHS}; - if (flags & ComponentCanBeDefinedAssignment) { - nestedFlags |= - CanBeDefinedAssignment | ComponentCanBeDefinedAssignment; - } - switch (comp.genre()) { - case typeInfo::Component::Genre::Data: - if (comp.category() == TypeCategory::Derived) { - StaticDescriptor statDesc[2]; - Descriptor &toCompDesc{statDesc[0].descriptor()}; - Descriptor &fromCompDesc{statDesc[1].descriptor()}; - comp.CreatePointerDescriptor(toCompDesc, to, terminator, toAt); - comp.CreatePointerDescriptor( - fromCompDesc, from, terminator, fromAt); - Assign(toCompDesc, fromCompDesc, terminator, nestedFlags); - } else { // Component has intrinsic type; simply copy raw bytes - std::size_t componentByteSize{comp.SizeInBytes(to)}; - memmoveFct(to.Element(toAt) + comp.offset(), - from.Element(fromAt) + comp.offset(), - componentByteSize); - } - break; - case typeInfo::Component::Genre::Pointer: { - std::size_t componentByteSize{comp.SizeInBytes(to)}; - memmoveFct(to.Element(toAt) + comp.offset(), - from.Element(fromAt) + comp.offset(), - componentByteSize); - } break; - case typeInfo::Component::Genre::Allocatable: - case typeInfo::Component::Genre::Automatic: { - auto *toDesc{reinterpret_cast( - to.Element(toAt) + comp.offset())}; - const auto *fromDesc{reinterpret_cast( - from.Element(fromAt) + comp.offset())}; - // Allocatable components of the LHS are unconditionally - // deallocated before assignment (F'2018 10.2.1.3(13)(1)), - // unlike a "top-level" assignment to a variable, where - // deallocation is optional. - // - // Be careful not to destroy/reallocate the LHS, if there is - // overlap between LHS and RHS (it seems that partial overlap - // is not possible, though). - // Invoke Assign() recursively to deal with potential aliasing. - if (toDesc->IsAllocatable()) { - if (!fromDesc->IsAllocated()) { - // No aliasing. - // - // If to is not allocated, the Destroy() call is a no-op. - // This is just a shortcut, because the recursive Assign() - // below would initiate the destruction for to. - // No finalization is required. - toDesc->Destroy( - /*finalize=*/false, /*destroyPointers=*/false, &terminator); - continue; // F'2018 10.2.1.3(13)(2) - } - } - // Force LHS deallocation with DeallocateLHS flag. - // The actual deallocation may be avoided, if the existing - // location can be reoccupied. - Assign(*toDesc, *fromDesc, terminator, nestedFlags | DeallocateLHS); - } break; - } + if (toDerived_) { + if (toDerived_->noDefinedAssignment()) { // componentwise + if (int status{workQueue.BeginDerivedAssign( + to_, *from_, *toDerived_, flags_, memmoveFct_, toDeallocate_)}; + status != StatOk && status != StatContinue) { + return status; } - // Copy procedure pointer components - const Descriptor &procPtrDesc{updatedToDerived->procPtr()}; - std::size_t numProcPtrs{procPtrDesc.Elements()}; - for (std::size_t k{0}; k < numProcPtrs; ++k) { - const auto &procPtr{ - *procPtrDesc.ZeroBasedIndexedElement( - k)}; - memmoveFct(to.Element(toAt) + procPtr.offset, - from.Element(fromAt) + procPtr.offset, - sizeof(typeInfo::ProcedurePointer)); + } else { // elementwise + if (int status{workQueue.BeginDerivedAssign( + to_, *from_, *toDerived_, flags_, memmoveFct_, toDeallocate_)}; + status != StatOk && status != StatContinue) { + return status; } } - } else { // intrinsic type, intrinsic assignment - if (isSimpleMemmove()) { - memmoveFct(to.raw().base_addr, from.raw().base_addr, - toElements * toElementBytes); - } else if (toElementBytes > fromElementBytes) { // blank padding - switch (to.type().raw()) { + toDeallocate_ = nullptr; + } else if (IsSimpleMemmove()) { + memmoveFct_(to_.raw().base_addr, from_->raw().base_addr, + toElements * toElementBytes); + } else { + // Scalar expansion of the RHS is implied by using the same empty + // subscript values on each (seemingly) elemental reference into + // "from". + SubscriptValue toAt[maxRank]; + to_.GetLowerBounds(toAt); + SubscriptValue fromAt[maxRank]; + from_->GetLowerBounds(fromAt); + if (toElementBytes > fromElementBytes) { // blank padding + switch (to_.type().raw()) { case CFI_type_signed_char: case CFI_type_char: - BlankPadCharacterAssignment(to, from, toAt, fromAt, toElements, + BlankPadCharacterAssignment(to_, *from_, toAt, fromAt, toElements, toElementBytes, fromElementBytes); break; case CFI_type_char16_t: - BlankPadCharacterAssignment(to, from, toAt, fromAt, + BlankPadCharacterAssignment(to_, *from_, toAt, fromAt, toElements, toElementBytes, fromElementBytes); break; case CFI_type_char32_t: - BlankPadCharacterAssignment(to, from, toAt, fromAt, + BlankPadCharacterAssignment(to_, *from_, toAt, fromAt, toElements, toElementBytes, fromElementBytes); break; default: - terminator.Crash("unexpected type code %d in blank padded Assign()", - to.type().raw()); + workQueue.terminator().Crash( + "unexpected type code %d in blank padded Assign()", + to_.type().raw()); } } else { // elemental copies, possibly with character truncation for (std::size_t n{toElements}; n-- > 0; - to.IncrementSubscripts(toAt), from.IncrementSubscripts(fromAt)) { - memmoveFct(to.Element(toAt), from.Element(fromAt), + to_.IncrementSubscripts(toAt), from_->IncrementSubscripts(fromAt)) { + memmoveFct_(to_.Element(toAt), from_->Element(fromAt), toElementBytes); } } } - if (deferDeallocation) { - // deferDeallocation is used only when LHS is an allocatable. - // The finalization has already been run for it. - deferDeallocation->Destroy( - /*finalize=*/false, /*destroyPointers=*/false, &terminator); + if (persist_) { + done_ = true; + return StatContinue; + } else { + if (toDeallocate_) { + toDeallocate_->Deallocate(); + toDeallocate_ = nullptr; + } + return StatOk; } } -RT_OFFLOAD_API_GROUP_BEGIN +template +RT_API_ATTRS int DerivedAssignTicket::Begin( + WorkQueue &workQueue) { + if (toIsContiguous_ && fromIsContiguous_ && + this->derived_.noDestructionNeeded() && + this->derived_.noDefinedAssignment() && + this->instance_.rank() == this->from_->rank()) { + if (std::size_t elementBytes{this->instance_.ElementBytes()}; + elementBytes == this->from_->ElementBytes()) { + // Fastest path. Both LHS and RHS are contiguous, RHS is not a scalar + // to be expanded, the types have the same size, and there are no + // allocatable components or defined ASSIGNMENT(=) at any level. + memmoveFct_(this->instance_.template OffsetElement(), + this->from_->template OffsetElement(), + this->instance_.Elements() * elementBytes); + return StatOk; + } + } + // Use PolymorphicLHS for components so that the right things happen + // when the components are polymorphic; when they're not, they're both + // not, and their declared types will match. + int nestedFlags{MaybeReallocate | PolymorphicLHS}; + if (flags_ & ComponentCanBeDefinedAssignment) { + nestedFlags |= CanBeDefinedAssignment | ComponentCanBeDefinedAssignment; + } + flags_ = nestedFlags; + // Copy procedure pointer components + const Descriptor &procPtrDesc{this->derived_.procPtr()}; + bool noDataComponents{this->IsComplete()}; + if (std::size_t numProcPtrs{procPtrDesc.Elements()}) { + for (std::size_t k{0}; k < numProcPtrs; ++k) { + const auto &procPtr{ + *procPtrDesc.ZeroBasedIndexedElement(k)}; + // Loop only over elements + if (k > 0) { + Elementwise::Reset(); + } + for (; !Elementwise::IsComplete(); Elementwise::Advance()) { + memmoveFct_(this->instance_.template ElementComponent( + this->subscripts_, procPtr.offset), + this->from_->template ElementComponent( + this->fromSubscripts_, procPtr.offset), + sizeof(typeInfo::ProcedurePointer)); + } + } + if (noDataComponents) { + return StatOk; + } + Elementwise::Reset(); + } + if (noDataComponents) { + return StatOk; + } + return StatContinue; +} +template RT_API_ATTRS int DerivedAssignTicket::Begin(WorkQueue &); +template RT_API_ATTRS int DerivedAssignTicket::Begin(WorkQueue &); + +template +RT_API_ATTRS int DerivedAssignTicket::Continue( + WorkQueue &workQueue) { + while (!this->IsComplete()) { + // Copy the data components (incl. the parent) first. + switch (this->component_->genre()) { + case typeInfo::Component::Genre::Data: + if (this->component_->category() == TypeCategory::Derived) { + Descriptor &toCompDesc{this->componentDescriptor_.descriptor()}; + Descriptor &fromCompDesc{this->fromComponentDescriptor_.descriptor()}; + this->component_->CreatePointerDescriptor(toCompDesc, this->instance_, + workQueue.terminator(), this->subscripts_); + this->component_->CreatePointerDescriptor(fromCompDesc, *this->from_, + workQueue.terminator(), this->fromSubscripts_); + const auto *componentDerived{this->component_->derivedType()}; + this->Advance(); + if (int status{workQueue.BeginAssign(toCompDesc, fromCompDesc, flags_, + memmoveFct_, componentDerived)}; + status != StatOk) { + return status; + } + } else { // Component has intrinsic type; simply copy raw bytes + std::size_t componentByteSize{ + this->component_->SizeInBytes(this->instance_)}; + if (IS_COMPONENTWISE && toIsContiguous_ && fromIsContiguous_) { + std::size_t offset{this->component_->offset()}; + char *to{this->instance_.template OffsetElement(offset)}; + const char *from{ + this->from_->template OffsetElement(offset)}; + std::size_t toElementStride{this->instance_.ElementBytes()}; + std::size_t fromElementStride{ + this->from_->rank() == 0 ? 0 : this->from_->ElementBytes()}; + if (toElementStride == fromElementStride && + toElementStride == componentByteSize) { + memmoveFct_(to, from, this->elements_ * componentByteSize); + } else { + for (std::size_t n{this->elements_}; n--; + to += toElementStride, from += fromElementStride) { + memmoveFct_(to, from, componentByteSize); + } + } + this->Componentwise::Advance(); + } else { + memmoveFct_( + this->instance_.template Element(this->subscripts_) + + this->component_->offset(), + this->from_->template Element(this->fromSubscripts_) + + this->component_->offset(), + componentByteSize); + this->Advance(); + } + } + break; + case typeInfo::Component::Genre::Pointer: { + std::size_t componentByteSize{ + this->component_->SizeInBytes(this->instance_)}; + if (IS_COMPONENTWISE && toIsContiguous_ && fromIsContiguous_) { + std::size_t offset{this->component_->offset()}; + char *to{this->instance_.template OffsetElement(offset)}; + const char *from{ + this->from_->template OffsetElement(offset)}; + std::size_t toElementStride{this->instance_.ElementBytes()}; + std::size_t fromElementStride{ + this->from_->rank() == 0 ? 0 : this->from_->ElementBytes()}; + if (toElementStride == fromElementStride && + toElementStride == componentByteSize) { + memmoveFct_(to, from, this->elements_ * componentByteSize); + } else { + for (std::size_t n{this->elements_}; n--; + to += toElementStride, from += fromElementStride) { + memmoveFct_(to, from, componentByteSize); + } + } + this->Componentwise::Advance(); + } else { + memmoveFct_(this->instance_.template Element(this->subscripts_) + + this->component_->offset(), + this->from_->template Element(this->fromSubscripts_) + + this->component_->offset(), + componentByteSize); + this->Advance(); + } + } break; + case typeInfo::Component::Genre::Allocatable: + case typeInfo::Component::Genre::Automatic: { + auto *toDesc{reinterpret_cast( + this->instance_.template Element(this->subscripts_) + + this->component_->offset())}; + const auto *fromDesc{reinterpret_cast( + this->from_->template Element(this->fromSubscripts_) + + this->component_->offset())}; + const auto *componentDerived{this->component_->derivedType()}; + if (toDesc->IsAllocatable() && !fromDesc->IsAllocated()) { + if (toDesc->IsAllocated()) { + if (this->phase_ == 0) { + this->phase_++; + if (componentDerived && !componentDerived->noDestructionNeeded()) { + if (int status{workQueue.BeginDestroy( + *toDesc, *componentDerived, /*finalize=*/false)}; + status != StatOk) { + return status; + } + } + } + toDesc->Deallocate(); + } + this->Advance(); + } else { + // Allocatable components of the LHS are unconditionally + // deallocated before assignment (F'2018 10.2.1.3(13)(1)), + // unlike a "top-level" assignment to a variable, where + // deallocation is optional. + int nestedFlags{flags_}; + if (!componentDerived || + (componentDerived->noFinalizationNeeded() && + componentDerived->noInitializationNeeded() && + componentDerived->noDestructionNeeded())) { + // The actual deallocation might be avoidable when the existing + // location can be reoccupied. + nestedFlags |= MaybeReallocate | UpdateLHSBounds; + } else { + // Force LHS deallocation with DeallocateLHS flag. + nestedFlags |= DeallocateLHS; + } + this->Advance(); + if (int status{workQueue.BeginAssign(*toDesc, *fromDesc, nestedFlags, + memmoveFct_, componentDerived)}; + status != StatOk) { + return status; + } + } + } break; + } + } + if (deallocateAfter_) { + deallocateAfter_->Deallocate(); + } + return StatOk; +} +template RT_API_ATTRS int DerivedAssignTicket::Continue(WorkQueue &); +template RT_API_ATTRS int DerivedAssignTicket::Continue(WorkQueue &); RT_API_ATTRS void DoFromSourceAssign(Descriptor &alloc, const Descriptor &source, Terminator &terminator, MemmoveFct memmoveFct) { @@ -582,7 +783,6 @@ void RTDEF(AssignTemporary)(Descriptor &to, const Descriptor &from, } } } - Assign(to, from, terminator, MaybeReallocate | PolymorphicLHS); } @@ -599,7 +799,6 @@ void RTDEF(CopyInAssign)(Descriptor &temp, const Descriptor &var, void RTDEF(CopyOutAssign)( Descriptor *var, Descriptor &temp, const char *sourceFile, int sourceLine) { Terminator terminator{sourceFile, sourceLine}; - // Copyout from the temporary must not cause any finalizations // for LHS. The variable must be properly initialized already. if (var) { diff --git a/external/llvm-project/flang-rt/lib/runtime/derived.cpp b/external/llvm-project/flang-rt/lib/runtime/derived.cpp index 64a24b9052fe..4e36b1e2edfc 100644 --- a/external/llvm-project/flang-rt/lib/runtime/derived.cpp +++ b/external/llvm-project/flang-rt/lib/runtime/derived.cpp @@ -12,6 +12,7 @@ #include "flang-rt/runtime/terminator.h" #include "flang-rt/runtime/tools.h" #include "flang-rt/runtime/type-info.h" +#include "flang-rt/runtime/work-queue.h" namespace Fortran::runtime { @@ -30,180 +31,192 @@ static RT_API_ATTRS void GetComponentExtents(SubscriptValue (&extents)[maxRank], } RT_API_ATTRS int Initialize(const Descriptor &instance, - const typeInfo::DerivedType &derived, Terminator &terminator, bool hasStat, - const Descriptor *errMsg) { - const Descriptor &componentDesc{derived.component()}; - std::size_t elements{instance.Elements()}; - int stat{StatOk}; - // Initialize data components in each element; the per-element iterations - // constitute the inner loops, not the outer ones - std::size_t myComponents{componentDesc.Elements()}; - for (std::size_t k{0}; k < myComponents; ++k) { - const auto &comp{ - *componentDesc.ZeroBasedIndexedElement(k)}; - SubscriptValue at[maxRank]; - instance.GetLowerBounds(at); - if (comp.genre() == typeInfo::Component::Genre::Allocatable || - comp.genre() == typeInfo::Component::Genre::Automatic) { - for (std::size_t j{0}; j++ < elements; instance.IncrementSubscripts(at)) { - Descriptor &allocDesc{ - *instance.ElementComponent(at, comp.offset())}; - comp.EstablishDescriptor(allocDesc, instance, terminator); + const typeInfo::DerivedType &derived, Terminator &terminator, bool, + const Descriptor *) { + WorkQueue workQueue{terminator}; + int status{workQueue.BeginInitialize(instance, derived)}; + return status == StatContinue ? workQueue.Run() : status; +} + +RT_API_ATTRS int InitializeTicket::Begin(WorkQueue &) { + // Initialize procedure pointer components in each element + const Descriptor &procPtrDesc{derived_.procPtr()}; + if (std::size_t numProcPtrs{procPtrDesc.Elements()}) { + for (std::size_t k{0}; k < numProcPtrs; ++k) { + const auto &comp{ + *procPtrDesc.ZeroBasedIndexedElement(k)}; + // Loop only over elements + if (k > 0) { + Elementwise::Reset(); + } + for (; !Elementwise::IsComplete(); Elementwise::Advance()) { + auto &pptr{*instance_.ElementComponent( + subscripts_, comp.offset)}; + pptr = comp.procInitialization; + } + } + if (IsComplete()) { + return StatOk; + } + Elementwise::Reset(); + } + return StatContinue; +} + +RT_API_ATTRS int InitializeTicket::Continue(WorkQueue &workQueue) { + while (!IsComplete()) { + if (component_->genre() == typeInfo::Component::Genre::Allocatable) { + // Establish allocatable descriptors + for (; !Elementwise::IsComplete(); Elementwise::Advance()) { + Descriptor &allocDesc{*instance_.ElementComponent( + subscripts_, component_->offset())}; + component_->EstablishDescriptor( + allocDesc, instance_, workQueue.terminator()); allocDesc.raw().attribute = CFI_attribute_allocatable; - if (comp.genre() == typeInfo::Component::Genre::Automatic) { - stat = ReturnError( - terminator, allocDesc.Allocate(kNoAsyncObject), errMsg, hasStat); - if (stat == StatOk) { - if (const DescriptorAddendum * addendum{allocDesc.Addendum()}) { - if (const auto *derived{addendum->derivedType()}) { - if (!derived->noInitializationNeeded()) { - stat = Initialize( - allocDesc, *derived, terminator, hasStat, errMsg); - } - } - } - } - if (stat != StatOk) { - break; - } - } } - } else if (const void *init{comp.initialization()}) { + SkipToNextComponent(); + } else if (const void *init{component_->initialization()}) { // Explicit initialization of data pointers and // non-allocatable non-automatic components - std::size_t bytes{comp.SizeInBytes(instance)}; - for (std::size_t j{0}; j++ < elements; instance.IncrementSubscripts(at)) { - char *ptr{instance.ElementComponent(at, comp.offset())}; - Fortran::runtime::memcpy(ptr, init, bytes); + std::size_t bytes{component_->SizeInBytes(instance_)}; + for (; !Elementwise::IsComplete(); Elementwise::Advance()) { + char *ptr{instance_.ElementComponent( + subscripts_, component_->offset())}; + std::memcpy(ptr, init, bytes); } - } else if (comp.genre() == typeInfo::Component::Genre::Pointer) { + SkipToNextComponent(); + } else if (component_->genre() == typeInfo::Component::Genre::Pointer) { // Data pointers without explicit initialization are established // so that they are valid right-hand side targets of pointer // assignment statements. - for (std::size_t j{0}; j++ < elements; instance.IncrementSubscripts(at)) { - Descriptor &ptrDesc{ - *instance.ElementComponent(at, comp.offset())}; - comp.EstablishDescriptor(ptrDesc, instance, terminator); + for (; !Elementwise::IsComplete(); Elementwise::Advance()) { + Descriptor &ptrDesc{*instance_.ElementComponent( + subscripts_, component_->offset())}; + component_->EstablishDescriptor( + ptrDesc, instance_, workQueue.terminator()); ptrDesc.raw().attribute = CFI_attribute_pointer; } - } else if (comp.genre() == typeInfo::Component::Genre::Data && - comp.derivedType() && !comp.derivedType()->noInitializationNeeded()) { + SkipToNextComponent(); + } else if (component_->genre() == typeInfo::Component::Genre::Data && + component_->derivedType() && + !component_->derivedType()->noInitializationNeeded()) { // Default initialization of non-pointer non-allocatable/automatic - // data component. Handles parent component's elements. Recursive. + // data component. Handles parent component's elements. SubscriptValue extents[maxRank]; - GetComponentExtents(extents, comp, instance); - StaticDescriptor staticDescriptor; - Descriptor &compDesc{staticDescriptor.descriptor()}; - const typeInfo::DerivedType &compType{*comp.derivedType()}; - for (std::size_t j{0}; j++ < elements; instance.IncrementSubscripts(at)) { - compDesc.Establish(compType, - instance.ElementComponent(at, comp.offset()), comp.rank(), - extents); - stat = Initialize(compDesc, compType, terminator, hasStat, errMsg); - if (stat != StatOk) { - break; - } + GetComponentExtents(extents, *component_, instance_); + Descriptor &compDesc{componentDescriptor_.descriptor()}; + const typeInfo::DerivedType &compType{*component_->derivedType()}; + compDesc.Establish(compType, + instance_.ElementComponent(subscripts_, component_->offset()), + component_->rank(), extents); + Advance(); + if (int status{workQueue.BeginInitialize(compDesc, compType)}; + status != StatOk) { + return status; } + } else { + SkipToNextComponent(); } } - // Initialize procedure pointer components in each element - const Descriptor &procPtrDesc{derived.procPtr()}; - std::size_t myProcPtrs{procPtrDesc.Elements()}; - for (std::size_t k{0}; k < myProcPtrs; ++k) { - const auto &comp{ - *procPtrDesc.ZeroBasedIndexedElement(k)}; - SubscriptValue at[maxRank]; - instance.GetLowerBounds(at); - for (std::size_t j{0}; j++ < elements; instance.IncrementSubscripts(at)) { - auto &pptr{*instance.ElementComponent( - at, comp.offset)}; - pptr = comp.procInitialization; - } - } - return stat; + return StatOk; } RT_API_ATTRS int InitializeClone(const Descriptor &clone, - const Descriptor &orig, const typeInfo::DerivedType &derived, + const Descriptor &original, const typeInfo::DerivedType &derived, Terminator &terminator, bool hasStat, const Descriptor *errMsg) { - const Descriptor &componentDesc{derived.component()}; - std::size_t elements{orig.Elements()}; - int stat{StatOk}; - - // Skip pointers and unallocated variables. - if (orig.IsPointer() || !orig.IsAllocated()) { - return stat; + if (original.IsPointer() || !original.IsAllocated()) { + return StatOk; // nothing to do + } else { + WorkQueue workQueue{terminator}; + int status{workQueue.BeginInitializeClone( + clone, original, derived, hasStat, errMsg)}; + return status == StatContinue ? workQueue.Run() : status; } - // Initialize each data component. - std::size_t components{componentDesc.Elements()}; - for (std::size_t i{0}; i < components; ++i) { - const typeInfo::Component &comp{ - *componentDesc.ZeroBasedIndexedElement(i)}; - SubscriptValue at[maxRank]; - orig.GetLowerBounds(at); - // Allocate allocatable components that are also allocated in the original - // object. - if (comp.genre() == typeInfo::Component::Genre::Allocatable) { - // Initialize each element. - for (std::size_t j{0}; j < elements; ++j, orig.IncrementSubscripts(at)) { - Descriptor &origDesc{ - *orig.ElementComponent(at, comp.offset())}; - Descriptor &cloneDesc{ - *clone.ElementComponent(at, comp.offset())}; - if (origDesc.IsAllocated()) { +} + +RT_API_ATTRS int InitializeCloneTicket::Continue(WorkQueue &workQueue) { + while (!IsComplete()) { + if (component_->genre() == typeInfo::Component::Genre::Allocatable) { + Descriptor &origDesc{*instance_.ElementComponent( + subscripts_, component_->offset())}; + if (origDesc.IsAllocated()) { + Descriptor &cloneDesc{*clone_.ElementComponent( + subscripts_, component_->offset())}; + if (phase_ == 0) { + ++phase_; cloneDesc.ApplyMold(origDesc, origDesc.rank()); - stat = ReturnError( - terminator, cloneDesc.Allocate(kNoAsyncObject), errMsg, hasStat); - if (stat == StatOk) { - if (const DescriptorAddendum * addendum{cloneDesc.Addendum()}) { - if (const typeInfo::DerivedType * - derived{addendum->derivedType()}) { - if (!derived->noInitializationNeeded()) { - // Perform default initialization for the allocated element. - stat = Initialize( - cloneDesc, *derived, terminator, hasStat, errMsg); - } - // Initialize derived type's allocatables. - if (stat == StatOk) { - stat = InitializeClone(cloneDesc, origDesc, *derived, - terminator, hasStat, errMsg); + if (int stat{ReturnError(workQueue.terminator(), + cloneDesc.Allocate(kNoAsyncObject), errMsg_, hasStat_)}; + stat != StatOk) { + return stat; + } + if (const DescriptorAddendum *addendum{cloneDesc.Addendum()}) { + if (const typeInfo::DerivedType *derived{addendum->derivedType()}) { + if (!derived->noInitializationNeeded()) { + // Perform default initialization for the allocated element. + if (int status{workQueue.BeginInitialize(cloneDesc, *derived)}; + status != StatOk) { + return status; } } } } } - if (stat != StatOk) { - break; + if (phase_ == 1) { + ++phase_; + if (const DescriptorAddendum *addendum{cloneDesc.Addendum()}) { + if (const typeInfo::DerivedType *derived{addendum->derivedType()}) { + // Initialize derived type's allocatables. + if (int status{workQueue.BeginInitializeClone( + cloneDesc, origDesc, *derived, hasStat_, errMsg_)}; + status != StatOk) { + return status; + } + } + } } } - } else if (comp.genre() == typeInfo::Component::Genre::Data && - comp.derivedType()) { - // Handle nested derived types. - const typeInfo::DerivedType &compType{*comp.derivedType()}; - SubscriptValue extents[maxRank]; - GetComponentExtents(extents, comp, orig); - // Data components don't have descriptors, allocate them. - StaticDescriptor origStaticDesc; - StaticDescriptor cloneStaticDesc; - Descriptor &origDesc{origStaticDesc.descriptor()}; - Descriptor &cloneDesc{cloneStaticDesc.descriptor()}; - // Initialize each element. - for (std::size_t j{0}; j < elements; ++j, orig.IncrementSubscripts(at)) { + Advance(); + } else if (component_->genre() == typeInfo::Component::Genre::Data) { + if (component_->derivedType()) { + // Handle nested derived types. + const typeInfo::DerivedType &compType{*component_->derivedType()}; + SubscriptValue extents[maxRank]; + GetComponentExtents(extents, *component_, instance_); + Descriptor &origDesc{componentDescriptor_.descriptor()}; + Descriptor &cloneDesc{cloneComponentDescriptor_.descriptor()}; origDesc.Establish(compType, - orig.ElementComponent(at, comp.offset()), comp.rank(), - extents); + instance_.ElementComponent(subscripts_, component_->offset()), + component_->rank(), extents); cloneDesc.Establish(compType, - clone.ElementComponent(at, comp.offset()), comp.rank(), - extents); - stat = InitializeClone( - cloneDesc, origDesc, compType, terminator, hasStat, errMsg); - if (stat != StatOk) { - break; + clone_.ElementComponent(subscripts_, component_->offset()), + component_->rank(), extents); + Advance(); + if (int status{workQueue.BeginInitializeClone( + cloneDesc, origDesc, compType, hasStat_, errMsg_)}; + status != StatOk) { + return status; } + } else { + SkipToNextComponent(); } + } else { + SkipToNextComponent(); + } + } + return StatOk; +} + +// Fortran 2018 subclause 7.5.6.2 +RT_API_ATTRS void Finalize(const Descriptor &descriptor, + const typeInfo::DerivedType &derived, Terminator *terminator) { + if (!derived.noFinalizationNeeded() && descriptor.IsAllocated()) { + Terminator stubTerminator{"Finalize() in Fortran runtime", 0}; + WorkQueue workQueue{terminator ? *terminator : stubTerminator}; + if (workQueue.BeginFinalize(descriptor, derived) == StatContinue) { + workQueue.Run(); } } - return stat; } static RT_API_ATTRS const typeInfo::SpecialBinding *FindFinal( @@ -221,7 +234,7 @@ static RT_API_ATTRS const typeInfo::SpecialBinding *FindFinal( } static RT_API_ATTRS void CallFinalSubroutine(const Descriptor &descriptor, - const typeInfo::DerivedType &derived, Terminator *terminator) { + const typeInfo::DerivedType &derived, Terminator &terminator) { if (const auto *special{FindFinal(derived, descriptor.rank())}) { if (special->which() == typeInfo::SpecialBinding::Which::ElementalFinal) { std::size_t elements{descriptor.Elements()}; @@ -258,9 +271,7 @@ static RT_API_ATTRS void CallFinalSubroutine(const Descriptor &descriptor, copy = descriptor; copy.set_base_addr(nullptr); copy.raw().attribute = CFI_attribute_allocatable; - Terminator stubTerminator{"CallFinalProcedure() in Fortran runtime", 0}; - RUNTIME_CHECK(terminator ? *terminator : stubTerminator, - copy.Allocate(kNoAsyncObject) == CFI_SUCCESS); + RUNTIME_CHECK(terminator, copy.Allocate(kNoAsyncObject) == CFI_SUCCESS); ShallowCopyDiscontiguousToContiguous(copy, descriptor); argDescriptor = © } @@ -284,87 +295,94 @@ static RT_API_ATTRS void CallFinalSubroutine(const Descriptor &descriptor, } } -// Fortran 2018 subclause 7.5.6.2 -RT_API_ATTRS void Finalize(const Descriptor &descriptor, - const typeInfo::DerivedType &derived, Terminator *terminator) { - if (derived.noFinalizationNeeded() || !descriptor.IsAllocated()) { - return; - } - CallFinalSubroutine(descriptor, derived, terminator); - const auto *parentType{derived.GetParentType()}; - bool recurse{parentType && !parentType->noFinalizationNeeded()}; +RT_API_ATTRS int FinalizeTicket::Begin(WorkQueue &workQueue) { + CallFinalSubroutine(instance_, derived_, workQueue.terminator()); // If there's a finalizable parent component, handle it last, as required // by the Fortran standard (7.5.6.2), and do so recursively with the same // descriptor so that the rank is preserved. - const Descriptor &componentDesc{derived.component()}; - std::size_t myComponents{componentDesc.Elements()}; - std::size_t elements{descriptor.Elements()}; - for (auto k{recurse ? std::size_t{1} - /* skip first component, it's the parent */ - : 0}; - k < myComponents; ++k) { - const auto &comp{ - *componentDesc.ZeroBasedIndexedElement(k)}; - SubscriptValue at[maxRank]; - descriptor.GetLowerBounds(at); - if (comp.genre() == typeInfo::Component::Genre::Allocatable && - comp.category() == TypeCategory::Derived) { + finalizableParentType_ = derived_.GetParentType(); + if (finalizableParentType_) { + if (finalizableParentType_->noFinalizationNeeded()) { + finalizableParentType_ = nullptr; + } else { + SkipToNextComponent(); + } + } + return StatContinue; +} + +RT_API_ATTRS int FinalizeTicket::Continue(WorkQueue &workQueue) { + while (!IsComplete()) { + if (component_->genre() == typeInfo::Component::Genre::Allocatable && + component_->category() == TypeCategory::Derived) { // Component may be polymorphic or unlimited polymorphic. Need to use the // dynamic type to check whether finalization is needed. - for (std::size_t j{0}; j++ < elements; - descriptor.IncrementSubscripts(at)) { - const Descriptor &compDesc{ - *descriptor.ElementComponent(at, comp.offset())}; - if (compDesc.IsAllocated()) { - if (const DescriptorAddendum * addendum{compDesc.Addendum()}) { - if (const typeInfo::DerivedType * - compDynamicType{addendum->derivedType()}) { - if (!compDynamicType->noFinalizationNeeded()) { - Finalize(compDesc, *compDynamicType, terminator); + const Descriptor &compDesc{*instance_.ElementComponent( + subscripts_, component_->offset())}; + Advance(); + if (compDesc.IsAllocated()) { + if (const DescriptorAddendum *addendum{compDesc.Addendum()}) { + if (const typeInfo::DerivedType *compDynamicType{ + addendum->derivedType()}) { + if (!compDynamicType->noFinalizationNeeded()) { + if (int status{ + workQueue.BeginFinalize(compDesc, *compDynamicType)}; + status != StatOk) { + return status; } } } } } - } else if (comp.genre() == typeInfo::Component::Genre::Allocatable || - comp.genre() == typeInfo::Component::Genre::Automatic) { - if (const typeInfo::DerivedType * compType{comp.derivedType()}) { - if (!compType->noFinalizationNeeded()) { - for (std::size_t j{0}; j++ < elements; - descriptor.IncrementSubscripts(at)) { - const Descriptor &compDesc{ - *descriptor.ElementComponent(at, comp.offset())}; - if (compDesc.IsAllocated()) { - Finalize(compDesc, *compType, terminator); - } + } else if (component_->genre() == typeInfo::Component::Genre::Allocatable || + component_->genre() == typeInfo::Component::Genre::Automatic) { + if (const typeInfo::DerivedType *compType{component_->derivedType()}; + compType && !compType->noFinalizationNeeded()) { + const Descriptor &compDesc{*instance_.ElementComponent( + subscripts_, component_->offset())}; + Advance(); + if (compDesc.IsAllocated()) { + if (int status{workQueue.BeginFinalize(compDesc, *compType)}; + status != StatOk) { + return status; } } + } else { + SkipToNextComponent(); } - } else if (comp.genre() == typeInfo::Component::Genre::Data && - comp.derivedType() && !comp.derivedType()->noFinalizationNeeded()) { + } else if (component_->genre() == typeInfo::Component::Genre::Data && + component_->derivedType() && + !component_->derivedType()->noFinalizationNeeded()) { SubscriptValue extents[maxRank]; - GetComponentExtents(extents, comp, descriptor); - StaticDescriptor staticDescriptor; - Descriptor &compDesc{staticDescriptor.descriptor()}; - const typeInfo::DerivedType &compType{*comp.derivedType()}; - for (std::size_t j{0}; j++ < elements; - descriptor.IncrementSubscripts(at)) { - compDesc.Establish(compType, - descriptor.ElementComponent(at, comp.offset()), comp.rank(), - extents); - Finalize(compDesc, compType, terminator); + GetComponentExtents(extents, *component_, instance_); + Descriptor &compDesc{componentDescriptor_.descriptor()}; + const typeInfo::DerivedType &compType{*component_->derivedType()}; + compDesc.Establish(compType, + instance_.ElementComponent(subscripts_, component_->offset()), + component_->rank(), extents); + Advance(); + if (int status{workQueue.BeginFinalize(compDesc, compType)}; + status != StatOk) { + return status; } + } else { + SkipToNextComponent(); } } - if (recurse) { - StaticDescriptor statDesc; - Descriptor &tmpDesc{statDesc.descriptor()}; - tmpDesc = descriptor; + // Last, do the parent component, if any and finalizable. + if (finalizableParentType_) { + Descriptor &tmpDesc{componentDescriptor_.descriptor()}; + tmpDesc = instance_; tmpDesc.raw().attribute = CFI_attribute_pointer; - tmpDesc.Addendum()->set_derivedType(parentType); - tmpDesc.raw().elem_len = parentType->sizeInBytes(); - Finalize(tmpDesc, *parentType, terminator); + tmpDesc.Addendum()->set_derivedType(finalizableParentType_); + tmpDesc.raw().elem_len = finalizableParentType_->sizeInBytes(); + const auto &parentType{*finalizableParentType_}; + finalizableParentType_ = nullptr; + // Don't return StatOk here if the nested FInalize is still running; + // it needs this->componentDescriptor_. + return workQueue.BeginFinalize(tmpDesc, parentType); } + return StatOk; } // The order of finalization follows Fortran 2018 7.5.6.2, with @@ -373,51 +391,71 @@ RT_API_ATTRS void Finalize(const Descriptor &descriptor, // preceding any deallocation. RT_API_ATTRS void Destroy(const Descriptor &descriptor, bool finalize, const typeInfo::DerivedType &derived, Terminator *terminator) { - if (derived.noDestructionNeeded() || !descriptor.IsAllocated()) { - return; + if (descriptor.IsAllocated() && !derived.noDestructionNeeded()) { + Terminator stubTerminator{"Destroy() in Fortran runtime", 0}; + WorkQueue workQueue{terminator ? *terminator : stubTerminator}; + if (workQueue.BeginDestroy(descriptor, derived, finalize) == StatContinue) { + workQueue.Run(); + } } - if (finalize && !derived.noFinalizationNeeded()) { - Finalize(descriptor, derived, terminator); +} + +RT_API_ATTRS int DestroyTicket::Begin(WorkQueue &workQueue) { + if (finalize_ && !derived_.noFinalizationNeeded()) { + if (int status{workQueue.BeginFinalize(instance_, derived_)}; + status != StatOk && status != StatContinue) { + return status; + } } + return StatContinue; +} + +RT_API_ATTRS int DestroyTicket::Continue(WorkQueue &workQueue) { // Deallocate all direct and indirect allocatable and automatic components. // Contrary to finalization, the order of deallocation does not matter. - const Descriptor &componentDesc{derived.component()}; - std::size_t myComponents{componentDesc.Elements()}; - std::size_t elements{descriptor.Elements()}; - SubscriptValue at[maxRank]; - descriptor.GetLowerBounds(at); - for (std::size_t k{0}; k < myComponents; ++k) { - const auto &comp{ - *componentDesc.ZeroBasedIndexedElement(k)}; - const bool destroyComp{ - comp.derivedType() && !comp.derivedType()->noDestructionNeeded()}; - if (comp.genre() == typeInfo::Component::Genre::Allocatable || - comp.genre() == typeInfo::Component::Genre::Automatic) { - for (std::size_t j{0}; j < elements; ++j) { - Descriptor *d{ - descriptor.ElementComponent(at, comp.offset())}; - if (destroyComp) { - Destroy(*d, /*finalize=*/false, *comp.derivedType(), terminator); + while (!IsComplete()) { + const auto *componentDerived{component_->derivedType()}; + if (component_->genre() == typeInfo::Component::Genre::Allocatable || + component_->genre() == typeInfo::Component::Genre::Automatic) { + Descriptor *d{instance_.ElementComponent( + subscripts_, component_->offset())}; + if (d->IsAllocated()) { + if (phase_ == 0) { + ++phase_; + if (componentDerived && !componentDerived->noDestructionNeeded()) { + if (int status{workQueue.BeginDestroy( + *d, *componentDerived, /*finalize=*/false)}; + status != StatOk) { + return status; + } + } } d->Deallocate(); - descriptor.IncrementSubscripts(at); } - } else if (destroyComp && - comp.genre() == typeInfo::Component::Genre::Data) { - SubscriptValue extents[maxRank]; - GetComponentExtents(extents, comp, descriptor); - StaticDescriptor staticDescriptor; - Descriptor &compDesc{staticDescriptor.descriptor()}; - const typeInfo::DerivedType &compType{*comp.derivedType()}; - for (std::size_t j{0}; j++ < elements; - descriptor.IncrementSubscripts(at)) { + Advance(); + } else if (component_->genre() == typeInfo::Component::Genre::Data) { + if (!componentDerived || componentDerived->noDestructionNeeded()) { + SkipToNextComponent(); + } else { + SubscriptValue extents[maxRank]; + GetComponentExtents(extents, *component_, instance_); + Descriptor &compDesc{componentDescriptor_.descriptor()}; + const typeInfo::DerivedType &compType{*componentDerived}; compDesc.Establish(compType, - descriptor.ElementComponent(at, comp.offset()), comp.rank(), - extents); - Destroy(compDesc, /*finalize=*/false, *comp.derivedType(), terminator); + instance_.ElementComponent(subscripts_, component_->offset()), + component_->rank(), extents); + Advance(); + if (int status{workQueue.BeginDestroy( + compDesc, *componentDerived, /*finalize=*/false)}; + status != StatOk) { + return status; + } } + } else { + SkipToNextComponent(); } } + return StatOk; } RT_API_ATTRS bool HasDynamicComponent(const Descriptor &descriptor) { diff --git a/external/llvm-project/flang-rt/lib/runtime/descriptor-io.cpp b/external/llvm-project/flang-rt/lib/runtime/descriptor-io.cpp index aa72f40d8019..ce080adbc916 100644 --- a/external/llvm-project/flang-rt/lib/runtime/descriptor-io.cpp +++ b/external/llvm-project/flang-rt/lib/runtime/descriptor-io.cpp @@ -7,15 +7,44 @@ //===----------------------------------------------------------------------===// #include "descriptor-io.h" +#include "edit-input.h" +#include "edit-output.h" +#include "unit.h" +#include "flang-rt/runtime/descriptor.h" +#include "flang-rt/runtime/io-stmt.h" +#include "flang-rt/runtime/namelist.h" +#include "flang-rt/runtime/terminator.h" +#include "flang-rt/runtime/type-info.h" +#include "flang-rt/runtime/work-queue.h" +#include "flang/Common/optional.h" #include "flang/Common/restorer.h" +#include "flang/Common/uint128.h" +#include "flang/Runtime/cpp-type.h" #include "flang/Runtime/freestanding-tools.h" +// Implementation of I/O data list item transfers based on descriptors. +// (All I/O items come through here so that the code is exercised for test; +// some scalar I/O data transfer APIs could be changed to bypass their use +// of descriptors in the future for better efficiency.) + namespace Fortran::runtime::io::descr { RT_OFFLOAD_API_GROUP_BEGIN +template +inline RT_API_ATTRS A &ExtractElement(IoStatementState &io, + const Descriptor &descriptor, const SubscriptValue subscripts[]) { + A *p{descriptor.Element(subscripts)}; + if (!p) { + io.GetIoErrorHandler().Crash("Bad address for I/O item -- null base " + "address or subscripts out of range"); + } + return *p; +} + // Defined formatted I/O (maybe) -Fortran::common::optional DefinedFormattedIo(IoStatementState &io, - const Descriptor &descriptor, const typeInfo::DerivedType &derived, +static RT_API_ATTRS Fortran::common::optional DefinedFormattedIo( + IoStatementState &io, const Descriptor &descriptor, + const typeInfo::DerivedType &derived, const typeInfo::SpecialBinding &special, const SubscriptValue subscripts[]) { Fortran::common::optional peek{ @@ -65,10 +94,13 @@ Fortran::common::optional DefinedFormattedIo(IoStatementState &io, // I/O subroutine reads counts towards READ(SIZE=). startPos = io.InquirePos(); } + const auto *bindings{ + derived.binding().OffsetElement()}; if (special.IsArgDescriptor(0)) { // "dtv" argument is "class(t)", pass a descriptor auto *p{special.GetProc()}; + const Descriptor &, int &, char *, std::size_t, std::size_t)>( + bindings)}; StaticDescriptor<1, true, 10 /*?*/> elementStatDesc; Descriptor &elementDesc{elementStatDesc.descriptor()}; elementDesc.Establish( @@ -79,7 +111,8 @@ Fortran::common::optional DefinedFormattedIo(IoStatementState &io, } else { // "dtv" argument is "type(t)", pass a raw pointer auto *p{special.GetProc()}; + const Descriptor &, int &, char *, std::size_t, std::size_t)>( + bindings)}; p(descriptor.Element(subscripts), unit, ioType, vListDesc, ioStat, ioMsg, ioTypeLen, sizeof ioMsg); } @@ -104,8 +137,8 @@ Fortran::common::optional DefinedFormattedIo(IoStatementState &io, } // Defined unformatted I/O -bool DefinedUnformattedIo(IoStatementState &io, const Descriptor &descriptor, - const typeInfo::DerivedType &derived, +static RT_API_ATTRS bool DefinedUnformattedIo(IoStatementState &io, + const Descriptor &descriptor, const typeInfo::DerivedType &derived, const typeInfo::SpecialBinding &special) { // Unformatted I/O must have an external unit (or child thereof). IoErrorHandler &handler{io.GetIoErrorHandler()}; @@ -121,10 +154,12 @@ bool DefinedUnformattedIo(IoStatementState &io, const Descriptor &descriptor, std::size_t numElements{descriptor.Elements()}; SubscriptValue subscripts[maxRank]; descriptor.GetLowerBounds(subscripts); + const auto *bindings{ + derived.binding().OffsetElement()}; if (special.IsArgDescriptor(0)) { // "dtv" argument is "class(t)", pass a descriptor auto *p{special.GetProc()}; + const Descriptor &, int &, int &, char *, std::size_t)>(bindings)}; StaticDescriptor<1, true, 10 /*?*/> elementStatDesc; Descriptor &elementDesc{elementStatDesc.descriptor()}; elementDesc.Establish(derived, nullptr, 0, nullptr, CFI_attribute_pointer); @@ -137,8 +172,9 @@ bool DefinedUnformattedIo(IoStatementState &io, const Descriptor &descriptor, } } else { // "dtv" argument is "type(t)", pass a raw pointer - auto *p{special.GetProc()}; + auto *p{special + .GetProc( + bindings)}; for (; numElements-- > 0; descriptor.IncrementSubscripts(subscripts)) { p(descriptor.Element(subscripts), unit, ioStat, ioMsg, sizeof ioMsg); @@ -152,5 +188,619 @@ bool DefinedUnformattedIo(IoStatementState &io, const Descriptor &descriptor, return handler.GetIoStat() == IostatOk; } +// Per-category descriptor-based I/O templates + +// TODO (perhaps as a nontrivial but small starter project): implement +// automatic repetition counts, like "10*3.14159", for list-directed and +// NAMELIST array output. + +template +inline RT_API_ATTRS bool FormattedIntegerIO(IoStatementState &io, + const Descriptor &descriptor, [[maybe_unused]] bool isSigned) { + std::size_t numElements{descriptor.Elements()}; + SubscriptValue subscripts[maxRank]; + descriptor.GetLowerBounds(subscripts); + using IntType = CppTypeFor; + bool anyInput{false}; + for (std::size_t j{0}; j < numElements; ++j) { + if (auto edit{io.GetNextDataEdit()}) { + IntType &x{ExtractElement(io, descriptor, subscripts)}; + if constexpr (DIR == Direction::Output) { + if (!EditIntegerOutput(io, *edit, x, isSigned)) { + return false; + } + } else if (edit->descriptor != DataEdit::ListDirectedNullValue) { + if (EditIntegerInput( + io, *edit, reinterpret_cast(&x), KIND, isSigned)) { + anyInput = true; + } else { + return anyInput && edit->IsNamelist(); + } + } + if (!descriptor.IncrementSubscripts(subscripts) && j + 1 < numElements) { + io.GetIoErrorHandler().Crash( + "FormattedIntegerIO: subscripts out of bounds"); + } + } else { + return false; + } + } + return true; +} + +template +inline RT_API_ATTRS bool FormattedRealIO( + IoStatementState &io, const Descriptor &descriptor) { + std::size_t numElements{descriptor.Elements()}; + SubscriptValue subscripts[maxRank]; + descriptor.GetLowerBounds(subscripts); + using RawType = typename RealOutputEditing::BinaryFloatingPoint; + bool anyInput{false}; + for (std::size_t j{0}; j < numElements; ++j) { + if (auto edit{io.GetNextDataEdit()}) { + RawType &x{ExtractElement(io, descriptor, subscripts)}; + if constexpr (DIR == Direction::Output) { + if (!RealOutputEditing{io, x}.Edit(*edit)) { + return false; + } + } else if (edit->descriptor != DataEdit::ListDirectedNullValue) { + if (EditRealInput(io, *edit, reinterpret_cast(&x))) { + anyInput = true; + } else { + return anyInput && edit->IsNamelist(); + } + } + if (!descriptor.IncrementSubscripts(subscripts) && j + 1 < numElements) { + io.GetIoErrorHandler().Crash( + "FormattedRealIO: subscripts out of bounds"); + } + } else { + return false; + } + } + return true; +} + +template +inline RT_API_ATTRS bool FormattedComplexIO( + IoStatementState &io, const Descriptor &descriptor) { + std::size_t numElements{descriptor.Elements()}; + SubscriptValue subscripts[maxRank]; + descriptor.GetLowerBounds(subscripts); + bool isListOutput{ + io.get_if>() != nullptr}; + using RawType = typename RealOutputEditing::BinaryFloatingPoint; + bool anyInput{false}; + for (std::size_t j{0}; j < numElements; ++j) { + RawType *x{&ExtractElement(io, descriptor, subscripts)}; + if (isListOutput) { + DataEdit rEdit, iEdit; + rEdit.descriptor = DataEdit::ListDirectedRealPart; + iEdit.descriptor = DataEdit::ListDirectedImaginaryPart; + rEdit.modes = iEdit.modes = io.mutableModes(); + if (!RealOutputEditing{io, x[0]}.Edit(rEdit) || + !RealOutputEditing{io, x[1]}.Edit(iEdit)) { + return false; + } + } else { + for (int k{0}; k < 2; ++k, ++x) { + auto edit{io.GetNextDataEdit()}; + if (!edit) { + return false; + } else if constexpr (DIR == Direction::Output) { + if (!RealOutputEditing{io, *x}.Edit(*edit)) { + return false; + } + } else if (edit->descriptor == DataEdit::ListDirectedNullValue) { + break; + } else if (EditRealInput( + io, *edit, reinterpret_cast(x))) { + anyInput = true; + } else { + return anyInput && edit->IsNamelist(); + } + } + } + if (!descriptor.IncrementSubscripts(subscripts) && j + 1 < numElements) { + io.GetIoErrorHandler().Crash( + "FormattedComplexIO: subscripts out of bounds"); + } + } + return true; +} + +template +inline RT_API_ATTRS bool FormattedCharacterIO( + IoStatementState &io, const Descriptor &descriptor) { + std::size_t numElements{descriptor.Elements()}; + SubscriptValue subscripts[maxRank]; + descriptor.GetLowerBounds(subscripts); + std::size_t length{descriptor.ElementBytes() / sizeof(A)}; + auto *listOutput{io.get_if>()}; + bool anyInput{false}; + for (std::size_t j{0}; j < numElements; ++j) { + A *x{&ExtractElement(io, descriptor, subscripts)}; + if (listOutput) { + if (!ListDirectedCharacterOutput(io, *listOutput, x, length)) { + return false; + } + } else if (auto edit{io.GetNextDataEdit()}) { + if constexpr (DIR == Direction::Output) { + if (!EditCharacterOutput(io, *edit, x, length)) { + return false; + } + } else { // input + if (edit->descriptor != DataEdit::ListDirectedNullValue) { + if (EditCharacterInput(io, *edit, x, length)) { + anyInput = true; + } else { + return anyInput && edit->IsNamelist(); + } + } + } + } else { + return false; + } + if (!descriptor.IncrementSubscripts(subscripts) && j + 1 < numElements) { + io.GetIoErrorHandler().Crash( + "FormattedCharacterIO: subscripts out of bounds"); + } + } + return true; +} + +template +inline RT_API_ATTRS bool FormattedLogicalIO( + IoStatementState &io, const Descriptor &descriptor) { + std::size_t numElements{descriptor.Elements()}; + SubscriptValue subscripts[maxRank]; + descriptor.GetLowerBounds(subscripts); + auto *listOutput{io.get_if>()}; + using IntType = CppTypeFor; + bool anyInput{false}; + for (std::size_t j{0}; j < numElements; ++j) { + IntType &x{ExtractElement(io, descriptor, subscripts)}; + if (listOutput) { + if (!ListDirectedLogicalOutput(io, *listOutput, x != 0)) { + return false; + } + } else if (auto edit{io.GetNextDataEdit()}) { + if constexpr (DIR == Direction::Output) { + if (!EditLogicalOutput(io, *edit, x != 0)) { + return false; + } + } else { + if (edit->descriptor != DataEdit::ListDirectedNullValue) { + bool truth{}; + if (EditLogicalInput(io, *edit, truth)) { + x = truth; + anyInput = true; + } else { + return anyInput && edit->IsNamelist(); + } + } + } + } else { + return false; + } + if (!descriptor.IncrementSubscripts(subscripts) && j + 1 < numElements) { + io.GetIoErrorHandler().Crash( + "FormattedLogicalIO: subscripts out of bounds"); + } + } + return true; +} + +template +RT_API_ATTRS int DerivedIoTicket::Continue(WorkQueue &workQueue) { + while (!IsComplete()) { + if (component_->genre() == typeInfo::Component::Genre::Data) { + // Create a descriptor for the component + Descriptor &compDesc{componentDescriptor_.descriptor()}; + component_->CreatePointerDescriptor( + compDesc, instance_, io_.GetIoErrorHandler(), subscripts_); + Advance(); + if (int status{workQueue.BeginDescriptorIo( + io_, compDesc, table_, anyIoTookPlace_)}; + status != StatOk) { + return status; + } + } else { + // Component is itself a descriptor + char *pointer{ + instance_.Element(subscripts_) + component_->offset()}; + const Descriptor &compDesc{ + *reinterpret_cast(pointer)}; + Advance(); + if (compDesc.IsAllocated()) { + if (int status{workQueue.BeginDescriptorIo( + io_, compDesc, table_, anyIoTookPlace_)}; + status != StatOk) { + return status; + } + } + } + } + return StatOk; +} + +template RT_API_ATTRS int DerivedIoTicket::Continue( + WorkQueue &); +template RT_API_ATTRS int DerivedIoTicket::Continue( + WorkQueue &); + +template +RT_API_ATTRS int DescriptorIoTicket::Begin(WorkQueue &workQueue) { + IoErrorHandler &handler{io_.GetIoErrorHandler()}; + if (handler.InError()) { + return handler.GetIoStat(); + } + if (!io_.get_if>()) { + handler.Crash("DescriptorIO() called for wrong I/O direction"); + return handler.GetIoStat(); + } + if constexpr (DIR == Direction::Input) { + if (!io_.BeginReadingRecord()) { + return StatOk; + } + } + if (!io_.get_if>()) { + // Unformatted I/O + IoErrorHandler &handler{io_.GetIoErrorHandler()}; + const DescriptorAddendum *addendum{instance_.Addendum()}; + if (const typeInfo::DerivedType *type{ + addendum ? addendum->derivedType() : nullptr}) { + // derived type unformatted I/O + if (table_) { + if (const auto *definedIo{table_->Find(*type, + DIR == Direction::Input + ? common::DefinedIo::ReadUnformatted + : common::DefinedIo::WriteUnformatted)}) { + if (definedIo->subroutine) { + typeInfo::SpecialBinding special{DIR == Direction::Input + ? typeInfo::SpecialBinding::Which::ReadUnformatted + : typeInfo::SpecialBinding::Which::WriteUnformatted, + definedIo->subroutine, definedIo->isDtvArgPolymorphic, false, + false}; + if (DefinedUnformattedIo(io_, instance_, *type, special)) { + anyIoTookPlace_ = true; + return StatOk; + } + } else { + int status{workQueue.BeginDerivedIo( + io_, instance_, *type, table_, anyIoTookPlace_)}; + return status == StatContinue ? StatOk : status; // done here + } + } + } + if (const typeInfo::SpecialBinding *special{ + type->FindSpecialBinding(DIR == Direction::Input + ? typeInfo::SpecialBinding::Which::ReadUnformatted + : typeInfo::SpecialBinding::Which::WriteUnformatted)}) { + if (!table_ || !table_->ignoreNonTbpEntries || special->IsTypeBound()) { + // defined derived type unformatted I/O + if (DefinedUnformattedIo(io_, instance_, *type, *special)) { + anyIoTookPlace_ = true; + return StatOk; + } else { + return IostatEnd; + } + } + } + // Default derived type unformatted I/O + // TODO: If no component at any level has defined READ or WRITE + // (as appropriate), the elements are contiguous, and no byte swapping + // is active, do a block transfer via the code below. + int status{workQueue.BeginDerivedIo( + io_, instance_, *type, table_, anyIoTookPlace_)}; + return status == StatContinue ? StatOk : status; // done here + } else { + // intrinsic type unformatted I/O + auto *externalUnf{io_.get_if>()}; + ChildUnformattedIoStatementState *childUnf{nullptr}; + InquireIOLengthState *inq{nullptr}; + bool swapEndianness{false}; + if (externalUnf) { + swapEndianness = externalUnf->unit().swapEndianness(); + } else { + childUnf = io_.get_if>(); + if (!childUnf) { + inq = DIR == Direction::Output ? io_.get_if() + : nullptr; + RUNTIME_CHECK(handler, inq != nullptr); + } + } + std::size_t elementBytes{instance_.ElementBytes()}; + std::size_t swappingBytes{elementBytes}; + if (auto maybeCatAndKind{instance_.type().GetCategoryAndKind()}) { + // Byte swapping units can be smaller than elements, namely + // for COMPLEX and CHARACTER. + if (maybeCatAndKind->first == TypeCategory::Character) { + // swap each character position independently + swappingBytes = maybeCatAndKind->second; // kind + } else if (maybeCatAndKind->first == TypeCategory::Complex) { + // swap real and imaginary components independently + swappingBytes /= 2; + } + } + using CharType = + std::conditional_t; + auto Transfer{[=](CharType &x, std::size_t totalBytes) -> bool { + if constexpr (DIR == Direction::Output) { + return externalUnf ? externalUnf->Emit(&x, totalBytes, swappingBytes) + : childUnf ? childUnf->Emit(&x, totalBytes, swappingBytes) + : inq->Emit(&x, totalBytes, swappingBytes); + } else { + return externalUnf + ? externalUnf->Receive(&x, totalBytes, swappingBytes) + : childUnf->Receive(&x, totalBytes, swappingBytes); + } + }}; + if (!swapEndianness && + instance_.IsContiguous()) { // contiguous unformatted I/O + char &x{ExtractElement(io_, instance_, subscripts_)}; + if (Transfer(x, elements_ * elementBytes)) { + anyIoTookPlace_ = true; + } else { + return IostatEnd; + } + } else { // non-contiguous or byte-swapped intrinsic type unformatted I/O + for (; !IsComplete(); Advance()) { + char &x{ExtractElement(io_, instance_, subscripts_)}; + if (Transfer(x, elementBytes)) { + anyIoTookPlace_ = true; + } else { + return IostatEnd; + } + } + } + } + // Unformatted I/O never needs to call Continue(). + return StatOk; + } + // Formatted I/O + if (auto catAndKind{instance_.type().GetCategoryAndKind()}) { + TypeCategory cat{catAndKind->first}; + int kind{catAndKind->second}; + bool any{false}; + switch (cat) { + case TypeCategory::Integer: + switch (kind) { + case 1: + any = FormattedIntegerIO<1, DIR>(io_, instance_, true); + break; + case 2: + any = FormattedIntegerIO<2, DIR>(io_, instance_, true); + break; + case 4: + any = FormattedIntegerIO<4, DIR>(io_, instance_, true); + break; + case 8: + any = FormattedIntegerIO<8, DIR>(io_, instance_, true); + break; + case 16: + any = FormattedIntegerIO<16, DIR>(io_, instance_, true); + break; + default: + handler.Crash( + "not yet implemented: INTEGER(KIND=%d) in formatted IO", kind); + return IostatEnd; + } + break; + case TypeCategory::Unsigned: + switch (kind) { + case 1: + any = FormattedIntegerIO<1, DIR>(io_, instance_, false); + break; + case 2: + any = FormattedIntegerIO<2, DIR>(io_, instance_, false); + break; + case 4: + any = FormattedIntegerIO<4, DIR>(io_, instance_, false); + break; + case 8: + any = FormattedIntegerIO<8, DIR>(io_, instance_, false); + break; + case 16: + any = FormattedIntegerIO<16, DIR>(io_, instance_, false); + break; + default: + handler.Crash( + "not yet implemented: UNSIGNED(KIND=%d) in formatted IO", kind); + return IostatEnd; + } + break; + case TypeCategory::Real: + switch (kind) { + case 2: + any = FormattedRealIO<2, DIR>(io_, instance_); + break; + case 3: + any = FormattedRealIO<3, DIR>(io_, instance_); + break; + case 4: + any = FormattedRealIO<4, DIR>(io_, instance_); + break; + case 8: + any = FormattedRealIO<8, DIR>(io_, instance_); + break; + case 10: + any = FormattedRealIO<10, DIR>(io_, instance_); + break; + // TODO: case double/double + case 16: + any = FormattedRealIO<16, DIR>(io_, instance_); + break; + default: + handler.Crash( + "not yet implemented: REAL(KIND=%d) in formatted IO", kind); + return IostatEnd; + } + break; + case TypeCategory::Complex: + switch (kind) { + case 2: + any = FormattedComplexIO<2, DIR>(io_, instance_); + break; + case 3: + any = FormattedComplexIO<3, DIR>(io_, instance_); + break; + case 4: + any = FormattedComplexIO<4, DIR>(io_, instance_); + break; + case 8: + any = FormattedComplexIO<8, DIR>(io_, instance_); + break; + case 10: + any = FormattedComplexIO<10, DIR>(io_, instance_); + break; + // TODO: case double/double + case 16: + any = FormattedComplexIO<16, DIR>(io_, instance_); + break; + default: + handler.Crash( + "not yet implemented: COMPLEX(KIND=%d) in formatted IO", kind); + return IostatEnd; + } + break; + case TypeCategory::Character: + switch (kind) { + case 1: + any = FormattedCharacterIO(io_, instance_); + break; + case 2: + any = FormattedCharacterIO(io_, instance_); + break; + case 4: + any = FormattedCharacterIO(io_, instance_); + break; + default: + handler.Crash( + "not yet implemented: CHARACTER(KIND=%d) in formatted IO", kind); + return IostatEnd; + } + break; + case TypeCategory::Logical: + switch (kind) { + case 1: + any = FormattedLogicalIO<1, DIR>(io_, instance_); + break; + case 2: + any = FormattedLogicalIO<2, DIR>(io_, instance_); + break; + case 4: + any = FormattedLogicalIO<4, DIR>(io_, instance_); + break; + case 8: + any = FormattedLogicalIO<8, DIR>(io_, instance_); + break; + default: + handler.Crash( + "not yet implemented: LOGICAL(KIND=%d) in formatted IO", kind); + return IostatEnd; + } + break; + case TypeCategory::Derived: { + // Derived type information must be present for formatted I/O. + IoErrorHandler &handler{io_.GetIoErrorHandler()}; + const DescriptorAddendum *addendum{instance_.Addendum()}; + RUNTIME_CHECK(handler, addendum != nullptr); + derived_ = addendum->derivedType(); + RUNTIME_CHECK(handler, derived_ != nullptr); + if (table_) { + if (const auto *definedIo{table_->Find(*derived_, + DIR == Direction::Input ? common::DefinedIo::ReadFormatted + : common::DefinedIo::WriteFormatted)}) { + if (definedIo->subroutine) { + nonTbpSpecial_.emplace(DIR == Direction::Input + ? typeInfo::SpecialBinding::Which::ReadFormatted + : typeInfo::SpecialBinding::Which::WriteFormatted, + definedIo->subroutine, definedIo->isDtvArgPolymorphic, false, + false); + special_ = &*nonTbpSpecial_; + } + } + } + if (!special_) { + if (const typeInfo::SpecialBinding *binding{ + derived_->FindSpecialBinding(DIR == Direction::Input + ? typeInfo::SpecialBinding::Which::ReadFormatted + : typeInfo::SpecialBinding::Which::WriteFormatted)}) { + if (!table_ || !table_->ignoreNonTbpEntries || + binding->IsTypeBound()) { + special_ = binding; + } + } + } + return StatContinue; + } + } + if (any) { + anyIoTookPlace_ = true; + } else { + return IostatEnd; + } + } else { + handler.Crash("DescriptorIO: bad type code (%d) in descriptor", + static_cast(instance_.type().raw())); + return handler.GetIoStat(); + } + return StatOk; +} + +template RT_API_ATTRS int DescriptorIoTicket::Begin( + WorkQueue &); +template RT_API_ATTRS int DescriptorIoTicket::Begin( + WorkQueue &); + +template +RT_API_ATTRS int DescriptorIoTicket::Continue(WorkQueue &workQueue) { + // Only derived type formatted I/O gets here. + while (!IsComplete()) { + if (special_) { + if (auto defined{DefinedFormattedIo( + io_, instance_, *derived_, *special_, subscripts_)}) { + anyIoTookPlace_ |= *defined; + Advance(); + continue; + } + } + Descriptor &elementDesc{elementDescriptor_.descriptor()}; + elementDesc.Establish( + *derived_, nullptr, 0, nullptr, CFI_attribute_pointer); + elementDesc.set_base_addr(instance_.Element(subscripts_)); + Advance(); + if (int status{workQueue.BeginDerivedIo( + io_, elementDesc, *derived_, table_, anyIoTookPlace_)}; + status != StatOk) { + return status; + } + } + return StatOk; +} + +template RT_API_ATTRS int DescriptorIoTicket::Continue( + WorkQueue &); +template RT_API_ATTRS int DescriptorIoTicket::Continue( + WorkQueue &); + +template +RT_API_ATTRS bool DescriptorIO(IoStatementState &io, + const Descriptor &descriptor, const NonTbpDefinedIoTable *table) { + bool anyIoTookPlace{false}; + WorkQueue workQueue{io.GetIoErrorHandler()}; + if (workQueue.BeginDescriptorIo(io, descriptor, table, anyIoTookPlace) == + StatContinue) { + workQueue.Run(); + } + return anyIoTookPlace; +} + +template RT_API_ATTRS bool DescriptorIO( + IoStatementState &, const Descriptor &, const NonTbpDefinedIoTable *); +template RT_API_ATTRS bool DescriptorIO( + IoStatementState &, const Descriptor &, const NonTbpDefinedIoTable *); + RT_OFFLOAD_API_GROUP_END } // namespace Fortran::runtime::io::descr diff --git a/external/llvm-project/flang-rt/lib/runtime/descriptor-io.h b/external/llvm-project/flang-rt/lib/runtime/descriptor-io.h index eb60f106c920..88ad59bd24b5 100644 --- a/external/llvm-project/flang-rt/lib/runtime/descriptor-io.h +++ b/external/llvm-project/flang-rt/lib/runtime/descriptor-io.h @@ -9,619 +9,27 @@ #ifndef FLANG_RT_RUNTIME_DESCRIPTOR_IO_H_ #define FLANG_RT_RUNTIME_DESCRIPTOR_IO_H_ -// Implementation of I/O data list item transfers based on descriptors. -// (All I/O items come through here so that the code is exercised for test; -// some scalar I/O data transfer APIs could be changed to bypass their use -// of descriptors in the future for better efficiency.) +#include "flang-rt/runtime/connection.h" -#include "edit-input.h" -#include "edit-output.h" -#include "unit.h" -#include "flang-rt/runtime/descriptor.h" -#include "flang-rt/runtime/io-stmt.h" -#include "flang-rt/runtime/namelist.h" -#include "flang-rt/runtime/terminator.h" -#include "flang-rt/runtime/type-info.h" -#include "flang/Common/optional.h" -#include "flang/Common/uint128.h" -#include "flang/Runtime/cpp-type.h" +namespace Fortran::runtime { +class Descriptor; +} // namespace Fortran::runtime -namespace Fortran::runtime::io::descr { -template -inline RT_API_ATTRS A &ExtractElement(IoStatementState &io, - const Descriptor &descriptor, const SubscriptValue subscripts[]) { - A *p{descriptor.Element(subscripts)}; - if (!p) { - io.GetIoErrorHandler().Crash("Bad address for I/O item -- null base " - "address or subscripts out of range"); - } - return *p; -} - -// Per-category descriptor-based I/O templates - -// TODO (perhaps as a nontrivial but small starter project): implement -// automatic repetition counts, like "10*3.14159", for list-directed and -// NAMELIST array output. - -template -inline RT_API_ATTRS bool FormattedIntegerIO(IoStatementState &io, - const Descriptor &descriptor, [[maybe_unused]] bool isSigned) { - std::size_t numElements{descriptor.Elements()}; - SubscriptValue subscripts[maxRank]; - descriptor.GetLowerBounds(subscripts); - using IntType = CppTypeFor; - bool anyInput{false}; - for (std::size_t j{0}; j < numElements; ++j) { - if (auto edit{io.GetNextDataEdit()}) { - IntType &x{ExtractElement(io, descriptor, subscripts)}; - if constexpr (DIR == Direction::Output) { - if (!EditIntegerOutput(io, *edit, x, isSigned)) { - return false; - } - } else if (edit->descriptor != DataEdit::ListDirectedNullValue) { - if (EditIntegerInput( - io, *edit, reinterpret_cast(&x), KIND, isSigned)) { - anyInput = true; - } else { - return anyInput && edit->IsNamelist(); - } - } - if (!descriptor.IncrementSubscripts(subscripts) && j + 1 < numElements) { - io.GetIoErrorHandler().Crash( - "FormattedIntegerIO: subscripts out of bounds"); - } - } else { - return false; - } - } - return true; -} - -template -inline RT_API_ATTRS bool FormattedRealIO( - IoStatementState &io, const Descriptor &descriptor) { - std::size_t numElements{descriptor.Elements()}; - SubscriptValue subscripts[maxRank]; - descriptor.GetLowerBounds(subscripts); - using RawType = typename RealOutputEditing::BinaryFloatingPoint; - bool anyInput{false}; - for (std::size_t j{0}; j < numElements; ++j) { - if (auto edit{io.GetNextDataEdit()}) { - RawType &x{ExtractElement(io, descriptor, subscripts)}; - if constexpr (DIR == Direction::Output) { - if (!RealOutputEditing{io, x}.Edit(*edit)) { - return false; - } - } else if (edit->descriptor != DataEdit::ListDirectedNullValue) { - if (EditRealInput(io, *edit, reinterpret_cast(&x))) { - anyInput = true; - } else { - return anyInput && edit->IsNamelist(); - } - } - if (!descriptor.IncrementSubscripts(subscripts) && j + 1 < numElements) { - io.GetIoErrorHandler().Crash( - "FormattedRealIO: subscripts out of bounds"); - } - } else { - return false; - } - } - return true; -} +namespace Fortran::runtime::io { +class IoStatementState; +struct NonTbpDefinedIoTable; +} // namespace Fortran::runtime::io -template -inline RT_API_ATTRS bool FormattedComplexIO( - IoStatementState &io, const Descriptor &descriptor) { - std::size_t numElements{descriptor.Elements()}; - SubscriptValue subscripts[maxRank]; - descriptor.GetLowerBounds(subscripts); - bool isListOutput{ - io.get_if>() != nullptr}; - using RawType = typename RealOutputEditing::BinaryFloatingPoint; - bool anyInput{false}; - for (std::size_t j{0}; j < numElements; ++j) { - RawType *x{&ExtractElement(io, descriptor, subscripts)}; - if (isListOutput) { - DataEdit rEdit, iEdit; - rEdit.descriptor = DataEdit::ListDirectedRealPart; - iEdit.descriptor = DataEdit::ListDirectedImaginaryPart; - rEdit.modes = iEdit.modes = io.mutableModes(); - if (!RealOutputEditing{io, x[0]}.Edit(rEdit) || - !RealOutputEditing{io, x[1]}.Edit(iEdit)) { - return false; - } - } else { - for (int k{0}; k < 2; ++k, ++x) { - auto edit{io.GetNextDataEdit()}; - if (!edit) { - return false; - } else if constexpr (DIR == Direction::Output) { - if (!RealOutputEditing{io, *x}.Edit(*edit)) { - return false; - } - } else if (edit->descriptor == DataEdit::ListDirectedNullValue) { - break; - } else if (EditRealInput( - io, *edit, reinterpret_cast(x))) { - anyInput = true; - } else { - return anyInput && edit->IsNamelist(); - } - } - } - if (!descriptor.IncrementSubscripts(subscripts) && j + 1 < numElements) { - io.GetIoErrorHandler().Crash( - "FormattedComplexIO: subscripts out of bounds"); - } - } - return true; -} - -template -inline RT_API_ATTRS bool FormattedCharacterIO( - IoStatementState &io, const Descriptor &descriptor) { - std::size_t numElements{descriptor.Elements()}; - SubscriptValue subscripts[maxRank]; - descriptor.GetLowerBounds(subscripts); - std::size_t length{descriptor.ElementBytes() / sizeof(A)}; - auto *listOutput{io.get_if>()}; - bool anyInput{false}; - for (std::size_t j{0}; j < numElements; ++j) { - A *x{&ExtractElement(io, descriptor, subscripts)}; - if (listOutput) { - if (!ListDirectedCharacterOutput(io, *listOutput, x, length)) { - return false; - } - } else if (auto edit{io.GetNextDataEdit()}) { - if constexpr (DIR == Direction::Output) { - if (!EditCharacterOutput(io, *edit, x, length)) { - return false; - } - } else { // input - if (edit->descriptor != DataEdit::ListDirectedNullValue) { - if (EditCharacterInput(io, *edit, x, length)) { - anyInput = true; - } else { - return anyInput && edit->IsNamelist(); - } - } - } - } else { - return false; - } - if (!descriptor.IncrementSubscripts(subscripts) && j + 1 < numElements) { - io.GetIoErrorHandler().Crash( - "FormattedCharacterIO: subscripts out of bounds"); - } - } - return true; -} - -template -inline RT_API_ATTRS bool FormattedLogicalIO( - IoStatementState &io, const Descriptor &descriptor) { - std::size_t numElements{descriptor.Elements()}; - SubscriptValue subscripts[maxRank]; - descriptor.GetLowerBounds(subscripts); - auto *listOutput{io.get_if>()}; - using IntType = CppTypeFor; - bool anyInput{false}; - for (std::size_t j{0}; j < numElements; ++j) { - IntType &x{ExtractElement(io, descriptor, subscripts)}; - if (listOutput) { - if (!ListDirectedLogicalOutput(io, *listOutput, x != 0)) { - return false; - } - } else if (auto edit{io.GetNextDataEdit()}) { - if constexpr (DIR == Direction::Output) { - if (!EditLogicalOutput(io, *edit, x != 0)) { - return false; - } - } else { - if (edit->descriptor != DataEdit::ListDirectedNullValue) { - bool truth{}; - if (EditLogicalInput(io, *edit, truth)) { - x = truth; - anyInput = true; - } else { - return anyInput && edit->IsNamelist(); - } - } - } - } else { - return false; - } - if (!descriptor.IncrementSubscripts(subscripts) && j + 1 < numElements) { - io.GetIoErrorHandler().Crash( - "FormattedLogicalIO: subscripts out of bounds"); - } - } - return true; -} +namespace Fortran::runtime::io::descr { template -static RT_API_ATTRS bool DescriptorIO(IoStatementState &, const Descriptor &, +RT_API_ATTRS bool DescriptorIO(IoStatementState &, const Descriptor &, const NonTbpDefinedIoTable * = nullptr); -// For intrinsic (not defined) derived type I/O, formatted & unformatted -template -static RT_API_ATTRS bool DefaultComponentIO(IoStatementState &io, - const typeInfo::Component &component, const Descriptor &origDescriptor, - const SubscriptValue origSubscripts[], Terminator &terminator, - const NonTbpDefinedIoTable *table) { -#if !defined(RT_DEVICE_AVOID_RECURSION) - if (component.genre() == typeInfo::Component::Genre::Data) { - // Create a descriptor for the component - StaticDescriptor statDesc; - Descriptor &desc{statDesc.descriptor()}; - component.CreatePointerDescriptor( - desc, origDescriptor, terminator, origSubscripts); - return DescriptorIO(io, desc, table); - } else { - // Component is itself a descriptor - char *pointer{ - origDescriptor.Element(origSubscripts) + component.offset()}; - const Descriptor &compDesc{*reinterpret_cast(pointer)}; - return compDesc.IsAllocated() && DescriptorIO(io, compDesc, table); - } -#else - terminator.Crash("not yet implemented: component IO"); -#endif -} - -template -static RT_API_ATTRS bool DefaultComponentwiseFormattedIO(IoStatementState &io, - const Descriptor &descriptor, const typeInfo::DerivedType &type, - const NonTbpDefinedIoTable *table, const SubscriptValue subscripts[]) { - IoErrorHandler &handler{io.GetIoErrorHandler()}; - const Descriptor &compArray{type.component()}; - RUNTIME_CHECK(handler, compArray.rank() == 1); - std::size_t numComponents{compArray.Elements()}; - SubscriptValue at[maxRank]; - compArray.GetLowerBounds(at); - for (std::size_t k{0}; k < numComponents; - ++k, compArray.IncrementSubscripts(at)) { - const typeInfo::Component &component{ - *compArray.Element(at)}; - if (!DefaultComponentIO( - io, component, descriptor, subscripts, handler, table)) { - // Return true for NAMELIST input if any component appeared. - auto *listInput{ - io.get_if>()}; - return DIR == Direction::Input && k > 0 && listInput && - listInput->inNamelistSequence(); - } - } - return true; -} - -template -static RT_API_ATTRS bool DefaultComponentwiseUnformattedIO(IoStatementState &io, - const Descriptor &descriptor, const typeInfo::DerivedType &type, - const NonTbpDefinedIoTable *table) { - IoErrorHandler &handler{io.GetIoErrorHandler()}; - const Descriptor &compArray{type.component()}; - RUNTIME_CHECK(handler, compArray.rank() == 1); - std::size_t numComponents{compArray.Elements()}; - std::size_t numElements{descriptor.Elements()}; - SubscriptValue subscripts[maxRank]; - descriptor.GetLowerBounds(subscripts); - for (std::size_t j{0}; j < numElements; - ++j, descriptor.IncrementSubscripts(subscripts)) { - SubscriptValue at[maxRank]; - compArray.GetLowerBounds(at); - for (std::size_t k{0}; k < numComponents; - ++k, compArray.IncrementSubscripts(at)) { - const typeInfo::Component &component{ - *compArray.Element(at)}; - if (!DefaultComponentIO( - io, component, descriptor, subscripts, handler, table)) { - return false; - } - } - } - return true; -} - -RT_API_ATTRS Fortran::common::optional DefinedFormattedIo( - IoStatementState &, const Descriptor &, const typeInfo::DerivedType &, - const typeInfo::SpecialBinding &, const SubscriptValue[]); - -template -static RT_API_ATTRS bool FormattedDerivedTypeIO(IoStatementState &io, - const Descriptor &descriptor, const NonTbpDefinedIoTable *table) { - IoErrorHandler &handler{io.GetIoErrorHandler()}; - // Derived type information must be present for formatted I/O. - const DescriptorAddendum *addendum{descriptor.Addendum()}; - RUNTIME_CHECK(handler, addendum != nullptr); - const typeInfo::DerivedType *type{addendum->derivedType()}; - RUNTIME_CHECK(handler, type != nullptr); - Fortran::common::optional nonTbpSpecial; - const typeInfo::SpecialBinding *special{nullptr}; - if (table) { - if (const auto *definedIo{table->Find(*type, - DIR == Direction::Input ? common::DefinedIo::ReadFormatted - : common::DefinedIo::WriteFormatted)}) { - if (definedIo->subroutine) { - nonTbpSpecial.emplace(DIR == Direction::Input - ? typeInfo::SpecialBinding::Which::ReadFormatted - : typeInfo::SpecialBinding::Which::WriteFormatted, - definedIo->subroutine, definedIo->isDtvArgPolymorphic, false, - false); - special = &*nonTbpSpecial; - } - } - } - if (!special) { - if (const typeInfo::SpecialBinding * - binding{type->FindSpecialBinding(DIR == Direction::Input - ? typeInfo::SpecialBinding::Which::ReadFormatted - : typeInfo::SpecialBinding::Which::WriteFormatted)}) { - if (!table || !table->ignoreNonTbpEntries || binding->isTypeBound()) { - special = binding; - } - } - } - SubscriptValue subscripts[maxRank]; - descriptor.GetLowerBounds(subscripts); - std::size_t numElements{descriptor.Elements()}; - for (std::size_t j{0}; j < numElements; - ++j, descriptor.IncrementSubscripts(subscripts)) { - Fortran::common::optional result; - if (special) { - result = DefinedFormattedIo(io, descriptor, *type, *special, subscripts); - } - if (!result) { - result = DefaultComponentwiseFormattedIO( - io, descriptor, *type, table, subscripts); - } - if (!result.value()) { - // Return true for NAMELIST input if we got anything. - auto *listInput{ - io.get_if>()}; - return DIR == Direction::Input && j > 0 && listInput && - listInput->inNamelistSequence(); - } - } - return true; -} - -RT_API_ATTRS bool DefinedUnformattedIo(IoStatementState &, const Descriptor &, - const typeInfo::DerivedType &, const typeInfo::SpecialBinding &); +extern template RT_API_ATTRS bool DescriptorIO( + IoStatementState &, const Descriptor &, const NonTbpDefinedIoTable *); +extern template RT_API_ATTRS bool DescriptorIO( + IoStatementState &, const Descriptor &, const NonTbpDefinedIoTable *); -// Unformatted I/O -template -static RT_API_ATTRS bool UnformattedDescriptorIO(IoStatementState &io, - const Descriptor &descriptor, const NonTbpDefinedIoTable *table = nullptr) { - IoErrorHandler &handler{io.GetIoErrorHandler()}; - const DescriptorAddendum *addendum{descriptor.Addendum()}; - if (const typeInfo::DerivedType * - type{addendum ? addendum->derivedType() : nullptr}) { - // derived type unformatted I/O - if (table) { - if (const auto *definedIo{table->Find(*type, - DIR == Direction::Input ? common::DefinedIo::ReadUnformatted - : common::DefinedIo::WriteUnformatted)}) { - if (definedIo->subroutine) { - typeInfo::SpecialBinding special{DIR == Direction::Input - ? typeInfo::SpecialBinding::Which::ReadUnformatted - : typeInfo::SpecialBinding::Which::WriteUnformatted, - definedIo->subroutine, definedIo->isDtvArgPolymorphic, false, - false}; - if (Fortran::common::optional wasDefined{ - DefinedUnformattedIo(io, descriptor, *type, special)}) { - return *wasDefined; - } - } else { - return DefaultComponentwiseUnformattedIO( - io, descriptor, *type, table); - } - } - } - if (const typeInfo::SpecialBinding * - special{type->FindSpecialBinding(DIR == Direction::Input - ? typeInfo::SpecialBinding::Which::ReadUnformatted - : typeInfo::SpecialBinding::Which::WriteUnformatted)}) { - if (!table || !table->ignoreNonTbpEntries || special->isTypeBound()) { - // defined derived type unformatted I/O - return DefinedUnformattedIo(io, descriptor, *type, *special); - } - } - // Default derived type unformatted I/O - // TODO: If no component at any level has defined READ or WRITE - // (as appropriate), the elements are contiguous, and no byte swapping - // is active, do a block transfer via the code below. - return DefaultComponentwiseUnformattedIO(io, descriptor, *type, table); - } else { - // intrinsic type unformatted I/O - auto *externalUnf{io.get_if>()}; - auto *childUnf{io.get_if>()}; - auto *inq{ - DIR == Direction::Output ? io.get_if() : nullptr}; - RUNTIME_CHECK(handler, externalUnf || childUnf || inq); - std::size_t elementBytes{descriptor.ElementBytes()}; - std::size_t numElements{descriptor.Elements()}; - std::size_t swappingBytes{elementBytes}; - if (auto maybeCatAndKind{descriptor.type().GetCategoryAndKind()}) { - // Byte swapping units can be smaller than elements, namely - // for COMPLEX and CHARACTER. - if (maybeCatAndKind->first == TypeCategory::Character) { - // swap each character position independently - swappingBytes = maybeCatAndKind->second; // kind - } else if (maybeCatAndKind->first == TypeCategory::Complex) { - // swap real and imaginary components independently - swappingBytes /= 2; - } - } - SubscriptValue subscripts[maxRank]; - descriptor.GetLowerBounds(subscripts); - using CharType = - std::conditional_t; - auto Transfer{[=](CharType &x, std::size_t totalBytes) -> bool { - if constexpr (DIR == Direction::Output) { - return externalUnf ? externalUnf->Emit(&x, totalBytes, swappingBytes) - : childUnf ? childUnf->Emit(&x, totalBytes, swappingBytes) - : inq->Emit(&x, totalBytes, swappingBytes); - } else { - return externalUnf ? externalUnf->Receive(&x, totalBytes, swappingBytes) - : childUnf->Receive(&x, totalBytes, swappingBytes); - } - }}; - bool swapEndianness{externalUnf && externalUnf->unit().swapEndianness()}; - if (!swapEndianness && - descriptor.IsContiguous()) { // contiguous unformatted I/O - char &x{ExtractElement(io, descriptor, subscripts)}; - return Transfer(x, numElements * elementBytes); - } else { // non-contiguous or byte-swapped intrinsic type unformatted I/O - for (std::size_t j{0}; j < numElements; ++j) { - char &x{ExtractElement(io, descriptor, subscripts)}; - if (!Transfer(x, elementBytes)) { - return false; - } - if (!descriptor.IncrementSubscripts(subscripts) && - j + 1 < numElements) { - handler.Crash("DescriptorIO: subscripts out of bounds"); - } - } - return true; - } - } -} - -template -static RT_API_ATTRS bool DescriptorIO(IoStatementState &io, - const Descriptor &descriptor, const NonTbpDefinedIoTable *table) { - IoErrorHandler &handler{io.GetIoErrorHandler()}; - if (handler.InError()) { - return false; - } - if (!io.get_if>()) { - handler.Crash("DescriptorIO() called for wrong I/O direction"); - return false; - } - if constexpr (DIR == Direction::Input) { - if (!io.BeginReadingRecord()) { - return false; - } - } - if (!io.get_if>()) { - return UnformattedDescriptorIO(io, descriptor, table); - } - if (auto catAndKind{descriptor.type().GetCategoryAndKind()}) { - TypeCategory cat{catAndKind->first}; - int kind{catAndKind->second}; - switch (cat) { - case TypeCategory::Integer: - switch (kind) { - case 1: - return FormattedIntegerIO<1, DIR>(io, descriptor, true); - case 2: - return FormattedIntegerIO<2, DIR>(io, descriptor, true); - case 4: - return FormattedIntegerIO<4, DIR>(io, descriptor, true); - case 8: - return FormattedIntegerIO<8, DIR>(io, descriptor, true); - case 16: - return FormattedIntegerIO<16, DIR>(io, descriptor, true); - default: - handler.Crash( - "not yet implemented: INTEGER(KIND=%d) in formatted IO", kind); - return false; - } - case TypeCategory::Unsigned: - switch (kind) { - case 1: - return FormattedIntegerIO<1, DIR>(io, descriptor, false); - case 2: - return FormattedIntegerIO<2, DIR>(io, descriptor, false); - case 4: - return FormattedIntegerIO<4, DIR>(io, descriptor, false); - case 8: - return FormattedIntegerIO<8, DIR>(io, descriptor, false); - case 16: - return FormattedIntegerIO<16, DIR>(io, descriptor, false); - default: - handler.Crash( - "not yet implemented: UNSIGNED(KIND=%d) in formatted IO", kind); - return false; - } - case TypeCategory::Real: - switch (kind) { - case 2: - return FormattedRealIO<2, DIR>(io, descriptor); - case 3: - return FormattedRealIO<3, DIR>(io, descriptor); - case 4: - return FormattedRealIO<4, DIR>(io, descriptor); - case 8: - return FormattedRealIO<8, DIR>(io, descriptor); - case 10: - return FormattedRealIO<10, DIR>(io, descriptor); - // TODO: case double/double - case 16: - return FormattedRealIO<16, DIR>(io, descriptor); - default: - handler.Crash( - "not yet implemented: REAL(KIND=%d) in formatted IO", kind); - return false; - } - case TypeCategory::Complex: - switch (kind) { - case 2: - return FormattedComplexIO<2, DIR>(io, descriptor); - case 3: - return FormattedComplexIO<3, DIR>(io, descriptor); - case 4: - return FormattedComplexIO<4, DIR>(io, descriptor); - case 8: - return FormattedComplexIO<8, DIR>(io, descriptor); - case 10: - return FormattedComplexIO<10, DIR>(io, descriptor); - // TODO: case double/double - case 16: - return FormattedComplexIO<16, DIR>(io, descriptor); - default: - handler.Crash( - "not yet implemented: COMPLEX(KIND=%d) in formatted IO", kind); - return false; - } - case TypeCategory::Character: - switch (kind) { - case 1: - return FormattedCharacterIO(io, descriptor); - case 2: - return FormattedCharacterIO(io, descriptor); - case 4: - return FormattedCharacterIO(io, descriptor); - default: - handler.Crash( - "not yet implemented: CHARACTER(KIND=%d) in formatted IO", kind); - return false; - } - case TypeCategory::Logical: - switch (kind) { - case 1: - return FormattedLogicalIO<1, DIR>(io, descriptor); - case 2: - return FormattedLogicalIO<2, DIR>(io, descriptor); - case 4: - return FormattedLogicalIO<4, DIR>(io, descriptor); - case 8: - return FormattedLogicalIO<8, DIR>(io, descriptor); - default: - handler.Crash( - "not yet implemented: LOGICAL(KIND=%d) in formatted IO", kind); - return false; - } - case TypeCategory::Derived: - return FormattedDerivedTypeIO(io, descriptor, table); - } - } - handler.Crash("DescriptorIO: bad type code (%d) in descriptor", - static_cast(descriptor.type().raw())); - return false; -} } // namespace Fortran::runtime::io::descr #endif // FLANG_RT_RUNTIME_DESCRIPTOR_IO_H_ diff --git a/external/llvm-project/flang-rt/lib/runtime/environment.cpp b/external/llvm-project/flang-rt/lib/runtime/environment.cpp index 1d5304254ed0..0f0564403c0e 100644 --- a/external/llvm-project/flang-rt/lib/runtime/environment.cpp +++ b/external/llvm-project/flang-rt/lib/runtime/environment.cpp @@ -143,6 +143,10 @@ void ExecutionEnvironment::Configure(int ac, const char *av[], } } + if (auto *x{std::getenv("FLANG_RT_DEBUG")}) { + internalDebugging = std::strtol(x, nullptr, 10); + } + if (auto *x{std::getenv("ACC_OFFLOAD_STACK_SIZE")}) { char *end; auto n{std::strtoul(x, &end, 10)}; diff --git a/external/llvm-project/flang-rt/lib/runtime/namelist.cpp b/external/llvm-project/flang-rt/lib/runtime/namelist.cpp index b0cf2180fc6d..1bef387a9771 100644 --- a/external/llvm-project/flang-rt/lib/runtime/namelist.cpp +++ b/external/llvm-project/flang-rt/lib/runtime/namelist.cpp @@ -10,6 +10,7 @@ #include "descriptor-io.h" #include "flang-rt/runtime/emit-encoded.h" #include "flang-rt/runtime/io-stmt.h" +#include "flang-rt/runtime/type-info.h" #include "flang/Runtime/io-api.h" #include #include diff --git a/external/llvm-project/flang-rt/lib/runtime/tools.cpp b/external/llvm-project/flang-rt/lib/runtime/tools.cpp index bfb4cd8ea57a..60e360ee766a 100644 --- a/external/llvm-project/flang-rt/lib/runtime/tools.cpp +++ b/external/llvm-project/flang-rt/lib/runtime/tools.cpp @@ -205,7 +205,7 @@ RT_API_ATTRS void ShallowCopyInner(const Descriptor &to, const Descriptor &from, // Doing the recursion upwards instead of downwards puts the more common // cases earlier in the if-chain and has a tangible impact on performance. template struct ShallowCopyRankSpecialize { - static bool execute(const Descriptor &to, const Descriptor &from, + static RT_API_ATTRS bool execute(const Descriptor &to, const Descriptor &from, bool toIsContiguous, bool fromIsContiguous) { if (to.rank() == RANK && from.rank() == RANK) { ShallowCopyInner(to, from, toIsContiguous, fromIsContiguous); @@ -217,7 +217,7 @@ template struct ShallowCopyRankSpecialize { }; template struct ShallowCopyRankSpecialize { - static bool execute(const Descriptor &to, const Descriptor &from, + static RT_API_ATTRS bool execute(const Descriptor &to, const Descriptor &from, bool toIsContiguous, bool fromIsContiguous) { return false; } diff --git a/external/llvm-project/flang-rt/lib/runtime/type-info.cpp b/external/llvm-project/flang-rt/lib/runtime/type-info.cpp index 82182696d70c..d023c3392d55 100644 --- a/external/llvm-project/flang-rt/lib/runtime/type-info.cpp +++ b/external/llvm-project/flang-rt/lib/runtime/type-info.cpp @@ -140,11 +140,11 @@ RT_API_ATTRS void Component::CreatePointerDescriptor(Descriptor &descriptor, const SubscriptValue *subscripts) const { RUNTIME_CHECK(terminator, genre_ == Genre::Data); EstablishDescriptor(descriptor, container, terminator); + std::size_t offset{offset_}; if (subscripts) { - descriptor.set_base_addr(container.Element(subscripts) + offset_); - } else { - descriptor.set_base_addr(container.OffsetElement() + offset_); + offset += container.SubscriptsToByteOffset(subscripts); } + descriptor.set_base_addr(container.OffsetElement() + offset); descriptor.raw().attribute = CFI_attribute_pointer; } @@ -279,6 +279,10 @@ FILE *Component::Dump(FILE *f) const { } std::fprintf(f, " category %d kind %d rank %d offset 0x%zx\n", category_, kind_, rank_, static_cast(offset_)); + const auto &dtDesc{derivedType_.descriptor()}; + if (dtDesc.raw().base_addr) { + std::fprintf(f, " derivedType_ %p\n", dtDesc.raw().base_addr); + } if (initialization_) { std::fprintf(f, " initialization @ %p:\n", reinterpret_cast(initialization_)); @@ -325,7 +329,7 @@ FILE *SpecialBinding::Dump(FILE *f) const { break; } std::fprintf(f, " isArgDescriptorSet: 0x%x\n", isArgDescriptorSet_); - std::fprintf(f, " isTypeBound: 0x%x\n", isTypeBound_); + std::fprintf(f, " isTypeBound: %d\n", isTypeBound_); std::fprintf(f, " isArgContiguousSet: 0x%x\n", isArgContiguousSet_); std::fprintf(f, " proc: %p\n", reinterpret_cast(proc_)); return f; diff --git a/external/llvm-project/flang-rt/lib/runtime/work-queue.cpp b/external/llvm-project/flang-rt/lib/runtime/work-queue.cpp new file mode 100644 index 000000000000..a508ecb63710 --- /dev/null +++ b/external/llvm-project/flang-rt/lib/runtime/work-queue.cpp @@ -0,0 +1,161 @@ +//===-- lib/runtime/work-queue.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 "flang-rt/runtime/work-queue.h" +#include "flang-rt/runtime/environment.h" +#include "flang-rt/runtime/memory.h" +#include "flang-rt/runtime/type-info.h" +#include "flang/Common/visit.h" + +namespace Fortran::runtime { + +#if !defined(RT_DEVICE_COMPILATION) +// FLANG_RT_DEBUG code is disabled when false. +static constexpr bool enableDebugOutput{false}; +#endif + +RT_OFFLOAD_API_GROUP_BEGIN + +RT_API_ATTRS Componentwise::Componentwise(const typeInfo::DerivedType &derived) + : derived_{derived}, components_{derived_.component().Elements()} { + GetComponent(); +} + +RT_API_ATTRS void Componentwise::GetComponent() { + if (IsComplete()) { + component_ = nullptr; + } else { + const Descriptor &componentDesc{derived_.component()}; + component_ = componentDesc.ZeroBasedIndexedElement( + componentAt_); + } +} + +RT_API_ATTRS int Ticket::Continue(WorkQueue &workQueue) { + if (!begun) { + begun = true; + return common::visit( + [&workQueue]( + auto &specificTicket) { return specificTicket.Begin(workQueue); }, + u); + } else { + return common::visit( + [&workQueue](auto &specificTicket) { + return specificTicket.Continue(workQueue); + }, + u); + } +} + +RT_API_ATTRS WorkQueue::~WorkQueue() { + if (last_) { + if ((last_->next = firstFree_)) { + last_->next->previous = last_; + } + firstFree_ = first_; + first_ = last_ = nullptr; + } + while (firstFree_) { + TicketList *next{firstFree_->next}; + if (!firstFree_->isStatic) { + FreeMemory(firstFree_); + } + firstFree_ = next; + } +} + +RT_API_ATTRS Ticket &WorkQueue::StartTicket() { + if (!firstFree_) { + void *p{AllocateMemoryOrCrash(terminator_, sizeof(TicketList))}; + firstFree_ = new (p) TicketList; + firstFree_->isStatic = false; + } + TicketList *newTicket{firstFree_}; + if ((firstFree_ = newTicket->next)) { + firstFree_->previous = nullptr; + } + TicketList *after{insertAfter_ ? insertAfter_->next : nullptr}; + if ((newTicket->previous = insertAfter_ ? insertAfter_ : last_)) { + newTicket->previous->next = newTicket; + } else { + first_ = newTicket; + } + if ((newTicket->next = after)) { + after->previous = newTicket; + } else { + last_ = newTicket; + } + newTicket->ticket.begun = false; +#if !defined(RT_DEVICE_COMPILATION) + if (enableDebugOutput && + (executionEnvironment.internalDebugging & + ExecutionEnvironment::WorkQueue)) { + std::fprintf(stderr, "WQ: new ticket\n"); + } +#endif + return newTicket->ticket; +} + +RT_API_ATTRS int WorkQueue::Run() { + while (last_) { + TicketList *at{last_}; + insertAfter_ = last_; +#if !defined(RT_DEVICE_COMPILATION) + if (enableDebugOutput && + (executionEnvironment.internalDebugging & + ExecutionEnvironment::WorkQueue)) { + std::fprintf(stderr, "WQ: %zd %s\n", at->ticket.u.index(), + at->ticket.begun ? "Continue" : "Begin"); + } +#endif + int stat{at->ticket.Continue(*this)}; +#if !defined(RT_DEVICE_COMPILATION) + if (enableDebugOutput && + (executionEnvironment.internalDebugging & + ExecutionEnvironment::WorkQueue)) { + std::fprintf(stderr, "WQ: ... stat %d\n", stat); + } +#endif + insertAfter_ = nullptr; + if (stat == StatOk) { + if (at->previous) { + at->previous->next = at->next; + } else { + first_ = at->next; + } + if (at->next) { + at->next->previous = at->previous; + } else { + last_ = at->previous; + } + if ((at->next = firstFree_)) { + at->next->previous = at; + } + at->previous = nullptr; + firstFree_ = at; + } else if (stat != StatContinue) { + Stop(); + return stat; + } + } + return StatOk; +} + +RT_API_ATTRS void WorkQueue::Stop() { + if (last_) { + if ((last_->next = firstFree_)) { + last_->next->previous = last_; + } + firstFree_ = first_; + first_ = last_ = nullptr; + } +} + +RT_OFFLOAD_API_GROUP_END + +} // namespace Fortran::runtime diff --git a/external/llvm-project/flang-rt/unittests/Runtime/ExternalIOTest.cpp b/external/llvm-project/flang-rt/unittests/Runtime/ExternalIOTest.cpp index 3833e48be3dd..6c148b1de6f8 100644 --- a/external/llvm-project/flang-rt/unittests/Runtime/ExternalIOTest.cpp +++ b/external/llvm-project/flang-rt/unittests/Runtime/ExternalIOTest.cpp @@ -184,7 +184,7 @@ TEST(ExternalIOTests, TestSequentialFixedUnformatted) { io = IONAME(BeginInquireIoLength)(__FILE__, __LINE__); for (int j{1}; j <= 3; ++j) { ASSERT_TRUE(IONAME(OutputDescriptor)(io, desc)) - << "OutputDescriptor() for InquireIoLength"; + << "OutputDescriptor() for InquireIoLength " << j; } ASSERT_EQ(IONAME(GetIoLength)(io), 3 * recl) << "GetIoLength"; ASSERT_EQ(IONAME(EndIoStatement)(io), IostatOk) diff --git a/external/llvm-project/flang/CMakeLists.txt b/external/llvm-project/flang/CMakeLists.txt index 56a96f590f0a..068d134671db 100644 --- a/external/llvm-project/flang/CMakeLists.txt +++ b/external/llvm-project/flang/CMakeLists.txt @@ -421,7 +421,7 @@ endif() if (LLVM_COMPILER_IS_GCC_COMPATIBLE) if (NOT "${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang") - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-strict-aliasing -fno-semantic-interposition") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-semantic-interposition") else() set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-unused-command-line-argument -Wstring-conversion \ -Wcovered-switch-default") diff --git a/external/llvm-project/flang/docs/CMakeLists.txt b/external/llvm-project/flang/docs/CMakeLists.txt index a9f5811fcd06..568f942cb4aa 100644 --- a/external/llvm-project/flang/docs/CMakeLists.txt +++ b/external/llvm-project/flang/docs/CMakeLists.txt @@ -82,20 +82,14 @@ if (LLVM_ENABLE_DOXYGEN) endif() endif() -function (gen_rst_file_from_td output_file td_option source) +function (gen_rst_file_from_td output_file td_option source target) if (NOT EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/${source}") message(FATAL_ERROR "Cannot find source file: ${source} in ${CMAKE_CURRENT_SOURCE_DIR}") endif() get_filename_component(TABLEGEN_INCLUDE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/${source}" DIRECTORY) list(APPEND LLVM_TABLEGEN_FLAGS "-I${TABLEGEN_INCLUDE_DIR}") list(APPEND LLVM_TABLEGEN_FLAGS "-I${CMAKE_CURRENT_SOURCE_DIR}/../../clang/include/clang/Driver/") - clang_tablegen(Source/${output_file} ${td_option} SOURCE ${source} TARGET "gen-${output_file}") - # clang_tablegen() does not create the output directory automatically, - # so we have to create it explicitly. - add_custom_target(create-flang-rst-output-dir - COMMAND ${CMAKE_COMMAND} -E make_directory ${CMAKE_CURRENT_BINARY_DIR}/Source - ) - add_dependencies("gen-${output_file}" create-flang-rst-output-dir) + clang_tablegen(Source/${output_file} ${td_option} SOURCE ${source} TARGET ${target}) endfunction() if (LLVM_ENABLE_SPHINX) @@ -107,14 +101,22 @@ if (LLVM_ENABLE_SPHINX) # CLANG_TABLEGEN_EXE variable needs to be set for clang_tablegen to run without error find_program(CLANG_TABLEGEN_EXE "clang-tblgen" ${LLVM_TOOLS_BINARY_DIR} NO_DEFAULT_PATH) - # Generate the RST file from TableGen (shared by both HTML and MAN builds) - gen_rst_file_from_td(FlangCommandLineReference.rst -gen-opt-docs FlangOptionsDocs.td) + # Generate the RST file from TableGen (for both HTML and MAN builds) + gen_rst_file_from_td(FlangCommandLineReference.rst -gen-opt-docs FlangOptionsDocs.td "gen-FlangCommandLineReference.rst") + gen_rst_file_from_td(FlangCommandLineOptions.rst -gen-opt-docs FlangOptionsMan.td "gen-FlangCommandLineOptions.rst") + # clang_tablegen() (called from gen_rst_file_from_td()) does not create the + # output directory automatically, so we have to create it explicitly. + add_custom_target(create-flang-rst-output-dir + COMMAND ${CMAKE_COMMAND} -E make_directory ${CMAKE_CURRENT_BINARY_DIR}/Source + ) + add_dependencies("gen-FlangCommandLineReference.rst" create-flang-rst-output-dir) + add_dependencies("gen-FlangCommandLineOptions.rst" create-flang-rst-output-dir) if (${SPHINX_OUTPUT_HTML}) message(STATUS "Using index.md for html build") # Copy the entire flang/docs directory to the build Source dir, - # then remove the index.rst file, to avoid clash with index.md + # then remove the index.rst file, to avoid clash with index.md # which is used for the HTML build. add_custom_target(copy-flang-src-docs-html COMMAND "${CMAKE_COMMAND}" -E copy_directory @@ -141,12 +143,12 @@ if (LLVM_ENABLE_SPHINX) # MAN BUILD SETUP # ---------------------------- if (${SPHINX_OUTPUT_MAN}) - message(STATUS "NOTE: The Flang man page is currently a placeholder with a TODO. See docs/CommandGuide/index.rst for details") + message(STATUS "Using CommandGuide/index.rst for man build") # Create minimal Source dir with ONLY the files needed for man build: # - conf.py (Sphinx config) # - index.rst (top-level man page) - # - FlangCommandLineReference.rst (generated reference) + # - FlangCommandLineOptions.rst (generated reference) add_custom_target(copy-flang-src-docs-man COMMAND "${CMAKE_COMMAND}" -E make_directory "${FLANG_DOCS_MAN_DIR}" @@ -154,13 +156,13 @@ if (LLVM_ENABLE_SPHINX) "${CMAKE_CURRENT_SOURCE_DIR}/conf.py" "${FLANG_DOCS_MAN_DIR}/conf.py" COMMAND "${CMAKE_COMMAND}" -E copy - "${CMAKE_CURRENT_BINARY_DIR}/Source/FlangCommandLineReference.rst" - "${FLANG_DOCS_MAN_DIR}/FlangCommandLineReference.rst" + "${CMAKE_CURRENT_BINARY_DIR}/Source/FlangCommandLineOptions.rst" + "${FLANG_DOCS_MAN_DIR}/FlangCommandLineOptions.rst" COMMAND "${CMAKE_COMMAND}" -E copy "${CMAKE_CURRENT_SOURCE_DIR}/CommandGuide/index.rst" "${FLANG_DOCS_MAN_DIR}/index.rst" - DEPENDS flang-doc gen-FlangCommandLineReference.rst) - + DEPENDS flang-doc gen-FlangCommandLineOptions.rst) + add_sphinx_target(man flang SOURCE_DIR "${FLANG_DOCS_MAN_DIR}") add_dependencies(docs-flang-man copy-flang-src-docs-man) endif() diff --git a/external/llvm-project/flang/docs/CommandGuide/index.rst b/external/llvm-project/flang/docs/CommandGuide/index.rst index 093c79fa185b..1ba97464242e 100644 --- a/external/llvm-project/flang/docs/CommandGuide/index.rst +++ b/external/llvm-project/flang/docs/CommandGuide/index.rst @@ -1,22 +1,63 @@ -Flang Manual Page (In Progress) -================================================== - -.. note:: - This man page is under development. - -For full documentation, please see the online HTML docs: - -https://flang.llvm.org/docs/ - -.. - The placeholder text "FlangCommandLineReference" below should eventually be replaced with the actual man page contents. - ----- - -Flang Command Line Reference ----------------------------- +flang - the Flang Fortran compiler +================================== + +SYNOPSIS +-------- + +:program:`flang` [*options*] *filename ...* + +DESCRIPTION +----------- + +:program:`flang` is a Fortran compiler which supports all of the Fortran 95 and +many newer language features. Flang supports OpenMP and has some support for +OpenACC and CUDA. It encompasses preprocessing, parsing, optimization, code +generation, assembly, and linking. Depending on the options passed in, Flang +will perform only some, or all, of these actions. While Flang is highly +integrated, it is important to understand the stages of compilation in order to +understand how to invoke it. These stages are: + +Driver + The flang executable is actually a small driver that orchestrates the + execution of other tools such as the compiler, assembler and linker. + Typically you do not need to interact with the driver, but you + transparently use it to run the other tools. + +Preprocessing + This stage performs tokenization of the input source file, macro expansion, + #include expansion and handles other preprocessor directives. + +Parsing and Semantic Analysis + This stage parses the input file, translating preprocessor tokens into a + parse tree. Once in the form of a parse tree, it applies semantic + analysis to compute types for expressions and determine whether + the code is well formed. Parse errors and most compiler warnings + are generated by this stage. + +Code Generation and Optimization + This stage translates the parse tree into intermediate code (known as + "LLVM IR") and, ultimately, machine code. It also optimizes this + intermediate code and handles target-specific code generation. The output + of this stage is typically a ".s" file, referred to as an "assembly" file. + + Flang also supports the use of an integrated assembler, in which the code + generator produces object files directly. This avoids the overhead of + generating the ".s" file and calling the target assembler explicitly. + +Assembler + This stage runs the target assembler to translate the output of the + compiler into a target object file. The output of this stage is typically + a ".o" file, referred to as an "object" file. + +Linker + This stage runs the target linker to merge multiple object files into an + executable or dynamic library. The output of this stage is typically + an "a.out", ".dylib" or ".so" file. + +OPTIONS +------- .. toctree:: :maxdepth: 1 - FlangCommandLineReference + FlangCommandLineOptions diff --git a/external/llvm-project/flang/docs/Extensions.md b/external/llvm-project/flang/docs/Extensions.md index 78d871c593e1..871749934810 100644 --- a/external/llvm-project/flang/docs/Extensions.md +++ b/external/llvm-project/flang/docs/Extensions.md @@ -858,6 +858,16 @@ print *, [(j,j=1,10)] warning since such values may have become defined by the time the nested expression's value is required. +* Intrinsic assignment of arrays is defined elementally, and intrinsic + assignment of derived type components is defined componentwise. + However, when intrinsic assignment takes place for an array of derived + type, the order of the loop nesting is not defined. + Some compilers will loop over the elements, assigning all of the components + of each element before proceeding to the next element. + This compiler loops over all of the components, and assigns all of + the elements for each component before proceeding to the next component. + A program using defined assignment might be able to detect the difference. + ## De Facto Standard Features * `EXTENDS_TYPE_OF()` returns `.TRUE.` if both of its arguments have the diff --git a/external/llvm-project/flang/docs/FlangOptionsDocs.td b/external/llvm-project/flang/docs/FlangOptionsDocs.td index 14d033f8587e..f2847f07afdf 100644 --- a/external/llvm-project/flang/docs/FlangOptionsDocs.td +++ b/external/llvm-project/flang/docs/FlangOptionsDocs.td @@ -1,4 +1,4 @@ -//==--- FlangOptionDocs.td - Option documentation -------------------------===// +//==--- FlangOptionsDocs.td - Options documentation -----------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/external/llvm-project/flang/docs/FlangOptionsMan.td b/external/llvm-project/flang/docs/FlangOptionsMan.td new file mode 100644 index 000000000000..86cde115eb6f --- /dev/null +++ b/external/llvm-project/flang/docs/FlangOptionsMan.td @@ -0,0 +1,23 @@ +//==--- FlangOptionsMan.td - Options documentation ------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +def GlobalDocumentation { + code Intro =[{.. + ------------------------------------------------------------------- + NOTE: This file is automatically generated by running clang-tblgen + -gen-opt-docs. Do not edit this file by hand!! + ------------------------------------------------------------------- +}]; + + string Program = "Flang"; + list VisibilityMask = ["FlangOption"]; + list IgnoreFlags = ["HelpHidden", "Unsupported", "Ignored"]; +} + +#define GENERATING_DOCS +include "Options.td" diff --git a/external/llvm-project/flang/docs/conf.py b/external/llvm-project/flang/docs/conf.py index a470d8afd718..0942dbf70ff1 100644 --- a/external/llvm-project/flang/docs/conf.py +++ b/external/llvm-project/flang/docs/conf.py @@ -233,7 +233,7 @@ ( "index", "flang", - "Flang Documentation (In Progress)", + "flang - the Flang Fortran compiler", ["Flang Contributors"], 1, ) diff --git a/external/llvm-project/flang/include/flang/Evaluate/tools.h b/external/llvm-project/flang/include/flang/Evaluate/tools.h index 1959d5f3a589..e04621f71f9a 100644 --- a/external/llvm-project/flang/include/flang/Evaluate/tools.h +++ b/external/llvm-project/flang/include/flang/Evaluate/tools.h @@ -1389,6 +1389,154 @@ inline bool HasCUDAImplicitTransfer(const Expr &expr) { return (hasConstant || (hostSymbols > 0)) && deviceSymbols > 0; } +// Checks whether the symbol on the LHS is present in the RHS expression. +bool CheckForSymbolMatch(const Expr *lhs, const Expr *rhs); + +namespace operation { + +enum class Operator { + Unknown, + Add, + And, + Associated, + Call, + Constant, + Convert, + Div, + Eq, + Eqv, + False, + Ge, + Gt, + Identity, + Intrinsic, + Le, + Lt, + Max, + Min, + Mul, + Ne, + Neqv, + Not, + Or, + Pow, + Resize, // Convert within the same TypeCategory + Sub, + True, +}; + +std::string ToString(Operator op); + +template +Operator OperationCode( + const evaluate::Operation, Ts...> &op) { + switch (op.derived().logicalOperator) { + case common::LogicalOperator::And: + return Operator::And; + case common::LogicalOperator::Or: + return Operator::Or; + case common::LogicalOperator::Eqv: + return Operator::Eqv; + case common::LogicalOperator::Neqv: + return Operator::Neqv; + case common::LogicalOperator::Not: + return Operator::Not; + } + return Operator::Unknown; +} + +template +Operator OperationCode( + const evaluate::Operation, Ts...> &op) { + switch (op.derived().opr) { + case common::RelationalOperator::LT: + return Operator::Lt; + case common::RelationalOperator::LE: + return Operator::Le; + case common::RelationalOperator::EQ: + return Operator::Eq; + case common::RelationalOperator::NE: + return Operator::Ne; + case common::RelationalOperator::GE: + return Operator::Ge; + case common::RelationalOperator::GT: + return Operator::Gt; + } + return Operator::Unknown; +} + +template +Operator OperationCode(const evaluate::Operation, Ts...> &op) { + return Operator::Add; +} + +template +Operator OperationCode( + const evaluate::Operation, Ts...> &op) { + return Operator::Sub; +} + +template +Operator OperationCode( + const evaluate::Operation, Ts...> &op) { + return Operator::Mul; +} + +template +Operator OperationCode( + const evaluate::Operation, Ts...> &op) { + return Operator::Div; +} + +template +Operator OperationCode( + const evaluate::Operation, Ts...> &op) { + return Operator::Pow; +} + +template +Operator OperationCode( + const evaluate::Operation, Ts...> &op) { + return Operator::Pow; +} + +template +Operator OperationCode( + const evaluate::Operation, Ts...> &op) { + if constexpr (C == T::category) { + return Operator::Resize; + } else { + return Operator::Convert; + } +} + +template Operator OperationCode(const evaluate::Constant &x) { + return Operator::Constant; +} + +template Operator OperationCode(const T &) { + return Operator::Unknown; +} + +Operator OperationCode(const evaluate::ProcedureDesignator &proc); + +} // namespace operation + +// Return information about the top-level operation (ignoring parentheses): +// the operation code and the list of arguments. +std::pair>> +GetTopLevelOperation(const Expr &expr); + +// Check if expr is same as x, or a sequence of Convert operations on x. +bool IsSameOrConvertOf(const Expr &expr, const Expr &x); + +// Strip away any top-level Convert operations (if any exist) and return +// the input value. A ComplexConstructor(x, 0) is also considered as a +// convert operation. +// If the input is not Operation, Designator, FunctionRef or Constant, +// it returns std::nullopt. +std::optional> GetConvertInput(const Expr &x); + } // namespace Fortran::evaluate namespace Fortran::semantics { diff --git a/external/llvm-project/flang/include/flang/Lower/PFTBuilder.h b/external/llvm-project/flang/include/flang/Lower/PFTBuilder.h index 42d6546b7755..ac87fcd7c3b9 100644 --- a/external/llvm-project/flang/include/flang/Lower/PFTBuilder.h +++ b/external/llvm-project/flang/include/flang/Lower/PFTBuilder.h @@ -184,6 +184,11 @@ static constexpr bool isExecutableDirective{common::HasMember< A, std::tuple>}; +template +static constexpr bool isOpenMPDirective{ + common::HasMember>}; + template static constexpr bool isFunctionLike{common::HasMember< A, std::tuple>; }}); } + constexpr bool isOpenMPDirective() const { + return visit(common::visitors{[](auto &r) { + return pft::isOpenMPDirective>; + }}); + } /// Return the predicate: "This is a non-initial, non-terminal construct /// statement." For an IfConstruct, this is ElseIfStmt and ElseStmt. diff --git a/external/llvm-project/flang/include/flang/Optimizer/Dialect/FIROps.td b/external/llvm-project/flang/include/flang/Optimizer/Dialect/FIROps.td index 90e05ce3d5ca..8ac847dd7dd0 100644 --- a/external/llvm-project/flang/include/flang/Optimizer/Dialect/FIROps.td +++ b/external/llvm-project/flang/include/flang/Optimizer/Dialect/FIROps.td @@ -2323,9 +2323,13 @@ def fir_DoLoopOp : region_Op<"do_loop", [AttrSizedOperandSegments, }]; } -def fir_IfOp : region_Op<"if", [DeclareOpInterfaceMethods, RecursiveMemoryEffects, - NoRegionArguments]> { +def fir_IfOp + : region_Op< + "if", [DeclareOpInterfaceMethods< + RegionBranchOpInterface, ["getRegionInvocationBounds", + "getEntrySuccessorRegions"]>, + RecursiveMemoryEffects, NoRegionArguments, + WeightedRegionBranchOpInterface]> { let summary = "if-then-else conditional operation"; let description = [{ Used to conditionally execute operations. This operation is the FIR @@ -2342,7 +2346,8 @@ def fir_IfOp : region_Op<"if", [DeclareOpInterfaceMethods:$region_weights); let results = (outs Variadic:$results); let regions = (region @@ -2371,6 +2376,21 @@ def fir_IfOp : region_Op<"if", [DeclareOpInterfaceMethods &results, unsigned resultNum); + + /// Returns the display name string for the region_weights attribute. + static constexpr llvm::StringRef getWeightsAttrAssemblyName() { + return "weights"; + } + + /// Sets WeightedRegionBranchOpInterface weights to indicate + /// that either THEN or ELSE branch is unlikely. + /// By default, THEN branch is set to be unlikely. + void setUnlikelyIfWeights(bool unlikelyElse = false) { + if (unlikelyElse) + setWeights({1, 0}); + else + setWeights({0, 1}); + } }]; } diff --git a/external/llvm-project/flang/include/flang/Parser/dump-parse-tree.h b/external/llvm-project/flang/include/flang/Parser/dump-parse-tree.h index c6a5150a85a4..e3eed6aed807 100644 --- a/external/llvm-project/flang/include/flang/Parser/dump-parse-tree.h +++ b/external/llvm-project/flang/include/flang/Parser/dump-parse-tree.h @@ -565,6 +565,7 @@ class ParseTreeDumper { NODE_ENUM(OmpDependenceType, Value) NODE(parser, OmpTaskDependenceType) NODE_ENUM(OmpTaskDependenceType, Value) + NODE(parser, OmpIndirectClause) NODE(parser, OmpIterationOffset) NODE(parser, OmpIteration) NODE(parser, OmpIterationVector) diff --git a/external/llvm-project/flang/include/flang/Parser/parse-tree.h b/external/llvm-project/flang/include/flang/Parser/parse-tree.h index 67405f88e09f..61f97b855b0e 100644 --- a/external/llvm-project/flang/include/flang/Parser/parse-tree.h +++ b/external/llvm-project/flang/include/flang/Parser/parse-tree.h @@ -4300,6 +4300,12 @@ struct OmpHoldsClause { WRAPPER_CLASS_BOILERPLATE(OmpHoldsClause, common::Indirection); }; +// Ref: [5.2: 209] +struct OmpIndirectClause { + WRAPPER_CLASS_BOILERPLATE( + OmpIndirectClause, std::optional); +}; + // Ref: [5.2:72-73], in 4.5-5.1 it's scattered over individual directives // that allow the IF clause. // diff --git a/external/llvm-project/flang/include/flang/Runtime/assign.h b/external/llvm-project/flang/include/flang/Runtime/assign.h index bc80997a1bec..7d198bdcc9e8 100644 --- a/external/llvm-project/flang/include/flang/Runtime/assign.h +++ b/external/llvm-project/flang/include/flang/Runtime/assign.h @@ -38,7 +38,8 @@ enum AssignFlags { ComponentCanBeDefinedAssignment = 1 << 3, ExplicitLengthCharacterLHS = 1 << 4, PolymorphicLHS = 1 << 5, - DeallocateLHS = 1 << 6 + DeallocateLHS = 1 << 6, + UpdateLHSBounds = 1 << 7, }; #ifdef RT_DEVICE_COMPILATION diff --git a/external/llvm-project/flang/include/flang/Semantics/dump-expr.h b/external/llvm-project/flang/include/flang/Semantics/dump-expr.h index 2f445429a10b..9cc52b4da487 100644 --- a/external/llvm-project/flang/include/flang/Semantics/dump-expr.h +++ b/external/llvm-project/flang/include/flang/Semantics/dump-expr.h @@ -16,6 +16,7 @@ #include #include +#include #include #include @@ -38,6 +39,43 @@ class DumpEvaluateExpr { } private: + template struct TypeOf { + static constexpr std::string_view get() { +#if defined(__GNUC__) +#define DUMP_EXPR_SHOW_TYPE + std::string_view v(__PRETTY_FUNCTION__); + // Extract the "xyz" from the "pretty function" string: + // "... [with T = xyz; std::string_view = ...]" + std::string_view front("with T = "); + std::string_view back("; std::string_view ="); + +#elif defined(_MSC_VER) +#define DUMP_EXPR_SHOW_TYPE + std::string_view v(__FUNCSIG__); + // Extract the "xyz" from the "pretty function" string: + // "...TypeOf::get(void)" + std::string_view front("TypeOf<"); + std::string_view back(">::get(void)"); + +#endif + +#if defined(DUMP_EXPR_SHOW_TYPE) +#undef DUMP_EXPR_SHOW_TYPE + if (auto fpos{v.find(front)}; fpos != v.npos) { + v.remove_prefix(fpos + front.size()); + if (auto bpos{v.find(back)}; bpos != v.npos) { + v.remove_suffix(v.size() - bpos); + return v; + } + } +#endif + + return ""; + } + + static constexpr std::string_view name{TypeOf::get()}; + }; + template void Show(const common::Indirection &x) { Show(x.value()); } @@ -76,7 +114,7 @@ class DumpEvaluateExpr { void Show(const evaluate::NullPointer &); template void Show(const evaluate::Constant &x) { if constexpr (T::category == common::TypeCategory::Derived) { - Indent("derived constant"); + Indent("derived constant "s + std::string(TypeOf::name)); for (const auto &map : x.values()) { for (const auto &pair : map) { Show(pair.second.value()); @@ -84,7 +122,7 @@ class DumpEvaluateExpr { } Outdent(); } else { - Print("constant"); + Print("constant "s + std::string(TypeOf::name)); } } void Show(const Symbol &symbol); @@ -102,7 +140,7 @@ class DumpEvaluateExpr { void Show(const evaluate::Substring &x); void Show(const evaluate::ComplexPart &x); template void Show(const evaluate::Designator &x) { - Indent("designator"); + Indent("designator "s + std::string(TypeOf::name)); Show(x.u); Outdent(); } @@ -117,7 +155,7 @@ class DumpEvaluateExpr { Outdent(); } template void Show(const evaluate::FunctionRef &x) { - Indent("function ref"); + Indent("function ref "s + std::string(TypeOf::name)); Show(x.proc()); Show(x.arguments()); Outdent(); @@ -127,14 +165,14 @@ class DumpEvaluateExpr { } template void Show(const evaluate::ArrayConstructorValues &x) { - Indent("array constructor value"); + Indent("array constructor value "s + std::string(TypeOf::name)); for (auto &v : x) { Show(v); } Outdent(); } template void Show(const evaluate::ImpliedDo &x) { - Indent("implied do"); + Indent("implied do "s + std::string(TypeOf::name)); Show(x.lower()); Show(x.upper()); Show(x.stride()); @@ -148,20 +186,20 @@ class DumpEvaluateExpr { void Show(const evaluate::StructureConstructor &x); template void Show(const evaluate::Operation &op) { - Indent("unary op"); + Indent("unary op "s + std::string(TypeOf::name)); Show(op.left()); Outdent(); } template void Show(const evaluate::Operation &op) { - Indent("binary op"); + Indent("binary op "s + std::string(TypeOf::name)); Show(op.left()); Show(op.right()); Outdent(); } void Show(const evaluate::Relational &x); template void Show(const evaluate::Expr &x) { - Indent("expr T"); + Indent("expr <" + std::string(TypeOf::name) + ">"); Show(x.u); Outdent(); } diff --git a/external/llvm-project/flang/include/flang/Semantics/tools.h b/external/llvm-project/flang/include/flang/Semantics/tools.h index b13370512e5c..f3cfa9b99fb4 100644 --- a/external/llvm-project/flang/include/flang/Semantics/tools.h +++ b/external/llvm-project/flang/include/flang/Semantics/tools.h @@ -182,9 +182,12 @@ const Symbol *HasImpureFinal( const Symbol &, std::optional rank = std::nullopt); // Is this type finalizable or does it contain any polymorphic allocatable // ultimate components? -bool MayRequireFinalization(const DerivedTypeSpec &derived); +bool MayRequireFinalization(const DerivedTypeSpec &); // Does this type have an allocatable direct component? -bool HasAllocatableDirectComponent(const DerivedTypeSpec &derived); +bool HasAllocatableDirectComponent(const DerivedTypeSpec &); +// Does this type have any defined assignment at any level (or any polymorphic +// allocatable)? +bool MayHaveDefinedAssignment(const DerivedTypeSpec &); bool IsInBlankCommon(const Symbol &); bool IsAssumedLengthCharacter(const Symbol &); @@ -753,154 +756,5 @@ std::string GetCommonBlockObjectName(const Symbol &, bool underscoring); // Check for ambiguous USE associations bool HadUseError(SemanticsContext &, SourceName at, const Symbol *); -// Checks whether the symbol on the LHS is present in the RHS expression. -bool CheckForSymbolMatch(const SomeExpr *lhs, const SomeExpr *rhs); - -namespace operation { - -enum class Operator { - Unknown, - Add, - And, - Associated, - Call, - Constant, - Convert, - Div, - Eq, - Eqv, - False, - Ge, - Gt, - Identity, - Intrinsic, - Le, - Lt, - Max, - Min, - Mul, - Ne, - Neqv, - Not, - Or, - Pow, - Resize, // Convert within the same TypeCategory - Sub, - True, -}; - -std::string ToString(Operator op); - -template -Operator OperationCode( - const evaluate::Operation, Ts...> &op) { - switch (op.derived().logicalOperator) { - case common::LogicalOperator::And: - return Operator::And; - case common::LogicalOperator::Or: - return Operator::Or; - case common::LogicalOperator::Eqv: - return Operator::Eqv; - case common::LogicalOperator::Neqv: - return Operator::Neqv; - case common::LogicalOperator::Not: - return Operator::Not; - } - return Operator::Unknown; -} - -template -Operator OperationCode( - const evaluate::Operation, Ts...> &op) { - switch (op.derived().opr) { - case common::RelationalOperator::LT: - return Operator::Lt; - case common::RelationalOperator::LE: - return Operator::Le; - case common::RelationalOperator::EQ: - return Operator::Eq; - case common::RelationalOperator::NE: - return Operator::Ne; - case common::RelationalOperator::GE: - return Operator::Ge; - case common::RelationalOperator::GT: - return Operator::Gt; - } - return Operator::Unknown; -} - -template -Operator OperationCode(const evaluate::Operation, Ts...> &op) { - return Operator::Add; -} - -template -Operator OperationCode( - const evaluate::Operation, Ts...> &op) { - return Operator::Sub; -} - -template -Operator OperationCode( - const evaluate::Operation, Ts...> &op) { - return Operator::Mul; -} - -template -Operator OperationCode( - const evaluate::Operation, Ts...> &op) { - return Operator::Div; -} - -template -Operator OperationCode( - const evaluate::Operation, Ts...> &op) { - return Operator::Pow; -} - -template -Operator OperationCode( - const evaluate::Operation, Ts...> &op) { - return Operator::Pow; -} - -template -Operator OperationCode( - const evaluate::Operation, Ts...> &op) { - if constexpr (C == T::category) { - return Operator::Resize; - } else { - return Operator::Convert; - } -} - -template // -Operator OperationCode(const evaluate::Constant &x) { - return Operator::Constant; -} - -template // -Operator OperationCode(const T &) { - return Operator::Unknown; -} - -Operator OperationCode(const evaluate::ProcedureDesignator &proc); - -} // namespace operation - -/// Return information about the top-level operation (ignoring parentheses): -/// the operation code and the list of arguments. -std::pair> GetTopLevelOperation( - const SomeExpr &expr); - -/// Check if expr is same as x, or a sequence of Convert operations on x. -bool IsSameOrConvertOf(const SomeExpr &expr, const SomeExpr &x); - -/// Strip away any top-level Convert operations (if any exist) and return -/// the input value. A ComplexConstructor(x, 0) is also considered as a -/// convert operation. -/// If the input is not Operation, Designator, FunctionRef or Constant, -/// it returns std::nullopt. -MaybeExpr GetConvertInput(const SomeExpr &x); } // namespace Fortran::semantics #endif // FORTRAN_SEMANTICS_TOOLS_H_ diff --git a/external/llvm-project/flang/include/flang/Support/Fortran-features.h b/external/llvm-project/flang/include/flang/Support/Fortran-features.h index 5798297761f1..04fa26d72a10 100644 --- a/external/llvm-project/flang/include/flang/Support/Fortran-features.h +++ b/external/llvm-project/flang/include/flang/Support/Fortran-features.h @@ -82,6 +82,9 @@ ENUM_CLASS(UsageWarning, Portability, PointerToUndefinable, using LanguageFeatures = EnumSet; using UsageWarnings = EnumSet; +using LanguageFeatureOrWarning = std::variant; +using LanguageControlFlag = + std::pair; class LanguageFeatureControl { public: @@ -95,6 +98,13 @@ class LanguageFeatureControl { void EnableWarning(UsageWarning w, bool yes = true) { warnUsage_.set(w, yes); } + void EnableWarning(LanguageFeatureOrWarning flag, bool yes = true) { + if (std::holds_alternative(flag)) { + EnableWarning(std::get(flag), yes); + } else { + EnableWarning(std::get(flag), yes); + } + } void WarnOnAllNonstandard(bool yes = true); bool IsWarnOnAllNonstandard() const { return warnAllLanguage_; } void WarnOnAllUsage(bool yes = true); @@ -117,9 +127,11 @@ class LanguageFeatureControl { bool ShouldWarn(LanguageFeature f) const { return warnLanguage_.test(f); } bool ShouldWarn(UsageWarning w) const { return warnUsage_.test(w); } // Cli options + // Find a warning by its Cli spelling, i.e. '[no-]warning-name'. + std::optional FindWarning(std::string_view input); // Take a string from the Cli and apply it to the LanguageFeatureControl. // Return true if the option was recognized (and hence applied). - bool ApplyCliOption(std::string input); + bool EnableWarning(std::string_view input); // The add and replace functions are not currently used but are provided // to allow a flexible many-to-one mapping from Cli spellings to enum values. // Taking a string by value because the functions own this string after the diff --git a/external/llvm-project/flang/include/flang/Support/OpenMP-features.h b/external/llvm-project/flang/include/flang/Support/OpenMP-features.h index 1dd7ea560cc9..349cd19c1224 100644 --- a/external/llvm-project/flang/include/flang/Support/OpenMP-features.h +++ b/external/llvm-project/flang/include/flang/Support/OpenMP-features.h @@ -42,6 +42,9 @@ void setOpenMPMacro(int version, FortranPredefinitions &predefinitions) { case 52: predefinitions.emplace_back("_OPENMP", "202111"); break; + case 60: + predefinitions.emplace_back("_OPENMP", "202411"); + break; case 11: default: predefinitions.emplace_back("_OPENMP", "199911"); diff --git a/external/llvm-project/flang/lib/Evaluate/tools.cpp b/external/llvm-project/flang/lib/Evaluate/tools.cpp index 222c32a9c332..68838564f87b 100644 --- a/external/llvm-project/flang/lib/Evaluate/tools.cpp +++ b/external/llvm-project/flang/lib/Evaluate/tools.cpp @@ -13,6 +13,7 @@ #include "flang/Evaluate/traverse.h" #include "flang/Parser/message.h" #include "flang/Semantics/tools.h" +#include "llvm/ADT/StringSwitch.h" #include #include @@ -1595,6 +1596,316 @@ bool CheckForCoindexedObject(parser::ContextualMessages &messages, } } +bool CheckForSymbolMatch(const Expr *lhs, const Expr *rhs) { + if (lhs && rhs) { + if (SymbolVector lhsSymbols{GetSymbolVector(*lhs)}; !lhsSymbols.empty()) { + const Symbol &first{*lhsSymbols.front()}; + for (const Symbol &symbol : GetSymbolVector(*rhs)) { + if (first == symbol) { + return true; + } + } + } + } + return false; +} + +namespace operation { +template Expr AsSomeExpr(const T &x) { + return AsGenericExpr(common::Clone(x)); +} + +template +struct ArgumentExtractor + : public Traverse, + std::pair>>, false> { + using Arguments = std::vector>; + using Result = std::pair; + using Base = + Traverse, Result, false>; + static constexpr auto IgnoreResizes{IgnoreResizingConverts}; + static constexpr auto Logical{common::TypeCategory::Logical}; + ArgumentExtractor() : Base(*this) {} + + Result Default() const { return {}; } + + using Base::operator(); + + template + Result operator()(const Constant> &x) const { + if (const auto &val{x.GetScalarValue()}) { + return val->IsTrue() + ? std::make_pair(operation::Operator::True, Arguments{}) + : std::make_pair(operation::Operator::False, Arguments{}); + } + return Default(); + } + + template Result operator()(const FunctionRef &x) const { + Result result{operation::OperationCode(x.proc()), {}}; + for (size_t i{0}, e{x.arguments().size()}; i != e; ++i) { + if (auto *e{x.UnwrapArgExpr(i)}) { + result.second.push_back(*e); + } + } + return result; + } + + template + Result operator()(const Operation &x) const { + if constexpr (std::is_same_v>) { + // Ignore top-level parentheses. + return (*this)(x.template operand<0>()); + } + if constexpr (IgnoreResizes && std::is_same_v>) { + // Ignore conversions within the same category. + // Atomic operations on int(kind=1) may be implicitly widened + // to int(kind=4) for example. + return (*this)(x.template operand<0>()); + } else { + return std::make_pair(operation::OperationCode(x), + OperationArgs(x, std::index_sequence_for{})); + } + } + + template Result operator()(const Designator &x) const { + return {operation::Operator::Identity, {AsSomeExpr(x)}}; + } + + template Result operator()(const Constant &x) const { + return {operation::Operator::Identity, {AsSomeExpr(x)}}; + } + + template + Result Combine(Result &&result, Rs &&...results) const { + // There shouldn't be any combining needed, since we're stopping the + // traversal at the top-level operation, but implement one that picks + // the first non-empty result. + if constexpr (sizeof...(Rs) == 0) { + return std::move(result); + } else { + if (!result.second.empty()) { + return std::move(result); + } else { + return Combine(std::move(results)...); + } + } + } + +private: + template + Arguments OperationArgs( + const Operation &x, std::index_sequence) const { + return Arguments{Expr(x.template operand())...}; + } +}; +} // namespace operation + +std::string operation::ToString(operation::Operator op) { + switch (op) { + case Operator::Unknown: + return "??"; + case Operator::Add: + return "+"; + case Operator::And: + return "AND"; + case Operator::Associated: + return "ASSOCIATED"; + case Operator::Call: + return "function-call"; + case Operator::Constant: + return "constant"; + case Operator::Convert: + return "type-conversion"; + case Operator::Div: + return "/"; + case Operator::Eq: + return "=="; + case Operator::Eqv: + return "EQV"; + case Operator::False: + return ".FALSE."; + case Operator::Ge: + return ">="; + case Operator::Gt: + return ">"; + case Operator::Identity: + return "identity"; + case Operator::Intrinsic: + return "intrinsic"; + case Operator::Le: + return "<="; + case Operator::Lt: + return "<"; + case Operator::Max: + return "MAX"; + case Operator::Min: + return "MIN"; + case Operator::Mul: + return "*"; + case Operator::Ne: + return "/="; + case Operator::Neqv: + return "NEQV/EOR"; + case Operator::Not: + return "NOT"; + case Operator::Or: + return "OR"; + case Operator::Pow: + return "**"; + case Operator::Resize: + return "resize"; + case Operator::Sub: + return "-"; + case Operator::True: + return ".TRUE."; + } + llvm_unreachable("Unhandler operator"); +} + +operation::Operator operation::OperationCode(const ProcedureDesignator &proc) { + Operator code{llvm::StringSwitch(proc.GetName()) + .Case("associated", Operator::Associated) + .Case("min", Operator::Min) + .Case("max", Operator::Max) + .Case("iand", Operator::And) + .Case("ior", Operator::Or) + .Case("ieor", Operator::Neqv) + .Default(Operator::Call)}; + if (code == Operator::Call && proc.GetSpecificIntrinsic()) { + return Operator::Intrinsic; + } + return code; +} + +std::pair>> +GetTopLevelOperation(const Expr &expr) { + return operation::ArgumentExtractor{}(expr); +} + +namespace operation { +struct ConvertCollector + : public Traverse>, std::vector>, + false> { + using Result = + std::pair>, std::vector>; + using Base = Traverse; + ConvertCollector() : Base(*this) {} + + Result Default() const { return {}; } + + using Base::operator(); + + template Result operator()(const Designator &x) const { + return {AsSomeExpr(x), {}}; + } + + template Result operator()(const FunctionRef &x) const { + return {AsSomeExpr(x), {}}; + } + + template Result operator()(const Constant &x) const { + return {AsSomeExpr(x), {}}; + } + + template + Result operator()(const Operation &x) const { + if constexpr (std::is_same_v>) { + // Ignore parentheses. + return (*this)(x.template operand<0>()); + } else if constexpr (is_convert_v) { + // Convert should always have a typed result, so it should be safe to + // dereference x.GetType(). + return Combine( + {std::nullopt, {*x.GetType()}}, (*this)(x.template operand<0>())); + } else if constexpr (is_complex_constructor_v) { + // This is a conversion iff the imaginary operand is 0. + if (IsZero(x.template operand<1>())) { + return Combine( + {std::nullopt, {*x.GetType()}}, (*this)(x.template operand<0>())); + } else { + return {AsSomeExpr(x.derived()), {}}; + } + } else { + return {AsSomeExpr(x.derived()), {}}; + } + } + + template + Result Combine(Result &&result, Rs &&...results) const { + Result v(std::move(result)); + auto setValue{[](std::optional> &x, + std::optional> &&y) { + assert((!x.has_value() || !y.has_value()) && "Multiple designators"); + if (!x.has_value()) { + x = std::move(y); + } + }}; + auto moveAppend{[](auto &accum, auto &&other) { + for (auto &&s : other) { + accum.push_back(std::move(s)); + } + }}; + (setValue(v.first, std::move(results).first), ...); + (moveAppend(v.second, std::move(results).second), ...); + return v; + } + +private: + template static bool IsZero(const A &x) { return false; } + template static bool IsZero(const Expr &x) { + return common::visit([](auto &&s) { return IsZero(s); }, x.u); + } + template static bool IsZero(const Constant &x) { + if (auto &&maybeScalar{x.GetScalarValue()}) { + return maybeScalar->IsZero(); + } else { + return false; + } + } + + template struct is_convert { + static constexpr bool value{false}; + }; + template + struct is_convert> { + static constexpr bool value{true}; + }; + template struct is_convert> { + // Conversion from complex to real. + static constexpr bool value{true}; + }; + template + static constexpr bool is_convert_v{is_convert::value}; + + template struct is_complex_constructor { + static constexpr bool value{false}; + }; + template struct is_complex_constructor> { + static constexpr bool value{true}; + }; + template + static constexpr bool is_complex_constructor_v{ + is_complex_constructor::value}; +}; +} // namespace operation + +std::optional> GetConvertInput(const Expr &x) { + // This returns Expr{x} when x is a designator/functionref/constant. + return operation::ConvertCollector{}(x).first; +} + +bool IsSameOrConvertOf(const Expr &expr, const Expr &x) { + // Check if expr is same as x, or a sequence of Convert operations on x. + if (expr == x) { + return true; + } else if (auto maybe{GetConvertInput(expr)}) { + return *maybe == x; + } else { + return false; + } +} } // namespace Fortran::evaluate namespace Fortran::semantics { diff --git a/external/llvm-project/flang/lib/Frontend/CompilerInvocation.cpp b/external/llvm-project/flang/lib/Frontend/CompilerInvocation.cpp index 9f9a4e48f709..302bd20be1b2 100644 --- a/external/llvm-project/flang/lib/Frontend/CompilerInvocation.cpp +++ b/external/llvm-project/flang/lib/Frontend/CompilerInvocation.cpp @@ -1027,7 +1027,7 @@ static bool parseDiagArgs(CompilerInvocation &res, llvm::opt::ArgList &args, if (wArg == "error") { res.setWarnAsErr(true); // -W(no-) - } else if (!features.ApplyCliOption(wArg)) { + } else if (!features.EnableWarning(wArg)) { const unsigned diagID = diags.getCustomDiagID( clang::DiagnosticsEngine::Error, "Unknown diagnostic option: -W%0"); diags.Report(diagID) << wArg; diff --git a/external/llvm-project/flang/lib/Lower/CMakeLists.txt b/external/llvm-project/flang/lib/Lower/CMakeLists.txt index bc817ff8f1f3..53a4c51736d2 100644 --- a/external/llvm-project/flang/lib/Lower/CMakeLists.txt +++ b/external/llvm-project/flang/lib/Lower/CMakeLists.txt @@ -23,6 +23,7 @@ add_flang_library(FortranLower LoweringOptions.cpp Mangler.cpp OpenACC.cpp + OpenMP/Atomic.cpp OpenMP/ClauseProcessor.cpp OpenMP/Clauses.cpp OpenMP/DataSharingProcessor.cpp diff --git a/external/llvm-project/flang/lib/Lower/OpenACC.cpp b/external/llvm-project/flang/lib/Lower/OpenACC.cpp index 69e9c53baa74..3ef3330cba2d 100644 --- a/external/llvm-project/flang/lib/Lower/OpenACC.cpp +++ b/external/llvm-project/flang/lib/Lower/OpenACC.cpp @@ -654,7 +654,7 @@ void genAtomicCapture(Fortran::lower::AbstractConverter &converter, mlir::Block &block = atomicCaptureOp->getRegion(0).back(); firOpBuilder.setInsertionPointToStart(&block); if (Fortran::parser::CheckForSingleVariableOnRHS(stmt1)) { - if (Fortran::semantics::CheckForSymbolMatch( + if (Fortran::evaluate::CheckForSymbolMatch( Fortran::semantics::GetExpr(stmt2Var), Fortran::semantics::GetExpr(stmt2Expr))) { // Atomic capture construct is of the form [capture-stmt, update-stmt] diff --git a/external/llvm-project/flang/lib/Lower/OpenMP/Atomic.cpp b/external/llvm-project/flang/lib/Lower/OpenMP/Atomic.cpp new file mode 100644 index 000000000000..e641a48a0335 --- /dev/null +++ b/external/llvm-project/flang/lib/Lower/OpenMP/Atomic.cpp @@ -0,0 +1,510 @@ +//===-- Atomic.cpp -- Lowering of atomic constructs -----------------------===// +// +// 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 "Atomic.h" +#include "flang/Lower/OpenMP/Clauses.h" +#include "flang/Evaluate/expression.h" +#include "flang/Evaluate/fold.h" +#include "flang/Evaluate/tools.h" +#include "flang/Lower/AbstractConverter.h" +#include "flang/Lower/PFTBuilder.h" +#include "flang/Lower/StatementContext.h" +#include "flang/Lower/SymbolMap.h" +#include "flang/Optimizer/Builder/FIRBuilder.h" +#include "flang/Optimizer/Builder/Todo.h" +#include "flang/Parser/parse-tree.h" +#include "flang/Semantics/semantics.h" +#include "flang/Semantics/type.h" +#include "flang/Support/Fortran.h" +#include "mlir/Dialect/OpenMP/OpenMPDialect.h" +#include "llvm/ADT/STLExtras.h" +#include "llvm/Support/CommandLine.h" +#include "llvm/Support/raw_ostream.h" + +#include +#include +#include +#include +#include + +static llvm::cl::opt DumpAtomicAnalysis("fdebug-dump-atomic-analysis"); + +using namespace Fortran; + +// Don't import the entire Fortran::lower. +namespace omp { +using namespace Fortran::lower::omp; +} + +[[maybe_unused]] static void +dumpAtomicAnalysis(const parser::OpenMPAtomicConstruct::Analysis &analysis) { + auto whatStr = [](int k) { + std::string txt = "?"; + switch (k & parser::OpenMPAtomicConstruct::Analysis::Action) { + case parser::OpenMPAtomicConstruct::Analysis::None: + txt = "None"; + break; + case parser::OpenMPAtomicConstruct::Analysis::Read: + txt = "Read"; + break; + case parser::OpenMPAtomicConstruct::Analysis::Write: + txt = "Write"; + break; + case parser::OpenMPAtomicConstruct::Analysis::Update: + txt = "Update"; + break; + } + switch (k & parser::OpenMPAtomicConstruct::Analysis::Condition) { + case parser::OpenMPAtomicConstruct::Analysis::IfTrue: + txt += " | IfTrue"; + break; + case parser::OpenMPAtomicConstruct::Analysis::IfFalse: + txt += " | IfFalse"; + break; + } + return txt; + }; + + auto exprStr = [&](const parser::TypedExpr &expr) { + if (auto *maybe = expr.get()) { + if (maybe->v) + return maybe->v->AsFortran(); + } + return ""s; + }; + auto assignStr = [&](const parser::AssignmentStmt::TypedAssignment &assign) { + if (auto *maybe = assign.get(); maybe && maybe->v) { + std::string str; + llvm::raw_string_ostream os(str); + maybe->v->AsFortran(os); + return str; + } + return ""s; + }; + + const semantics::SomeExpr &atom = *analysis.atom.get()->v; + + llvm::errs() << "Analysis {\n"; + llvm::errs() << " atom: " << atom.AsFortran() << "\n"; + llvm::errs() << " cond: " << exprStr(analysis.cond) << "\n"; + llvm::errs() << " op0 {\n"; + llvm::errs() << " what: " << whatStr(analysis.op0.what) << "\n"; + llvm::errs() << " assign: " << assignStr(analysis.op0.assign) << "\n"; + llvm::errs() << " }\n"; + llvm::errs() << " op1 {\n"; + llvm::errs() << " what: " << whatStr(analysis.op1.what) << "\n"; + llvm::errs() << " assign: " << assignStr(analysis.op1.assign) << "\n"; + llvm::errs() << " }\n"; + llvm::errs() << "}\n"; +} + +static bool isPointerAssignment(const evaluate::Assignment &assign) { + return common::visit( + common::visitors{ + [](const evaluate::Assignment::BoundsSpec &) { return true; }, + [](const evaluate::Assignment::BoundsRemapping &) { return true; }, + [](const auto &) { return false; }, + }, + assign.u); +} + +static fir::FirOpBuilder::InsertPoint +getInsertionPointBefore(mlir::Operation *op) { + return fir::FirOpBuilder::InsertPoint(op->getBlock(), + mlir::Block::iterator(op)); +} + +static fir::FirOpBuilder::InsertPoint +getInsertionPointAfter(mlir::Operation *op) { + return fir::FirOpBuilder::InsertPoint(op->getBlock(), + ++mlir::Block::iterator(op)); +} + +static mlir::IntegerAttr getAtomicHint(lower::AbstractConverter &converter, + const omp::List &clauses) { + fir::FirOpBuilder &builder = converter.getFirOpBuilder(); + for (const omp::Clause &clause : clauses) { + if (clause.id != llvm::omp::Clause::OMPC_hint) + continue; + auto &hint = std::get(clause.u); + auto maybeVal = evaluate::ToInt64(hint.v); + CHECK(maybeVal); + return builder.getI64IntegerAttr(*maybeVal); + } + return nullptr; +} + +static mlir::omp::ClauseMemoryOrderKind +getMemoryOrderKind(common::OmpMemoryOrderType kind) { + switch (kind) { + case common::OmpMemoryOrderType::Acq_Rel: + return mlir::omp::ClauseMemoryOrderKind::Acq_rel; + case common::OmpMemoryOrderType::Acquire: + return mlir::omp::ClauseMemoryOrderKind::Acquire; + case common::OmpMemoryOrderType::Relaxed: + return mlir::omp::ClauseMemoryOrderKind::Relaxed; + case common::OmpMemoryOrderType::Release: + return mlir::omp::ClauseMemoryOrderKind::Release; + case common::OmpMemoryOrderType::Seq_Cst: + return mlir::omp::ClauseMemoryOrderKind::Seq_cst; + } + llvm_unreachable("Unexpected kind"); +} + +static std::optional +getMemoryOrderKind(llvm::omp::Clause clauseId) { + switch (clauseId) { + case llvm::omp::Clause::OMPC_acq_rel: + return mlir::omp::ClauseMemoryOrderKind::Acq_rel; + case llvm::omp::Clause::OMPC_acquire: + return mlir::omp::ClauseMemoryOrderKind::Acquire; + case llvm::omp::Clause::OMPC_relaxed: + return mlir::omp::ClauseMemoryOrderKind::Relaxed; + case llvm::omp::Clause::OMPC_release: + return mlir::omp::ClauseMemoryOrderKind::Release; + case llvm::omp::Clause::OMPC_seq_cst: + return mlir::omp::ClauseMemoryOrderKind::Seq_cst; + default: + return std::nullopt; + } +} + +static std::optional +getMemoryOrderFromRequires(const semantics::Scope &scope) { + // The REQUIRES construct is only allowed in the main program scope + // and module scope, but seems like we also accept it in a subprogram + // scope. + // For safety, traverse all enclosing scopes and check if their symbol + // contains REQUIRES. + for (const auto *sc{&scope}; sc->kind() != semantics::Scope::Kind::Global; + sc = &sc->parent()) { + const semantics::Symbol *sym = sc->symbol(); + if (!sym) + continue; + + const common::OmpMemoryOrderType *admo = common::visit( + [](auto &&s) { + using WithOmpDeclarative = semantics::WithOmpDeclarative; + if constexpr (std::is_convertible_v) { + return s.ompAtomicDefaultMemOrder(); + } + return static_cast(nullptr); + }, + sym->details()); + if (admo) + return getMemoryOrderKind(*admo); + } + + return std::nullopt; +} + +static std::optional +getDefaultAtomicMemOrder(semantics::SemanticsContext &semaCtx) { + unsigned version = semaCtx.langOptions().OpenMPVersion; + if (version > 50) + return mlir::omp::ClauseMemoryOrderKind::Relaxed; + return std::nullopt; +} + +static std::optional +getAtomicMemoryOrder(semantics::SemanticsContext &semaCtx, + const omp::List &clauses, + const semantics::Scope &scope) { + for (const omp::Clause &clause : clauses) { + if (auto maybeKind = getMemoryOrderKind(clause.id)) + return *maybeKind; + } + + if (auto maybeKind = getMemoryOrderFromRequires(scope)) + return *maybeKind; + + return getDefaultAtomicMemOrder(semaCtx); +} + +static mlir::omp::ClauseMemoryOrderKindAttr +makeMemOrderAttr(lower::AbstractConverter &converter, + std::optional maybeKind) { + if (maybeKind) { + return mlir::omp::ClauseMemoryOrderKindAttr::get( + converter.getFirOpBuilder().getContext(), *maybeKind); + } + return nullptr; +} + +static mlir::Operation * // +genAtomicRead(lower::AbstractConverter &converter, + semantics::SemanticsContext &semaCtx, mlir::Location loc, + lower::StatementContext &stmtCtx, mlir::Value atomAddr, + const semantics::SomeExpr &atom, + const evaluate::Assignment &assign, mlir::IntegerAttr hint, + std::optional memOrder, + fir::FirOpBuilder::InsertPoint preAt, + fir::FirOpBuilder::InsertPoint atomicAt, + fir::FirOpBuilder::InsertPoint postAt) { + fir::FirOpBuilder &builder = converter.getFirOpBuilder(); + builder.restoreInsertionPoint(preAt); + + // If the atomic clause is read then the memory-order clause must + // not be release. + if (memOrder) { + if (*memOrder == mlir::omp::ClauseMemoryOrderKind::Release) { + // Reset it back to the default. + memOrder = getDefaultAtomicMemOrder(semaCtx); + } else if (*memOrder == mlir::omp::ClauseMemoryOrderKind::Acq_rel) { + // The MLIR verifier doesn't like acq_rel either. + memOrder = mlir::omp::ClauseMemoryOrderKind::Acquire; + } + } + + mlir::Value storeAddr = + fir::getBase(converter.genExprAddr(assign.lhs, stmtCtx, &loc)); + mlir::Type atomType = fir::unwrapRefType(atomAddr.getType()); + mlir::Type storeType = fir::unwrapRefType(storeAddr.getType()); + + mlir::Value toAddr = [&]() { + if (atomType == storeType) + return storeAddr; + return builder.createTemporary(loc, atomType, ".tmp.atomval"); + }(); + + builder.restoreInsertionPoint(atomicAt); + mlir::Operation *op = builder.create( + loc, atomAddr, toAddr, mlir::TypeAttr::get(atomType), hint, + makeMemOrderAttr(converter, memOrder)); + + if (atomType != storeType) { + lower::ExprToValueMap overrides; + // The READ operation could be a part of UPDATE CAPTURE, so make sure + // we don't emit extra code into the body of the atomic op. + builder.restoreInsertionPoint(postAt); + mlir::Value load = builder.create(loc, toAddr); + overrides.try_emplace(&atom, load); + + converter.overrideExprValues(&overrides); + mlir::Value value = + fir::getBase(converter.genExprValue(assign.rhs, stmtCtx, &loc)); + converter.resetExprOverrides(); + + builder.create(loc, value, storeAddr); + } + return op; +} + +static mlir::Operation * // +genAtomicWrite(lower::AbstractConverter &converter, + semantics::SemanticsContext &semaCtx, mlir::Location loc, + lower::StatementContext &stmtCtx, mlir::Value atomAddr, + const semantics::SomeExpr &atom, + const evaluate::Assignment &assign, mlir::IntegerAttr hint, + std::optional memOrder, + fir::FirOpBuilder::InsertPoint preAt, + fir::FirOpBuilder::InsertPoint atomicAt, + fir::FirOpBuilder::InsertPoint postAt) { + fir::FirOpBuilder &builder = converter.getFirOpBuilder(); + builder.restoreInsertionPoint(preAt); + + // If the atomic clause is write then the memory-order clause must + // not be acquire. + if (memOrder) { + if (*memOrder == mlir::omp::ClauseMemoryOrderKind::Acquire) { + // Reset it back to the default. + memOrder = getDefaultAtomicMemOrder(semaCtx); + } else if (*memOrder == mlir::omp::ClauseMemoryOrderKind::Acq_rel) { + // The MLIR verifier doesn't like acq_rel either. + memOrder = mlir::omp::ClauseMemoryOrderKind::Release; + } + } + + mlir::Value value = + fir::getBase(converter.genExprValue(assign.rhs, stmtCtx, &loc)); + mlir::Type atomType = fir::unwrapRefType(atomAddr.getType()); + mlir::Value converted = builder.createConvert(loc, atomType, value); + + builder.restoreInsertionPoint(atomicAt); + mlir::Operation *op = builder.create( + loc, atomAddr, converted, hint, makeMemOrderAttr(converter, memOrder)); + return op; +} + +static mlir::Operation * +genAtomicUpdate(lower::AbstractConverter &converter, + semantics::SemanticsContext &semaCtx, mlir::Location loc, + lower::StatementContext &stmtCtx, mlir::Value atomAddr, + const semantics::SomeExpr &atom, + const evaluate::Assignment &assign, mlir::IntegerAttr hint, + std::optional memOrder, + fir::FirOpBuilder::InsertPoint preAt, + fir::FirOpBuilder::InsertPoint atomicAt, + fir::FirOpBuilder::InsertPoint postAt) { + lower::ExprToValueMap overrides; + lower::StatementContext naCtx; + fir::FirOpBuilder &builder = converter.getFirOpBuilder(); + builder.restoreInsertionPoint(preAt); + + mlir::Type atomType = fir::unwrapRefType(atomAddr.getType()); + + // This must exist by now. + semantics::SomeExpr input = *evaluate::GetConvertInput(assign.rhs); + std::vector args = + evaluate::GetTopLevelOperation(input).second; + assert(!args.empty() && "Update operation without arguments"); + for (auto &arg : args) { + if (!evaluate::IsSameOrConvertOf(arg, atom)) { + mlir::Value val = fir::getBase(converter.genExprValue(arg, naCtx, &loc)); + overrides.try_emplace(&arg, val); + } + } + + builder.restoreInsertionPoint(atomicAt); + auto updateOp = builder.create( + loc, atomAddr, hint, makeMemOrderAttr(converter, memOrder)); + + mlir::Region ®ion = updateOp->getRegion(0); + mlir::Block *block = builder.createBlock(®ion, {}, {atomType}, {loc}); + mlir::Value localAtom = fir::getBase(block->getArgument(0)); + overrides.try_emplace(&atom, localAtom); + + converter.overrideExprValues(&overrides); + mlir::Value updated = + fir::getBase(converter.genExprValue(assign.rhs, stmtCtx, &loc)); + mlir::Value converted = builder.createConvert(loc, atomType, updated); + builder.create(loc, converted); + converter.resetExprOverrides(); + + builder.restoreInsertionPoint(postAt); // For naCtx cleanups + return updateOp; +} + +static mlir::Operation * +genAtomicOperation(lower::AbstractConverter &converter, + semantics::SemanticsContext &semaCtx, mlir::Location loc, + lower::StatementContext &stmtCtx, int action, + mlir::Value atomAddr, const semantics::SomeExpr &atom, + const evaluate::Assignment &assign, mlir::IntegerAttr hint, + std::optional memOrder, + fir::FirOpBuilder::InsertPoint preAt, + fir::FirOpBuilder::InsertPoint atomicAt, + fir::FirOpBuilder::InsertPoint postAt) { + if (isPointerAssignment(assign)) { + TODO(loc, "Code generation for pointer assignment is not implemented yet"); + } + + // This function and the functions called here do not preserve the + // builder's insertion point, or set it to anything specific. + switch (action) { + case parser::OpenMPAtomicConstruct::Analysis::Read: + return genAtomicRead(converter, semaCtx, loc, stmtCtx, atomAddr, atom, + assign, hint, memOrder, preAt, atomicAt, postAt); + case parser::OpenMPAtomicConstruct::Analysis::Write: + return genAtomicWrite(converter, semaCtx, loc, stmtCtx, atomAddr, atom, + assign, hint, memOrder, preAt, atomicAt, postAt); + case parser::OpenMPAtomicConstruct::Analysis::Update: + return genAtomicUpdate(converter, semaCtx, loc, stmtCtx, atomAddr, atom, + assign, hint, memOrder, preAt, atomicAt, postAt); + default: + return nullptr; + } +} + +void Fortran::lower::omp::lowerAtomic( + AbstractConverter &converter, SymMap &symTable, + semantics::SemanticsContext &semaCtx, pft::Evaluation &eval, + const parser::OpenMPAtomicConstruct &construct) { + auto get = [](auto &&typedWrapper) -> decltype(&*typedWrapper.get()->v) { + if (auto *maybe = typedWrapper.get(); maybe && maybe->v) { + return &*maybe->v; + } else { + return nullptr; + } + }; + + fir::FirOpBuilder &builder = converter.getFirOpBuilder(); + auto &dirSpec = std::get(construct.t); + omp::List clauses = makeClauses(dirSpec.Clauses(), semaCtx); + lower::StatementContext stmtCtx; + + const parser::OpenMPAtomicConstruct::Analysis &analysis = construct.analysis; + if (DumpAtomicAnalysis) + dumpAtomicAnalysis(analysis); + + const semantics::SomeExpr &atom = *get(analysis.atom); + mlir::Location loc = converter.genLocation(construct.source); + mlir::Value atomAddr = + fir::getBase(converter.genExprAddr(atom, stmtCtx, &loc)); + mlir::IntegerAttr hint = getAtomicHint(converter, clauses); + std::optional memOrder = + getAtomicMemoryOrder(semaCtx, clauses, + semaCtx.FindScope(construct.source)); + + if (auto *cond = get(analysis.cond)) { + (void)cond; + TODO(loc, "OpenMP ATOMIC COMPARE"); + } else { + int action0 = analysis.op0.what & analysis.Action; + int action1 = analysis.op1.what & analysis.Action; + mlir::Operation *captureOp = nullptr; + fir::FirOpBuilder::InsertPoint preAt = builder.saveInsertionPoint(); + fir::FirOpBuilder::InsertPoint atomicAt, postAt; + + if (construct.IsCapture()) { + // Capturing operation. + assert(action0 != analysis.None && action1 != analysis.None && + "Expexcing two actions"); + (void)action0; + (void)action1; + captureOp = builder.create( + loc, hint, makeMemOrderAttr(converter, memOrder)); + // Set the non-atomic insertion point to before the atomic.capture. + preAt = getInsertionPointBefore(captureOp); + + mlir::Block *block = builder.createBlock(&captureOp->getRegion(0)); + builder.setInsertionPointToEnd(block); + // Set the atomic insertion point to before the terminator inside + // atomic.capture. + mlir::Operation *term = builder.create(loc); + atomicAt = getInsertionPointBefore(term); + postAt = getInsertionPointAfter(captureOp); + hint = nullptr; + memOrder = std::nullopt; + } else { + // Non-capturing operation. + assert(action0 != analysis.None && action1 == analysis.None && + "Expexcing single action"); + assert(!(analysis.op0.what & analysis.Condition)); + postAt = atomicAt = preAt; + } + + // The builder's insertion point needs to be specifically set before + // each call to `genAtomicOperation`. + mlir::Operation *firstOp = genAtomicOperation( + converter, semaCtx, loc, stmtCtx, analysis.op0.what, atomAddr, atom, + *get(analysis.op0.assign), hint, memOrder, preAt, atomicAt, postAt); + assert(firstOp && "Should have created an atomic operation"); + atomicAt = getInsertionPointAfter(firstOp); + + mlir::Operation *secondOp = nullptr; + if (analysis.op1.what != analysis.None) { + secondOp = genAtomicOperation( + converter, semaCtx, loc, stmtCtx, analysis.op1.what, atomAddr, atom, + *get(analysis.op1.assign), hint, memOrder, preAt, atomicAt, postAt); + } + + if (construct.IsCapture()) { + // If this is a capture operation, the first/second ops will be inside + // of it. Set the insertion point to past the capture op itself. + builder.restoreInsertionPoint(postAt); + } else { + if (secondOp) { + builder.setInsertionPointAfter(secondOp); + } else { + builder.setInsertionPointAfter(firstOp); + } + } + } +} diff --git a/external/llvm-project/flang/lib/Lower/OpenMP/Atomic.h b/external/llvm-project/flang/lib/Lower/OpenMP/Atomic.h new file mode 100644 index 000000000000..96db4d7e90c8 --- /dev/null +++ b/external/llvm-project/flang/lib/Lower/OpenMP/Atomic.h @@ -0,0 +1,36 @@ +//===-- Atomic.h -- Lowering of atomic constructs -------------------------===// +// +// 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 FORTRAN_LOWER_OPENMP_ATOMIC_H +#define FORTRAN_LOWER_OPENMP_ATOMIC_H + +namespace Fortran { +namespace lower { +class AbstractConverter; +class SymMap; + +namespace pft { +struct Evaluation; +} +} // namespace lower + +namespace parser { +struct OpenMPAtomicConstruct; +} + +namespace semantics { +class SemanticsContext; +} +} // namespace Fortran + +namespace Fortran::lower::omp { +void lowerAtomic(AbstractConverter &converter, SymMap &symTable, + semantics::SemanticsContext &semaCtx, pft::Evaluation &eval, + const parser::OpenMPAtomicConstruct &construct); +} + +#endif // FORTRAN_LOWER_OPENMP_ATOMIC_H diff --git a/external/llvm-project/flang/lib/Lower/OpenMP/ClauseProcessor.cpp b/external/llvm-project/flang/lib/Lower/OpenMP/ClauseProcessor.cpp index 47d9c9083664..c1f4e92ef86d 100644 --- a/external/llvm-project/flang/lib/Lower/OpenMP/ClauseProcessor.cpp +++ b/external/llvm-project/flang/lib/Lower/OpenMP/ClauseProcessor.cpp @@ -728,12 +728,15 @@ class TypeInfo { // Is the type inside a box? bool isBox() const { return inBox; } + bool isBoxChar() const { return inBoxChar; } + private: void typeScan(mlir::Type type); std::optional charLen; llvm::SmallVector shape; bool inBox = false; + bool inBoxChar = false; }; void TypeInfo::typeScan(mlir::Type ty) { @@ -749,6 +752,9 @@ void TypeInfo::typeScan(mlir::Type ty) { typeScan(cty.getEleTy()); } else if (auto cty = mlir::dyn_cast(ty)) { charLen = cty.getLen(); + } else if (auto cty = mlir::dyn_cast(ty)) { + inBoxChar = true; + typeScan(cty.getEleTy()); } else if (auto hty = mlir::dyn_cast(ty)) { typeScan(hty.getEleTy()); } else if (auto pty = mlir::dyn_cast(ty)) { @@ -792,12 +798,6 @@ createCopyFunc(mlir::Location loc, lower::AbstractConverter &converter, fir::FortranVariableFlagsAttr attrs; if (varAttrs != fir::FortranVariableFlagsEnum::None) attrs = fir::FortranVariableFlagsAttr::get(builder.getContext(), varAttrs); - llvm::SmallVector typeparams; - if (typeInfo.getCharLength().has_value()) { - mlir::Value charLen = builder.createIntegerConstant( - loc, builder.getCharacterLengthType(), *typeInfo.getCharLength()); - typeparams.push_back(charLen); - } mlir::Value shape; if (!typeInfo.isBox() && !typeInfo.getShape().empty()) { llvm::SmallVector extents; @@ -806,11 +806,34 @@ createCopyFunc(mlir::Location loc, lower::AbstractConverter &converter, builder.createIntegerConstant(loc, builder.getIndexType(), extent)); shape = builder.create(loc, extents); } + mlir::Value dst = funcOp.getArgument(0); + mlir::Value src = funcOp.getArgument(1); + llvm::SmallVector typeparams; + if (typeInfo.isBoxChar()) { + // fir.boxchar will be passed here as fir.ref + auto loadDst = builder.create(loc, dst); + auto loadSrc = builder.create(loc, src); + // get the actual fir.ref type + mlir::Type refType = + fir::ReferenceType::get(mlir::cast(eleTy).getEleTy()); + auto unboxedDst = builder.create( + loc, refType, builder.getIndexType(), loadDst); + auto unboxedSrc = builder.create( + loc, refType, builder.getIndexType(), loadSrc); + // Add length to type parameters + typeparams.push_back(unboxedDst.getResult(1)); + dst = unboxedDst.getResult(0); + src = unboxedSrc.getResult(0); + } else if (typeInfo.getCharLength().has_value()) { + mlir::Value charLen = builder.createIntegerConstant( + loc, builder.getCharacterLengthType(), *typeInfo.getCharLength()); + typeparams.push_back(charLen); + } auto declDst = builder.create( - loc, funcOp.getArgument(0), copyFuncName + "_dst", shape, typeparams, + loc, dst, copyFuncName + "_dst", shape, typeparams, /*dummy_scope=*/nullptr, attrs); auto declSrc = builder.create( - loc, funcOp.getArgument(1), copyFuncName + "_src", shape, typeparams, + loc, src, copyFuncName + "_src", shape, typeparams, /*dummy_scope=*/nullptr, attrs); converter.copyVar(loc, declDst.getBase(), declSrc.getBase(), varAttrs); builder.create(loc); @@ -836,10 +859,13 @@ bool ClauseProcessor::processCopyprivate( // CopyPrivate variables must be passed by reference. However, in the case // of assumed shapes/vla the type is not a !fir.ref, but a !fir.box. - // In these cases to retrieve the appropriate !fir.ref> to - // access the data we need we must perform an alloca and then store to it - // and retrieve the data from the new alloca. - if (mlir::isa(symType)) { + // In the case of character types, the passed in type can also be + // !fir.boxchar. In these cases to retrieve the appropriate + // !fir.ref> or !fir.ref> to access the data + // we need we must perform an alloca and then store to it and retrieve the + // data from the new alloca. + if (mlir::isa(symType) || + mlir::isa(symType)) { fir::FirOpBuilder &builder = converter.getFirOpBuilder(); auto alloca = builder.create(currentLocation, symType); builder.create(currentLocation, symVal, alloca); @@ -1210,7 +1236,7 @@ void ClauseProcessor::processMapObjects( bool ClauseProcessor::processMap( mlir::Location currentLocation, lower::StatementContext &stmtCtx, - mlir::omp::MapClauseOps &result, + mlir::omp::MapClauseOps &result, llvm::omp::Directive directive, llvm::SmallVectorImpl *mapSyms) const { // We always require tracking of symbols, even if the caller does not, // so we create an optionally used local set of symbols when the mapSyms @@ -1228,9 +1254,18 @@ bool ClauseProcessor::processMap( llvm::omp::OpenMPOffloadMappingFlags mapTypeBits = llvm::omp::OpenMPOffloadMappingFlags::OMP_MAP_NONE; std::string mapperIdName = "__implicit_mapper"; - // If the map type is specified, then process it else Tofrom is the - // default. - Map::MapType type = mapType.value_or(Map::MapType::Tofrom); + // If the map type is specified, then process it else set the appropriate + // default value + Map::MapType type; + if (directive == llvm::omp::Directive::OMPD_target_enter_data && + semaCtx.langOptions().OpenMPVersion >= 52) + type = mapType.value_or(Map::MapType::To); + else if (directive == llvm::omp::Directive::OMPD_target_exit_data && + semaCtx.langOptions().OpenMPVersion >= 52) + type = mapType.value_or(Map::MapType::From); + else + type = mapType.value_or(Map::MapType::Tofrom); + switch (type) { case Map::MapType::To: mapTypeBits |= llvm::omp::OpenMPOffloadMappingFlags::OMP_MAP_TO; diff --git a/external/llvm-project/flang/lib/Lower/OpenMP/ClauseProcessor.h b/external/llvm-project/flang/lib/Lower/OpenMP/ClauseProcessor.h index 748f86b781e9..75b3bdb3014d 100644 --- a/external/llvm-project/flang/lib/Lower/OpenMP/ClauseProcessor.h +++ b/external/llvm-project/flang/lib/Lower/OpenMP/ClauseProcessor.h @@ -138,6 +138,7 @@ class ClauseProcessor { bool processMap(mlir::Location currentLocation, lower::StatementContext &stmtCtx, mlir::omp::MapClauseOps &result, + llvm::omp::Directive directive = llvm::omp::OMPD_unknown, llvm::SmallVectorImpl *mapSyms = nullptr) const; bool processMotionClauses(lower::StatementContext &stmtCtx, diff --git a/external/llvm-project/flang/lib/Lower/OpenMP/Clauses.cpp b/external/llvm-project/flang/lib/Lower/OpenMP/Clauses.cpp index fd36053c03ca..22a07219d3a5 100644 --- a/external/llvm-project/flang/lib/Lower/OpenMP/Clauses.cpp +++ b/external/llvm-project/flang/lib/Lower/OpenMP/Clauses.cpp @@ -905,8 +905,8 @@ Inclusive make(const parser::OmpClause::Inclusive &inp, Indirect make(const parser::OmpClause::Indirect &inp, semantics::SemanticsContext &semaCtx) { - // inp -> empty - llvm_unreachable("Empty: indirect"); + // inp.v.v -> std::optional + return Indirect{maybeApply(makeExprFn(semaCtx), inp.v.v)}; } Init make(const parser::OmpClause::Init &inp, @@ -1043,7 +1043,7 @@ Map make(const parser::OmpClause::Map &inp, auto type = [&]() -> std::optional { if (t3) return convert1(t3->v); - return Map::MapType::Tofrom; + return std::nullopt; }(); Map::MapTypeModifiers typeMods; diff --git a/external/llvm-project/flang/lib/Lower/OpenMP/DataSharingProcessor.cpp b/external/llvm-project/flang/lib/Lower/OpenMP/DataSharingProcessor.cpp index 78e4e64309e7..657fa1485e0f 100644 --- a/external/llvm-project/flang/lib/Lower/OpenMP/DataSharingProcessor.cpp +++ b/external/llvm-project/flang/lib/Lower/OpenMP/DataSharingProcessor.cpp @@ -210,6 +210,42 @@ void DataSharingProcessor::collectOmpObjectListSymbol( } void DataSharingProcessor::collectSymbolsForPrivatization() { + // Add checks here for exceptional cases where privatization is not + // needed and be deferred to a later phase (like OpenMP IRBuilder). + // Such cases are suggested to be clearly documented and explained + // instead of being silently skipped + auto isException = [&](const Fortran::semantics::Symbol *sym) -> bool { + // `OmpPreDetermined` symbols cannot be exceptions since + // their privatized symbols are heavily used in FIR. + if (sym->test(Fortran::semantics::Symbol::Flag::OmpPreDetermined)) + return false; + + // The handling of linear clause is deferred to the OpenMP + // IRBuilder which is responsible for all its aspects, + // including privatization. Privatizing linear variables at this point would + // cause the following structure: + // + // omp.op linear(%linear = %step : !fir.ref) { + // Use %linear in this BB + // } + // + // to be changed to the following: + // + // omp. op linear(%linear = %step : !fir.ref) + // private(%linear -> %arg0 : !fir.ref) { + // Declare and use %arg0 in this BB + // } + // + // The OpenMP IRBuilder needs to map the linear MLIR value + // (i.e. %linear) to its `uses` in the BB to correctly + // implement the functionalities of linear clause. However, + // privatizing here disallows the IRBuilder to + // draw a relation between %linear and %arg0. Hence skip. + if (sym->test(Fortran::semantics::Symbol::Flag::OmpLinear)) + return true; + return false; + }; + for (const omp::Clause &clause : clauses) { if (const auto &privateClause = std::get_if(&clause.u)) { @@ -228,10 +264,11 @@ void DataSharingProcessor::collectSymbolsForPrivatization() { } // TODO For common blocks, add the underlying objects within the block. Doing - // so, we won't need to explicitely handle block objects (or forget to do + // so, we won't need to explicitly handle block objects (or forget to do // so). for (auto *sym : explicitlyPrivatizedSymbols) - allPrivatizedSymbols.insert(sym); + if (!isException(sym)) + allPrivatizedSymbols.insert(sym); } bool DataSharingProcessor::needBarrier() { diff --git a/external/llvm-project/flang/lib/Lower/OpenMP/OpenMP.cpp b/external/llvm-project/flang/lib/Lower/OpenMP/OpenMP.cpp index 1f8c7e058e4a..5544d85128ed 100644 --- a/external/llvm-project/flang/lib/Lower/OpenMP/OpenMP.cpp +++ b/external/llvm-project/flang/lib/Lower/OpenMP/OpenMP.cpp @@ -12,6 +12,7 @@ #include "flang/Lower/OpenMP.h" +#include "Atomic.h" #include "ClauseProcessor.h" #include "DataSharingProcessor.h" #include "Decomposer.h" @@ -41,13 +42,10 @@ #include "mlir/Transforms/RegionUtils.h" #include "llvm/ADT/STLExtras.h" #include "llvm/Frontend/OpenMP/OMPConstants.h" -#include "llvm/Support/CommandLine.h" using namespace Fortran::lower::omp; using namespace Fortran::common::openmp; -static llvm::cl::opt DumpAtomicAnalysis("fdebug-dump-atomic-analysis"); - //===----------------------------------------------------------------------===// // Code generation helper functions //===----------------------------------------------------------------------===// @@ -201,6 +199,8 @@ class HostEvalInfo { /// structures, but it will probably still require some further work to support /// reverse offloading. static llvm::SmallVector hostEvalInfo; +static llvm::SmallVector + sectionsStack; /// Bind symbols to their corresponding entry block arguments. /// @@ -1125,16 +1125,6 @@ markDeclareTarget(mlir::Operation *op, lower::AbstractConverter &converter, declareTargetOp.setDeclareTarget(deviceType, captureClause); } -static bool isPointerAssignment(const evaluate::Assignment &assign) { - return common::visit( - common::visitors{ - [](const evaluate::Assignment::BoundsSpec &) { return true; }, - [](const evaluate::Assignment::BoundsRemapping &) { return true; }, - [](const auto &) { return false; }, - }, - assign.u); -} - //===----------------------------------------------------------------------===// // Op body generation helper structures and functions //===----------------------------------------------------------------------===// @@ -1733,7 +1723,8 @@ static void genTargetClauses( } cp.processIf(llvm::omp::Directive::OMPD_target, clauseOps); cp.processIsDevicePtr(clauseOps, isDevicePtrSyms); - cp.processMap(loc, stmtCtx, clauseOps, &mapSyms); + cp.processMap(loc, stmtCtx, clauseOps, llvm::omp::Directive::OMPD_unknown, + &mapSyms); cp.processNowait(clauseOps); cp.processThreadLimit(stmtCtx, clauseOps); @@ -1789,7 +1780,7 @@ static void genTargetEnterExitUpdateDataClauses( if (directive == llvm::omp::Directive::OMPD_target_update) cp.processMotionClauses(stmtCtx, clauseOps); else - cp.processMap(loc, stmtCtx, clauseOps); + cp.processMap(loc, stmtCtx, clauseOps, directive); cp.processNowait(clauseOps); } @@ -2128,8 +2119,12 @@ static mlir::omp::SectionsOp genSectionsOp(lower::AbstractConverter &converter, lower::SymMap &symTable, semantics::SemanticsContext &semaCtx, lower::pft::Evaluation &eval, mlir::Location loc, - const ConstructQueue &queue, ConstructQueue::const_iterator item, - const parser::OmpSectionBlocks §ionBlocks) { + const ConstructQueue &queue, + ConstructQueue::const_iterator item) { + assert(!sectionsStack.empty()); + const auto §ionBlocks = + std::get(sectionsStack.back()->t); + sectionsStack.pop_back(); mlir::omp::SectionsOperands clauseOps; llvm::SmallVector reductionSyms; genSectionsClauses(converter, semaCtx, item->clauses, loc, clauseOps, @@ -2579,6 +2574,7 @@ genTeamsOp(lower::AbstractConverter &converter, lower::SymMap &symTable, semantics::SemanticsContext &semaCtx, lower::pft::Evaluation &eval, mlir::Location loc, const ConstructQueue &queue, ConstructQueue::const_iterator item) { + lower::SymMapScope scope(symTable); mlir::omp::TeamsOperands clauseOps; llvm::SmallVector reductionSyms; genTeamsClauses(converter, semaCtx, stmtCtx, item->clauses, loc, clauseOps, @@ -2597,220 +2593,6 @@ genTeamsOp(lower::AbstractConverter &converter, lower::SymMap &symTable, queue, item, clauseOps); } -//===----------------------------------------------------------------------===// -// Code generation for atomic operations -//===----------------------------------------------------------------------===// -static fir::FirOpBuilder::InsertPoint -getInsertionPointBefore(mlir::Operation *op) { - return fir::FirOpBuilder::InsertPoint(op->getBlock(), - mlir::Block::iterator(op)); -} - -static fir::FirOpBuilder::InsertPoint -getInsertionPointAfter(mlir::Operation *op) { - return fir::FirOpBuilder::InsertPoint(op->getBlock(), - ++mlir::Block::iterator(op)); -} - -static mlir::IntegerAttr getAtomicHint(lower::AbstractConverter &converter, - const List &clauses) { - fir::FirOpBuilder &builder = converter.getFirOpBuilder(); - for (const Clause &clause : clauses) { - if (clause.id != llvm::omp::Clause::OMPC_hint) - continue; - auto &hint = std::get(clause.u); - auto maybeVal = evaluate::ToInt64(hint.v); - CHECK(maybeVal); - return builder.getI64IntegerAttr(*maybeVal); - } - return nullptr; -} - -static mlir::omp::ClauseMemoryOrderKindAttr -getAtomicMemoryOrder(lower::AbstractConverter &converter, - semantics::SemanticsContext &semaCtx, - const List &clauses) { - std::optional kind; - unsigned version = semaCtx.langOptions().OpenMPVersion; - - for (const Clause &clause : clauses) { - switch (clause.id) { - case llvm::omp::Clause::OMPC_acq_rel: - kind = mlir::omp::ClauseMemoryOrderKind::Acq_rel; - break; - case llvm::omp::Clause::OMPC_acquire: - kind = mlir::omp::ClauseMemoryOrderKind::Acquire; - break; - case llvm::omp::Clause::OMPC_relaxed: - kind = mlir::omp::ClauseMemoryOrderKind::Relaxed; - break; - case llvm::omp::Clause::OMPC_release: - kind = mlir::omp::ClauseMemoryOrderKind::Release; - break; - case llvm::omp::Clause::OMPC_seq_cst: - kind = mlir::omp::ClauseMemoryOrderKind::Seq_cst; - break; - default: - break; - } - } - - // Starting with 5.1, if no memory-order clause is present, the effect - // is as if "relaxed" was present. - if (!kind) { - if (version <= 50) - return nullptr; - kind = mlir::omp::ClauseMemoryOrderKind::Relaxed; - } - fir::FirOpBuilder &builder = converter.getFirOpBuilder(); - return mlir::omp::ClauseMemoryOrderKindAttr::get(builder.getContext(), *kind); -} - -static mlir::Operation * // -genAtomicRead(lower::AbstractConverter &converter, mlir::Location loc, - lower::StatementContext &stmtCtx, mlir::Value atomAddr, - const semantics::SomeExpr &atom, - const evaluate::Assignment &assign, mlir::IntegerAttr hint, - mlir::omp::ClauseMemoryOrderKindAttr memOrder, - fir::FirOpBuilder::InsertPoint preAt, - fir::FirOpBuilder::InsertPoint atomicAt, - fir::FirOpBuilder::InsertPoint postAt) { - fir::FirOpBuilder &builder = converter.getFirOpBuilder(); - builder.restoreInsertionPoint(preAt); - - mlir::Value storeAddr = - fir::getBase(converter.genExprAddr(assign.lhs, stmtCtx, &loc)); - mlir::Type atomType = fir::unwrapRefType(atomAddr.getType()); - mlir::Type storeType = fir::unwrapRefType(storeAddr.getType()); - - mlir::Value toAddr = [&]() { - if (atomType == storeType) - return storeAddr; - return builder.createTemporary(loc, atomType, ".tmp.atomval"); - }(); - - builder.restoreInsertionPoint(atomicAt); - mlir::Operation *op = builder.create( - loc, atomAddr, toAddr, mlir::TypeAttr::get(atomType), hint, memOrder); - - if (atomType != storeType) { - lower::ExprToValueMap overrides; - // The READ operation could be a part of UPDATE CAPTURE, so make sure - // we don't emit extra code into the body of the atomic op. - builder.restoreInsertionPoint(postAt); - mlir::Value load = builder.create(loc, toAddr); - overrides.try_emplace(&atom, load); - - converter.overrideExprValues(&overrides); - mlir::Value value = - fir::getBase(converter.genExprValue(assign.rhs, stmtCtx, &loc)); - converter.resetExprOverrides(); - - builder.create(loc, value, storeAddr); - } - return op; -} - -static mlir::Operation * // -genAtomicWrite(lower::AbstractConverter &converter, mlir::Location loc, - lower::StatementContext &stmtCtx, mlir::Value atomAddr, - const semantics::SomeExpr &atom, - const evaluate::Assignment &assign, mlir::IntegerAttr hint, - mlir::omp::ClauseMemoryOrderKindAttr memOrder, - fir::FirOpBuilder::InsertPoint preAt, - fir::FirOpBuilder::InsertPoint atomicAt, - fir::FirOpBuilder::InsertPoint postAt) { - fir::FirOpBuilder &builder = converter.getFirOpBuilder(); - builder.restoreInsertionPoint(preAt); - - mlir::Value value = - fir::getBase(converter.genExprValue(assign.rhs, stmtCtx, &loc)); - mlir::Type atomType = fir::unwrapRefType(atomAddr.getType()); - mlir::Value converted = builder.createConvert(loc, atomType, value); - - builder.restoreInsertionPoint(atomicAt); - mlir::Operation *op = builder.create( - loc, atomAddr, converted, hint, memOrder); - return op; -} - -static mlir::Operation * -genAtomicUpdate(lower::AbstractConverter &converter, mlir::Location loc, - lower::StatementContext &stmtCtx, mlir::Value atomAddr, - const semantics::SomeExpr &atom, - const evaluate::Assignment &assign, mlir::IntegerAttr hint, - mlir::omp::ClauseMemoryOrderKindAttr memOrder, - fir::FirOpBuilder::InsertPoint preAt, - fir::FirOpBuilder::InsertPoint atomicAt, - fir::FirOpBuilder::InsertPoint postAt) { - lower::ExprToValueMap overrides; - lower::StatementContext naCtx; - fir::FirOpBuilder &builder = converter.getFirOpBuilder(); - builder.restoreInsertionPoint(preAt); - - mlir::Type atomType = fir::unwrapRefType(atomAddr.getType()); - - // This must exist by now. - SomeExpr input = *semantics::GetConvertInput(assign.rhs); - std::vector args{semantics::GetTopLevelOperation(input).second}; - assert(!args.empty() && "Update operation without arguments"); - for (auto &arg : args) { - if (!semantics::IsSameOrConvertOf(arg, atom)) { - mlir::Value val = fir::getBase(converter.genExprValue(arg, naCtx, &loc)); - overrides.try_emplace(&arg, val); - } - } - - builder.restoreInsertionPoint(atomicAt); - auto updateOp = - builder.create(loc, atomAddr, hint, memOrder); - - mlir::Region ®ion = updateOp->getRegion(0); - mlir::Block *block = builder.createBlock(®ion, {}, {atomType}, {loc}); - mlir::Value localAtom = fir::getBase(block->getArgument(0)); - overrides.try_emplace(&atom, localAtom); - - converter.overrideExprValues(&overrides); - mlir::Value updated = - fir::getBase(converter.genExprValue(assign.rhs, stmtCtx, &loc)); - mlir::Value converted = builder.createConvert(loc, atomType, updated); - builder.create(loc, converted); - converter.resetExprOverrides(); - - builder.restoreInsertionPoint(postAt); // For naCtx cleanups - return updateOp; -} - -static mlir::Operation * -genAtomicOperation(lower::AbstractConverter &converter, mlir::Location loc, - lower::StatementContext &stmtCtx, int action, - mlir::Value atomAddr, const semantics::SomeExpr &atom, - const evaluate::Assignment &assign, mlir::IntegerAttr hint, - mlir::omp::ClauseMemoryOrderKindAttr memOrder, - fir::FirOpBuilder::InsertPoint preAt, - fir::FirOpBuilder::InsertPoint atomicAt, - fir::FirOpBuilder::InsertPoint postAt) { - if (isPointerAssignment(assign)) { - TODO(loc, "Code generation for pointer assignment is not implemented yet"); - } - - // This function and the functions called here do not preserve the - // builder's insertion point, or set it to anything specific. - switch (action) { - case parser::OpenMPAtomicConstruct::Analysis::Read: - return genAtomicRead(converter, loc, stmtCtx, atomAddr, atom, assign, hint, - memOrder, preAt, atomicAt, postAt); - case parser::OpenMPAtomicConstruct::Analysis::Write: - return genAtomicWrite(converter, loc, stmtCtx, atomAddr, atom, assign, hint, - memOrder, preAt, atomicAt, postAt); - case parser::OpenMPAtomicConstruct::Analysis::Update: - return genAtomicUpdate(converter, loc, stmtCtx, atomAddr, atom, assign, - hint, memOrder, preAt, atomicAt, postAt); - default: - return nullptr; - } -} - //===----------------------------------------------------------------------===// // Code generation functions for the standalone version of constructs that can // also be a leaf of a composite construct @@ -2888,6 +2670,7 @@ static mlir::omp::ParallelOp genStandaloneParallel( lower::StatementContext &stmtCtx, semantics::SemanticsContext &semaCtx, lower::pft::Evaluation &eval, mlir::Location loc, const ConstructQueue &queue, ConstructQueue::const_iterator item) { + lower::SymMapScope scope(symTable); mlir::omp::ParallelOperands parallelClauseOps; llvm::SmallVector parallelReductionSyms; genParallelClauses(converter, semaCtx, stmtCtx, item->clauses, loc, @@ -3380,10 +3163,7 @@ static void genOMPDispatch(lower::AbstractConverter &converter, // Lowered in the enclosing genSectionsOp. break; case llvm::omp::Directive::OMPD_sections: - // Called directly from genOMP([...], OpenMPSectionsConstruct) because it - // has a different prototype. - // This code path is still taken when iterating through the construct queue - // in genBodyOfOp + genSectionsOp(converter, symTable, semaCtx, eval, loc, queue, item); break; case llvm::omp::Directive::OMPD_simd: newOp = @@ -3728,162 +3508,11 @@ static void genOMP(lower::AbstractConverter &converter, lower::SymMap &symTable, // OpenMPConstruct visitors //===----------------------------------------------------------------------===// -[[maybe_unused]] static void -dumpAtomicAnalysis(const parser::OpenMPAtomicConstruct::Analysis &analysis) { - auto whatStr = [](int k) { - std::string txt = "?"; - switch (k & parser::OpenMPAtomicConstruct::Analysis::Action) { - case parser::OpenMPAtomicConstruct::Analysis::None: - txt = "None"; - break; - case parser::OpenMPAtomicConstruct::Analysis::Read: - txt = "Read"; - break; - case parser::OpenMPAtomicConstruct::Analysis::Write: - txt = "Write"; - break; - case parser::OpenMPAtomicConstruct::Analysis::Update: - txt = "Update"; - break; - } - switch (k & parser::OpenMPAtomicConstruct::Analysis::Condition) { - case parser::OpenMPAtomicConstruct::Analysis::IfTrue: - txt += " | IfTrue"; - break; - case parser::OpenMPAtomicConstruct::Analysis::IfFalse: - txt += " | IfFalse"; - break; - } - return txt; - }; - - auto exprStr = [&](const parser::TypedExpr &expr) { - if (auto *maybe = expr.get()) { - if (maybe->v) - return maybe->v->AsFortran(); - } - return ""s; - }; - auto assignStr = [&](const parser::AssignmentStmt::TypedAssignment &assign) { - if (auto *maybe = assign.get(); maybe && maybe->v) { - std::string str; - llvm::raw_string_ostream os(str); - maybe->v->AsFortran(os); - return str; - } - return ""s; - }; - - const SomeExpr &atom = *analysis.atom.get()->v; - - llvm::errs() << "Analysis {\n"; - llvm::errs() << " atom: " << atom.AsFortran() << "\n"; - llvm::errs() << " cond: " << exprStr(analysis.cond) << "\n"; - llvm::errs() << " op0 {\n"; - llvm::errs() << " what: " << whatStr(analysis.op0.what) << "\n"; - llvm::errs() << " assign: " << assignStr(analysis.op0.assign) << "\n"; - llvm::errs() << " }\n"; - llvm::errs() << " op1 {\n"; - llvm::errs() << " what: " << whatStr(analysis.op1.what) << "\n"; - llvm::errs() << " assign: " << assignStr(analysis.op1.assign) << "\n"; - llvm::errs() << " }\n"; - llvm::errs() << "}\n"; -} - static void genOMP(lower::AbstractConverter &converter, lower::SymMap &symTable, semantics::SemanticsContext &semaCtx, lower::pft::Evaluation &eval, const parser::OpenMPAtomicConstruct &construct) { - auto get = [](auto &&typedWrapper) -> decltype(&*typedWrapper.get()->v) { - if (auto *maybe = typedWrapper.get(); maybe && maybe->v) { - return &*maybe->v; - } else { - return nullptr; - } - }; - - fir::FirOpBuilder &builder = converter.getFirOpBuilder(); - auto &dirSpec = std::get(construct.t); - List clauses = makeClauses(dirSpec.Clauses(), semaCtx); - lower::StatementContext stmtCtx; - - const parser::OpenMPAtomicConstruct::Analysis &analysis = construct.analysis; - if (DumpAtomicAnalysis) - dumpAtomicAnalysis(analysis); - - const semantics::SomeExpr &atom = *get(analysis.atom); - mlir::Location loc = converter.genLocation(construct.source); - mlir::Value atomAddr = - fir::getBase(converter.genExprAddr(atom, stmtCtx, &loc)); - mlir::IntegerAttr hint = getAtomicHint(converter, clauses); - mlir::omp::ClauseMemoryOrderKindAttr memOrder = - getAtomicMemoryOrder(converter, semaCtx, clauses); - - if (auto *cond = get(analysis.cond)) { - (void)cond; - TODO(loc, "OpenMP ATOMIC COMPARE"); - } else { - int action0 = analysis.op0.what & analysis.Action; - int action1 = analysis.op1.what & analysis.Action; - mlir::Operation *captureOp = nullptr; - fir::FirOpBuilder::InsertPoint preAt = builder.saveInsertionPoint(); - fir::FirOpBuilder::InsertPoint atomicAt, postAt; - - if (construct.IsCapture()) { - // Capturing operation. - assert(action0 != analysis.None && action1 != analysis.None && - "Expexcing two actions"); - (void)action0; - (void)action1; - captureOp = - builder.create(loc, hint, memOrder); - // Set the non-atomic insertion point to before the atomic.capture. - preAt = getInsertionPointBefore(captureOp); - - mlir::Block *block = builder.createBlock(&captureOp->getRegion(0)); - builder.setInsertionPointToEnd(block); - // Set the atomic insertion point to before the terminator inside - // atomic.capture. - mlir::Operation *term = builder.create(loc); - atomicAt = getInsertionPointBefore(term); - postAt = getInsertionPointAfter(captureOp); - hint = nullptr; - memOrder = nullptr; - } else { - // Non-capturing operation. - assert(action0 != analysis.None && action1 == analysis.None && - "Expexcing single action"); - assert(!(analysis.op0.what & analysis.Condition)); - postAt = atomicAt = preAt; - } - - // The builder's insertion point needs to be specifically set before - // each call to `genAtomicOperation`. - mlir::Operation *firstOp = genAtomicOperation( - converter, loc, stmtCtx, analysis.op0.what, atomAddr, atom, - *get(analysis.op0.assign), hint, memOrder, preAt, atomicAt, postAt); - assert(firstOp && "Should have created an atomic operation"); - atomicAt = getInsertionPointAfter(firstOp); - - mlir::Operation *secondOp = nullptr; - if (analysis.op1.what != analysis.None) { - secondOp = genAtomicOperation(converter, loc, stmtCtx, analysis.op1.what, - atomAddr, atom, *get(analysis.op1.assign), - hint, memOrder, preAt, atomicAt, postAt); - } - - if (construct.IsCapture()) { - // If this is a capture operation, the first/second ops will be inside - // of it. Set the insertion point to past the capture op itself. - builder.restoreInsertionPoint(postAt); - } else { - if (secondOp) { - builder.setInsertionPointAfter(secondOp); - } else { - builder.setInsertionPointAfter(firstOp); - } - } - } + lowerAtomic(converter, symTable, semaCtx, eval, construct); } static void genOMP(lower::AbstractConverter &converter, lower::SymMap &symTable, @@ -3946,13 +3575,6 @@ static void genOMP(lower::AbstractConverter &converter, lower::SymMap &symTable, parser::ToUpperCaseLetters(llvm::omp::getOpenMPClauseName(clause.id)); TODO(clauseLocation, name + " clause is not implemented yet"); } - - if (std::holds_alternative(clause.u) && - origDirective == llvm::omp::Directive::OMPD_target_teams) - TODO(clauseLocation, "TARGET TEAMS PRIVATE is not implemented yet"); - if (std::holds_alternative(clause.u) && - origDirective == llvm::omp::Directive::OMPD_target_parallel) - TODO(clauseLocation, "TARGET PARALLEL PRIVATE is not implemented yet"); } llvm::omp::Directive directive = @@ -4059,8 +3681,6 @@ static void genOMP(lower::AbstractConverter &converter, lower::SymMap &symTable, std::get(beginSectionsDirective.t), semaCtx); const auto &endSectionsDirective = std::get(sectionsConstruct.t); - const auto §ionBlocks = - std::get(sectionsConstruct.t); clauses.append(makeClauses( std::get(endSectionsDirective.t), semaCtx)); mlir::Location currentLocation = converter.getCurrentLocation(); @@ -4072,22 +3692,10 @@ static void genOMP(lower::AbstractConverter &converter, lower::SymMap &symTable, ConstructQueue queue{ buildConstructQueue(converter.getFirOpBuilder().getModule(), semaCtx, eval, source, directive, clauses)}; - ConstructQueue::iterator next = queue.begin(); - // Generate constructs that come first e.g. Parallel - while (next != queue.end() && - next->id != llvm::omp::Directive::OMPD_sections) { - genOMPDispatch(converter, symTable, semaCtx, eval, currentLocation, queue, - next); - next = std::next(next); - } - // call genSectionsOp directly (not via genOMPDispatch) so that we can add the - // sectionBlocks argument - assert(next != queue.end()); - assert(next->id == llvm::omp::Directive::OMPD_sections); - genSectionsOp(converter, symTable, semaCtx, eval, currentLocation, queue, - next, sectionBlocks); - assert(std::next(next) == queue.end()); + sectionsStack.push_back(§ionsConstruct); + genOMPDispatch(converter, symTable, semaCtx, eval, currentLocation, queue, + queue.begin()); } static void genOMP(lower::AbstractConverter &converter, lower::SymMap &symTable, diff --git a/external/llvm-project/flang/lib/Lower/PFTBuilder.cpp b/external/llvm-project/flang/lib/Lower/PFTBuilder.cpp index 2cc458cb6130..68023610c3c5 100644 --- a/external/llvm-project/flang/lib/Lower/PFTBuilder.cpp +++ b/external/llvm-project/flang/lib/Lower/PFTBuilder.cpp @@ -1096,7 +1096,9 @@ class PFTBuilder { // The first executable statement in the subprogram is preceded by a // branch to the entry point, so it starts a new block. - if (initialEval->hasNestedEvaluations()) + // OpenMP directives can generate code around the nested evaluations. + if (initialEval->hasNestedEvaluations() && + !initialEval->isOpenMPDirective()) initialEval = &initialEval->getFirstNestedEvaluation(); else if (initialEval->isA()) initialEval = initialEval->lexicalSuccessor; diff --git a/external/llvm-project/flang/lib/Optimizer/Builder/FIRBuilder.cpp b/external/llvm-project/flang/lib/Optimizer/Builder/FIRBuilder.cpp index a997a0e83890..61b312722556 100644 --- a/external/llvm-project/flang/lib/Optimizer/Builder/FIRBuilder.cpp +++ b/external/llvm-project/flang/lib/Optimizer/Builder/FIRBuilder.cpp @@ -283,6 +283,9 @@ mlir::Block *fir::FirOpBuilder::getAllocaBlock() { if (auto doConcurentOp = getRegion().getParentOfType()) return doConcurentOp.getBody(); + if (auto firLocalOp = getRegion().getParentOfType()) + return &getRegion().front(); + return getEntryBlock(); } diff --git a/external/llvm-project/flang/lib/Optimizer/CodeGen/LowerRepackArrays.cpp b/external/llvm-project/flang/lib/Optimizer/CodeGen/LowerRepackArrays.cpp index de97a0bbc184..2774382c22bf 100644 --- a/external/llvm-project/flang/lib/Optimizer/CodeGen/LowerRepackArrays.cpp +++ b/external/llvm-project/flang/lib/Optimizer/CodeGen/LowerRepackArrays.cpp @@ -250,6 +250,8 @@ PackArrayConversion::genRepackedBox(fir::FirOpBuilder &builder, fir::IfOp ifOp = builder.create(loc, boxType, doPack, /*withElseRegion=*/true); + // Assume that the repacking is unlikely. + ifOp.setUnlikelyIfWeights(); // Return original box. builder.setInsertionPointToStart(&ifOp.getElseRegion().front()); @@ -322,20 +324,24 @@ UnpackArrayConversion::matchAndRewrite(fir::UnpackArrayOp op, auto isNotSame = builder.genPtrCompare(loc, mlir::arith::CmpIPredicate::ne, tempAddr, originalAddr); - builder.genIfThen(loc, isNotSame).genThen([&]() {}); - // Copy from temporary to the original. - if (!op.getNoCopy()) - fir::runtime::genShallowCopy(builder, loc, originalBox, tempBox, - /*resultIsAllocated=*/true); - - // Deallocate, if it was allocated in heap. - // Note that the stack attribute does not always mean - // that the allocation was actually done in stack memory. - // There are currently cases where we delegate the allocation - // to the runtime that uses heap memory, even when the stack - // attribute is set on fir.pack_array. - if (!op.getStack() || !canAllocateTempOnStack(originalBox)) - builder.create(loc, tempAddr); + builder.genIfThen(loc, isNotSame) + .genThen([&]() { + // Copy from temporary to the original. + if (!op.getNoCopy()) + fir::runtime::genShallowCopy(builder, loc, originalBox, tempBox, + /*resultIsAllocated=*/true); + + // Deallocate, if it was allocated in heap. + // Note that the stack attribute does not always mean + // that the allocation was actually done in stack memory. + // There are currently cases where we delegate the allocation + // to the runtime that uses heap memory, even when the stack + // attribute is set on fir.pack_array. + if (!op.getStack() || !canAllocateTempOnStack(originalBox)) + builder.create(loc, tempAddr); + }) + .getIfOp() + .setUnlikelyIfWeights(); }); rewriter.eraseOp(op); return mlir::success(); diff --git a/external/llvm-project/flang/lib/Optimizer/Dialect/FIROps.cpp b/external/llvm-project/flang/lib/Optimizer/Dialect/FIROps.cpp index 6181e1fad424..ecfa2939e96a 100644 --- a/external/llvm-project/flang/lib/Optimizer/Dialect/FIROps.cpp +++ b/external/llvm-project/flang/lib/Optimizer/Dialect/FIROps.cpp @@ -4418,6 +4418,19 @@ mlir::ParseResult fir::IfOp::parse(mlir::OpAsmParser &parser, parser.resolveOperand(cond, i1Type, result.operands)) return mlir::failure(); + if (mlir::succeeded( + parser.parseOptionalKeyword(getWeightsAttrAssemblyName()))) { + if (parser.parseLParen()) + return mlir::failure(); + mlir::DenseI32ArrayAttr weights; + if (parser.parseCustomAttributeWithFallback(weights, mlir::Type{})) + return mlir::failure(); + if (weights) + result.addAttribute(getRegionWeightsAttrName(result.name), weights); + if (parser.parseRParen()) + return mlir::failure(); + } + if (parser.parseOptionalArrowTypeList(result.types)) return mlir::failure(); @@ -4449,6 +4462,11 @@ llvm::LogicalResult fir::IfOp::verify() { void fir::IfOp::print(mlir::OpAsmPrinter &p) { bool printBlockTerminators = false; p << ' ' << getCondition(); + if (auto weights = getRegionWeightsAttr()) { + p << ' ' << getWeightsAttrAssemblyName() << '('; + p.printStrippedAttrOrType(weights); + p << ')'; + } if (!getResults().empty()) { p << " -> (" << getResultTypes() << ')'; printBlockTerminators = true; @@ -4464,7 +4482,8 @@ void fir::IfOp::print(mlir::OpAsmPrinter &p) { p.printRegion(otherReg, /*printEntryBlockArgs=*/false, printBlockTerminators); } - p.printOptionalAttrDict((*this)->getAttrs()); + p.printOptionalAttrDict((*this)->getAttrs(), + /*elideAttrs=*/{getRegionWeightsAttrName()}); } void fir::IfOp::resultToSourceOps(llvm::SmallVectorImpl &results, diff --git a/external/llvm-project/flang/lib/Optimizer/Transforms/ControlFlowConverter.cpp b/external/llvm-project/flang/lib/Optimizer/Transforms/ControlFlowConverter.cpp index 8a9e9b80134b..3d35803e6a2d 100644 --- a/external/llvm-project/flang/lib/Optimizer/Transforms/ControlFlowConverter.cpp +++ b/external/llvm-project/flang/lib/Optimizer/Transforms/ControlFlowConverter.cpp @@ -212,9 +212,12 @@ class CfgIfConv : public mlir::OpRewritePattern { } rewriter.setInsertionPointToEnd(condBlock); - rewriter.create( + auto branchOp = rewriter.create( loc, ifOp.getCondition(), ifOpBlock, llvm::ArrayRef(), otherwiseBlock, llvm::ArrayRef()); + llvm::ArrayRef weights = ifOp.getWeights(); + if (!weights.empty()) + branchOp.setWeights(weights); rewriter.replaceOp(ifOp, continueBlock->getArguments()); return success(); } diff --git a/external/llvm-project/flang/lib/Optimizer/Transforms/FIRToSCF.cpp b/external/llvm-project/flang/lib/Optimizer/Transforms/FIRToSCF.cpp index 9a0071a6c6ae..f06ad2db90d5 100644 --- a/external/llvm-project/flang/lib/Optimizer/Transforms/FIRToSCF.cpp +++ b/external/llvm-project/flang/lib/Optimizer/Transforms/FIRToSCF.cpp @@ -87,48 +87,13 @@ struct DoLoopConversion : public OpRewritePattern { return success(); } }; - -struct IfConversion : public OpRewritePattern { - using OpRewritePattern::OpRewritePattern; - LogicalResult matchAndRewrite(fir::IfOp ifOp, - PatternRewriter &rewriter) const override { - mlir::Location loc = ifOp.getLoc(); - mlir::detail::TypedValue condition = ifOp.getCondition(); - ValueTypeRange resultTypes = ifOp.getResultTypes(); - mlir::scf::IfOp scfIfOp = rewriter.create( - loc, resultTypes, condition, !ifOp.getElseRegion().empty()); - // then region - scfIfOp.getThenRegion().takeBody(ifOp.getThenRegion()); - Block &scfThenBlock = scfIfOp.getThenRegion().front(); - Operation *scfThenTerminator = scfThenBlock.getTerminator(); - // fir.result->scf.yield - rewriter.setInsertionPointToEnd(&scfThenBlock); - rewriter.replaceOpWithNewOp(scfThenTerminator, - scfThenTerminator->getOperands()); - - // else region - if (!ifOp.getElseRegion().empty()) { - scfIfOp.getElseRegion().takeBody(ifOp.getElseRegion()); - mlir::Block &elseBlock = scfIfOp.getElseRegion().front(); - mlir::Operation *elseTerminator = elseBlock.getTerminator(); - - rewriter.setInsertionPointToEnd(&elseBlock); - rewriter.replaceOpWithNewOp(elseTerminator, - elseTerminator->getOperands()); - } - - scfIfOp->setAttrs(ifOp->getAttrs()); - rewriter.replaceOp(ifOp, scfIfOp); - return success(); - } -}; } // namespace void FIRToSCFPass::runOnOperation() { RewritePatternSet patterns(&getContext()); - patterns.add(patterns.getContext()); + patterns.add(patterns.getContext()); ConversionTarget target(getContext()); - target.addIllegalOp(); + target.addIllegalOp(); target.markUnknownOpDynamicallyLegal([](Operation *) { return true; }); if (failed( applyPartialConversion(getOperation(), target, std::move(patterns)))) diff --git a/external/llvm-project/flang/lib/Parser/openmp-parsers.cpp b/external/llvm-project/flang/lib/Parser/openmp-parsers.cpp index 9b112a213391..c55642d96950 100644 --- a/external/llvm-project/flang/lib/Parser/openmp-parsers.cpp +++ b/external/llvm-project/flang/lib/Parser/openmp-parsers.cpp @@ -1004,6 +1004,8 @@ TYPE_PARSER( // "IF" >> construct(construct( parenthesized(Parser{}))) || "INBRANCH" >> construct(construct()) || + "INDIRECT" >> construct(construct( + maybe(parenthesized(scalarLogicalExpr)))) || "INIT" >> construct(construct( parenthesized(Parser{}))) || "INCLUSIVE" >> construct(construct( diff --git a/external/llvm-project/flang/lib/Semantics/CMakeLists.txt b/external/llvm-project/flang/lib/Semantics/CMakeLists.txt index 18c89587843a..c0fda3631c01 100644 --- a/external/llvm-project/flang/lib/Semantics/CMakeLists.txt +++ b/external/llvm-project/flang/lib/Semantics/CMakeLists.txt @@ -40,7 +40,6 @@ add_flang_library(FortranSemantics resolve-directives.cpp resolve-names-utils.cpp resolve-names.cpp - rewrite-directives.cpp rewrite-parse-tree.cpp runtime-type-info.cpp scope.cpp diff --git a/external/llvm-project/flang/lib/Semantics/check-allocate.cpp b/external/llvm-project/flang/lib/Semantics/check-allocate.cpp index 2c215f45bf51..08053594c12e 100644 --- a/external/llvm-project/flang/lib/Semantics/check-allocate.cpp +++ b/external/llvm-project/flang/lib/Semantics/check-allocate.cpp @@ -10,6 +10,7 @@ #include "assignment.h" #include "definable.h" #include "flang/Evaluate/fold.h" +#include "flang/Evaluate/shape.h" #include "flang/Evaluate/type.h" #include "flang/Parser/parse-tree.h" #include "flang/Parser/tools.h" @@ -33,6 +34,7 @@ struct AllocateCheckerInfo { bool gotMold{false}; bool gotStream{false}; bool gotPinned{false}; + std::optional sourceExprShape; }; class AllocationCheckerHelper { @@ -259,6 +261,9 @@ static std::optional CheckAllocateOptions( CheckCopyabilityInPureScope(messages, *expr, scope); } } + auto maybeShape{evaluate::GetShape(context.foldingContext(), *expr)}; + info.sourceExprShape = + evaluate::AsConstantExtents(context.foldingContext(), maybeShape); } else { // Error already reported on source expression. // Do not continue allocate checks. @@ -581,6 +586,52 @@ bool AllocationCheckerHelper::RunChecks(SemanticsContext &context) { .Attach( ultimate_->name(), "Declared here with rank %d"_en_US, rank_); return false; + } else if (allocateInfo_.gotSource && allocateInfo_.sourceExprShape && + allocateInfo_.sourceExprShape->size() == + static_cast(allocateShapeSpecRank_)) { + std::size_t j{0}; + for (const auto &shapeSpec : + std::get>(allocation_.t)) { + if (j >= allocateInfo_.sourceExprShape->size()) { + break; + } + std::optional lbound; + if (const auto &lb{std::get<0>(shapeSpec.t)}) { + lbound.reset(); + const auto &lbExpr{lb->thing.thing.value()}; + if (const auto *expr{GetExpr(context, lbExpr)}) { + auto folded{ + evaluate::Fold(context.foldingContext(), SomeExpr(*expr))}; + lbound = evaluate::ToInt64(folded); + evaluate::SetExpr(lbExpr, std::move(folded)); + } + } else { + lbound = 1; + } + if (lbound) { + const auto &ubExpr{std::get<1>(shapeSpec.t).thing.thing.value()}; + if (const auto *expr{GetExpr(context, ubExpr)}) { + auto folded{ + evaluate::Fold(context.foldingContext(), SomeExpr(*expr))}; + auto ubound{evaluate::ToInt64(folded)}; + evaluate::SetExpr(ubExpr, std::move(folded)); + if (ubound) { + auto extent{*ubound - *lbound + 1}; + if (extent < 0) { + extent = 0; + } + if (extent != allocateInfo_.sourceExprShape->at(j)) { + context.Say(name_.source, + "Allocation has extent %jd on dimension %d, but SOURCE= has extent %jd"_err_en_US, + static_cast(extent), j + 1, + static_cast( + allocateInfo_.sourceExprShape->at(j))); + } + } + } + } + ++j; + } } } } else { // allocating a scalar object diff --git a/external/llvm-project/flang/lib/Semantics/check-omp-structure.cpp b/external/llvm-project/flang/lib/Semantics/check-omp-structure.cpp index c2792c90aa2a..cac1b18a0a31 100644 --- a/external/llvm-project/flang/lib/Semantics/check-omp-structure.cpp +++ b/external/llvm-project/flang/lib/Semantics/check-omp-structure.cpp @@ -12,6 +12,7 @@ #include "flang/Evaluate/check-expression.h" #include "flang/Evaluate/expression.h" #include "flang/Evaluate/shape.h" +#include "flang/Evaluate/tools.h" #include "flang/Evaluate/type.h" #include "flang/Parser/parse-tree.h" #include "flang/Semantics/expression.h" @@ -1706,6 +1707,22 @@ void OmpStructureChecker::Leave(const parser::OpenMPDepobjConstruct &x) { void OmpStructureChecker::Enter(const parser::OpenMPRequiresConstruct &x) { const auto &dir{std::get(x.t)}; PushContextAndClauseSets(dir.source, llvm::omp::Directive::OMPD_requires); + + if (visitedAtomicSource_.empty()) { + return; + } + const auto &clauseList{std::get(x.t)}; + for (const parser::OmpClause &clause : clauseList.v) { + llvm::omp::Clause id{clause.Id()}; + if (id == llvm::omp::Clause::OMPC_atomic_default_mem_order) { + parser::MessageFormattedText txt( + "REQUIRES directive with '%s' clause found lexically after atomic operation without a memory order clause"_err_en_US, + parser::ToUpperCaseLetters(llvm::omp::getOpenMPClauseName(id))); + parser::Message message(clause.source, txt); + message.Attach(visitedAtomicSource_, "Previous atomic construct"_en_US); + context_.Say(std::move(message)); + } + } } void OmpStructureChecker::Leave(const parser::OpenMPRequiresConstruct &) { @@ -1807,15 +1824,24 @@ void OmpStructureChecker::Leave(const parser::OmpDeclareTargetWithClause &x) { const parser::OmpClause *toClause = FindClause(llvm::omp::Clause::OMPC_to); const parser::OmpClause *linkClause = FindClause(llvm::omp::Clause::OMPC_link); + const parser::OmpClause *indirectClause = + FindClause(llvm::omp::Clause::OMPC_indirect); if (!enterClause && !toClause && !linkClause) { context_.Say(x.source, "If the DECLARE TARGET directive has a clause, it must contain at least one ENTER clause or LINK clause"_err_en_US); } + if (indirectClause && !enterClause) { + context_.Say(x.source, + "The INDIRECT clause cannot be used without the ENTER clause with the DECLARE TARGET directive."_err_en_US); + } unsigned version{context_.langOptions().OpenMPVersion}; if (toClause && version >= 52) { context_.Warn(common::UsageWarning::OpenMPUsage, toClause->source, "The usage of TO clause on DECLARE TARGET directive has been deprecated. Use ENTER clause instead."_warn_en_US); } + if (indirectClause) { + CheckAllowedClause(llvm::omp::Clause::OMPC_indirect); + } } } @@ -2949,6 +2975,8 @@ static bool IsPointerAssignment(const evaluate::Assignment &x) { std::holds_alternative(x.u); } +namespace operation = Fortran::evaluate::operation; + static bool IsCheckForAssociated(const SomeExpr &cond) { return GetTopLevelOperation(cond).first == operation::Operator::Associated; } @@ -3488,37 +3516,56 @@ void OmpStructureChecker::CheckAtomicUpdateAssignment( operation::ToString(top.first)); return; } - // Check if `atom` occurs exactly once in the argument list. + // Check how many times `atom` occurs as an argument, if it's a subexpression + // of an argument, and collect the non-atom arguments. std::vector nonAtom; - auto unique{[&]() { // -> iterator - auto found{top.second.end()}; - for (auto i{top.second.begin()}, e{top.second.end()}; i != e; ++i) { - if (IsSameOrConvertOf(*i, atom)) { - if (found != top.second.end()) { - return top.second.end(); - } - found = i; + MaybeExpr subExpr; + auto atomCount{[&]() { + int count{0}; + for (const SomeExpr &arg : top.second) { + if (IsSameOrConvertOf(arg, atom)) { + ++count; } else { - nonAtom.push_back(*i); + if (!subExpr && IsSubexpressionOf(atom, arg)) { + subExpr = arg; + } + nonAtom.push_back(arg); } } - return found; + return count; }()}; - if (unique == top.second.end()) { - if (top.first == operation::Operator::Identity) { - // This is "x = y". + bool hasError{false}; + if (subExpr) { + context_.Say(rsrc, + "The atomic variable %s cannot be a proper subexpression of an argument (here: %s) in the update operation"_err_en_US, + atom.AsFortran(), subExpr->AsFortran()); + hasError = true; + } + if (top.first == operation::Operator::Identity) { + // This is "x = y". + assert((atomCount == 0 || atomCount == 1) && "Unexpected count"); + if (atomCount == 0) { context_.Say(rsrc, "The atomic variable %s should appear as an argument in the update operation"_err_en_US, atom.AsFortran()); - } else { - assert(top.first != operation::Operator::Identity && - "Handle this separately"); + hasError = true; + } + } else { + if (atomCount == 0) { context_.Say(rsrc, - "The atomic variable %s should occur exactly once among the arguments of the top-level %s operator"_err_en_US, + "The atomic variable %s should appear as an argument of the top-level %s operator"_err_en_US, atom.AsFortran(), operation::ToString(top.first)); + hasError = true; + } else if (atomCount > 1) { + context_.Say(rsrc, + "The atomic variable %s should be exactly one of the arguments of the top-level %s operator"_err_en_US, + atom.AsFortran(), operation::ToString(top.first)); + hasError = true; } - } else { + } + + if (!hasError) { CheckStorageOverlap(atom, nonAtom, source); } } @@ -4015,6 +4062,9 @@ void OmpStructureChecker::CheckAtomicUpdate( } void OmpStructureChecker::Enter(const parser::OpenMPAtomicConstruct &x) { + if (visitedAtomicSource_.empty()) + visitedAtomicSource_ = x.source; + // All of the following groups have the "exclusive" property, i.e. at // most one clause from each group is allowed. // The exclusivity-checking code should eventually be unified for all diff --git a/external/llvm-project/flang/lib/Semantics/check-omp-structure.h b/external/llvm-project/flang/lib/Semantics/check-omp-structure.h index 2074ec611dc2..beb6e0528e81 100644 --- a/external/llvm-project/flang/lib/Semantics/check-omp-structure.h +++ b/external/llvm-project/flang/lib/Semantics/check-omp-structure.h @@ -360,6 +360,7 @@ class OmpStructureChecker }; int directiveNest_[LastType + 1] = {0}; + parser::CharBlock visitedAtomicSource_; SymbolSourceMap deferredNonVariables_; using LoopConstruct = std::variant &x) { - Indent("expr some type"); + Indent("relational some type"); Show(x.u); Outdent(); } diff --git a/external/llvm-project/flang/lib/Semantics/mod-file.cpp b/external/llvm-project/flang/lib/Semantics/mod-file.cpp index 9f9e9f584045..82c8536902eb 100644 --- a/external/llvm-project/flang/lib/Semantics/mod-file.cpp +++ b/external/llvm-project/flang/lib/Semantics/mod-file.cpp @@ -109,15 +109,14 @@ bool ModFileWriter::WriteAll() { } void ModFileWriter::WriteAll(const Scope &scope) { - for (const auto &child : scope.children()) { + for (const Scope &child : scope.children()) { WriteOne(child); } } void ModFileWriter::WriteOne(const Scope &scope) { if (scope.kind() == Scope::Kind::Module) { - auto *symbol{scope.symbol()}; - if (!symbol->test(Symbol::Flag::ModFile)) { + if (const auto *symbol{scope.symbol()}) { Write(*symbol); } WriteAll(scope); // write out submodules @@ -134,7 +133,7 @@ static std::string ModFileName(const SourceName &name, // Write the module file for symbol, which must be a module or submodule. void ModFileWriter::Write(const Symbol &symbol) { const auto &module{symbol.get()}; - if (module.moduleFileHash()) { + if (symbol.test(Symbol::Flag::ModFile) || module.moduleFileHash()) { return; // already written } const auto *ancestor{module.ancestor()}; @@ -372,16 +371,19 @@ void ModFileWriter::PutSymbols( CollectSymbols(scope, sorted, uses, modules); // Write module files for dependencies first so that their // hashes are known. - for (auto ref : modules) { + for (const Symbol &mod : modules) { if (hermeticModules) { - hermeticModules->insert(*ref); + hermeticModules->insert(mod); } else { - Write(*ref); - needs_ << ModHeader::need - << CheckSumString( - ref->get().moduleFileHash().value()) - << (ref->owner().IsIntrinsicModules() ? " i " : " n ") - << ref->name().ToString() << '\n'; + Write(mod); + // It's possible that the module's file already existed and + // without its own hash due to being embedded in a hermetic + // module file. + if (auto hash{mod.get().moduleFileHash()}) { + needs_ << ModHeader::need << CheckSumString(*hash) + << (mod.owner().IsIntrinsicModules() ? " i " : " n ") + << mod.name().ToString() << '\n'; + } } } std::string buf; // stuff after CONTAINS in derived type @@ -855,25 +857,25 @@ void CollectSymbols(const Scope &scope, SymbolVector &sorted, auto symbols{scope.GetSymbols()}; std::size_t commonSize{scope.commonBlocks().size()}; sorted.reserve(symbols.size() + commonSize); - for (SymbolRef symbol : symbols) { - const auto *generic{symbol->detailsIf()}; + for (const Symbol &symbol : symbols) { + const auto *generic{symbol.detailsIf()}; if (generic) { uses.insert(uses.end(), generic->uses().begin(), generic->uses().end()); - for (auto ref : generic->uses()) { - modules.insert(GetUsedModule(ref->get())); + for (const Symbol &used : generic->uses()) { + modules.insert(GetUsedModule(used.get())); } - } else if (const auto *use{symbol->detailsIf()}) { + } else if (const auto *use{symbol.detailsIf()}) { modules.insert(GetUsedModule(*use)); } - if (symbol->test(Symbol::Flag::ParentComp)) { - } else if (symbol->has()) { + if (symbol.test(Symbol::Flag::ParentComp)) { + } else if (symbol.has()) { namelist.push_back(symbol); } else if (generic) { if (generic->specific() && - &generic->specific()->owner() == &symbol->owner()) { + &generic->specific()->owner() == &symbol.owner()) { sorted.push_back(*generic->specific()); } else if (generic->derivedType() && - &generic->derivedType()->owner() == &symbol->owner()) { + &generic->derivedType()->owner() == &symbol.owner()) { sorted.push_back(*generic->derivedType()); } generics.push_back(symbol); diff --git a/external/llvm-project/flang/lib/Semantics/resolve-directives.cpp b/external/llvm-project/flang/lib/Semantics/resolve-directives.cpp index b5f8667fe36f..885c02e6ec74 100644 --- a/external/llvm-project/flang/lib/Semantics/resolve-directives.cpp +++ b/external/llvm-project/flang/lib/Semantics/resolve-directives.cpp @@ -23,6 +23,7 @@ #include "flang/Semantics/openmp-modifiers.h" #include "flang/Semantics/symbol.h" #include "flang/Semantics/tools.h" +#include "llvm/Frontend/OpenMP/OMP.h.inc" #include "llvm/Support/Debug.h" #include #include @@ -384,6 +385,9 @@ class OmpAttributeVisitor : DirectiveAttributeVisitor { bool Pre(const parser::OpenMPSectionsConstruct &); void Post(const parser::OpenMPSectionsConstruct &) { PopContext(); } + bool Pre(const parser::OpenMPSectionConstruct &); + void Post(const parser::OpenMPSectionConstruct &) { PopContext(); } + bool Pre(const parser::OpenMPCriticalConstruct &critical); void Post(const parser::OpenMPCriticalConstruct &) { PopContext(); } @@ -737,9 +741,7 @@ class OmpAttributeVisitor : DirectiveAttributeVisitor { } const parser::OmpClause *associatedClause{nullptr}; - void SetAssociatedClause(const parser::OmpClause &c) { - associatedClause = &c; - } + void SetAssociatedClause(const parser::OmpClause *c) { associatedClause = c; } const parser::OmpClause *GetAssociatedClause() { return associatedClause; } private: @@ -833,8 +835,8 @@ class OmpAttributeVisitor : DirectiveAttributeVisitor { void AddOmpRequiresToScope(Scope &, WithOmpDeclarative::RequiresFlags, std::optional); - void IssueNonConformanceWarning( - llvm::omp::Directive D, parser::CharBlock source); + void IssueNonConformanceWarning(llvm::omp::Directive D, + parser::CharBlock source, unsigned EmitFromVersion); void CreateImplicitSymbols(const Symbol *symbol); @@ -1666,7 +1668,7 @@ bool OmpAttributeVisitor::Pre(const parser::OpenMPBlockConstruct &x) { } if (beginDir.v == llvm::omp::Directive::OMPD_master || beginDir.v == llvm::omp::Directive::OMPD_parallel_master) - IssueNonConformanceWarning(beginDir.v, beginDir.source); + IssueNonConformanceWarning(beginDir.v, beginDir.source, 52); ClearDataSharingAttributeObjects(); ClearPrivateDataSharingAttributeObjects(); ClearAllocateNames(); @@ -1789,7 +1791,7 @@ bool OmpAttributeVisitor::Pre(const parser::OpenMPLoopConstruct &x) { beginDir.v == llvm::omp::OMPD_parallel_master_taskloop || beginDir.v == llvm::omp::OMPD_parallel_master_taskloop_simd || beginDir.v == llvm::omp::Directive::OMPD_target_loop) - IssueNonConformanceWarning(beginDir.v, beginDir.source); + IssueNonConformanceWarning(beginDir.v, beginDir.source, 52); ClearDataSharingAttributeObjects(); SetContextAssociatedLoopLevel(GetAssociatedLoopLevelFromClauses(clauseList)); @@ -1916,12 +1918,17 @@ std::int64_t OmpAttributeVisitor::GetAssociatedLoopLevelFromClauses( } if (orderedLevel && (!collapseLevel || orderedLevel >= collapseLevel)) { - SetAssociatedClause(*ordClause); + SetAssociatedClause(ordClause); return orderedLevel; } else if (!orderedLevel && collapseLevel) { - SetAssociatedClause(*collClause); + SetAssociatedClause(collClause); return collapseLevel; - } // orderedLevel < collapseLevel is an error handled in structural checks + } else { + SetAssociatedClause(nullptr); + } + // orderedLevel < collapseLevel is an error handled in structural + // checks + return 1; // default is outermost loop } @@ -1949,9 +1956,31 @@ void OmpAttributeVisitor::PrivatizeAssociatedLoopIndexAndCheckLoopLevel( ivDSA = Symbol::Flag::OmpLastPrivate; } + bool isLoopConstruct{ + GetContext().directive == llvm::omp::Directive::OMPD_loop}; + const parser::OmpClause *clause{GetAssociatedClause()}; + bool hasCollapseClause{ + clause ? (clause->Id() == llvm::omp::OMPC_collapse) : false}; + const auto &outer{std::get>(x.t)}; if (outer.has_value()) { for (const parser::DoConstruct *loop{&*outer}; loop && level > 0; --level) { + if (loop->IsDoConcurrent()) { + // DO CONCURRENT is explicitly allowed for the LOOP construct so long as + // there isn't a COLLAPSE clause + if (isLoopConstruct) { + if (hasCollapseClause) { + // hasCollapseClause implies clause != nullptr + context_.Say(clause->source, + "DO CONCURRENT loops cannot be used with the COLLAPSE clause."_err_en_US); + } + } else { + auto &stmt = + std::get>(loop->t); + context_.Say(stmt.source, + "DO CONCURRENT loops cannot form part of a loop nest."_err_en_US); + } + } // go through all the nested do-loops and resolve index variables const parser::Name *iv{GetLoopIndex(*loop)}; if (iv) { @@ -2003,6 +2032,12 @@ bool OmpAttributeVisitor::Pre(const parser::OpenMPSectionsConstruct &x) { return true; } +bool OmpAttributeVisitor::Pre(const parser::OpenMPSectionConstruct &x) { + PushContext(x.source, llvm::omp::Directive::OMPD_section); + GetContext().withinConstruct = true; + return true; +} + bool OmpAttributeVisitor::Pre(const parser::OpenMPCriticalConstruct &x) { const auto &beginCriticalDir{std::get(x.t)}; const auto &endCriticalDir{std::get(x.t)}; @@ -2073,7 +2108,8 @@ bool OmpAttributeVisitor::Pre(const parser::OpenMPDispatchConstruct &x) { } bool OmpAttributeVisitor::Pre(const parser::OpenMPExecutableAllocate &x) { - IssueNonConformanceWarning(llvm::omp::Directive::OMPD_allocate, x.source); + IssueNonConformanceWarning(llvm::omp::Directive::OMPD_allocate, x.source, 52); + PushContext(x.source, llvm::omp::Directive::OMPD_allocate); const auto &list{std::get>(x.t)}; if (list) { @@ -3024,8 +3060,13 @@ void OmpAttributeVisitor::CheckLabelContext(const parser::CharBlock source, const parser::CharBlock target, std::optional sourceContext, std::optional targetContext) { auto dirContextsSame = [](DirContext &lhs, DirContext &rhs) -> bool { - // Sometimes nested constructs share a scope but are different contexts - return (lhs.scope == rhs.scope) && (lhs.directive == rhs.directive); + // Sometimes nested constructs share a scope but are different contexts. + // The directiveSource comparison is for OmpSection. Sections do not have + // their own scopes and two different sections both have the same directive. + // Their source however is different. This string comparison is unfortunate + // but should only happen for GOTOs inside of SECTION. + return (lhs.scope == rhs.scope) && (lhs.directive == rhs.directive) && + (lhs.directiveSource == rhs.directiveSource); }; unsigned version{context_.langOptions().OpenMPVersion}; if (targetContext && @@ -3132,11 +3173,16 @@ void OmpAttributeVisitor::AddOmpRequiresToScope(Scope &scope, } while (!scopeIter->IsGlobal()); } -void OmpAttributeVisitor::IssueNonConformanceWarning( - llvm::omp::Directive D, parser::CharBlock source) { +void OmpAttributeVisitor::IssueNonConformanceWarning(llvm::omp::Directive D, + parser::CharBlock source, unsigned EmitFromVersion) { std::string warnStr; llvm::raw_string_ostream warnStrOS(warnStr); unsigned version{context_.langOptions().OpenMPVersion}; + // We only want to emit the warning when the version being used has the + // directive deprecated + if (version < EmitFromVersion) { + return; + } warnStrOS << "OpenMP directive " << parser::ToUpperCaseLetters( llvm::omp::getOpenMPDirectiveName(D, version).str()) diff --git a/external/llvm-project/flang/lib/Semantics/resolve-names.cpp b/external/llvm-project/flang/lib/Semantics/resolve-names.cpp index e23e91b674a7..9e465f8ff3e1 100644 --- a/external/llvm-project/flang/lib/Semantics/resolve-names.cpp +++ b/external/llvm-project/flang/lib/Semantics/resolve-names.cpp @@ -1729,7 +1729,6 @@ bool OmpVisitor::NeedsScope(const parser::OpenMPBlockConstruct &x) { switch (beginDir.v) { case llvm::omp::Directive::OMPD_master: case llvm::omp::Directive::OMPD_ordered: - case llvm::omp::Directive::OMPD_taskgroup: return false; default: return true; @@ -1801,9 +1800,9 @@ void OmpVisitor::ProcessMapperSpecifier(const parser::OmpMapperSpecifier &spec, Walk(std::get(spec.t)); auto &varName{std::get(spec.t)}; DeclareObjectEntity(varName); + EndDeclTypeSpec(); Walk(clauses); - EndDeclTypeSpec(); PopScope(); } diff --git a/external/llvm-project/flang/lib/Semantics/rewrite-directives.cpp b/external/llvm-project/flang/lib/Semantics/rewrite-directives.cpp deleted file mode 100644 index 91b60ea151de..000000000000 --- a/external/llvm-project/flang/lib/Semantics/rewrite-directives.cpp +++ /dev/null @@ -1,172 +0,0 @@ -//===-- lib/Semantics/rewrite-directives.cpp ------------------------------===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// - -#include "rewrite-directives.h" -#include "flang/Parser/parse-tree-visitor.h" -#include "flang/Parser/parse-tree.h" -#include "flang/Semantics/semantics.h" -#include "flang/Semantics/symbol.h" -#include "llvm/Frontend/OpenMP/OMP.h" -#include - -namespace Fortran::semantics { - -using namespace parser::literals; - -class DirectiveRewriteMutator { -public: - explicit DirectiveRewriteMutator(SemanticsContext &context) - : context_{context} {} - - // Default action for a parse tree node is to visit children. - template bool Pre(T &) { return true; } - template void Post(T &) {} - -protected: - SemanticsContext &context_; -}; - -// Rewrite atomic constructs to add an explicit memory ordering to all that do -// not specify it, honoring in this way the `atomic_default_mem_order` clause of -// the REQUIRES directive. -class OmpRewriteMutator : public DirectiveRewriteMutator { -public: - explicit OmpRewriteMutator(SemanticsContext &context) - : DirectiveRewriteMutator(context) {} - - template bool Pre(T &) { return true; } - template void Post(T &) {} - - bool Pre(parser::OpenMPAtomicConstruct &); - bool Pre(parser::OpenMPRequiresConstruct &); - -private: - bool atomicDirectiveDefaultOrderFound_{false}; -}; - -bool OmpRewriteMutator::Pre(parser::OpenMPAtomicConstruct &x) { - // Find top-level parent of the operation. - Symbol *topLevelParent{[&]() { - Symbol *symbol{nullptr}; - Scope *scope{&context_.FindScope( - std::get(x.t).source)}; - do { - if (Symbol * parent{scope->symbol()}) { - symbol = parent; - } - scope = &scope->parent(); - } while (!scope->IsGlobal()); - - assert(symbol && - "Atomic construct must be within a scope associated with a symbol"); - return symbol; - }()}; - - // Get the `atomic_default_mem_order` clause from the top-level parent. - std::optional defaultMemOrder; - common::visit( - [&](auto &details) { - if constexpr (std::is_convertible_v) { - if (details.has_ompAtomicDefaultMemOrder()) { - defaultMemOrder = *details.ompAtomicDefaultMemOrder(); - } - } - }, - topLevelParent->details()); - - if (!defaultMemOrder) { - return false; - } - - auto findMemOrderClause{[](const parser::OmpClauseList &clauses) { - return llvm::any_of( - clauses.v, [](auto &clause) -> const parser::OmpClause * { - switch (clause.Id()) { - case llvm::omp::Clause::OMPC_acq_rel: - case llvm::omp::Clause::OMPC_acquire: - case llvm::omp::Clause::OMPC_relaxed: - case llvm::omp::Clause::OMPC_release: - case llvm::omp::Clause::OMPC_seq_cst: - return &clause; - default: - return nullptr; - } - }); - }}; - - auto &dirSpec{std::get(x.t)}; - auto &clauseList{std::get>(dirSpec.t)}; - if (clauseList) { - if (findMemOrderClause(*clauseList)) { - return false; - } - } else { - clauseList = parser::OmpClauseList(decltype(parser::OmpClauseList::v){}); - } - - // Add a memory order clause to the atomic directive. - atomicDirectiveDefaultOrderFound_ = true; - llvm::omp::Clause kind{x.GetKind()}; - switch (*defaultMemOrder) { - case common::OmpMemoryOrderType::Acq_Rel: - // FIXME: Implement 5.0 rules, pending clarification on later spec - // versions. - // [5.0:62:22-26] - if (kind == llvm::omp::Clause::OMPC_read) { - clauseList->v.emplace_back( - parser::OmpClause{parser::OmpClause::Acquire{}}); - } else if (kind == llvm::omp::Clause::OMPC_update && x.IsCapture()) { - clauseList->v.emplace_back( - parser::OmpClause{parser::OmpClause::AcqRel{}}); - } else { - clauseList->v.emplace_back( - parser::OmpClause{parser::OmpClause::Release{}}); - } - break; - case common::OmpMemoryOrderType::Relaxed: - clauseList->v.emplace_back(parser::OmpClause{parser::OmpClause::Relaxed{}}); - break; - case common::OmpMemoryOrderType::Seq_Cst: - clauseList->v.emplace_back(parser::OmpClause{parser::OmpClause::SeqCst{}}); - break; - default: - // FIXME: Don't process other values at the moment since their validity - // depends on the OpenMP version (which is unavailable here). - break; - } - - return false; -} - -bool OmpRewriteMutator::Pre(parser::OpenMPRequiresConstruct &x) { - for (parser::OmpClause &clause : std::get(x.t).v) { - if (std::holds_alternative( - clause.u) && - atomicDirectiveDefaultOrderFound_) { - context_.Say(clause.source, - "REQUIRES directive with '%s' clause found lexically after atomic " - "operation without a memory order clause"_err_en_US, - parser::ToUpperCaseLetters(llvm::omp::getOpenMPClauseName( - llvm::omp::OMPC_atomic_default_mem_order) - .str())); - } - } - return false; -} - -bool RewriteOmpParts(SemanticsContext &context, parser::Program &program) { - if (!context.IsEnabled(common::LanguageFeature::OpenMP)) { - return true; - } - OmpRewriteMutator ompMutator{context}; - parser::Walk(program, ompMutator); - return !context.AnyFatalError(); -} - -} // namespace Fortran::semantics diff --git a/external/llvm-project/flang/lib/Semantics/rewrite-directives.h b/external/llvm-project/flang/lib/Semantics/rewrite-directives.h deleted file mode 100644 index 675962192842..000000000000 --- a/external/llvm-project/flang/lib/Semantics/rewrite-directives.h +++ /dev/null @@ -1,24 +0,0 @@ -//===-- lib/Semantics/rewrite-directives.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 FORTRAN_SEMANTICS_REWRITE_DIRECTIVES_H_ -#define FORTRAN_SEMANTICS_REWRITE_DIRECTIVES_H_ - -namespace Fortran::parser { -struct Program; -} // namespace Fortran::parser - -namespace Fortran::semantics { -class SemanticsContext; -} // namespace Fortran::semantics - -namespace Fortran::semantics { -bool RewriteOmpParts(SemanticsContext &, parser::Program &); -} // namespace Fortran::semantics - -#endif // FORTRAN_SEMANTICS_REWRITE_DIRECTIVES_H_ diff --git a/external/llvm-project/flang/lib/Semantics/rewrite-parse-tree.cpp b/external/llvm-project/flang/lib/Semantics/rewrite-parse-tree.cpp index 577558e7e33b..4eeb1b9ed3c1 100644 --- a/external/llvm-project/flang/lib/Semantics/rewrite-parse-tree.cpp +++ b/external/llvm-project/flang/lib/Semantics/rewrite-parse-tree.cpp @@ -7,7 +7,7 @@ //===----------------------------------------------------------------------===// #include "rewrite-parse-tree.h" -#include "rewrite-directives.h" + #include "flang/Common/indirection.h" #include "flang/Parser/parse-tree-visitor.h" #include "flang/Parser/parse-tree.h" @@ -229,7 +229,7 @@ void RewriteMutator::Post(parser::WriteStmt &x) { bool RewriteParseTree(SemanticsContext &context, parser::Program &program) { RewriteMutator mutator{context}; parser::Walk(program, mutator); - return !context.AnyFatalError() && RewriteOmpParts(context, program); + return !context.AnyFatalError(); } } // namespace Fortran::semantics diff --git a/external/llvm-project/flang/lib/Semantics/runtime-type-info.cpp b/external/llvm-project/flang/lib/Semantics/runtime-type-info.cpp index 26ae81f97895..51ba21a9e5ed 100644 --- a/external/llvm-project/flang/lib/Semantics/runtime-type-info.cpp +++ b/external/llvm-project/flang/lib/Semantics/runtime-type-info.cpp @@ -82,17 +82,17 @@ class RuntimeTableBuilder { const SomeExpr &genre, std::int64_t = 0) const; SomeExpr PackageIntValueExpr(const SomeExpr &genre, std::int64_t = 0) const; std::vector DescribeBindings( - const Scope &dtScope, Scope &); + const Scope &dtScope, Scope &, const SymbolVector &bindings); std::map DescribeSpecialGenerics( - const Scope &dtScope, const Scope &thisScope, - const DerivedTypeSpec *) const; + const Scope &dtScope, const Scope &thisScope, const DerivedTypeSpec *, + const SymbolVector &bindings) const; void DescribeSpecialGeneric(const GenericDetails &, std::map &, const Scope &, - const DerivedTypeSpec *) const; + const DerivedTypeSpec *, const SymbolVector &bindings) const; void DescribeSpecialProc(std::map &, const Symbol &specificOrBinding, bool isAssignment, bool isFinal, std::optional, const Scope *, const DerivedTypeSpec *, - bool isTypeBound) const; + const SymbolVector *bindings) const; void IncorporateDefinedIoGenericInterfaces( std::map &, common::DefinedIo, const Scope *, const DerivedTypeSpec *); @@ -595,8 +595,9 @@ const Symbol *RuntimeTableBuilder::DescribeType( // Compile the "vtable" of type-bound procedure bindings std::uint32_t specialBitSet{0}; if (!dtSymbol->attrs().test(Attr::ABSTRACT)) { + SymbolVector boundProcedures{CollectBindings(dtScope)}; std::vector bindings{ - DescribeBindings(dtScope, scope)}; + DescribeBindings(dtScope, scope, boundProcedures)}; AddValue(dtValues, derivedTypeSchema_, bindingDescCompName, SaveDerivedPointerTarget(scope, SaveObjectName( @@ -609,12 +610,14 @@ const Symbol *RuntimeTableBuilder::DescribeType( // subroutines override any parent bindings, but FINAL subroutines do not // (the runtime will call all of them). std::map specials{ - DescribeSpecialGenerics(dtScope, dtScope, derivedTypeSpec)}; + DescribeSpecialGenerics( + dtScope, dtScope, derivedTypeSpec, boundProcedures)}; if (derivedTypeSpec) { - for (auto &ref : FinalsForDerivedTypeInstantiation(*derivedTypeSpec)) { - DescribeSpecialProc(specials, *ref, /*isAssignment-*/ false, + for (const Symbol &symbol : + FinalsForDerivedTypeInstantiation(*derivedTypeSpec)) { + DescribeSpecialProc(specials, symbol, /*isAssignment-*/ false, /*isFinal=*/true, std::nullopt, nullptr, derivedTypeSpec, - /*isTypeBound=*/true); + &boundProcedures); } IncorporateDefinedIoGenericInterfaces(specials, common::DefinedIo::ReadFormatted, &scope, derivedTypeSpec); @@ -661,6 +664,10 @@ const Symbol *RuntimeTableBuilder::DescribeType( AddValue(dtValues, derivedTypeSchema_, "nofinalizationneeded"s, IntExpr<1>( derivedTypeSpec && !MayRequireFinalization(*derivedTypeSpec))); + // Similarly, a flag to enable optimized runtime assignment. + AddValue(dtValues, derivedTypeSchema_, "nodefinedassignment"s, + IntExpr<1>( + derivedTypeSpec && !MayHaveDefinedAssignment(*derivedTypeSpec))); } dtObject.get().set_init(MaybeExpr{ StructureExpr(Structure(derivedTypeSchema_, std::move(dtValues)))}); @@ -1041,15 +1048,16 @@ SymbolVector CollectBindings(const Scope &dtScope) { } std::vector -RuntimeTableBuilder::DescribeBindings(const Scope &dtScope, Scope &scope) { +RuntimeTableBuilder::DescribeBindings( + const Scope &dtScope, Scope &scope, const SymbolVector &bindings) { std::vector result; - for (const SymbolRef &ref : CollectBindings(dtScope)) { + for (const Symbol &symbol : bindings) { evaluate::StructureConstructorValues values; AddValue(values, bindingSchema_, procCompName, SomeExpr{evaluate::ProcedureDesignator{ - ref.get().get().symbol()}}); + symbol.get().symbol()}}); AddValue(values, bindingSchema_, "name"s, - SaveNameAsPointerTarget(scope, ref.get().name().ToString())); + SaveNameAsPointerTarget(scope, symbol.name().ToString())); result.emplace_back(DEREF(bindingSchema_.AsDerived()), std::move(values)); } return result; @@ -1057,16 +1065,18 @@ RuntimeTableBuilder::DescribeBindings(const Scope &dtScope, Scope &scope) { std::map RuntimeTableBuilder::DescribeSpecialGenerics(const Scope &dtScope, - const Scope &thisScope, const DerivedTypeSpec *derivedTypeSpec) const { + const Scope &thisScope, const DerivedTypeSpec *derivedTypeSpec, + const SymbolVector &bindings) const { std::map specials; if (const Scope * parentScope{dtScope.GetDerivedTypeParent()}) { - specials = - DescribeSpecialGenerics(*parentScope, thisScope, derivedTypeSpec); + specials = DescribeSpecialGenerics( + *parentScope, thisScope, derivedTypeSpec, bindings); } for (const auto &pair : dtScope) { const Symbol &symbol{*pair.second}; if (const auto *generic{symbol.detailsIf()}) { - DescribeSpecialGeneric(*generic, specials, thisScope, derivedTypeSpec); + DescribeSpecialGeneric( + *generic, specials, thisScope, derivedTypeSpec, bindings); } } return specials; @@ -1074,15 +1084,16 @@ RuntimeTableBuilder::DescribeSpecialGenerics(const Scope &dtScope, void RuntimeTableBuilder::DescribeSpecialGeneric(const GenericDetails &generic, std::map &specials, - const Scope &dtScope, const DerivedTypeSpec *derivedTypeSpec) const { + const Scope &dtScope, const DerivedTypeSpec *derivedTypeSpec, + const SymbolVector &bindings) const { common::visit( common::visitors{ [&](const GenericKind::OtherKind &k) { if (k == GenericKind::OtherKind::Assignment) { - for (auto ref : generic.specificProcs()) { - DescribeSpecialProc(specials, *ref, /*isAssignment=*/true, + for (const Symbol &specific : generic.specificProcs()) { + DescribeSpecialProc(specials, specific, /*isAssignment=*/true, /*isFinal=*/false, std::nullopt, &dtScope, derivedTypeSpec, - /*isTypeBound=*/true); + &bindings); } } }, @@ -1092,10 +1103,10 @@ void RuntimeTableBuilder::DescribeSpecialGeneric(const GenericDetails &generic, case common::DefinedIo::ReadUnformatted: case common::DefinedIo::WriteFormatted: case common::DefinedIo::WriteUnformatted: - for (auto ref : generic.specificProcs()) { - DescribeSpecialProc(specials, *ref, /*isAssignment=*/false, + for (const Symbol &specific : generic.specificProcs()) { + DescribeSpecialProc(specials, specific, /*isAssignment=*/false, /*isFinal=*/false, io, &dtScope, derivedTypeSpec, - /*isTypeBound=*/true); + &bindings); } break; } @@ -1109,7 +1120,8 @@ void RuntimeTableBuilder::DescribeSpecialProc( std::map &specials, const Symbol &specificOrBinding, bool isAssignment, bool isFinal, std::optional io, const Scope *dtScope, - const DerivedTypeSpec *derivedTypeSpec, bool isTypeBound) const { + const DerivedTypeSpec *derivedTypeSpec, + const SymbolVector *bindings) const { const auto *binding{specificOrBinding.detailsIf()}; if (binding && dtScope) { // use most recent override binding = &DEREF(dtScope->FindComponent(specificOrBinding.name())) @@ -1128,6 +1140,9 @@ void RuntimeTableBuilder::DescribeSpecialProc( // component assignment as part of intrinsic assignment. // Non-type-bound generic INTERFACEs and assignments from incompatible // types must not be used for component intrinsic assignment. + if (!binding) { + return; + } CHECK(proc->dummyArguments.size() == 2); const auto t1{ DEREF(std::get_if( @@ -1137,7 +1152,7 @@ void RuntimeTableBuilder::DescribeSpecialProc( DEREF(std::get_if( &proc->dummyArguments[1].u)) .type.type()}; - if (!binding || t1.category() != TypeCategory::Derived || + if (t1.category() != TypeCategory::Derived || t2.category() != TypeCategory::Derived || t1.IsUnlimitedPolymorphic() || t2.IsUnlimitedPolymorphic()) { return; @@ -1149,7 +1164,7 @@ void RuntimeTableBuilder::DescribeSpecialProc( } which = proc->IsElemental() ? elementalAssignmentEnum_ : scalarAssignmentEnum_; - if (binding && binding->passName() && + if (binding->passName() && *binding->passName() == proc->dummyArguments[1].name) { argThatMightBeDescriptor = 1; isArgDescriptorSet |= 2; @@ -1234,8 +1249,19 @@ void RuntimeTableBuilder::DescribeSpecialProc( values, specialSchema_, "which"s, SomeExpr{std::move(which.value())}); AddValue(values, specialSchema_, "isargdescriptorset"s, IntExpr<1>(isArgDescriptorSet)); - AddValue(values, specialSchema_, "istypebound"s, - IntExpr<1>(isTypeBound ? 1 : 0)); + int bindingIndex{0}; + if (bindings) { + int j{0}; + for (const Symbol &bind : DEREF(bindings)) { + ++j; + if (&bind.get().symbol() == &specific) { + bindingIndex = j; // index offset by 1 + break; + } + } + } + CHECK(bindingIndex <= 255); + AddValue(values, specialSchema_, "istypebound"s, IntExpr<1>(bindingIndex)); AddValue(values, specialSchema_, "isargcontiguousset"s, IntExpr<1>(isArgContiguousSet)); AddValue(values, specialSchema_, procCompName, @@ -1260,7 +1286,7 @@ void RuntimeTableBuilder::IncorporateDefinedIoGenericInterfaces( CHECK(std::get(genericDetails.kind().u) == definedIo); for (auto ref : genericDetails.specificProcs()) { DescribeSpecialProc(specials, *ref, false, false, definedIo, nullptr, - derivedTypeSpec, false); + derivedTypeSpec, /*bindings=*/nullptr); } } } diff --git a/external/llvm-project/flang/lib/Semantics/tools.cpp b/external/llvm-project/flang/lib/Semantics/tools.cpp index a1445187b1e9..d053179448c0 100644 --- a/external/llvm-project/flang/lib/Semantics/tools.cpp +++ b/external/llvm-project/flang/lib/Semantics/tools.cpp @@ -17,7 +17,6 @@ #include "flang/Semantics/tools.h" #include "flang/Semantics/type.h" #include "flang/Support/Fortran.h" -#include "llvm/ADT/StringSwitch.h" #include "llvm/Support/raw_ostream.h" #include #include @@ -814,6 +813,38 @@ bool HasAllocatableDirectComponent(const DerivedTypeSpec &derived) { return std::any_of(directs.begin(), directs.end(), IsAllocatable); } +static bool MayHaveDefinedAssignment( + const DerivedTypeSpec &derived, std::set &checked) { + if (const Scope *scope{derived.GetScope()}; + scope && checked.find(scope) == checked.end()) { + checked.insert(scope); + for (const auto &[_, symbolRef] : *scope) { + if (const auto *generic{symbolRef->detailsIf()}) { + if (generic->kind().IsAssignment()) { + return true; + } + } else if (symbolRef->has() && + !IsPointer(*symbolRef)) { + if (const DeclTypeSpec *type{symbolRef->GetType()}) { + if (type->IsPolymorphic()) { + return true; + } else if (const DerivedTypeSpec *derived{type->AsDerived()}) { + if (MayHaveDefinedAssignment(*derived, checked)) { + return true; + } + } + } + } + } + } + return false; +} + +bool MayHaveDefinedAssignment(const DerivedTypeSpec &derived) { + std::set checked; + return MayHaveDefinedAssignment(derived, checked); +} + bool IsAssumedLengthCharacter(const Symbol &symbol) { if (const DeclTypeSpec * type{symbol.GetType()}) { return type->category() == DeclTypeSpec::Character && @@ -1757,332 +1788,4 @@ bool HadUseError( } } -bool CheckForSymbolMatch(const SomeExpr *lhs, const SomeExpr *rhs) { - if (lhs && rhs) { - if (SymbolVector lhsSymbols{evaluate::GetSymbolVector(*lhs)}; - !lhsSymbols.empty()) { - const Symbol &first{*lhsSymbols.front()}; - for (const Symbol &symbol : evaluate::GetSymbolVector(*rhs)) { - if (first == symbol) { - return true; - } - } - } - } - return false; -} - -namespace operation { -template // -SomeExpr asSomeExpr(const T &x) { - auto copy{x}; - return AsGenericExpr(std::move(copy)); -} - -template // -struct ArgumentExtractor - : public evaluate::Traverse, - std::pair>, false> { - using Arguments = std::vector; - using Result = std::pair; - using Base = evaluate::Traverse, - Result, false>; - static constexpr auto IgnoreResizes = IgnoreResizingConverts; - static constexpr auto Logical = common::TypeCategory::Logical; - ArgumentExtractor() : Base(*this) {} - - Result Default() const { return {}; } - - using Base::operator(); - - template // - Result operator()( - const evaluate::Constant> &x) const { - if (const auto &val{x.GetScalarValue()}) { - return val->IsTrue() - ? std::make_pair(operation::Operator::True, Arguments{}) - : std::make_pair(operation::Operator::False, Arguments{}); - } - return Default(); - } - - template // - Result operator()(const evaluate::FunctionRef &x) const { - Result result{operation::OperationCode(x.proc()), {}}; - for (size_t i{0}, e{x.arguments().size()}; i != e; ++i) { - if (auto *e{x.UnwrapArgExpr(i)}) { - result.second.push_back(*e); - } - } - return result; - } - - template - Result operator()(const evaluate::Operation &x) const { - if constexpr (std::is_same_v>) { - // Ignore top-level parentheses. - return (*this)(x.template operand<0>()); - } - if constexpr (IgnoreResizes && - std::is_same_v>) { - // Ignore conversions within the same category. - // Atomic operations on int(kind=1) may be implicitly widened - // to int(kind=4) for example. - return (*this)(x.template operand<0>()); - } else { - return std::make_pair(operation::OperationCode(x), - OperationArgs(x, std::index_sequence_for{})); - } - } - - template // - Result operator()(const evaluate::Designator &x) const { - return {operation::Operator::Identity, {asSomeExpr(x)}}; - } - - template // - Result operator()(const evaluate::Constant &x) const { - return {operation::Operator::Identity, {asSomeExpr(x)}}; - } - - template // - Result Combine(Result &&result, Rs &&...results) const { - // There shouldn't be any combining needed, since we're stopping the - // traversal at the top-level operation, but implement one that picks - // the first non-empty result. - if constexpr (sizeof...(Rs) == 0) { - return std::move(result); - } else { - if (!result.second.empty()) { - return std::move(result); - } else { - return Combine(std::move(results)...); - } - } - } - -private: - template - Arguments OperationArgs(const evaluate::Operation &x, - std::index_sequence) const { - return Arguments{SomeExpr(x.template operand())...}; - } -}; -} // namespace operation - -std::string operation::ToString(operation::Operator op) { - switch (op) { - case Operator::Unknown: - return "??"; - case Operator::Add: - return "+"; - case Operator::And: - return "AND"; - case Operator::Associated: - return "ASSOCIATED"; - case Operator::Call: - return "function-call"; - case Operator::Constant: - return "constant"; - case Operator::Convert: - return "type-conversion"; - case Operator::Div: - return "/"; - case Operator::Eq: - return "=="; - case Operator::Eqv: - return "EQV"; - case Operator::False: - return ".FALSE."; - case Operator::Ge: - return ">="; - case Operator::Gt: - return ">"; - case Operator::Identity: - return "identity"; - case Operator::Intrinsic: - return "intrinsic"; - case Operator::Le: - return "<="; - case Operator::Lt: - return "<"; - case Operator::Max: - return "MAX"; - case Operator::Min: - return "MIN"; - case Operator::Mul: - return "*"; - case Operator::Ne: - return "/="; - case Operator::Neqv: - return "NEQV/EOR"; - case Operator::Not: - return "NOT"; - case Operator::Or: - return "OR"; - case Operator::Pow: - return "**"; - case Operator::Resize: - return "resize"; - case Operator::Sub: - return "-"; - case Operator::True: - return ".TRUE."; - } - llvm_unreachable("Unhandler operator"); -} - -operation::Operator operation::OperationCode( - const evaluate::ProcedureDesignator &proc) { - Operator code = llvm::StringSwitch(proc.GetName()) - .Case("associated", Operator::Associated) - .Case("min", Operator::Min) - .Case("max", Operator::Max) - .Case("iand", Operator::And) - .Case("ior", Operator::Or) - .Case("ieor", Operator::Neqv) - .Default(Operator::Call); - if (code == Operator::Call && proc.GetSpecificIntrinsic()) { - return Operator::Intrinsic; - } - return code; -} - -std::pair> GetTopLevelOperation( - const SomeExpr &expr) { - return operation::ArgumentExtractor{}(expr); -} - -namespace operation { -struct ConvertCollector - : public evaluate::Traverse>, false> { - using Result = std::pair>; - using Base = evaluate::Traverse; - ConvertCollector() : Base(*this) {} - - Result Default() const { return {}; } - - using Base::operator(); - - template // - Result operator()(const evaluate::Designator &x) const { - return {asSomeExpr(x), {}}; - } - - template // - Result operator()(const evaluate::FunctionRef &x) const { - return {asSomeExpr(x), {}}; - } - - template // - Result operator()(const evaluate::Constant &x) const { - return {asSomeExpr(x), {}}; - } - - template - Result operator()(const evaluate::Operation &x) const { - if constexpr (std::is_same_v>) { - // Ignore parentheses. - return (*this)(x.template operand<0>()); - } else if constexpr (is_convert_v) { - // Convert should always have a typed result, so it should be safe to - // dereference x.GetType(). - return Combine( - {std::nullopt, {*x.GetType()}}, (*this)(x.template operand<0>())); - } else if constexpr (is_complex_constructor_v) { - // This is a conversion iff the imaginary operand is 0. - if (IsZero(x.template operand<1>())) { - return Combine( - {std::nullopt, {*x.GetType()}}, (*this)(x.template operand<0>())); - } else { - return {asSomeExpr(x.derived()), {}}; - } - } else { - return {asSomeExpr(x.derived()), {}}; - } - } - - template // - Result Combine(Result &&result, Rs &&...results) const { - Result v(std::move(result)); - auto setValue{[](MaybeExpr &x, MaybeExpr &&y) { - assert((!x.has_value() || !y.has_value()) && "Multiple designators"); - if (!x.has_value()) { - x = std::move(y); - } - }}; - auto moveAppend{[](auto &accum, auto &&other) { - for (auto &&s : other) { - accum.push_back(std::move(s)); - } - }}; - (setValue(v.first, std::move(results).first), ...); - (moveAppend(v.second, std::move(results).second), ...); - return v; - } - -private: - template // - static bool IsZero(const T &x) { - return false; - } - template // - static bool IsZero(const evaluate::Expr &x) { - return common::visit([](auto &&s) { return IsZero(s); }, x.u); - } - template // - static bool IsZero(const evaluate::Constant &x) { - if (auto &&maybeScalar{x.GetScalarValue()}) { - return maybeScalar->IsZero(); - } else { - return false; - } - } - - template // - struct is_convert { - static constexpr bool value{false}; - }; - template // - struct is_convert> { - static constexpr bool value{true}; - }; - template // - struct is_convert> { - // Conversion from complex to real. - static constexpr bool value{true}; - }; - template // - static constexpr bool is_convert_v = is_convert::value; - - template // - struct is_complex_constructor { - static constexpr bool value{false}; - }; - template // - struct is_complex_constructor> { - static constexpr bool value{true}; - }; - template // - static constexpr bool is_complex_constructor_v = - is_complex_constructor::value; -}; -} // namespace operation - -MaybeExpr GetConvertInput(const SomeExpr &x) { - // This returns SomeExpr(x) when x is a designator/functionref/constant. - return operation::ConvertCollector{}(x).first; -} - -bool IsSameOrConvertOf(const SomeExpr &expr, const SomeExpr &x) { - // Check if expr is same as x, or a sequence of Convert operations on x. - if (expr == x) { - return true; - } else if (auto maybe{GetConvertInput(expr)}) { - return *maybe == x; - } else { - return false; - } -} } // namespace Fortran::semantics \ No newline at end of file diff --git a/external/llvm-project/flang/lib/Support/Fortran-features.cpp b/external/llvm-project/flang/lib/Support/Fortran-features.cpp index e36fe744cea2..a65a737f1544 100644 --- a/external/llvm-project/flang/lib/Support/Fortran-features.cpp +++ b/external/llvm-project/flang/lib/Support/Fortran-features.cpp @@ -152,22 +152,23 @@ LanguageFeatureControl::LanguageFeatureControl() { warnLanguage_.set(LanguageFeature::NullActualForAllocatable); } -// Take a string from the Cli and apply it to the LanguageFeatureControl. -bool LanguageFeatureControl::ApplyCliOption(std::string input) { +std::optional LanguageFeatureControl::FindWarning( + std::string_view input) { bool negated{false}; if (input.size() > 3 && input.substr(0, 3) == "no-") { negated = true; input = input.substr(3); } - if (auto it{cliOptions_.find(input)}; it != cliOptions_.end()) { - if (std::holds_alternative(it->second)) { - EnableWarning(std::get(it->second), !negated); - return true; - } - if (std::holds_alternative(it->second)) { - EnableWarning(std::get(it->second), !negated); - return true; - } + if (auto it{cliOptions_.find(std::string{input})}; it != cliOptions_.end()) { + return std::make_pair(it->second, !negated); + } + return std::nullopt; +} + +bool LanguageFeatureControl::EnableWarning(std::string_view input) { + if (auto warningAndEnabled{FindWarning(input)}) { + EnableWarning(warningAndEnabled->first, warningAndEnabled->second); + return true; } return false; } diff --git a/external/llvm-project/flang/module/__fortran_type_info.f90 b/external/llvm-project/flang/module/__fortran_type_info.f90 index b30a6bf69756..8dd27d6e4c01 100644 --- a/external/llvm-project/flang/module/__fortran_type_info.f90 +++ b/external/llvm-project/flang/module/__fortran_type_info.f90 @@ -52,7 +52,8 @@ integer(1) :: noInitializationNeeded ! 1 if no component w/ init integer(1) :: noDestructionNeeded ! 1 if no component w/ dealloc/final integer(1) :: noFinalizationNeeded ! 1 if nothing finalizeable - integer(1) :: __padding0(4) + integer(1) :: noDefinedAssignment ! 1 if no defined ASSIGNMENT(=) + integer(1) :: __padding0(3) end type type :: Binding @@ -116,7 +117,7 @@ type, bind(c) :: SpecialBinding integer(1) :: which ! SpecialBinding::Which integer(1) :: isArgDescriptorSet - integer(1) :: isTypeBound + integer(1) :: isTypeBound ! binding index + 1, if any integer(1) :: isArgContiguousSet integer(1) :: __padding0(4) type(__builtin_c_funptr) :: proc diff --git a/external/llvm-project/flang/test/Driver/flang-ld-aarch64.f90 b/external/llvm-project/flang/test/Driver/flang-ld-aarch64.f90 new file mode 100644 index 000000000000..61cd46cea5cd --- /dev/null +++ b/external/llvm-project/flang/test/Driver/flang-ld-aarch64.f90 @@ -0,0 +1,9 @@ +! Check linker flags for AArch64 linux, since it needs both libgcc and +! compiler-rt, with compiler-rt second when -rtlib=libgcc. + +! RUN: %flang -### -rtlib=libgcc --target=aarch64-linux-gnu %S/Inputs/hello.f90 2>&1 | FileCheck %s + +! CHECK-LABEL: "{{.*}}ld{{(\.exe)?}}" +! CHECK-SAME: "-lflang_rt.runtime" "-lm" +! CHECK-SAME: "-lgcc" "--as-needed" "-lgcc_s" "--no-as-needed" +! CHECK-SAME: "--as-needed" "{{.*}}{{\\|/}}libclang_rt.builtins.a" "--no-as-needed" diff --git a/external/llvm-project/flang/test/Driver/flang-openmp-version-macro.f90 b/external/llvm-project/flang/test/Driver/flang-openmp-version-macro.f90 index 714f6eac56f9..eacff0ab4626 100644 --- a/external/llvm-project/flang/test/Driver/flang-openmp-version-macro.f90 +++ b/external/llvm-project/flang/test/Driver/flang-openmp-version-macro.f90 @@ -2,7 +2,6 @@ ! RUN: %flang_fc1 -fopenmp -cpp -E %s | FileCheck %s --check-prefix=DEFAULT-OPENMP-VERSION ! RUN: %flang_fc1 -fopenmp -fopenmp-version=11 -cpp -E %s | FileCheck %s --check-prefix=OPENMP-VERSION-11 -! RUN: %flang_fc1 -fopenmp -fopenmp-version=11 -cpp -E %s | FileCheck %s --check-prefix=OPENMP-VERSION-11 ! RUN: %flang_fc1 -fopenmp -fopenmp-version=20 -cpp -E %s | FileCheck %s --check-prefix=OPENMP-VERSION-20 ! RUN: %flang_fc1 -fopenmp -fopenmp-version=25 -cpp -E %s | FileCheck %s --check-prefix=OPENMP-VERSION-25 ! RUN: %flang_fc1 -fopenmp -fopenmp-version=30 -cpp -E %s | FileCheck %s --check-prefix=OPENMP-VERSION-30 @@ -12,6 +11,7 @@ ! RUN: %flang_fc1 -fopenmp -fopenmp-version=50 -cpp -E %s | FileCheck %s --check-prefix=OPENMP-VERSION-50 ! RUN: %flang_fc1 -fopenmp -fopenmp-version=51 -cpp -E %s | FileCheck %s --check-prefix=OPENMP-VERSION-51 ! RUN: %flang_fc1 -fopenmp -fopenmp-version=52 -cpp -E %s | FileCheck %s --check-prefix=OPENMP-VERSION-52 +! RUN: %flang_fc1 -fopenmp -fopenmp-version=60 -cpp -E %s | FileCheck %s --check-prefix=OPENMP-VERSION-60 ! DEFAULT-OPENMP-VERSION: integer :: var1 = 202111 ! OPENMP-VERSION-11: integer :: var1 = 199911 @@ -24,6 +24,7 @@ ! OPENMP-VERSION-50: integer :: var1 = 201811 ! OPENMP-VERSION-51: integer :: var1 = 202011 ! OPENMP-VERSION-52: integer :: var1 = 202111 +! OPENMP-VERSION-60: integer :: var1 = 202411 #if _OPENMP integer :: var1 = _OPENMP diff --git a/external/llvm-project/flang/test/Fir/FirToSCF/if.fir b/external/llvm-project/flang/test/Fir/FirToSCF/if.fir deleted file mode 100644 index 9e43cf1cd11d..000000000000 --- a/external/llvm-project/flang/test/Fir/FirToSCF/if.fir +++ /dev/null @@ -1,56 +0,0 @@ -// RUN: fir-opt %s --fir-to-scf | FileCheck %s - -// CHECK: func.func @test_only(%[[ARG0:.*]]: i1, %[[ARG1:.*]]: i32) { -// CHECK: scf.if %[[ARG0:.*]] { -// CHECK: %[[VAL_1:.*]] = arith.addi %[[ARG1:.*]], %[[ARG1:.*]] : i32 -// CHECK: } -// CHECK: return -// CHECK: } -func.func @test_only(%arg0 : i1, %arg1 : i32) { - fir.if %arg0 { - %0 = arith.addi %arg1, %arg1 : i32 - } - return -} - -// CHECK: func.func @test_else() { -// CHECK: %[[VAL_1:.*]] = arith.constant false -// CHECK: %[[VAL_2:.*]] = arith.constant 2 : i32 -// CHECK: scf.if %[[VAL_1:.*]] { -// CHECK: %[[VAL_3:.*]] = arith.constant 3 : i32 -// CHECK: } else { -// CHECK: %[[VAL_3:.*]] = arith.constant 3 : i32 -// CHECK: } -// CHECK: return -// CHECK: } -func.func @test_else() { - %false = arith.constant false - %1 = arith.constant 2 : i32 - fir.if %false { - %2 = arith.constant 3 : i32 - } else { - %3 = arith.constant 3 : i32 - } - return -} - -// CHECK-LABEL: func.func @test_two_result() { -// CHECK: %[[VAL_1:.*]] = arith.constant 2.000000e+00 : f32 -// CHECK: %[[VAL_2:.*]] = arith.constant false -// CHECK: %[[RES:[0-9]+]]:2 = scf.if %[[VAL_2:.*]] -> (f32, f32) { -// CHECK: scf.yield %[[VAL_1:.*]], %[[VAL_1:.*]] : f32, f32 -// CHECK: } else { -// CHECK: scf.yield %[[VAL_1:.*]], %[[VAL_1:.*]] : f32, f32 -// CHECK: } -// CHECK: return -// CHECK: } -func.func @test_two_result() { - %1 = arith.constant 2.0 : f32 - %cmp = arith.constant false - %x, %y = fir.if %cmp -> (f32, f32) { - fir.result %1, %1 : f32, f32 - } else { - fir.result %1, %1 : f32, f32 - } - return -} diff --git a/external/llvm-project/flang/test/Fir/cfg-conversion-if.fir b/external/llvm-project/flang/test/Fir/cfg-conversion-if.fir new file mode 100644 index 000000000000..1e30ee8e64f0 --- /dev/null +++ b/external/llvm-project/flang/test/Fir/cfg-conversion-if.fir @@ -0,0 +1,46 @@ +// RUN: fir-opt --split-input-file --cfg-conversion %s | FileCheck %s + +func.func private @callee() -> none + +// CHECK-LABEL: func.func @if_then( +// CHECK-SAME: %[[ARG0:.*]]: i1) { +// CHECK: cf.cond_br %[[ARG0]] weights([10, 90]), ^bb1, ^bb2 +// CHECK: ^bb1: +// CHECK: %[[VAL_0:.*]] = fir.call @callee() : () -> none +// CHECK: cf.br ^bb2 +// CHECK: ^bb2: +// CHECK: return +// CHECK: } +func.func @if_then(%cond: i1) { + fir.if %cond weights([10, 90]) { + fir.call @callee() : () -> none + } + return +} + +// ----- + +// CHECK-LABEL: func.func @if_then_else( +// CHECK-SAME: %[[ARG0:.*]]: i1) -> i32 { +// CHECK: %[[VAL_0:.*]] = arith.constant 0 : i32 +// CHECK: %[[VAL_1:.*]] = arith.constant 1 : i32 +// CHECK: cf.cond_br %[[ARG0]] weights([90, 10]), ^bb1, ^bb2 +// CHECK: ^bb1: +// CHECK: cf.br ^bb3(%[[VAL_0]] : i32) +// CHECK: ^bb2: +// CHECK: cf.br ^bb3(%[[VAL_1]] : i32) +// CHECK: ^bb3(%[[VAL_2:.*]]: i32): +// CHECK: cf.br ^bb4 +// CHECK: ^bb4: +// CHECK: return %[[VAL_2]] : i32 +// CHECK: } +func.func @if_then_else(%cond: i1) -> i32 { + %c0 = arith.constant 0 : i32 + %c1 = arith.constant 1 : i32 + %result = fir.if %cond weights([90, 10]) -> i32 { + fir.result %c0 : i32 + } else { + fir.result %c1 : i32 + } + return %result : i32 +} diff --git a/external/llvm-project/flang/test/Fir/fir-ops.fir b/external/llvm-project/flang/test/Fir/fir-ops.fir index 9c444d2f4e0b..3585bf9efca3 100644 --- a/external/llvm-project/flang/test/Fir/fir-ops.fir +++ b/external/llvm-project/flang/test/Fir/fir-ops.fir @@ -1015,3 +1015,19 @@ func.func @test_box_total_elements(%arg0: !fir.class> %6 = arith.addi %2, %5 : index return %6 : index } + +// CHECK-LABEL: func.func @test_if_weights( +// CHECK-SAME: %[[ARG0:.*]]: i1) { +func.func @test_if_weights(%cond: i1) { +// CHECK: fir.if %[[ARG0]] weights([99, 1]) { +// CHECK: } + fir.if %cond weights([99, 1]) { + } +// CHECK: fir.if %[[ARG0]] weights([99, 1]) { +// CHECK: } else { +// CHECK: } + fir.if %cond weights ([99,1]) { + } else { + } + return +} diff --git a/external/llvm-project/flang/test/Fir/invalid.fir b/external/llvm-project/flang/test/Fir/invalid.fir index 45cae1f82cb8..aca0ecc1abdc 100644 --- a/external/llvm-project/flang/test/Fir/invalid.fir +++ b/external/llvm-project/flang/test/Fir/invalid.fir @@ -1393,3 +1393,31 @@ fir.local {type = local_init} @x.localizer : f32 init { ^bb0(%arg0: f32, %arg1: f32): fir.yield(%arg0 : f32) } + +// ----- + +func.func @wrong_weights_number_in_if_then(%cond: i1) { +// expected-error @below {{expects number of region weights to match number of regions: 1 vs 2}} + fir.if %cond weights([50]) { + } + return +} + +// ----- + +func.func @wrong_weights_number_in_if_then_else(%cond: i1) { +// expected-error @below {{expects number of region weights to match number of regions: 3 vs 2}} + fir.if %cond weights([50, 40, 10]) { + } else { + } + return +} + +// ----- + +func.func @negative_weight_in_if_then(%cond: i1) { +// expected-error @below {{weight #0 must be non-negative}} + fir.if %cond weights([-1, 101]) { + } + return +} diff --git a/external/llvm-project/flang/test/HLFIR/fir-local-alloca-block.fir b/external/llvm-project/flang/test/HLFIR/fir-local-alloca-block.fir new file mode 100644 index 000000000000..9d76e86fec3d --- /dev/null +++ b/external/llvm-project/flang/test/HLFIR/fir-local-alloca-block.fir @@ -0,0 +1,34 @@ +// Tests that `fir.local` ops are able to provide an alloca block when required. + +// RUN: fir-opt %s -convert-hlfir-to-fir | FileCheck %s + +fir.local {type = local_init} @localizer : !fir.box> copy { +^bb0(%arg0: !fir.ref>>, %arg1: !fir.ref>>): + %0 = fir.load %arg0 : !fir.ref>> + hlfir.assign %0 to %arg1 : !fir.box>, !fir.ref>> + fir.yield(%arg1 : !fir.ref>>) +} + +func.func @foo() { + %c1 = arith.constant 1 : index + %0 = fir.alloca !fir.box> + fir.do_concurrent { + fir.do_concurrent.loop (%arg0) = (%c1) to (%c1) step (%c1) local(@localizer %0 -> %arg1 : !fir.ref>>) { + } + } + return +} + +// CHECK: fir.local {type = local_init} @localizer : ![[TYPE:fir.box>]] copy { +// CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref, %[[VAL_1:.*]]: !fir.ref): +// CHECK: %[[VAL_2:.*]] = fir.alloca ![[TYPE]] +// CHECK: %[[VAL_3:.*]] = fir.load %[[VAL_0]] : !fir.ref +// CHECK: %[[VAL_4:.*]] = arith.constant 0 : index +// CHECK: %[[VAL_5:.*]]:3 = fir.box_dims %[[VAL_3]], %[[VAL_4]] : (![[TYPE]], index) -> (index, index, index) +// CHECK: %[[VAL_6:.*]] = fir.load %[[VAL_1]] : !fir.ref +// CHECK: fir.store %[[VAL_6]] to %[[VAL_2]] : !fir.ref +// CHECK: %[[VAL_10:.*]] = fir.convert %[[VAL_2]] : (!fir.ref) -> !fir.ref> +// CHECK: %[[VAL_11:.*]] = fir.convert %[[VAL_3]] : (![[TYPE]]) -> !fir.box +// CHECK: fir.call @_FortranAAssign(%[[VAL_10]], %[[VAL_11]], %{{.*}}, %{{.*}}) +// CHECK: fir.yield(%[[VAL_1]] : !fir.ref) +// CHECK: } diff --git a/external/llvm-project/flang/test/Integration/amdgpu/debug-target-var.f90 b/external/llvm-project/flang/test/Integration/amdgpu/debug-target-var.f90 index f47cf1e4405d..8d00b967b0b7 100644 --- a/external/llvm-project/flang/test/Integration/amdgpu/debug-target-var.f90 +++ b/external/llvm-project/flang/test/Integration/amdgpu/debug-target-var.f90 @@ -19,8 +19,8 @@ end subroutine fff ! CHECK-DAG: store ptr %[[ARG2]], ptr %[[CAST2:[0-9]+]]{{.*}} ! CHECK-DAG: %[[CAST2]] = addrspacecast ptr addrspace(5) %[[AL2:[0-9]+]] ! CHECK-DAG: %[[AL2]] = alloca{{.*}} -! CHECK-DAG: #dbg_declare(ptr {{.*}}%[[AL1]], ![[X:[0-9]+]], !DIExpression(DIOpArg(0, ptr addrspace(5)), DIOpDeref(ptr), DIOpDeref(ptr)), {{.*}}) -! CHECK-DAG: #dbg_declare(ptr {{.*}}%[[AL2]], ![[Y:[0-9]+]], !DIExpression(DIOpArg(0, ptr addrspace(5)), DIOpDeref(ptr), DIOpDeref(ptr)), {{.*}}) +! CHECK-DAG: #dbg_declare(ptr addrspace(5) %[[AL1]], ![[X:[0-9]+]], !DIExpression(DIOpArg(0, ptr addrspace(5)), DIOpDeref(ptr), DIOpDeref(ptr)), {{.*}}) +! CHECK-DAG: #dbg_declare(ptr addrspace(5) %[[AL2]], ![[Y:[0-9]+]], !DIExpression(DIOpArg(0, ptr addrspace(5)), DIOpDeref(ptr), DIOpDeref(ptr)), {{.*}}) ! CHECK: } ! CHECK-DAG: ![[SP]] = {{.*}}!DISubprogram(name: "[[FN]]"{{.*}}) diff --git a/external/llvm-project/flang/test/Integration/cold_array_repacking.f90 b/external/llvm-project/flang/test/Integration/cold_array_repacking.f90 new file mode 100644 index 000000000000..11b7d8c21b67 --- /dev/null +++ b/external/llvm-project/flang/test/Integration/cold_array_repacking.f90 @@ -0,0 +1,30 @@ +! Check that the branch weights used by the array repacking +! are propagated all the way to LLVM IR: +! RUN: %flang_fc1 -frepack-arrays -emit-llvm %s -o - | FileCheck %s + +! CHECK-LABEL: define void @test_( +! CHECK-SAME: ptr [[TMP0:%.*]]) +! CHECK: [[TMP4:%.*]] = ptrtoint ptr [[TMP0]] to i64 +! CHECK: [[TMP5:%.*]] = icmp ne i64 [[TMP4]], 0 +! CHECK: br i1 [[TMP5]], label %[[BB6:.*]], label %[[BB46:.*]] +! CHECK: [[BB6]]: +! CHECK: [[TMP7:%.*]] = call i1 @_FortranAIsContiguous(ptr [[TMP0]]) +! CHECK: [[TMP8:%.*]] = icmp eq i1 [[TMP7]], false +! CHECK: [[TMP13:%.*]] = and i1 [[TMP8]], [[TMP12:.*]] +! CHECK: br i1 [[TMP13]], label %[[BB14:.*]], label %[[BB46]], !prof [[PROF2:![0-9]+]] +! CHECK: [[BB14]]: +! CHECK: call void @_FortranAShallowCopyDirect +! CHECK: br label %[[BB46]] +! CHECK: [[BB46]]: +! CHECK: br i1 [[TMP5]], label %[[BB48:.*]], label %[[BB57:.*]] +! CHECK: [[BB48]]: +! CHECK: br i1 [[TMP55:.*]], label %[[BB56:.*]], label %[[BB57]], !prof [[PROF2]] +! CHECK: [[BB56]]: +! CHECK: call void @_FortranAShallowCopyDirect +! CHECK: br label %[[BB57]] +! CHECK: [[BB57]]: +! CHECK: ret void +! CHECK: [[PROF2]] = !{!"branch_weights", i32 0, i32 1} +subroutine test(x) + real :: x(:) +end subroutine test diff --git a/external/llvm-project/flang/test/Lower/OpenMP/Todo/declare-mapper-iterator.f90 b/external/llvm-project/flang/test/Lower/OpenMP/Todo/declare-mapper-iterator.f90 new file mode 100644 index 000000000000..dacd6d624659 --- /dev/null +++ b/external/llvm-project/flang/test/Lower/OpenMP/Todo/declare-mapper-iterator.f90 @@ -0,0 +1,11 @@ +!RUN: %not_todo_cmd %flang_fc1 -emit-hlfir -fopenmp -fopenmp-version=52 -o - %s 2>&1 | FileCheck %s + +!CHECK: Support for iterator modifiers is not implemented yet +subroutine f(arg) + type :: s + integer :: a(10) + end type + type(s) :: arg(:) + + !$omp declare mapper(m: s :: v) map(mapper(m), iterator(i = 1:10): v%a(i)) +end diff --git a/external/llvm-project/flang/test/Lower/OpenMP/Todo/omp-clause-indirect.f90 b/external/llvm-project/flang/test/Lower/OpenMP/Todo/omp-clause-indirect.f90 new file mode 100644 index 000000000000..d441cac47f5d --- /dev/null +++ b/external/llvm-project/flang/test/Lower/OpenMP/Todo/omp-clause-indirect.f90 @@ -0,0 +1,34 @@ +! This test checks the lowering of OpenMP Indirect Clause when used with the Declare Target directive + +! RUN: not flang -fc1 -emit-fir -fopenmp -fopenmp-version=52 %s 2>&1 | FileCheck %s + +module functions + implicit none + + interface + function func() result(i) + character(1) :: i + end function + end interface + +contains + function func1() result(i) + !CHECK: not yet implemented: Unhandled clause INDIRECT in DECLARE TARGET construct + !$omp declare target enter(func1) indirect(.true.) + character(1) :: i + i = 'a' + return + end function +end module + +program main + use functions + implicit none + procedure (func), pointer :: ptr1=>func1 + character(1) :: val1 + + !$omp target map(from: val1) + val1 = ptr1() + !$omp end target + +end program diff --git a/external/llvm-project/flang/test/Lower/OpenMP/Todo/omp-doconcurrent.f90 b/external/llvm-project/flang/test/Lower/OpenMP/Todo/omp-doconcurrent.f90 deleted file mode 100644 index a6d70fa44592..000000000000 --- a/external/llvm-project/flang/test/Lower/OpenMP/Todo/omp-doconcurrent.f90 +++ /dev/null @@ -1,10 +0,0 @@ -! RUN: %not_todo_cmd bbc -emit-fir -fopenmp -o - %s 2>&1 | FileCheck %s -! RUN: %not_todo_cmd %flang_fc1 -emit-fir -fopenmp -o - %s 2>&1 | FileCheck %s - -! CHECK: not yet implemented: Do Concurrent in Worksharing loop construct -subroutine sb() - !$omp do - do concurrent(i=1:10) - print *, i - end do -end subroutine diff --git a/external/llvm-project/flang/test/Lower/OpenMP/Todo/target-parallel-private.f90 b/external/llvm-project/flang/test/Lower/OpenMP/Todo/target-parallel-private.f90 deleted file mode 100644 index e820143021f9..000000000000 --- a/external/llvm-project/flang/test/Lower/OpenMP/Todo/target-parallel-private.f90 +++ /dev/null @@ -1,13 +0,0 @@ -! RUN: %not_todo_cmd bbc -emit-fir -fopenmp -fopenmp-version=50 -o - %s 2>&1 | FileCheck %s -! RUN: %not_todo_cmd %flang_fc1 -emit-fir -fopenmp -fopenmp-version=50 -o - %s 2>&1 | FileCheck %s - -!=============================================================================== -! `private` clause on `target parallel` -!=============================================================================== - -! CHECK: not yet implemented: TARGET PARALLEL PRIVATE is not implemented yet -subroutine target_teams_private() -integer, dimension(3) :: i -!$omp target parallel private(i) -!$omp end target parallel -end subroutine diff --git a/external/llvm-project/flang/test/Lower/OpenMP/Todo/target-teams-private.f90 b/external/llvm-project/flang/test/Lower/OpenMP/Todo/target-teams-private.f90 deleted file mode 100644 index c8d998a5cbf9..000000000000 --- a/external/llvm-project/flang/test/Lower/OpenMP/Todo/target-teams-private.f90 +++ /dev/null @@ -1,13 +0,0 @@ -! RUN: %not_todo_cmd bbc -emit-fir -fopenmp -fopenmp-version=50 -o - %s 2>&1 | FileCheck %s -! RUN: %not_todo_cmd %flang_fc1 -emit-fir -fopenmp -fopenmp-version=50 -o - %s 2>&1 | FileCheck %s - -!=============================================================================== -! `private` clause on `target teams` -!=============================================================================== - -! CHECK: not yet implemented: TARGET TEAMS PRIVATE is not implemented yet -subroutine target_teams_private() -integer, dimension(3) :: i -!$omp target teams private(i) -!$omp end target teams -end subroutine diff --git a/external/llvm-project/flang/test/Lower/OpenMP/copyprivate5.f90 b/external/llvm-project/flang/test/Lower/OpenMP/copyprivate5.f90 new file mode 100644 index 000000000000..c75eb82a45e9 --- /dev/null +++ b/external/llvm-project/flang/test/Lower/OpenMP/copyprivate5.f90 @@ -0,0 +1,36 @@ +! Test lowering of COPYPRIVATE with character arguments +! RUN: %flang_fc1 -emit-hlfir -fopenmp -o - %s 2>&1 | FileCheck %s + +! Testcase from: https://github.com/llvm/llvm-project/issues/142123 + +! CHECK-LABEL: func.func private @_copy_boxchar_c8xU( +! CHECK-SAME: %arg0: [[TYPE:!fir.ref>]], +! CHECK-SAME: %arg1: [[TYPE]]) attributes {llvm.linkage = #llvm.linkage} { +! CHECK: %[[RDST:.*]] = fir.load %arg0 : [[TYPE]] +! CHECK: %[[RSRC:.*]] = fir.load %arg1 : [[TYPE]] +! CHECK: %[[UDST:.*]]:2 = fir.unboxchar %[[RDST:.*]] : ([[UTYPE:!fir.boxchar<1>]]) -> ([[RTYPE:!fir.ref>]], [[ITYPE:index]]) +! CHECK: %[[USRC:.*]]:2 = fir.unboxchar %[[RSRC:.*]] : ([[UTYPE]]) -> ([[RTYPE]], [[ITYPE]]) +! CHECK: %[[DST:.*]]:2 = hlfir.declare %[[UDST:.*]]#0 typeparams %[[UDST:.*]]#1 {uniq_name = "[[NAME1:.*]]"} : ([[RTYPE]], [[ITYPE]]) -> ([[UTYPE]], [[RTYPE]]) +! CHECK: %[[SRC:.*]]:2 = hlfir.declare %[[USRC:.*]]#0 typeparams %[[UDST:.*]]#1 {uniq_name = "[[NAME2:.*]]"} : ([[RTYPE]], [[ITYPE]]) -> ([[UTYPE]], [[RTYPE]]) +! CHECK: hlfir.assign %[[SRC:.*]]#0 to %[[DST:.*]]#0 : [[UTYPE]], [[UTYPE]] +! CHECK: return +! CHECK: } + +! CHECK-LABEL: func.func @_QPs(%arg0: !fir.boxchar<1> {fir.bindc_name = "c"}) { +! CHECK: %[[ALLOC:.*]] = fir.alloca !fir.boxchar<1> +! CHECK: fir.store %[[SRC:.*]] to %[[ALLOC:.*]] : !fir.ref> +! CHECK: omp.single copyprivate([[ALLOC:.*]] -> @_copy_boxchar_c8xU : !fir.ref>) { +! CHECK: hlfir.assign %[[NEW_VAL:.*]] to %[[SRC:.*]] : !fir.ref>, !fir.boxchar<1> +! CHECK: omp.terminator +! CHECK: } + +subroutine s(c) +character(*) :: c +!$omp single copyprivate(c) +c = "bar" +!$omp end single +end subroutine + +character(len=3) :: c +call s(c) +end diff --git a/external/llvm-project/flang/test/Lower/OpenMP/implicit-dsa.f90 b/external/llvm-project/flang/test/Lower/OpenMP/implicit-dsa.f90 index f0f149bb415b..0d2db63edfe7 100644 --- a/external/llvm-project/flang/test/Lower/OpenMP/implicit-dsa.f90 +++ b/external/llvm-project/flang/test/Lower/OpenMP/implicit-dsa.f90 @@ -5,6 +5,14 @@ ! Privatizers +! CHECK-LABEL: omp.private +! CHECK-SAME: {type = firstprivate} @[[TEST7_Y_FIRSTPRIV:.*]] : i32 +! CHECK-SAME: copy { + +! CHECK-LABEL: omp.private +! CHECK-SAME: {type = firstprivate} @[[TEST7_X_FIRSTPRIV:.*]] : i32 +! CHECK-SAME: copy { + ! CHECK-LABEL: omp.private ! CHECK-SAME: {type = private} @[[TEST6_Y_PRIV:.*]] : i32 ! CHECK-NOT: copy { @@ -277,22 +285,19 @@ subroutine implicit_dsa_test6 !$omp end task end subroutine -! Test taskgroup - it uses the same scope as task. +! Test taskgroup. !CHECK-LABEL: func @_QPimplicit_dsa_test7 !CHECK: %[[X:.*]] = fir.alloca i32 {bindc_name = "x", uniq_name = "_QFimplicit_dsa_test7Ex"} !CHECK: %[[X_DECL:.*]]:2 = hlfir.declare %[[X]] {uniq_name = "_QFimplicit_dsa_test7Ex"} : (!fir.ref) -> (!fir.ref, !fir.ref) !CHECK: %[[Y:.*]] = fir.alloca i32 {bindc_name = "y", uniq_name = "_QFimplicit_dsa_test7Ey"} !CHECK: %[[Y_DECL:.*]]:2 = hlfir.declare %[[Y]] {uniq_name = "_QFimplicit_dsa_test7Ey"} : (!fir.ref) -> (!fir.ref, !fir.ref) -!CHECK: omp.task { +!CHECK: omp.task private(@[[TEST7_X_FIRSTPRIV]] %[[X_DECL]]#0 -> %[[PRIV_X:[^,]*]], +!CHECK-SAME: @[[TEST7_Y_FIRSTPRIV]] %[[Y_DECL]]#0 -> %[[PRIV_Y:.*]] : !fir.ref, !fir.ref) { +!CHECK: %[[PRIV_X_DECL:.*]]:2 = hlfir.declare %[[PRIV_X]] {uniq_name = "_QFimplicit_dsa_test7Ex"} +!CHECK: %[[PRIV_Y_DECL:.*]]:2 = hlfir.declare %[[PRIV_Y]] {uniq_name = "_QFimplicit_dsa_test7Ey"} !CHECK: omp.taskgroup { -!CHECK-NEXT: %[[PRIV_X:.*]] = fir.alloca i32 {bindc_name = "x", pinned, uniq_name = "_QFimplicit_dsa_test7Ex"} -!CHECK-NEXT: %[[PRIV_X_DECL:.*]]:2 = hlfir.declare %[[PRIV_X]] {uniq_name = "_QFimplicit_dsa_test7Ex"} : (!fir.ref) -> (!fir.ref, !fir.ref) -!CHECK-NEXT: %[[TEMP:.*]] = fir.load %[[X_DECL]]#0 : !fir.ref +!CHECK-NEXT: %[[TEMP:.*]] = fir.load %[[PRIV_Y_DECL]]#0 : !fir.ref !CHECK-NEXT: hlfir.assign %[[TEMP]] to %[[PRIV_X_DECL]]#0 : i32, !fir.ref -!CHECK-NEXT: %[[PRIV_Y:.*]] = fir.alloca i32 {bindc_name = "y", pinned, uniq_name = "_QFimplicit_dsa_test7Ey"} -!CHECK-NEXT: %[[PRIV_Y_DECL:.*]]:2 = hlfir.declare %[[PRIV_Y]] {uniq_name = "_QFimplicit_dsa_test7Ey"} : (!fir.ref) -> (!fir.ref, !fir.ref) -!CHECK-NEXT: %[[TEMP2:.*]] = fir.load %[[Y_DECL]]#0 : !fir.ref -!CHECK-NEXT: hlfir.assign %[[TEMP2]] to %[[PRIV_Y_DECL]]#0 : i32, !fir.ref !CHECK: } !CHECK: } subroutine implicit_dsa_test7 diff --git a/external/llvm-project/flang/test/Lower/OpenMP/multiple-entry-points.f90 b/external/llvm-project/flang/test/Lower/OpenMP/multiple-entry-points.f90 new file mode 100644 index 000000000000..2b8caa79eaa1 --- /dev/null +++ b/external/llvm-project/flang/test/Lower/OpenMP/multiple-entry-points.f90 @@ -0,0 +1,46 @@ +!RUN: %flang_fc1 -emit-hlfir -fopenmp %s -o - | FileCheck %s + +! Check the first entry point +!CHECK: func.func @_QPprocess_a +!CHECK: omp.parallel +!CHECK: omp.wsloop +!CHECK: %[[V0:[0-9]+]] = fir.load %{{[0-9]+}} : !fir.ref +!CHECK: %[[V1:[a-z_0-9]+]] = arith.constant 2.000000e+00 : f32 +!CHECK: = arith.mulf %[[V0]], %[[V1]] fastmath : f32 +!CHECK: omp.terminator +!CHECK-NOT: omp +!CHECK: return + +! Check the second entry point +!CHECK: func.func @_QPprocess_b +!CHECK: omp.parallel +!CHECK: fir.do_loop +!CHECK: %[[V3:[0-9]+]] = fir.load %[[V2:[0-9]+]]#0 : !fir.ref +!CHECK: %[[V4:[0-9]+]] = fir.load %[[V2]]#0 : !fir.ref +!CHECK: = arith.muli %[[V3]], %[[V4]] : i32 +!CHECK: omp.terminator +!CHECK-NOT: omp +!CHECK: return + +subroutine process_a(n, a) + integer, intent(in) :: n + real, intent(inout) :: a(n) + integer :: i + + !$omp parallel do + do i = 1, n + a(i) = a(i) * 2.0 + end do + !$omp end parallel do + + return + + entry process_b(n, b) + + !$omp parallel + do i = 1, n + a(i) = i * i + end do + !$omp end parallel + +end subroutine process_a diff --git a/external/llvm-project/flang/test/Lower/OpenMP/requires-admo-acqrel.f90 b/external/llvm-project/flang/test/Lower/OpenMP/requires-admo-acqrel.f90 new file mode 100644 index 000000000000..525a846f410d --- /dev/null +++ b/external/llvm-project/flang/test/Lower/OpenMP/requires-admo-acqrel.f90 @@ -0,0 +1,19 @@ +!RUN: %flang_fc1 -emit-hlfir -fopenmp -fopenmp-version=52 %s -o - | FileCheck %s + +module m +!$omp requires atomic_default_mem_order(acq_rel) + +contains + +subroutine f00(x, v) + integer :: x, v +!CHECK: omp.atomic.read %{{[ %#=0-9]+}} memory_order(acquire) + !$omp atomic read + v = x + +!CHECK: omp.atomic.write %{{[ %#=0-9]+}} memory_order(release) + !$omp atomic write + x = v +end + +end module diff --git a/external/llvm-project/flang/test/Lower/OpenMP/requires-admo-invalid1.f90 b/external/llvm-project/flang/test/Lower/OpenMP/requires-admo-invalid1.f90 new file mode 100644 index 000000000000..b21d3bbbc786 --- /dev/null +++ b/external/llvm-project/flang/test/Lower/OpenMP/requires-admo-invalid1.f90 @@ -0,0 +1,16 @@ +!RUN: %flang_fc1 -emit-hlfir -fopenmp -fopenmp-version=52 %s -o - | FileCheck %s + +module m +!$omp requires atomic_default_mem_order(acquire) + +contains + +subroutine f00(x, v) + integer :: x, v +!CHECK: omp.atomic.write %{{[ %#=0-9]+}} memory_order(relaxed) + !$omp atomic write + x = v +end + +end module + diff --git a/external/llvm-project/flang/test/Lower/OpenMP/requires-admo-invalid2.f90 b/external/llvm-project/flang/test/Lower/OpenMP/requires-admo-invalid2.f90 new file mode 100644 index 000000000000..33caa25dcc64 --- /dev/null +++ b/external/llvm-project/flang/test/Lower/OpenMP/requires-admo-invalid2.f90 @@ -0,0 +1,16 @@ +!RUN: %flang_fc1 -emit-hlfir -fopenmp -fopenmp-version=52 %s -o - | FileCheck %s + +module m +!$omp requires atomic_default_mem_order(release) + +contains + +subroutine f00(x, v) + integer :: x, v +!CHECK: omp.atomic.read {{[ %#=0-9]+}} memory_order(relaxed) + !$omp atomic read + v = x +end + +end module + diff --git a/external/llvm-project/flang/test/Lower/OpenMP/target-enter-data-default-openmp52.f90 b/external/llvm-project/flang/test/Lower/OpenMP/target-enter-data-default-openmp52.f90 new file mode 100644 index 000000000000..d5311d7f1a6d --- /dev/null +++ b/external/llvm-project/flang/test/Lower/OpenMP/target-enter-data-default-openmp52.f90 @@ -0,0 +1,27 @@ +! This test checks the lowering and application of default map types for the target enter/exit data constructs and map clauses +! XFAIL: * +!RUN: %flang -fc1 -emit-fir -fopenmp -fopenmp-version=52 -o - %s | FileCheck %s --check-prefix=CHECK-52 +!RUN: not %flang -fc1 -emit-fir -fopenmp -fopenmp-version=51 -o - %s 2>&1| FileCheck %s --check-prefix=CHECK-51 + +module test + real, allocatable :: A + +contains + subroutine initialize() + allocate(A) + !$omp target enter data map(A) + !CHECK-52: omp.map.info var_ptr(%2 : !fir.ref>>, f32) map_clauses(to) capture(ByRef) var_ptr_ptr(%5 : !fir.llvm_ptr>) -> !fir.llvm_ptr> {name = ""} + !CHECK-52: omp.map.info var_ptr(%2 : !fir.ref>>, !fir.box>) map_clauses(to) capture(ByRef) members(%6 : [0] : !fir.llvm_ptr>) -> !fir.ref>> {name = "a"} + !CHECK-51: to and alloc map types are permitted + + end subroutine initialize + + subroutine finalize() + !$omp target exit data map(A) + !CHECK-52: omp.map.info var_ptr(%2 : !fir.ref>>, f32) map_clauses(from) capture(ByRef) var_ptr_ptr(%3 : !fir.llvm_ptr>) -> !fir.llvm_ptr> {name = ""} + !CHECK-52: omp.map.info var_ptr(%2 : !fir.ref>>, !fir.box>) map_clauses(from) capture(ByRef) members(%4 : [0] : !fir.llvm_ptr>) -> !fir.ref>> {name = "a"} + !CHECK-51: from, release and delete map types are permitted + deallocate(A) + + end subroutine finalize +end module test diff --git a/external/llvm-project/flang/test/Lower/OpenMP/target-parallel-private.f90 b/external/llvm-project/flang/test/Lower/OpenMP/target-parallel-private.f90 new file mode 100644 index 000000000000..cc04b77e4a52 --- /dev/null +++ b/external/llvm-project/flang/test/Lower/OpenMP/target-parallel-private.f90 @@ -0,0 +1,21 @@ +! RUN: %flang_fc1 -emit-hlfir -fopenmp -mmlir --enable-delayed-privatization \ +! RUN: -o - %s 2>&1 | FileCheck %s +! RUN: bbc -emit-hlfir -fopenmp --enable-delayed-privatization -o - %s 2>&1 |\ +! RUN: FileCheck %s + +!=============================================================================== +! `private` clause on `target parallel` +!=============================================================================== + +subroutine target_parallel_private() +integer, dimension(3) :: i +!$omp target parallel private(i) +!$omp end target parallel +end subroutine + +! CHECK: omp.private {type = private} @[[PRIVATIZER:.*]] : {{.*}} + +! CHECK: omp.target {{.*}} { +! CHECK: omp.parallel private(@[[PRIVATIZER]] %{{.*}} -> %{{.*}} : {{.*}}) { +! CHECK: } +! CHECK: } diff --git a/external/llvm-project/flang/test/Lower/OpenMP/target-teams-private.f90 b/external/llvm-project/flang/test/Lower/OpenMP/target-teams-private.f90 new file mode 100644 index 000000000000..65d97649b5cf --- /dev/null +++ b/external/llvm-project/flang/test/Lower/OpenMP/target-teams-private.f90 @@ -0,0 +1,20 @@ +! RUN: %flang_fc1 -emit-hlfir -fopenmp -mmlir --enable-delayed-privatization \ +! RUN: -o - %s 2>&1 | FileCheck %s +! RUN: bbc -emit-hlfir -fopenmp --enable-delayed-privatization -o - %s 2>&1 |\ +! RUN: FileCheck %s + +!=============================================================================== +! `private` clause on `target teams` +!=============================================================================== + +subroutine target_teams_private() +integer, dimension(3) :: i +!$omp target teams private(i) +!$omp end target teams +end subroutine + +! CHECK: omp.target {{.*}} { +! CHECK: omp.teams { +! CHECK: %{{.*}} = fir.alloca !fir.array<3xi32> {bindc_name = "i", {{.*}}} +! CHECK: } +! CHECK: } diff --git a/external/llvm-project/flang/test/Lower/OpenMP/taskgroup02.f90 b/external/llvm-project/flang/test/Lower/OpenMP/taskgroup02.f90 new file mode 100644 index 000000000000..1e996a030c23 --- /dev/null +++ b/external/llvm-project/flang/test/Lower/OpenMP/taskgroup02.f90 @@ -0,0 +1,32 @@ +! RUN: %flang_fc1 -emit-hlfir -fopenmp -o - %s 2>&1 | FileCheck %s + +! Check that variables are not privatized twice when TASKGROUP is used. + +!CHECK-LABEL: func.func @_QPsub() { +!CHECK: omp.parallel { +!CHECK: %[[PAR_I:.*]]:2 = hlfir.declare %{{.*}} {uniq_name = "_QFsubEi"} +!CHECK: omp.master { +!CHECK: omp.taskgroup { +!CHECK-NEXT: omp.task private(@_QFsubEi_firstprivate_i32 %[[PAR_I]]#0 -> %[[TASK_I:.*]] : !fir.ref) { +!CHECK: %[[TASK_I_DECL:.*]]:2 = hlfir.declare %[[TASK_I]] {uniq_name = "_QFsubEi"} +!CHECK: } +!CHECK: } +!CHECK: } +!CHECK: } + +subroutine sub() + integer, dimension(10) :: a + integer :: i + + !$omp parallel + !$omp master + do i=1,10 + !$omp taskgroup + !$omp task shared(a) + a(i) = 1 + !$omp end task + !$omp end taskgroup + end do + !$omp end master + !$omp end parallel +end subroutine diff --git a/external/llvm-project/flang/test/Lower/volatile-openmp.f90 b/external/llvm-project/flang/test/Lower/volatile-openmp.f90 index 4b2d9e1b552b..489ba95c3cee 100644 --- a/external/llvm-project/flang/test/Lower/volatile-openmp.f90 +++ b/external/llvm-project/flang/test/Lower/volatile-openmp.f90 @@ -23,11 +23,11 @@ ! CHECK: %[[VAL_11:.*]] = fir.address_of(@_QFEcontainer) : !fir.ref>>}>> ! CHECK: %[[VAL_12:.*]] = fir.volatile_cast %[[VAL_11]] : (!fir.ref>>}>>) -> !fir.ref>>}>, volatile> ! CHECK: %[[VAL_13:.*]]:2 = hlfir.declare %[[VAL_12]] {fortran_attrs = #fir.var_attrs, uniq_name = "_QFEcontainer"} : (!fir.ref>>}>, volatile>) -> (!fir.ref>>}>, volatile>, !fir.ref>>}>, volatile>) -! CHECK: %[[VAL_14:.*]] = fir.address_of(@_QFE.c.t) : !fir.ref>>,genre:i8,category:i8,kind:i8,rank:i8,__padding0:!fir.array<4xi8>,offset:i64,characterlen:!fir.type<_QM__fortran_type_infoTvalue{{[<]?}}{genre:i8,__padding0:!fir.array<7xi8>,value:i64}{{[>]?}}>,derived:!fir.box,name:!fir.box>>}>>>>,name:!fir.box>>,sizeinbytes:i64,uninstantiated:!fir.box>>,kindparameter:!fir.box>>,lenparameterkind:!fir.box>>,component:!fir.box>>>,procptr:!fir.box>>,offset:i64,initialization:!fir.type<_QM__fortran_builtinsT__builtin_c_funptr{__address:i64}>}>>>>,special:!fir.box,proc:!fir.type<_QM__fortran_builtinsT__builtin_c_funptr{__address:i64}>}{{[>]?}}>>>>,specialbitset:i32,hasparent:i8,noinitializationneeded:i8,nodestructionneeded:i8,nofinalizationneeded:i8,__padding0:!fir.array<4xi8>}>>>,lenvalue:!fir.box,value:i64}{{[>]?}}>>>>,bounds:!fir.box,value:i64}{{[>]?}}>>>>,initialization:!fir.type<_QM__fortran_builtinsT__builtin_c_ptr{__address:i64}>}>>> +! CHECK: %[[VAL_14:.*]] = fir.address_of(@_QFE.c.t) : !fir.ref>>,genre:i8,category:i8,kind:i8,rank:i8,__padding0:!fir.array<4xi8>,offset:i64,characterlen:!fir.type<_QM__fortran_type_infoTvalue{{[<]?}}{genre:i8,__padding0:!fir.array<7xi8>,value:i64}{{[>]?}}>,derived:!fir.box,name:!fir.box>>}>>>>,name:!fir.box>>,sizeinbytes:i64,uninstantiated:!fir.box>>,kindparameter:!fir.box>>,lenparameterkind:!fir.box>>,component:!fir.box>>>,procptr:!fir.box>>,offset:i64,initialization:!fir.type<_QM__fortran_builtinsT__builtin_c_funptr{__address:i64}>}>>>>,special:!fir.box,proc:!fir.type<_QM__fortran_builtinsT__builtin_c_funptr{__address:i64}>}{{[>]?}}>>>>,specialbitset:i32,hasparent:i8,noinitializationneeded:i8,nodestructionneeded:i8,nofinalizationneeded:i8,nodefinedassignment:i8,__padding0:!fir.array<3xi8>}>>>,lenvalue:!fir.box,value:i64}{{[>]?}}>>>>,bounds:!fir.box,value:i64}{{[>]?}}>>>>,initialization:!fir.type<_QM__fortran_builtinsT__builtin_c_ptr{__address:i64}>}>>> ! CHECK: %[[VAL_15:.*]] = fir.shape_shift %[[VAL_0]], %[[VAL_1]] : (index, index) -> !fir.shapeshift<1> -! CHECK: %[[VAL_16:.*]]:2 = hlfir.declare %[[VAL_14]](%[[VAL_15]]) {fortran_attrs = #fir.var_attrs, uniq_name = "_QFE.c.t"} : (!fir.ref>>,genre:i8,category:i8,kind:i8,rank:i8,__padding0:!fir.array<4xi8>,offset:i64,characterlen:!fir.type<_QM__fortran_type_infoTvalue{{[<]?}}{genre:i8,__padding0:!fir.array<7xi8>,value:i64}{{[>]?}}>,derived:!fir.box,name:!fir.box>>}>>>>,name:!fir.box>>,sizeinbytes:i64,uninstantiated:!fir.box>>,kindparameter:!fir.box>>,lenparameterkind:!fir.box>>,component:!fir.box>>>,procptr:!fir.box>>,offset:i64,initialization:!fir.type<_QM__fortran_builtinsT__builtin_c_funptr{__address:i64}>}>>>>,special:!fir.box,proc:!fir.type<_QM__fortran_builtinsT__builtin_c_funptr{__address:i64}>}{{[>]?}}>>>>,specialbitset:i32,hasparent:i8,noinitializationneeded:i8,nodestructionneeded:i8,nofinalizationneeded:i8,__padding0:!fir.array<4xi8>}>>>,lenvalue:!fir.box,value:i64}{{[>]?}}>>>>,bounds:!fir.box,value:i64}{{[>]?}}>>>>,initialization:!fir.type<_QM__fortran_builtinsT__builtin_c_ptr{__address:i64}>}>>>, !fir.shapeshift<1>) -> (!fir.box>>,genre:i8,category:i8,kind:i8,rank:i8,__padding0:!fir.array<4xi8>,offset:i64,characterlen:!fir.type<_QM__fortran_type_infoTvalue{{[<]?}}{genre:i8,__padding0:!fir.array<7xi8>,value:i64}{{[>]?}}>,derived:!fir.box,name:!fir.box>>}>>>>,name:!fir.box>>,sizeinbytes:i64,uninstantiated:!fir.box>>,kindparameter:!fir.box>>,lenparameterkind:!fir.box>>,component:!fir.box>>>,procptr:!fir.box>>,offset:i64,initialization:!fir.type<_QM__fortran_builtinsT__builtin_c_funptr{__address:i64}>}>>>>,special:!fir.box,proc:!fir.type<_QM__fortran_builtinsT__builtin_c_funptr{__address:i64}>}{{[>]?}}>>>>,specialbitset:i32,hasparent:i8,noinitializationneeded:i8,nodestructionneeded:i8,nofinalizationneeded:i8,__padding0:!fir.array<4xi8>}>>>,lenvalue:!fir.box,value:i64}{{[>]?}}>>>>,bounds:!fir.box,value:i64}{{[>]?}}>>>>,initialization:!fir.type<_QM__fortran_builtinsT__builtin_c_ptr{__address:i64}>}>>>, !fir.ref>>,genre:i8,category:i8,kind:i8,rank:i8,__padding0:!fir.array<4xi8>,offset:i64,characterlen:!fir.type<_QM__fortran_type_infoTvalue{{[<]?}}{genre:i8,__padding0:!fir.array<7xi8>,value:i64}{{[>]?}}>,derived:!fir.box,name:!fir.box>>}>>>>,name:!fir.box>>,sizeinbytes:i64,uninstantiated:!fir.box>>,kindparameter:!fir.box>>,lenparameterkind:!fir.box>>,component:!fir.box>>>,procptr:!fir.box>>,offset:i64,initialization:!fir.type<_QM__fortran_builtinsT__builtin_c_funptr{__address:i64}>}>>>>,special:!fir.box,proc:!fir.type<_QM__fortran_builtinsT__builtin_c_funptr{__address:i64}>}{{[>]?}}>>>>,specialbitset:i32,hasparent:i8,noinitializationneeded:i8,nodestructionneeded:i8,nofinalizationneeded:i8,__padding0:!fir.array<4xi8>}>>>,lenvalue:!fir.box,value:i64}{{[>]?}}>>>>,bounds:!fir.box,value:i64}{{[>]?}}>>>>,initialization:!fir.type<_QM__fortran_builtinsT__builtin_c_ptr{__address:i64}>}>>>) -! CHECK: %[[VAL_17:.*]] = fir.address_of(@_QFE.dt.t) : !fir.ref,name:!fir.box>>}>>>>,name:!fir.box>>,sizeinbytes:i64,uninstantiated:!fir.box>>,kindparameter:!fir.box>>,lenparameterkind:!fir.box>>,component:!fir.box>>,genre:i8,category:i8,kind:i8,rank:i8,__padding0:!fir.array<4xi8>,offset:i64,characterlen:!fir.type<_QM__fortran_type_infoTvalue{{[<]?}}{genre:i8,__padding0:!fir.array<7xi8>,value:i64}{{[>]?}}>,derived:!fir.box>>,lenvalue:!fir.box,value:i64}{{[>]?}}>>>>,bounds:!fir.box,value:i64}{{[>]?}}>>>>,initialization:!fir.type<_QM__fortran_builtinsT__builtin_c_ptr{__address:i64}>}>>>>,procptr:!fir.box>>,offset:i64,initialization:!fir.type<_QM__fortran_builtinsT__builtin_c_funptr{__address:i64}>}>>>>,special:!fir.box,proc:!fir.type<_QM__fortran_builtinsT__builtin_c_funptr{__address:i64}>}{{[>]?}}>>>>,specialbitset:i32,hasparent:i8,noinitializationneeded:i8,nodestructionneeded:i8,nofinalizationneeded:i8,__padding0:!fir.array<4xi8>}>> -! CHECK: %[[VAL_18:.*]]:2 = hlfir.declare %[[VAL_17]] {fortran_attrs = #fir.var_attrs, uniq_name = "_QFE.dt.t"} : (!fir.ref,name:!fir.box>>}>>>>,name:!fir.box>>,sizeinbytes:i64,uninstantiated:!fir.box>>,kindparameter:!fir.box>>,lenparameterkind:!fir.box>>,component:!fir.box>>,genre:i8,category:i8,kind:i8,rank:i8,__padding0:!fir.array<4xi8>,offset:i64,characterlen:!fir.type<_QM__fortran_type_infoTvalue{{[<]?}}{genre:i8,__padding0:!fir.array<7xi8>,value:i64}{{[>]?}}>,derived:!fir.box>>,lenvalue:!fir.box,value:i64}{{[>]?}}>>>>,bounds:!fir.box,value:i64}{{[>]?}}>>>>,initialization:!fir.type<_QM__fortran_builtinsT__builtin_c_ptr{__address:i64}>}>>>>,procptr:!fir.box>>,offset:i64,initialization:!fir.type<_QM__fortran_builtinsT__builtin_c_funptr{__address:i64}>}>>>>,special:!fir.box,proc:!fir.type<_QM__fortran_builtinsT__builtin_c_funptr{__address:i64}>}{{[>]?}}>>>>,specialbitset:i32,hasparent:i8,noinitializationneeded:i8,nodestructionneeded:i8,nofinalizationneeded:i8,__padding0:!fir.array<4xi8>}>>) -> (!fir.ref,name:!fir.box>>}>>>>,name:!fir.box>>,sizeinbytes:i64,uninstantiated:!fir.box>>,kindparameter:!fir.box>>,lenparameterkind:!fir.box>>,component:!fir.box>>,genre:i8,category:i8,kind:i8,rank:i8,__padding0:!fir.array<4xi8>,offset:i64,characterlen:!fir.type<_QM__fortran_type_infoTvalue{{[<]?}}{genre:i8,__padding0:!fir.array<7xi8>,value:i64}{{[>]?}}>,derived:!fir.box>>,lenvalue:!fir.box,value:i64}{{[>]?}}>>>>,bounds:!fir.box,value:i64}{{[>]?}}>>>>,initialization:!fir.type<_QM__fortran_builtinsT__builtin_c_ptr{__address:i64}>}>>>>,procptr:!fir.box>>,offset:i64,initialization:!fir.type<_QM__fortran_builtinsT__builtin_c_funptr{__address:i64}>}>>>>,special:!fir.box,proc:!fir.type<_QM__fortran_builtinsT__builtin_c_funptr{__address:i64}>}{{[>]?}}>>>>,specialbitset:i32,hasparent:i8,noinitializationneeded:i8,nodestructionneeded:i8,nofinalizationneeded:i8,__padding0:!fir.array<4xi8>}>>, !fir.ref,name:!fir.box>>}>>>>,name:!fir.box>>,sizeinbytes:i64,uninstantiated:!fir.box>>,kindparameter:!fir.box>>,lenparameterkind:!fir.box>>,component:!fir.box>>,genre:i8,category:i8,kind:i8,rank:i8,__padding0:!fir.array<4xi8>,offset:i64,characterlen:!fir.type<_QM__fortran_type_infoTvalue{{[<]?}}{genre:i8,__padding0:!fir.array<7xi8>,value:i64}{{[>]?}}>,derived:!fir.box>>,lenvalue:!fir.box,value:i64}{{[>]?}}>>>>,bounds:!fir.box,value:i64}{{[>]?}}>>>>,initialization:!fir.type<_QM__fortran_builtinsT__builtin_c_ptr{__address:i64}>}>>>>,procptr:!fir.box>>,offset:i64,initialization:!fir.type<_QM__fortran_builtinsT__builtin_c_funptr{__address:i64}>}>>>>,special:!fir.box,proc:!fir.type<_QM__fortran_builtinsT__builtin_c_funptr{__address:i64}>}{{[>]?}}>>>>,specialbitset:i32,hasparent:i8,noinitializationneeded:i8,nodestructionneeded:i8,nofinalizationneeded:i8,__padding0:!fir.array<4xi8>}>>) +! CHECK: %[[VAL_16:.*]]:2 = hlfir.declare %[[VAL_14]](%[[VAL_15]]) {fortran_attrs = #fir.var_attrs, uniq_name = "_QFE.c.t"} : (!fir.ref>>,genre:i8,category:i8,kind:i8,rank:i8,__padding0:!fir.array<4xi8>,offset:i64,characterlen:!fir.type<_QM__fortran_type_infoTvalue{{[<]?}}{genre:i8,__padding0:!fir.array<7xi8>,value:i64}{{[>]?}}>,derived:!fir.box,name:!fir.box>>}>>>>,name:!fir.box>>,sizeinbytes:i64,uninstantiated:!fir.box>>,kindparameter:!fir.box>>,lenparameterkind:!fir.box>>,component:!fir.box>>>,procptr:!fir.box>>,offset:i64,initialization:!fir.type<_QM__fortran_builtinsT__builtin_c_funptr{__address:i64}>}>>>>,special:!fir.box,proc:!fir.type<_QM__fortran_builtinsT__builtin_c_funptr{__address:i64}>}{{[>]?}}>>>>,specialbitset:i32,hasparent:i8,noinitializationneeded:i8,nodestructionneeded:i8,nofinalizationneeded:i8,nodefinedassignment:i8,__padding0:!fir.array<3xi8>}>>>,lenvalue:!fir.box,value:i64}{{[>]?}}>>>>,bounds:!fir.box,value:i64}{{[>]?}}>>>>,initialization:!fir.type<_QM__fortran_builtinsT__builtin_c_ptr{__address:i64}>}>>>, !fir.shapeshift<1>) -> (!fir.box>>,genre:i8,category:i8,kind:i8,rank:i8,__padding0:!fir.array<4xi8>,offset:i64,characterlen:!fir.type<_QM__fortran_type_infoTvalue{{[<]?}}{genre:i8,__padding0:!fir.array<7xi8>,value:i64}{{[>]?}}>,derived:!fir.box,name:!fir.box>>}>>>>,name:!fir.box>>,sizeinbytes:i64,uninstantiated:!fir.box>>,kindparameter:!fir.box>>,lenparameterkind:!fir.box>>,component:!fir.box>>>,procptr:!fir.box>>,offset:i64,initialization:!fir.type<_QM__fortran_builtinsT__builtin_c_funptr{__address:i64}>}>>>>,special:!fir.box,proc:!fir.type<_QM__fortran_builtinsT__builtin_c_funptr{__address:i64}>}{{[>]?}}>>>>,specialbitset:i32,hasparent:i8,noinitializationneeded:i8,nodestructionneeded:i8,nofinalizationneeded:i8,nodefinedassignment:i8,__padding0:!fir.array<3xi8>}>>>,lenvalue:!fir.box,value:i64}{{[>]?}}>>>>,bounds:!fir.box,value:i64}{{[>]?}}>>>>,initialization:!fir.type<_QM__fortran_builtinsT__builtin_c_ptr{__address:i64}>}>>>, !fir.ref>>,genre:i8,category:i8,kind:i8,rank:i8,__padding0:!fir.array<4xi8>,offset:i64,characterlen:!fir.type<_QM__fortran_type_infoTvalue{{[<]?}}{genre:i8,__padding0:!fir.array<7xi8>,value:i64}{{[>]?}}>,derived:!fir.box,name:!fir.box>>}>>>>,name:!fir.box>>,sizeinbytes:i64,uninstantiated:!fir.box>>,kindparameter:!fir.box>>,lenparameterkind:!fir.box>>,component:!fir.box>>>,procptr:!fir.box>>,offset:i64,initialization:!fir.type<_QM__fortran_builtinsT__builtin_c_funptr{__address:i64}>}>>>>,special:!fir.box,proc:!fir.type<_QM__fortran_builtinsT__builtin_c_funptr{__address:i64}>}{{[>]?}}>>>>,specialbitset:i32,hasparent:i8,noinitializationneeded:i8,nodestructionneeded:i8,nofinalizationneeded:i8,nodefinedassignment:i8,__padding0:!fir.array<3xi8>}>>>,lenvalue:!fir.box,value:i64}{{[>]?}}>>>>,bounds:!fir.box,value:i64}{{[>]?}}>>>>,initialization:!fir.type<_QM__fortran_builtinsT__builtin_c_ptr{__address:i64}>}>>>) +! CHECK: %[[VAL_17:.*]] = fir.address_of(@_QFE.dt.t) : !fir.ref,name:!fir.box>>}>>>>,name:!fir.box>>,sizeinbytes:i64,uninstantiated:!fir.box>>,kindparameter:!fir.box>>,lenparameterkind:!fir.box>>,component:!fir.box>>,genre:i8,category:i8,kind:i8,rank:i8,__padding0:!fir.array<4xi8>,offset:i64,characterlen:!fir.type<_QM__fortran_type_infoTvalue{{[<]?}}{genre:i8,__padding0:!fir.array<7xi8>,value:i64}{{[>]?}}>,derived:!fir.box>>,lenvalue:!fir.box,value:i64}{{[>]?}}>>>>,bounds:!fir.box,value:i64}{{[>]?}}>>>>,initialization:!fir.type<_QM__fortran_builtinsT__builtin_c_ptr{__address:i64}>}>>>>,procptr:!fir.box>>,offset:i64,initialization:!fir.type<_QM__fortran_builtinsT__builtin_c_funptr{__address:i64}>}>>>>,special:!fir.box,proc:!fir.type<_QM__fortran_builtinsT__builtin_c_funptr{__address:i64}>}{{[>]?}}>>>>,specialbitset:i32,hasparent:i8,noinitializationneeded:i8,nodestructionneeded:i8,nofinalizationneeded:i8,nodefinedassignment:i8,__padding0:!fir.array<3xi8>}>> +! CHECK: %[[VAL_18:.*]]:2 = hlfir.declare %[[VAL_17]] {fortran_attrs = #fir.var_attrs, uniq_name = "_QFE.dt.t"} : (!fir.ref,name:!fir.box>>}>>>>,name:!fir.box>>,sizeinbytes:i64,uninstantiated:!fir.box>>,kindparameter:!fir.box>>,lenparameterkind:!fir.box>>,component:!fir.box>>,genre:i8,category:i8,kind:i8,rank:i8,__padding0:!fir.array<4xi8>,offset:i64,characterlen:!fir.type<_QM__fortran_type_infoTvalue{{[<]?}}{genre:i8,__padding0:!fir.array<7xi8>,value:i64}{{[>]?}}>,derived:!fir.box>>,lenvalue:!fir.box,value:i64}{{[>]?}}>>>>,bounds:!fir.box,value:i64}{{[>]?}}>>>>,initialization:!fir.type<_QM__fortran_builtinsT__builtin_c_ptr{__address:i64}>}>>>>,procptr:!fir.box>>,offset:i64,initialization:!fir.type<_QM__fortran_builtinsT__builtin_c_funptr{__address:i64}>}>>>>,special:!fir.box,proc:!fir.type<_QM__fortran_builtinsT__builtin_c_funptr{__address:i64}>}{{[>]?}}>>>>,specialbitset:i32,hasparent:i8,noinitializationneeded:i8,nodestructionneeded:i8,nofinalizationneeded:i8,nodefinedassignment:i8,__padding0:!fir.array<3xi8>}>>) -> (!fir.ref,name:!fir.box>>}>>>>,name:!fir.box>>,sizeinbytes:i64,uninstantiated:!fir.box>>,kindparameter:!fir.box>>,lenparameterkind:!fir.box>>,component:!fir.box>>,genre:i8,category:i8,kind:i8,rank:i8,__padding0:!fir.array<4xi8>,offset:i64,characterlen:!fir.type<_QM__fortran_type_infoTvalue{{[<]?}}{genre:i8,__padding0:!fir.array<7xi8>,value:i64}{{[>]?}}>,derived:!fir.box>>,lenvalue:!fir.box,value:i64}{{[>]?}}>>>>,bounds:!fir.box,value:i64}{{[>]?}}>>>>,initialization:!fir.type<_QM__fortran_builtinsT__builtin_c_ptr{__address:i64}>}>>>>,procptr:!fir.box>>,offset:i64,initialization:!fir.type<_QM__fortran_builtinsT__builtin_c_funptr{__address:i64}>}>>>>,special:!fir.box,proc:!fir.type<_QM__fortran_builtinsT__builtin_c_funptr{__address:i64}>}{{[>]?}}>>>>,specialbitset:i32,hasparent:i8,noinitializationneeded:i8,nodestructionneeded:i8,nofinalizationneeded:i8,nodefinedassignment:i8,__padding0:!fir.array<3xi8>}>>, !fir.ref,name:!fir.box>>}>>>>,name:!fir.box>>,sizeinbytes:i64,uninstantiated:!fir.box>>,kindparameter:!fir.box>>,lenparameterkind:!fir.box>>,component:!fir.box>>,genre:i8,category:i8,kind:i8,rank:i8,__padding0:!fir.array<4xi8>,offset:i64,characterlen:!fir.type<_QM__fortran_type_infoTvalue{{[<]?}}{genre:i8,__padding0:!fir.array<7xi8>,value:i64}{{[>]?}}>,derived:!fir.box>>,lenvalue:!fir.box,value:i64}{{[>]?}}>>>>,bounds:!fir.box,value:i64}{{[>]?}}>>>>,initialization:!fir.type<_QM__fortran_builtinsT__builtin_c_ptr{__address:i64}>}>>>>,procptr:!fir.box>>,offset:i64,initialization:!fir.type<_QM__fortran_builtinsT__builtin_c_funptr{__address:i64}>}>>>>,special:!fir.box,proc:!fir.type<_QM__fortran_builtinsT__builtin_c_funptr{__address:i64}>}{{[>]?}}>>>>,specialbitset:i32,hasparent:i8,noinitializationneeded:i8,nodestructionneeded:i8,nofinalizationneeded:i8,nodefinedassignment:i8,__padding0:!fir.array<3xi8>}>>) ! CHECK: %[[VAL_19:.*]] = hlfir.designate %[[VAL_13]]#0{"array"} {fortran_attrs = #fir.var_attrs} : (!fir.ref>>}>, volatile>) -> !fir.ref>>, volatile> ! CHECK: %[[VAL_20:.*]] = fir.load %[[VAL_19]] : !fir.ref>>, volatile> ! CHECK: %[[VAL_21:.*]]:3 = fir.box_dims %[[VAL_20]], %[[VAL_0]] : (!fir.box>>, index) -> (index, index, index) diff --git a/external/llvm-project/flang/test/Parser/OpenMP/declare-target-indirect-tree.f90 b/external/llvm-project/flang/test/Parser/OpenMP/declare-target-indirect-tree.f90 new file mode 100644 index 000000000000..df85942ec15a --- /dev/null +++ b/external/llvm-project/flang/test/Parser/OpenMP/declare-target-indirect-tree.f90 @@ -0,0 +1,53 @@ +! REQUIRES: openmp_runtime + +! RUN: %flang_fc1 %openmp_flags -fopenmp-version=52 -fdebug-dump-parse-tree %s | FileCheck %s +! RUN: %flang_fc1 %openmp_flags -fdebug-unparse -fopenmp-version=52 %s | FileCheck %s --check-prefix="UNPARSE" + +module functions + implicit none + + interface + function func() result(i) + character(1) :: i + end function + end interface + +contains + function func1() result(i) + !$omp declare target enter(func1) indirect(.true.) + !CHECK: | | | | | OmpDeclareTargetSpecifier -> OmpDeclareTargetWithClause -> OmpClauseList -> OmpClause -> Enter -> OmpObjectList -> OmpObject -> Designator -> DataRef -> Name = 'func1' + !CHECK-NEXT: | | | | | OmpClause -> Indirect -> OmpIndirectClause -> Scalar -> Logical -> Expr = '.true._4' + !CHECK-NEXT: | | | | | | LiteralConstant -> LogicalLiteralConstant + !CHECK-NEXT: | | | | | | | bool = 'true' + character(1) :: i + i = 'a' + return + end function + + function func2() result(i) + !$omp declare target enter(func2) indirect + !CHECK: | | | | | OmpDeclareTargetSpecifier -> OmpDeclareTargetWithClause -> OmpClauseList -> OmpClause -> Enter -> OmpObjectList -> OmpObject -> Designator -> DataRef -> Name = 'func2' + !CHECK-NEXT: | | | | | OmpClause -> Indirect -> OmpIndirectClause -> + character(1) :: i + i = 'b' + return + end function +end module + +program main + use functions + implicit none + procedure (func), pointer :: ptr1=>func1, ptr2=>func2 + character(1) :: val1, val2 + + !$omp target map(from: val1) + val1 = ptr1() + !$omp end target + !$omp target map(from: val2) + val2 = ptr2() + !$omp end target + +end program + +!UNPARSE: !$OMP DECLARE TARGET ENTER(func1) INDIRECT(.true._4) +!UNPARSE: !$OMP DECLARE TARGET ENTER(func2) INDIRECT() diff --git a/external/llvm-project/flang/test/Preprocessing/bug518.F b/external/llvm-project/flang/test/Preprocessing/bug518.F index 346e04cc56d3..0b680dd5751b 100644 --- a/external/llvm-project/flang/test/Preprocessing/bug518.F +++ b/external/llvm-project/flang/test/Preprocessing/bug518.F @@ -1,4 +1,4 @@ -! RUN: %flang -fc1 -fdebug-unparse %s 2>&1 | FileCheck %s +! RUN: %flang_fc1 -fdebug-unparse %s 2>&1 | FileCheck %s ! CHECK: k=1_4 k= 1_99999999 &4 diff --git a/external/llvm-project/flang/test/Semantics/OpenMP/allocate-align01.f90 b/external/llvm-project/flang/test/Semantics/OpenMP/allocate-align01.f90 index 4974f5e18397..bc17d7047bbb 100644 --- a/external/llvm-project/flang/test/Semantics/OpenMP/allocate-align01.f90 +++ b/external/llvm-project/flang/test/Semantics/OpenMP/allocate-align01.f90 @@ -1,6 +1,6 @@ ! REQUIRES: openmp_runtime -! RUN: %python %S/../test_errors.py %s %flang_fc1 %openmp_flags -fopenmp-version=51 +! RUN: %python %S/../test_errors.py %s %flang_fc1 %openmp_flags -fopenmp-version=52 ! OpenMP Version 5.2 ! The allocate clause's allocator modifier must be of type allocator_handle ! and the align modifier must be constant, positive integer expression diff --git a/external/llvm-project/flang/test/Semantics/OpenMP/allocate01.f90 b/external/llvm-project/flang/test/Semantics/OpenMP/allocate01.f90 index 8a680eee743e..b205b2c79d65 100644 --- a/external/llvm-project/flang/test/Semantics/OpenMP/allocate01.f90 +++ b/external/llvm-project/flang/test/Semantics/OpenMP/allocate01.f90 @@ -1,6 +1,6 @@ ! REQUIRES: openmp_runtime -! RUN: %python %S/../test_errors.py %s %flang_fc1 %openmp_flags +! RUN: %python %S/../test_errors.py %s %flang_fc1 %openmp_flags -fopenmp-version=52 ! OpenMP Version 5.0 ! 2.11.3 allocate Directive ! The allocate directive must appear in the same scope as the declarations of diff --git a/external/llvm-project/flang/test/Semantics/OpenMP/allocate02.f90 b/external/llvm-project/flang/test/Semantics/OpenMP/allocate02.f90 index 80ef60b31e70..16a9c3733077 100644 --- a/external/llvm-project/flang/test/Semantics/OpenMP/allocate02.f90 +++ b/external/llvm-project/flang/test/Semantics/OpenMP/allocate02.f90 @@ -1,6 +1,6 @@ ! REQUIRES: openmp_runtime -! RUN: %python %S/../test_errors.py %s %flang_fc1 %openmp_flags +! RUN: %python %S/../test_errors.py %s %flang_fc1 %openmp_flags -fopenmp-version=50 ! OpenMP Version 5.0 ! 2.11.3 allocate Directive ! At most one allocator clause can appear on the allocate directive. @@ -16,11 +16,9 @@ subroutine allocate() !ERROR: At most one ALLOCATOR clause can appear on the ALLOCATE directive !$omp allocate(x, y) allocator(omp_default_mem_alloc) allocator(omp_default_mem_alloc) - !WARNING: OpenMP directive ALLOCATE has been deprecated, please use ALLOCATORS instead. !$omp allocate(darray) allocator(omp_default_mem_alloc) allocate ( darray(a, b) ) - !WARNING: OpenMP directive ALLOCATE has been deprecated, please use ALLOCATORS instead. !ERROR: At most one ALLOCATOR clause can appear on the ALLOCATE directive !$omp allocate(darray) allocator(omp_default_mem_alloc) allocator(omp_default_mem_alloc) allocate ( darray(a, b) ) diff --git a/external/llvm-project/flang/test/Semantics/OpenMP/allocate03.f90 b/external/llvm-project/flang/test/Semantics/OpenMP/allocate03.f90 index b8c6b8e5dee7..3d500e6273c4 100644 --- a/external/llvm-project/flang/test/Semantics/OpenMP/allocate03.f90 +++ b/external/llvm-project/flang/test/Semantics/OpenMP/allocate03.f90 @@ -1,6 +1,6 @@ ! REQUIRES: openmp_runtime -! RUN: %python %S/../test_errors.py %s %flang_fc1 %openmp_flags +! RUN: %python %S/../test_errors.py %s %flang_fc1 %openmp_flags -fopenmp-version=50 ! OpenMP Version 5.0 ! 2.11.3 allocate Directive ! A variable that is part of another variable (as an array or @@ -18,7 +18,6 @@ subroutine allocate() !ERROR: A variable that is part of another variable (as an array or structure element) cannot appear on the ALLOCATE directive !$omp allocate(my_var%array) - !WARNING: OpenMP directive ALLOCATE has been deprecated, please use ALLOCATORS instead. !ERROR: A variable that is part of another variable (as an array or structure element) cannot appear on the ALLOCATE directive !$omp allocate(darray, my_var%array) allocator(omp_default_mem_alloc) allocate ( darray(a, b) ) diff --git a/external/llvm-project/flang/test/Semantics/OpenMP/allocate05.f90 b/external/llvm-project/flang/test/Semantics/OpenMP/allocate05.f90 index 2c81c4dbc82c..28ab40e31bcc 100644 --- a/external/llvm-project/flang/test/Semantics/OpenMP/allocate05.f90 +++ b/external/llvm-project/flang/test/Semantics/OpenMP/allocate05.f90 @@ -1,6 +1,6 @@ ! REQUIRES: openmp_runtime -! RUN: %python %S/../test_errors.py %s %flang_fc1 %openmp_flags +! RUN: %python %S/../test_errors.py %s %flang_fc1 %openmp_flags -fopenmp-version=50 ! OpenMP Version 5.0 ! 2.11.3 allocate Directive ! allocate directives that appear in a target region must specify an allocator @@ -13,13 +13,11 @@ subroutine allocate() real, dimension (:,:), allocatable :: darray !$omp target - !WARNING: OpenMP directive ALLOCATE has been deprecated, please use ALLOCATORS instead. !$omp allocate allocator(omp_default_mem_alloc) allocate ( darray(a, b) ) !$omp end target !$omp target - !WARNING: OpenMP directive ALLOCATE has been deprecated, please use ALLOCATORS instead. !ERROR: ALLOCATE directives that appear in a TARGET region must specify an allocator clause !$omp allocate allocate ( darray(a, b) ) diff --git a/external/llvm-project/flang/test/Semantics/OpenMP/allocate06.f90 b/external/llvm-project/flang/test/Semantics/OpenMP/allocate06.f90 index 7196bcac2b9b..60eb65e9a37b 100644 --- a/external/llvm-project/flang/test/Semantics/OpenMP/allocate06.f90 +++ b/external/llvm-project/flang/test/Semantics/OpenMP/allocate06.f90 @@ -1,6 +1,6 @@ ! REQUIRES: openmp_runtime -! RUN: %python %S/../test_errors.py %s %flang_fc1 %openmp_flags +! RUN: %python %S/../test_errors.py %s %flang_fc1 %openmp_flags -fopenmp-version=50 ! OpenMP Version 5.0 ! 2.11.3 allocate Directive ! List items specified in the allocate directive must not have the ALLOCATABLE attribute unless the directive is associated with an @@ -14,7 +14,6 @@ subroutine allocate() !ERROR: List items specified in the ALLOCATE directive must not have the ALLOCATABLE attribute unless the directive is associated with an ALLOCATE statement !$omp allocate(darray) allocator(omp_default_mem_alloc) - !WARNING: OpenMP directive ALLOCATE has been deprecated, please use ALLOCATORS instead. !$omp allocate(darray) allocator(omp_default_mem_alloc) allocate(darray(a, b)) diff --git a/external/llvm-project/flang/test/Semantics/OpenMP/allocate09.f90 b/external/llvm-project/flang/test/Semantics/OpenMP/allocate09.f90 index 645e97a3a33f..a36037a5f230 100644 --- a/external/llvm-project/flang/test/Semantics/OpenMP/allocate09.f90 +++ b/external/llvm-project/flang/test/Semantics/OpenMP/allocate09.f90 @@ -1,6 +1,6 @@ ! REQUIRES: openmp_runtime -! RUN: %python %S/../test_errors.py %s %flang_fc1 %openmp_flags +! RUN: %python %S/../test_errors.py %s %flang_fc1 %openmp_flags -fopenmp-version=50 ! OpenMP Version 5.0 ! 2.11.3 allocate Directive ! List items specified in an allocate directive that is associated @@ -12,28 +12,23 @@ subroutine allocate() integer, dimension(:), allocatable :: a, b, c, d, e, f, & g, h, i, j, k, l - !WARNING: OpenMP directive ALLOCATE has been deprecated, please use ALLOCATORS instead. !$omp allocate(a) allocator(omp_default_mem_alloc) allocate(a(1), b(2)) - !WARNING: OpenMP directive ALLOCATE has been deprecated, please use ALLOCATORS instead. !$omp allocate(c, d) allocator(omp_default_mem_alloc) allocate(c(3), d(4)) !$omp allocate(e) allocator(omp_default_mem_alloc) !$omp allocate(f, g) allocator(omp_default_mem_alloc) - !WARNING: OpenMP directive ALLOCATE has been deprecated, please use ALLOCATORS instead. !$omp allocate allocate(e(5), f(6), g(7)) - !WARNING: OpenMP directive ALLOCATE has been deprecated, please use ALLOCATORS instead. !ERROR: Object 'i' in ALLOCATE directive not found in corresponding ALLOCATE statement !$omp allocate(h, i) allocator(omp_default_mem_alloc) allocate(h(8)) !ERROR: Object 'j' in ALLOCATE directive not found in corresponding ALLOCATE statement !$omp allocate(j, k) allocator(omp_default_mem_alloc) - !WARNING: OpenMP directive ALLOCATE has been deprecated, please use ALLOCATORS instead. !$omp allocate(l) allocator(omp_default_mem_alloc) allocate(k(9), l(10)) diff --git a/external/llvm-project/flang/test/Semantics/OpenMP/atomic-update-only.f90 b/external/llvm-project/flang/test/Semantics/OpenMP/atomic-update-only.f90 index 28d0e264359c..3c027924a142 100644 --- a/external/llvm-project/flang/test/Semantics/OpenMP/atomic-update-only.f90 +++ b/external/llvm-project/flang/test/Semantics/OpenMP/atomic-update-only.f90 @@ -30,7 +30,8 @@ subroutine f03 integer :: x, y !$omp atomic update - !ERROR: The atomic variable x should occur exactly once among the arguments of the top-level + operator + !ERROR: The atomic variable x cannot be a proper subexpression of an argument (here: (x+y)) in the update operation + !ERROR: The atomic variable x should appear as an argument of the top-level + operator x = (x + y) + 1 end diff --git a/external/llvm-project/flang/test/Semantics/OpenMP/atomic03.f90 b/external/llvm-project/flang/test/Semantics/OpenMP/atomic03.f90 index b3a3c0d5e7a1..691a483e6e80 100644 --- a/external/llvm-project/flang/test/Semantics/OpenMP/atomic03.f90 +++ b/external/llvm-project/flang/test/Semantics/OpenMP/atomic03.f90 @@ -25,19 +25,19 @@ program OmpAtomic y = MIN(y, 8) !$omp atomic - !ERROR: The atomic variable z should occur exactly once among the arguments of the top-level AND operator + !ERROR: The atomic variable z should appear as an argument of the top-level AND operator z = IAND(y, 4) !$omp atomic - !ERROR: The atomic variable z should occur exactly once among the arguments of the top-level OR operator + !ERROR: The atomic variable z should appear as an argument of the top-level OR operator z = IOR(y, 5) !$omp atomic - !ERROR: The atomic variable z should occur exactly once among the arguments of the top-level NEQV/EOR operator + !ERROR: The atomic variable z should appear as an argument of the top-level NEQV/EOR operator z = IEOR(y, 6) !$omp atomic - !ERROR: The atomic variable z should occur exactly once among the arguments of the top-level MAX operator + !ERROR: The atomic variable z should appear as an argument of the top-level MAX operator z = MAX(y, 7, b, c) !$omp atomic - !ERROR: The atomic variable z should occur exactly once among the arguments of the top-level MIN operator + !ERROR: The atomic variable z should appear as an argument of the top-level MIN operator z = MIN(y, 8, a, d) !$omp atomic @@ -58,19 +58,19 @@ program OmpAtomic y = MIN(y, 8) !$omp atomic update - !ERROR: The atomic variable z should occur exactly once among the arguments of the top-level AND operator + !ERROR: The atomic variable z should appear as an argument of the top-level AND operator z = IAND(y, 4) !$omp atomic update - !ERROR: The atomic variable z should occur exactly once among the arguments of the top-level OR operator + !ERROR: The atomic variable z should appear as an argument of the top-level OR operator z = IOR(y, 5) !$omp atomic update - !ERROR: The atomic variable z should occur exactly once among the arguments of the top-level NEQV/EOR operator + !ERROR: The atomic variable z should appear as an argument of the top-level NEQV/EOR operator z = IEOR(y, 6) !$omp atomic update - !ERROR: The atomic variable z should occur exactly once among the arguments of the top-level MAX operator + !ERROR: The atomic variable z should appear as an argument of the top-level MAX operator z = MAX(y, 7) !$omp atomic update - !ERROR: The atomic variable z should occur exactly once among the arguments of the top-level MIN operator + !ERROR: The atomic variable z should appear as an argument of the top-level MIN operator z = MIN(y, 8) !$omp atomic update @@ -90,7 +90,7 @@ subroutine conflicting_types() type(simple) ::s z = 1 !$omp atomic - !ERROR: The atomic variable z should occur exactly once among the arguments of the top-level AND operator + !ERROR: The atomic variable z should appear as an argument of the top-level AND operator z = IAND(s%z, 4) end subroutine @@ -103,22 +103,22 @@ subroutine more_invalid_atomic_update_stmts() type(some_type) :: s !$omp atomic update - !ERROR: The atomic variable a should occur exactly once among the arguments of the top-level MIN operator + !ERROR: The atomic variable a should be exactly one of the arguments of the top-level MIN operator a = min(a, a, b) !$omp atomic - !ERROR: The atomic variable a should occur exactly once among the arguments of the top-level MAX operator + !ERROR: The atomic variable a should be exactly one of the arguments of the top-level MAX operator a = max(b, a, b, a) !$omp atomic a = min(b, a, b) !$omp atomic - !ERROR: The atomic variable a should occur exactly once among the arguments of the top-level MAX operator + !ERROR: The atomic variable a should be exactly one of the arguments of the top-level MAX operator a = max(b, a, b, a, b) !$omp atomic update - !ERROR: The atomic variable y should occur exactly once among the arguments of the top-level MIN operator + !ERROR: The atomic variable y should appear as an argument of the top-level MIN operator y = min(z, x) !$omp atomic @@ -126,7 +126,7 @@ subroutine more_invalid_atomic_update_stmts() !$omp atomic update !ERROR: Atomic variable k should be a scalar - !ERROR: The atomic variable k should occur exactly once among the arguments of the top-level MAX operator + !ERROR: The atomic variable k should appear as an argument of the top-level MAX operator k = max(x, y) !$omp atomic diff --git a/external/llvm-project/flang/test/Semantics/OpenMP/atomic04.f90 b/external/llvm-project/flang/test/Semantics/OpenMP/atomic04.f90 index 0f69befed141..fb87ca518661 100644 --- a/external/llvm-project/flang/test/Semantics/OpenMP/atomic04.f90 +++ b/external/llvm-project/flang/test/Semantics/OpenMP/atomic04.f90 @@ -17,10 +17,10 @@ program OmpAtomic !$omp atomic x = 1 + x !$omp atomic - !ERROR: The atomic variable x should occur exactly once among the arguments of the top-level + operator + !ERROR: The atomic variable x should appear as an argument of the top-level + operator x = y + 1 !$omp atomic - !ERROR: The atomic variable x should occur exactly once among the arguments of the top-level + operator + !ERROR: The atomic variable x should appear as an argument of the top-level + operator x = 1 + y !$omp atomic @@ -28,10 +28,10 @@ program OmpAtomic !$omp atomic x = 1 - x !$omp atomic - !ERROR: The atomic variable x should occur exactly once among the arguments of the top-level - operator + !ERROR: The atomic variable x should appear as an argument of the top-level - operator x = y - 1 !$omp atomic - !ERROR: The atomic variable x should occur exactly once among the arguments of the top-level - operator + !ERROR: The atomic variable x should appear as an argument of the top-level - operator x = 1 - y !$omp atomic @@ -50,10 +50,10 @@ program OmpAtomic !$omp atomic x = 1/x !$omp atomic - !ERROR: The atomic variable x should occur exactly once among the arguments of the top-level / operator + !ERROR: The atomic variable x should appear as an argument of the top-level / operator x = y/1 !$omp atomic - !ERROR: The atomic variable x should occur exactly once among the arguments of the top-level / operator + !ERROR: The atomic variable x should appear as an argument of the top-level / operator x = 1/y !$omp atomic @@ -61,7 +61,7 @@ program OmpAtomic !$omp atomic m = n .AND. m !$omp atomic - !ERROR: The atomic variable m should occur exactly once among the arguments of the top-level AND operator + !ERROR: The atomic variable m should appear as an argument of the top-level AND operator m = n .AND. l !$omp atomic @@ -69,7 +69,7 @@ program OmpAtomic !$omp atomic m = n .OR. m !$omp atomic - !ERROR: The atomic variable m should occur exactly once among the arguments of the top-level OR operator + !ERROR: The atomic variable m should appear as an argument of the top-level OR operator m = n .OR. l !$omp atomic @@ -77,7 +77,7 @@ program OmpAtomic !$omp atomic m = n .EQV. m !$omp atomic - !ERROR: The atomic variable m should occur exactly once among the arguments of the top-level EQV operator + !ERROR: The atomic variable m should appear as an argument of the top-level EQV operator m = n .EQV. l !$omp atomic @@ -85,7 +85,7 @@ program OmpAtomic !$omp atomic m = n .NEQV. m !$omp atomic - !ERROR: The atomic variable m should occur exactly once among the arguments of the top-level NEQV/EOR operator + !ERROR: The atomic variable m should appear as an argument of the top-level NEQV/EOR operator m = n .NEQV. l !$omp atomic update @@ -93,10 +93,10 @@ program OmpAtomic !$omp atomic update x = 1 + x !$omp atomic update - !ERROR: The atomic variable x should occur exactly once among the arguments of the top-level + operator + !ERROR: The atomic variable x should appear as an argument of the top-level + operator x = y + 1 !$omp atomic update - !ERROR: The atomic variable x should occur exactly once among the arguments of the top-level + operator + !ERROR: The atomic variable x should appear as an argument of the top-level + operator x = 1 + y !$omp atomic update @@ -104,10 +104,10 @@ program OmpAtomic !$omp atomic update x = 1 - x !$omp atomic update - !ERROR: The atomic variable x should occur exactly once among the arguments of the top-level - operator + !ERROR: The atomic variable x should appear as an argument of the top-level - operator x = y - 1 !$omp atomic update - !ERROR: The atomic variable x should occur exactly once among the arguments of the top-level - operator + !ERROR: The atomic variable x should appear as an argument of the top-level - operator x = 1 - y !$omp atomic update @@ -126,10 +126,10 @@ program OmpAtomic !$omp atomic update x = 1/x !$omp atomic update - !ERROR: The atomic variable x should occur exactly once among the arguments of the top-level / operator + !ERROR: The atomic variable x should appear as an argument of the top-level / operator x = y/1 !$omp atomic update - !ERROR: The atomic variable x should occur exactly once among the arguments of the top-level / operator + !ERROR: The atomic variable x should appear as an argument of the top-level / operator x = 1/y !$omp atomic update @@ -137,7 +137,7 @@ program OmpAtomic !$omp atomic update m = n .AND. m !$omp atomic update - !ERROR: The atomic variable m should occur exactly once among the arguments of the top-level AND operator + !ERROR: The atomic variable m should appear as an argument of the top-level AND operator m = n .AND. l !$omp atomic update @@ -145,7 +145,7 @@ program OmpAtomic !$omp atomic update m = n .OR. m !$omp atomic update - !ERROR: The atomic variable m should occur exactly once among the arguments of the top-level OR operator + !ERROR: The atomic variable m should appear as an argument of the top-level OR operator m = n .OR. l !$omp atomic update @@ -153,7 +153,7 @@ program OmpAtomic !$omp atomic update m = n .EQV. m !$omp atomic update - !ERROR: The atomic variable m should occur exactly once among the arguments of the top-level EQV operator + !ERROR: The atomic variable m should appear as an argument of the top-level EQV operator m = n .EQV. l !$omp atomic update @@ -161,7 +161,7 @@ program OmpAtomic !$omp atomic update m = n .NEQV. m !$omp atomic update - !ERROR: The atomic variable m should occur exactly once among the arguments of the top-level NEQV/EOR operator + !ERROR: The atomic variable m should appear as an argument of the top-level NEQV/EOR operator m = n .NEQV. l end program OmpAtomic @@ -184,27 +184,30 @@ subroutine more_invalid_atomic_update_stmts() x = 1 !$omp atomic update - !ERROR: Within atomic operation a and a*b access the same storage + !ERROR: The atomic variable a cannot be a proper subexpression of an argument (here: a*b) in the update operation a = a * b + a !$omp atomic - !ERROR: The atomic variable a should occur exactly once among the arguments of the top-level * operator + !ERROR: The atomic variable a cannot be a proper subexpression of an argument (here: (a+9_4)) in the update operation + !ERROR: The atomic variable a should appear as an argument of the top-level * operator a = b * (a + 9) !$omp atomic update - !ERROR: Within atomic operation a and (a+b) access the same storage + !ERROR: The atomic variable a cannot be a proper subexpression of an argument (here: (a+b)) in the update operation a = a * (a + b) !$omp atomic - !ERROR: Within atomic operation a and (b+a) access the same storage + !ERROR: The atomic variable a cannot be a proper subexpression of an argument (here: (b+a)) in the update operation a = (b + a) * a !$omp atomic - !ERROR: The atomic variable a should occur exactly once among the arguments of the top-level + operator + !ERROR: The atomic variable a cannot be a proper subexpression of an argument (here: a*b) in the update operation + !ERROR: The atomic variable a should appear as an argument of the top-level + operator a = a * b + c !$omp atomic update - !ERROR: The atomic variable a should occur exactly once among the arguments of the top-level + operator + !ERROR: The atomic variable a cannot be a proper subexpression of an argument (here: a+b) in the update operation + !ERROR: The atomic variable a should appear as an argument of the top-level + operator a = a + b + c !$omp atomic @@ -219,11 +222,12 @@ subroutine more_invalid_atomic_update_stmts() !$omp atomic update !ERROR: No intrinsic or user-defined ASSIGNMENT(=) matches scalar REAL(4) and rank 1 array of REAL(4) - !ERROR: The atomic variable x should occur exactly once among the arguments of the top-level / operator + !ERROR: The atomic variable x cannot be a proper subexpression of an argument (here: x*y) in the update operation + !ERROR: The atomic variable x should appear as an argument of the top-level / operator x = x * y / z !$omp atomic - !ERROR: The atomic variable p%m should occur exactly once among the arguments of the top-level + operator + !ERROR: The atomic variable p%m should appear as an argument of the top-level + operator p%m = x + y !$omp atomic update diff --git a/external/llvm-project/flang/test/Semantics/OpenMP/clause-validity01.f90 b/external/llvm-project/flang/test/Semantics/OpenMP/clause-validity01.f90 index 5e0d91914c44..6989a183e83e 100644 --- a/external/llvm-project/flang/test/Semantics/OpenMP/clause-validity01.f90 +++ b/external/llvm-project/flang/test/Semantics/OpenMP/clause-validity01.f90 @@ -1,6 +1,6 @@ ! REQUIRES: openmp_runtime -! RUN: %python %S/../test_errors.py %s %flang_fc1 %openmp_flags %openmp_module_flag -fopenmp-version=51 +! RUN: %python %S/../test_errors.py %s %flang_fc1 %openmp_flags %openmp_module_flag -fopenmp-version=52 use omp_lib ! Check OpenMP clause validity for the following directives: ! @@ -502,6 +502,7 @@ !$omp taskyield !$omp barrier !$omp taskwait + !WARNING: SOURCE dependence type is deprecated in OpenMP v5.2 !ERROR: The SINK and SOURCE dependence types can only be used with the ORDERED directive, used here in the TASKWAIT construct !$omp taskwait depend(source) ! !$omp taskwait depend(sink:i-1) @@ -509,12 +510,18 @@ ! !$omp target update from(arrayA) to(arrayB) ! !$omp target exit data map(from:arrayA) map(delete:arrayB) !$omp flush (c) + !WARNING: The syntax "FLUSH clause (object, ...)" has been deprecated, use "FLUSH(object, ...) clause" instead !$omp flush acq_rel + !WARNING: The syntax "FLUSH clause (object, ...)" has been deprecated, use "FLUSH(object, ...) clause" instead !$omp flush release + !WARNING: The syntax "FLUSH clause (object, ...)" has been deprecated, use "FLUSH(object, ...) clause" instead !$omp flush acquire + !WARNING: The syntax "FLUSH clause (object, ...)" has been deprecated, use "FLUSH(object, ...) clause" instead !ERROR: If memory-order-clause is RELEASE, ACQUIRE, or ACQ_REL, list items must not be specified on the FLUSH directive !$omp flush release (c) + !WARNING: The syntax "FLUSH clause (object, ...)" has been deprecated, use "FLUSH(object, ...) clause" instead !$omp flush seq_cst + !WARNING: The syntax "FLUSH clause (object, ...)" has been deprecated, use "FLUSH(object, ...) clause" instead !ERROR: RELAXED clause is not allowed on the FLUSH directive !$omp flush relaxed diff --git a/external/llvm-project/flang/test/Semantics/OpenMP/deprecation.f90 b/external/llvm-project/flang/test/Semantics/OpenMP/deprecation.f90 index e04f43026bbc..df15c3bcc0b1 100644 --- a/external/llvm-project/flang/test/Semantics/OpenMP/deprecation.f90 +++ b/external/llvm-project/flang/test/Semantics/OpenMP/deprecation.f90 @@ -1,4 +1,4 @@ -! RUN: %python %S/../test_errors.py %s %flang_fc1 -fopenmp -Werror +! RUN: %python %S/../test_errors.py %s %flang_fc1 -fopenmp -Werror -fopenmp-version=52 ! Check for deprecation of master directive and its combined/composite variants diff --git a/external/llvm-project/flang/test/Semantics/OpenMP/do-concurrent-collapse.f90 b/external/llvm-project/flang/test/Semantics/OpenMP/do-concurrent-collapse.f90 new file mode 100644 index 000000000000..bb1929249183 --- /dev/null +++ b/external/llvm-project/flang/test/Semantics/OpenMP/do-concurrent-collapse.f90 @@ -0,0 +1,39 @@ +!RUN: %python %S/../test_errors.py %s %flang -fopenmp + +integer :: i, j +!$omp parallel do collapse(2) +do i = 1, 1 + ! ERROR: DO CONCURRENT loops cannot form part of a loop nest. + do concurrent (j = 1:2) + print *, j + end do +end do + +!$omp parallel do +do i = 1, 1 + ! This should not lead to an error because it is not part of a loop nest: + do concurrent (j = 1:2) + print *, j + end do +end do + +!$omp parallel do +! ERROR: DO CONCURRENT loops cannot form part of a loop nest. +do concurrent (j = 1:2) + print *, j +end do + +!$omp loop +! Do concurrent is explicitly allowed inside of omp loop +do concurrent (j = 1:2) + print *, j +end do + +! ERROR: DO CONCURRENT loops cannot be used with the COLLAPSE clause. +!$omp loop collapse(2) +do i = 1, 1 + do concurrent (j = 1:2) + print *, j + end do +end do +end diff --git a/external/llvm-project/flang/test/Semantics/OpenMP/flush02.f90 b/external/llvm-project/flang/test/Semantics/OpenMP/flush02.f90 index 615332c6cf31..a7b170d58db5 100644 --- a/external/llvm-project/flang/test/Semantics/OpenMP/flush02.f90 +++ b/external/llvm-project/flang/test/Semantics/OpenMP/flush02.f90 @@ -78,7 +78,6 @@ !$omp parallel num_threads(4) array = (/1, 2, 3, 4, 5, 6, 7, 8, 9, 10/) - !WARNING: OpenMP directive MASTER has been deprecated, please use MASKED instead. !$omp master !$omp flush (array) !$omp end master diff --git a/external/llvm-project/flang/test/Semantics/OpenMP/implicit-dsa.f90 b/external/llvm-project/flang/test/Semantics/OpenMP/implicit-dsa.f90 index 4a07e256e2bb..1ee777d6b972 100644 --- a/external/llvm-project/flang/test/Semantics/OpenMP/implicit-dsa.f90 +++ b/external/llvm-project/flang/test/Semantics/OpenMP/implicit-dsa.f90 @@ -141,7 +141,7 @@ subroutine implicit_dsa_test6 !$omp end task end subroutine -! Test taskgroup - it uses the same scope as task. +! Test taskgroup. !DEF: /implicit_dsa_test7 (Subroutine) Subprogram subroutine implicit_dsa_test7 !DEF: /implicit_dsa_test7/x ObjectEntity INTEGER(4) @@ -150,8 +150,8 @@ subroutine implicit_dsa_test7 !$omp task !$omp taskgroup - !DEF: /implicit_dsa_test7/OtherConstruct1/x (OmpFirstPrivate, OmpImplicit) HostAssoc INTEGER(4) - !DEF: /implicit_dsa_test7/OtherConstruct1/y (OmpFirstPrivate, OmpImplicit) HostAssoc INTEGER(4) + !DEF: /implicit_dsa_test7/OtherConstruct1/OtherConstruct1/x HostAssoc INTEGER(4) + !DEF: /implicit_dsa_test7/OtherConstruct1/OtherConstruct1/y HostAssoc INTEGER(4) x = y !$omp end taskgroup !$omp end task diff --git a/external/llvm-project/flang/test/Semantics/OpenMP/nested-barrier.f90 b/external/llvm-project/flang/test/Semantics/OpenMP/nested-barrier.f90 index 5f51363d59e5..070964fbe863 100644 --- a/external/llvm-project/flang/test/Semantics/OpenMP/nested-barrier.f90 +++ b/external/llvm-project/flang/test/Semantics/OpenMP/nested-barrier.f90 @@ -1,4 +1,4 @@ -! RUN: %python %S/../test_errors.py %s %flang_fc1 -fopenmp +! RUN: %python %S/../test_errors.py %s %flang_fc1 -fopenmp -fopenmp-version=50 ! OpenMP Version 4.5 ! Various checks with the nesting of BARRIER construct @@ -75,7 +75,6 @@ program omp_nest_barrier end do !$omp end critical - !WARNING: OpenMP directive MASTER has been deprecated, please use MASKED instead. !$omp master do i = 1, 10 k = k + 1 @@ -108,7 +107,6 @@ program omp_nest_barrier end do !$omp end ordered - !WARNING: OpenMP directive MASTER has been deprecated, please use MASKED instead. !$omp master do i = 1, 10 !ERROR: `DISTRIBUTE` region has to be strictly nested inside `TEAMS` region. diff --git a/external/llvm-project/flang/test/Semantics/OpenMP/nested-master.f90 b/external/llvm-project/flang/test/Semantics/OpenMP/nested-master.f90 index d51e366eb584..79e2864fd271 100644 --- a/external/llvm-project/flang/test/Semantics/OpenMP/nested-master.f90 +++ b/external/llvm-project/flang/test/Semantics/OpenMP/nested-master.f90 @@ -1,4 +1,4 @@ -! RUN: %python %S/../test_errors.py %s %flang_fc1 -fopenmp +! RUN: %python %S/../test_errors.py %s %flang_fc1 -fopenmp -fopenmp-version=50 ! OpenMP Version 4.5 ! Various checks with the nesting of MASTER construct @@ -9,7 +9,6 @@ program omp_nest_master !$omp do do i = 1, 10 k = k + 1 - !WARNING: OpenMP directive MASTER has been deprecated, please use MASKED instead. !ERROR: `MASTER` region may not be closely nested inside of `WORKSHARING`, `LOOP`, `TASK`, `TASKLOOP`, or `ATOMIC` region. !$omp master j = j -1 @@ -17,7 +16,6 @@ program omp_nest_master end do !$omp sections - !WARNING: OpenMP directive MASTER has been deprecated, please use MASKED instead. !ERROR: `MASTER` region may not be closely nested inside of `WORKSHARING`, `LOOP`, `TASK`, `TASKLOOP`, or `ATOMIC` region. !$omp master do i = 1, 10 @@ -27,7 +25,6 @@ program omp_nest_master !$omp end sections !$omp single - !WARNING: OpenMP directive MASTER has been deprecated, please use MASKED instead. !ERROR: `MASTER` region may not be closely nested inside of `WORKSHARING`, `LOOP`, `TASK`, `TASKLOOP`, or `ATOMIC` region. !$omp master do i = 1, 10 @@ -41,7 +38,6 @@ program omp_nest_master !$omp task do i = 1, 10 k = k + 1 - !WARNING: OpenMP directive MASTER has been deprecated, please use MASKED instead. !ERROR: `MASTER` region may not be closely nested inside of `WORKSHARING`, `LOOP`, `TASK`, `TASKLOOP`, or `ATOMIC` region. !$omp master j = j -1 @@ -52,7 +48,6 @@ program omp_nest_master !$omp taskloop do i = 1, 10 k = k + 1 - !WARNING: OpenMP directive MASTER has been deprecated, please use MASKED instead. !ERROR: `MASTER` region may not be closely nested inside of `WORKSHARING`, `LOOP`, `TASK`, `TASKLOOP`, or `ATOMIC` region. !$omp master j = j -1 @@ -63,7 +58,6 @@ program omp_nest_master !$omp target parallel do simd do i = 1, 10 k = k + 1 - !WARNING: OpenMP directive MASTER has been deprecated, please use MASKED instead. !ERROR: The only OpenMP constructs that can be encountered during execution of a 'SIMD' region are the `ATOMIC` construct, the `LOOP` construct, the `SIMD` construct, the `SCAN` construct and the `ORDERED` construct with the `SIMD` clause. !ERROR: `MASTER` region may not be closely nested inside of `WORKSHARING`, `LOOP`, `TASK`, `TASKLOOP`, or `ATOMIC` region. !$omp master @@ -75,7 +69,6 @@ program omp_nest_master !$omp critical do i = 1, 10 k = k + 1 - !WARNING: OpenMP directive MASTER has been deprecated, please use MASKED instead. !$omp master j = j -1 !$omp end master @@ -85,7 +78,6 @@ program omp_nest_master !$omp ordered do i = 1, 10 k = k + 1 - !WARNING: OpenMP directive MASTER has been deprecated, please use MASKED instead. !$omp master j = j -1 !$omp end master @@ -99,7 +91,6 @@ program omp_nest_master !$omp distribute do k =1, 10 print *, "hello" - !WARNING: OpenMP directive MASTER has been deprecated, please use MASKED instead. !$omp master j = j -1 !$omp end master @@ -116,7 +107,6 @@ program omp_nest_master !$omp distribute do k =1, 10 print *, "hello" - !WARNING: OpenMP directive MASTER has been deprecated, please use MASKED instead. !$omp master j = j -1 !$omp end master @@ -133,7 +123,6 @@ program omp_nest_master !$omp distribute do k =1, 10 print *, "hello" - !WARNING: OpenMP directive MASTER has been deprecated, please use MASKED instead. !ERROR: `MASTER` region may not be closely nested inside of `WORKSHARING`, `LOOP`, `TASK`, `TASKLOOP`, or `ATOMIC` region. !$omp master j = j -1 @@ -151,7 +140,6 @@ program omp_nest_master !$omp distribute do k =1, 10 print *, "hello" - !WARNING: OpenMP directive MASTER has been deprecated, please use MASKED instead. !ERROR: `MASTER` region may not be closely nested inside of `WORKSHARING`, `LOOP`, `TASK`, `TASKLOOP`, or `ATOMIC` region. !$omp master j = j -1 diff --git a/external/llvm-project/flang/test/Semantics/OpenMP/nested-teams.f90 b/external/llvm-project/flang/test/Semantics/OpenMP/nested-teams.f90 index 974172ee9717..a960caeb1511 100644 --- a/external/llvm-project/flang/test/Semantics/OpenMP/nested-teams.f90 +++ b/external/llvm-project/flang/test/Semantics/OpenMP/nested-teams.f90 @@ -1,4 +1,4 @@ -! RUN: %python %S/../test_errors.py %s %flang -fopenmp +! RUN: %python %S/../test_errors.py %s %flang -fopenmp -fopenmp-version=50 ! OpenMP Version 5.0 ! Check OpenMP construct validity for the following directives: @@ -42,7 +42,6 @@ program main !$omp end teams end do - !WARNING: OpenMP directive MASTER has been deprecated, please use MASKED instead. !$omp master !ERROR: TEAMS region can only be strictly nested within the implicit parallel region or TARGET region !$omp teams diff --git a/external/llvm-project/flang/test/Semantics/OpenMP/ordered-simd.f90 b/external/llvm-project/flang/test/Semantics/OpenMP/ordered-simd.f90 index c90ffb3bd1c5..f46c46269fab 100644 --- a/external/llvm-project/flang/test/Semantics/OpenMP/ordered-simd.f90 +++ b/external/llvm-project/flang/test/Semantics/OpenMP/ordered-simd.f90 @@ -1,4 +1,4 @@ -! RUN: %python %S/../test_errors.py %s %flang -fopenmp +! RUN: %python %S/../test_errors.py %s %flang -fopenmp -fopenmp-version=50 ! OpenMP Version 4.5 ! Various checks with the ordered construct @@ -95,7 +95,6 @@ SUBROUTINE ORDERED_BAD(N) !$OMP CRITICAL C = C - A * B - !WARNING: OpenMP directive MASTER has been deprecated, please use MASKED instead. !$OMP MASTER DO I = 1,N !ERROR: `ORDERED` region may not be closely nested inside of `CRITICAL`, `ORDERED`, explicit `TASK` or `TASKLOOP` region. @@ -108,7 +107,6 @@ SUBROUTINE ORDERED_BAD(N) !$OMP ORDERED C = C - A * B - !WARNING: OpenMP directive MASTER has been deprecated, please use MASKED instead. !$OMP MASTER DO I = 1,N !ERROR: `ORDERED` region may not be closely nested inside of `CRITICAL`, `ORDERED`, explicit `TASK` or `TASKLOOP` region. @@ -121,7 +119,6 @@ SUBROUTINE ORDERED_BAD(N) !$OMP TASK C = C - A * B - !WARNING: OpenMP directive MASTER has been deprecated, please use MASKED instead. !ERROR: `MASTER` region may not be closely nested inside of `WORKSHARING`, `LOOP`, `TASK`, `TASKLOOP`, or `ATOMIC` region. !$OMP MASTER DO I = 1,N @@ -136,7 +133,6 @@ SUBROUTINE ORDERED_BAD(N) !$OMP TASKLOOP DO J= 1,N C = C - A * B - !WARNING: OpenMP directive MASTER has been deprecated, please use MASKED instead. !ERROR: `MASTER` region may not be closely nested inside of `WORKSHARING`, `LOOP`, `TASK`, `TASKLOOP`, or `ATOMIC` region. !$OMP MASTER DO I = 1,N diff --git a/external/llvm-project/flang/test/Semantics/OpenMP/parallel-master-goto.f90 b/external/llvm-project/flang/test/Semantics/OpenMP/parallel-master-goto.f90 index 72c8002ab4c5..5167f6657ef0 100644 --- a/external/llvm-project/flang/test/Semantics/OpenMP/parallel-master-goto.f90 +++ b/external/llvm-project/flang/test/Semantics/OpenMP/parallel-master-goto.f90 @@ -1,4 +1,4 @@ -! RUN: %python %S/../test_errors.py %s %flang -fopenmp +! RUN: %python %S/../test_errors.py %s %flang -fopenmp -fopenmp-version=50 ! Regression test for #143229 !$omp parallel @@ -7,7 +7,6 @@ !ERROR: invalid branch leaving an OpenMP structured block goto 10 end do -!WARNING: OpenMP directive MASTER has been deprecated, please use MASKED instead. !$omp master 10 print *, i !$omp end master diff --git a/external/llvm-project/flang/test/Semantics/OpenMP/parallel-sections01.f90 b/external/llvm-project/flang/test/Semantics/OpenMP/parallel-sections01.f90 index 6c5a053bf49c..19448258af76 100644 --- a/external/llvm-project/flang/test/Semantics/OpenMP/parallel-sections01.f90 +++ b/external/llvm-project/flang/test/Semantics/OpenMP/parallel-sections01.f90 @@ -35,6 +35,8 @@ program OmpConstructSections01 !$omp section print *, "This is a single statement structured block" !$omp section + !ERROR: invalid branch into an OpenMP structured block + !ERROR: invalid branch leaving an OpenMP structured block open (10, file="random-file-name.txt", err=30) !ERROR: invalid branch into an OpenMP structured block !ERROR: invalid branch leaving an OpenMP structured block diff --git a/external/llvm-project/flang/test/Semantics/OpenMP/requires-atomic01.f90 b/external/llvm-project/flang/test/Semantics/OpenMP/requires-atomic01.f90 deleted file mode 100644 index e8817c3f5ef6..000000000000 --- a/external/llvm-project/flang/test/Semantics/OpenMP/requires-atomic01.f90 +++ /dev/null @@ -1,121 +0,0 @@ -! RUN: %flang_fc1 -fopenmp -fopenmp-version=50 -fdebug-dump-parse-tree %s 2>&1 | FileCheck %s -! Ensure that requires atomic_default_mem_order is used to update atomic -! operations with no explicit memory order set. -program requires - implicit none - !$omp requires atomic_default_mem_order(seq_cst) - integer :: i, j - - ! ---------------------------------------------------------------------------- - ! READ - ! ---------------------------------------------------------------------------- - - ! CHECK-LABEL: OpenMPAtomicConstruct - ! CHECK: OmpClause -> Read - ! CHECK: OmpClause -> SeqCst - !$omp atomic read - i = j - - ! CHECK-LABEL: OpenMPAtomicConstruct - ! CHECK-NOT: OmpClause -> SeqCst - ! CHECK: OmpClause -> Relaxed - ! CHECK: OmpClause -> Read - !$omp atomic relaxed read - i = j - - ! CHECK-LABEL: OpenMPAtomicConstruct - ! CHECK: OmpClause -> Read - ! CHECK-NOT: OmpClause -> SeqCst - ! CHECK: OmpClause -> Relaxed - !$omp atomic read relaxed - i = j - - ! ---------------------------------------------------------------------------- - ! WRITE - ! ---------------------------------------------------------------------------- - - ! CHECK-LABEL: OpenMPAtomicConstruct - ! CHECK: OmpClause -> Write - ! CHECK: OmpClause -> SeqCst - !$omp atomic write - i = j - - ! CHECK-LABEL: OpenMPAtomicConstruct - ! CHECK-NOT: OmpClause -> SeqCst - ! CHECK: OmpClause -> Relaxed - ! CHECK: OmpClause -> Write - !$omp atomic relaxed write - i = j - - ! CHECK-LABEL: OpenMPAtomicConstruct - ! CHECK: OmpClause -> Write - ! CHECK-NOT: OmpClause -> SeqCst - ! CHECK: OmpClause -> Relaxed - !$omp atomic write relaxed - i = j - - ! ---------------------------------------------------------------------------- - ! UPDATE - ! ---------------------------------------------------------------------------- - - ! CHECK-LABEL: OpenMPAtomicConstruct - ! CHECK: OmpClause -> Update - ! CHECK: OmpClause -> SeqCst - !$omp atomic update - i = i + j - - ! CHECK-LABEL: OpenMPAtomicConstruct - ! CHECK-NOT: OmpClause -> SeqCst - ! CHECK: OmpClause -> Relaxed - ! CHECK: OmpClause -> Update - !$omp atomic relaxed update - i = i + j - - ! CHECK-LABEL: OpenMPAtomicConstruct - ! CHECK: OmpClause -> Update - ! CHECK-NOT: OmpClause -> SeqCst - ! CHECK: OmpClause -> Relaxed - !$omp atomic update relaxed - i = i + j - - ! CHECK-LABEL: OpenMPAtomicConstruct - ! CHECK: OmpClause -> SeqCst - !$omp atomic - i = i + j - - ! CHECK-LABEL: OpenMPAtomicConstruct - ! CHECK-NOT: OmpClause -> SeqCst - ! CHECK: OmpClause -> Relaxed - !$omp atomic relaxed - i = i + j - - ! ---------------------------------------------------------------------------- - ! CAPTURE - ! ---------------------------------------------------------------------------- - - ! CHECK-LABEL: OpenMPAtomicConstruct - ! CHECK: OmpClause -> Capture - ! CHECK: OmpClause -> SeqCst - !$omp atomic capture - i = j - j = j + 1 - !$omp end atomic - - ! CHECK-LABEL: OpenMPAtomicConstruct - ! CHECK-NOT: OmpClause -> SeqCst - ! CHECK: OmpClause -> Relaxed - ! CHECK: OmpClause -> Capture - !$omp atomic relaxed capture - i = j - j = j + 1 - !$omp end atomic - - ! CHECK-LABEL: OpenMPAtomicConstruct - ! CHECK: OmpClause -> Capture - ! CHECK-NOT: OmpClause -> SeqCst - ! CHECK: OmpClause -> Relaxed - !$omp atomic capture relaxed - i = j - j = j + 1 - !$omp end atomic -end program requires diff --git a/external/llvm-project/flang/test/Semantics/OpenMP/requires-atomic02.f90 b/external/llvm-project/flang/test/Semantics/OpenMP/requires-atomic02.f90 deleted file mode 100644 index 04a9b7a09aa9..000000000000 --- a/external/llvm-project/flang/test/Semantics/OpenMP/requires-atomic02.f90 +++ /dev/null @@ -1,121 +0,0 @@ -! RUN: %flang_fc1 -fopenmp -fopenmp-version=50 -fdebug-dump-parse-tree %s 2>&1 | FileCheck %s -! Ensure that requires atomic_default_mem_order is used to update atomic -! operations with no explicit memory order set. ACQ_REL clause tested here. -program requires - implicit none - !$omp requires atomic_default_mem_order(acq_rel) - integer :: i, j - - ! ---------------------------------------------------------------------------- - ! READ - ! ---------------------------------------------------------------------------- - - ! CHECK-LABEL: OpenMPAtomicConstruct - ! CHECK: OmpClause -> Read - ! CHECK: OmpClause -> Acquire - !$omp atomic read - i = j - - ! CHECK-LABEL: OpenMPAtomicConstruct - ! CHECK-NOT: OmpClause -> AcqRel - ! CHECK: OmpClause -> Relaxed - ! CHECK: OmpClause -> Read - !$omp atomic relaxed read - i = j - - ! CHECK-LABEL: OpenMPAtomicConstruct - ! CHECK: OmpClause -> Read - ! CHECK-NOT: OmpClause -> AcqRel - ! CHECK: OmpClause -> Relaxed - !$omp atomic read relaxed - i = j - - ! ---------------------------------------------------------------------------- - ! WRITE - ! ---------------------------------------------------------------------------- - - ! CHECK-LABEL: OpenMPAtomicConstruct - ! CHECK: OmpClause -> Write - ! CHECK: OmpClause -> Release - !$omp atomic write - i = j - - ! CHECK-LABEL: OpenMPAtomicConstruct - ! CHECK-NOT: OmpClause -> AcqRel - ! CHECK: OmpClause -> Relaxed - ! CHECK: OmpClause -> Write - !$omp atomic relaxed write - i = j - - ! CHECK-LABEL: OpenMPAtomicConstruct - ! CHECK: OmpClause -> Write - ! CHECK-NOT: OmpClause -> AcqRel - ! CHECK: OmpClause -> Relaxed - !$omp atomic write relaxed - i = j - - ! ---------------------------------------------------------------------------- - ! UPDATE - ! ---------------------------------------------------------------------------- - - ! CHECK-LABEL: OpenMPAtomicConstruct - ! CHECK: OmpClause -> Update - ! CHECK: OmpClause -> Release - !$omp atomic update - i = i + j - - ! CHECK-LABEL: OpenMPAtomicConstruct - ! CHECK-NOT: OmpClause -> AcqRel - ! CHECK: OmpClause -> Relaxed - ! CHECK: OmpClause -> Update - !$omp atomic relaxed update - i = i + j - - ! CHECK-LABEL: OpenMPAtomicConstruct - ! CHECK: OmpClause -> Update - ! CHECK-NOT: OmpClause -> AcqRel - ! CHECK: OmpClause -> Relaxed - !$omp atomic update relaxed - i = i + j - - ! CHECK-LABEL: OpenMPAtomicConstruct - ! CHECK: OmpClause -> Release - !$omp atomic - i = i + j - - ! CHECK-LABEL: OpenMPAtomicConstruct - ! CHECK-NOT: OmpClause -> AcqRel - ! CHECK: OmpClause -> Relaxed - !$omp atomic relaxed - i = i + j - - ! ---------------------------------------------------------------------------- - ! CAPTURE - ! ---------------------------------------------------------------------------- - - ! CHECK-LABEL: OpenMPAtomicConstruct - ! CHECK: OmpClause -> Capture - ! CHECK: OmpClause -> AcqRel - !$omp atomic capture - i = j - j = j + 1 - !$omp end atomic - - ! CHECK-LABEL: OpenMPAtomicConstruct - ! CHECK-NOT: OmpClause -> AcqRel - ! CHECK: OmpClause -> Relaxed - ! CHECK: OmpClause -> Capture - !$omp atomic relaxed capture - i = j - j = j + 1 - !$omp end atomic - - ! CHECK-LABEL: OpenMPAtomicConstruct - ! CHECK-NOT: OmpClause -> AcqRel - ! CHECK: OmpClause -> Capture - ! CHECK: OmpClause -> Relaxed - !$omp atomic capture relaxed - i = j - j = j + 1 - !$omp end atomic -end program requires diff --git a/external/llvm-project/flang/test/Semantics/OpenMP/sections-goto.f90 b/external/llvm-project/flang/test/Semantics/OpenMP/sections-goto.f90 new file mode 100644 index 000000000000..9fa9df9f50b9 --- /dev/null +++ b/external/llvm-project/flang/test/Semantics/OpenMP/sections-goto.f90 @@ -0,0 +1,11 @@ +! RUN: %python %S/../test_errors.py %s %flang -fopenmp +! Regression test for #143231 + +!$omp sections +! ERROR: invalid branch into an OpenMP structured block +! ERROR: invalid branch leaving an OpenMP structured block +goto 10 +!$omp section +10 print *, "Invalid jump" +!$omp end sections +end diff --git a/external/llvm-project/flang/test/Semantics/OpenMP/sections02.f90 b/external/llvm-project/flang/test/Semantics/OpenMP/sections02.f90 index ee29922a72c0..8144b491071d 100644 --- a/external/llvm-project/flang/test/Semantics/OpenMP/sections02.f90 +++ b/external/llvm-project/flang/test/Semantics/OpenMP/sections02.f90 @@ -19,6 +19,8 @@ program OmpConstructSections01 !$omp section print *, "This is a single statement structured block" !$omp section + !ERROR: invalid branch into an OpenMP structured block + !ERROR: invalid branch leaving an OpenMP structured block open (10, file="random-file-name.txt", err=30) !ERROR: invalid branch into an OpenMP structured block !ERROR: invalid branch leaving an OpenMP structured block diff --git a/external/llvm-project/flang/test/Semantics/allocate11.f90 b/external/llvm-project/flang/test/Semantics/allocate11.f90 index 1b7495e9fc07..8aeb069df09f 100644 --- a/external/llvm-project/flang/test/Semantics/allocate11.f90 +++ b/external/llvm-project/flang/test/Semantics/allocate11.f90 @@ -163,6 +163,7 @@ subroutine C938_C947(var2, ptr, ptr2, fptr, my_team, srca) allocate(var2(2)[5:*], MOLD=my_team) !ERROR: SOURCE or MOLD expression type must not be C_PTR or C_FUNPTR from ISO_C_BINDING when an allocatable object is a coarray allocate(var2(2)[5:*], MOLD=ptr) + !ERROR: Allocation has extent 2 on dimension 1, but SOURCE= has extent 9 !ERROR: SOURCE or MOLD expression type must not be C_PTR or C_FUNPTR from ISO_C_BINDING when an allocatable object is a coarray allocate(var2(2)[5:*], SOURCE=ptr2) !ERROR: SOURCE or MOLD expression type must not be C_PTR or C_FUNPTR from ISO_C_BINDING when an allocatable object is a coarray diff --git a/external/llvm-project/flang/test/Semantics/indirect01.f90 b/external/llvm-project/flang/test/Semantics/indirect01.f90 new file mode 100644 index 000000000000..59850662275d --- /dev/null +++ b/external/llvm-project/flang/test/Semantics/indirect01.f90 @@ -0,0 +1,34 @@ +! This test checks the lowering of OpenMP Indirect Clause when used with the Declare Target directive + +! RUN: not flang -fopenmp -fopenmp-version=52 %s 2>&1 | FileCheck %s + +module functions + implicit none + + interface + function func() result(i) + character(1) :: i + end function + end interface + +contains + function func1() result(i) + !CHECK: The INDIRECT clause cannot be used without the ENTER clause with the DECLARE TARGET directive. + !$omp declare target indirect(.true.) + character(1) :: i + i = 'a' + return + end function +end module + +program main + use functions + implicit none + procedure (func), pointer :: ptr1=>func1 + character(1) :: val1 + + !$omp target map(from: val1) + val1 = ptr1() + !$omp end target + +end program diff --git a/external/llvm-project/flang/test/Semantics/indirect02.f90 b/external/llvm-project/flang/test/Semantics/indirect02.f90 new file mode 100644 index 000000000000..273f8856626b --- /dev/null +++ b/external/llvm-project/flang/test/Semantics/indirect02.f90 @@ -0,0 +1,36 @@ +! This test checks the lowering of OpenMP Indirect Clause when used with the Declare Target directive + +! RUN: not flang -fopenmp -fopenmp-version=50 %s 2>&1 | FileCheck %s --check-prefix="CHECK-50" +! RUN: not flang -fopenmp -fopenmp-version=52 %s 2>&1 | FileCheck %s --check-prefix="CHECK-52" + +module functions + implicit none + + interface + function func() result(i) + character(1) :: i + end function + end interface + +contains + function func1() result(i) + !CHECK-50: INDIRECT clause is not allowed on directive DECLARE TARGET in OpenMP v5.0, try -fopenmp-version=51 + !CHECK-52: not yet implemented: Unhandled clause INDIRECT in DECLARE TARGET construct + !$omp declare target enter(func1) indirect(.true.) + character(1) :: i + i = 'a' + return + end function +end module + +program main + use functions + implicit none + procedure (func), pointer :: ptr1=>func1 + character(1) :: val1 + + !$omp target map(from: val1) + val1 = ptr1() + !$omp end target + +end program diff --git a/external/llvm-project/flang/test/Semantics/modfile71.F90 b/external/llvm-project/flang/test/Semantics/modfile71.F90 index 7c3c7f5b4895..7f32eb18c6f8 100644 --- a/external/llvm-project/flang/test/Semantics/modfile71.F90 +++ b/external/llvm-project/flang/test/Semantics/modfile71.F90 @@ -1,6 +1,7 @@ -!RUN: %flang_fc1 -fsyntax-only -fhermetic-module-files -DSTEP=1 %s -!RUN: %flang_fc1 -fsyntax-only -DSTEP=2 %s -!RUN: not %flang_fc1 -fsyntax-only -pedantic %s 2>&1 | FileCheck %s +!RUN: rm -rf %t && mkdir -p %t +!RUN: %flang_fc1 -fsyntax-only -fhermetic-module-files -DSTEP=1 -J%t %s +!RUN: %flang_fc1 -fsyntax-only -DSTEP=2 -J%t %s +!RUN: not %flang_fc1 -fsyntax-only -pedantic -J%t %s 2>&1 | FileCheck %s ! Tests that a module captured in a hermetic module file is compatible when ! USE'd with a module of the same name USE'd directly. diff --git a/external/llvm-project/flang/test/Semantics/modfile75.F90 b/external/llvm-project/flang/test/Semantics/modfile75.F90 index aba00ffac848..8f7adafe7204 100644 --- a/external/llvm-project/flang/test/Semantics/modfile75.F90 +++ b/external/llvm-project/flang/test/Semantics/modfile75.F90 @@ -1,4 +1,5 @@ -!RUN: %flang -c -fhermetic-module-files -DWHICH=1 %s && %flang -c -fhermetic-module-files -DWHICH=2 %s && %flang_fc1 -fdebug-unparse %s | FileCheck %s +!RUN: rm -rf %t && mkdir -p %t +!RUN: %flang -c -fhermetic-module-files -DWHICH=1 -J%t %s && %flang -c -fhermetic-module-files -DWHICH=2 -J%t %s && %flang_fc1 -fdebug-unparse -J%t %s | FileCheck %s #if WHICH == 1 module modfile75a diff --git a/external/llvm-project/flang/test/Semantics/modfile76.F90 b/external/llvm-project/flang/test/Semantics/modfile76.F90 index 50ee9a088e11..c7ae91bd42be 100644 --- a/external/llvm-project/flang/test/Semantics/modfile76.F90 +++ b/external/llvm-project/flang/test/Semantics/modfile76.F90 @@ -1,23 +1,24 @@ -!RUN: %flang_fc1 -fsyntax-only -fhermetic-module-files -DSTEP=1 %s -!RUN: %flang_fc1 -fsyntax-only %s +!RUN: rm -rf %t && mkdir -p %t +!RUN: %flang_fc1 -fsyntax-only -fhermetic-module-files -DSTEP=1 -J%t %s +!RUN: %flang_fc1 -fsyntax-only -J%t %s ! Tests that a BIND(C) variable in a module A captured in a hermetic module ! file USE'd in a module B is not creating bogus complaints about BIND(C) name ! conflict when both module A and B are later accessed. #if STEP == 1 -module modfile75a +module modfile76a integer, bind(c) :: x end -module modfile75b - use modfile75a ! capture hermetically +module modfile76b + use modfile76a ! capture hermetically end #else subroutine test - use modfile75a - use modfile75b + use modfile76a + use modfile76b implicit none print *, x end subroutine diff --git a/external/llvm-project/flang/test/Semantics/modfile77.F90 b/external/llvm-project/flang/test/Semantics/modfile77.F90 index a82904ebbcc2..9ad615c16c43 100644 --- a/external/llvm-project/flang/test/Semantics/modfile77.F90 +++ b/external/llvm-project/flang/test/Semantics/modfile77.F90 @@ -1,4 +1,5 @@ -!RUN: %flang -c -fhermetic-module-files -DWHICH=1 %s && %flang -c -fhermetic-module-files -DWHICH=2 %s && %flang -c -fhermetic-module-files %s && cat modfile77c.mod | FileCheck %s +!RUN: rm -rf %t && mkdir -p %t +!RUN: %flang -c -fhermetic-module-files -DWHICH=1 -J%t %s && %flang -c -fhermetic-module-files -DWHICH=2 -J%t %s && %flang -c -fhermetic-module-files -J%t %s && cat %t/modfile77c.mod | FileCheck %s #if WHICH == 1 module modfile77a diff --git a/external/llvm-project/flang/test/Semantics/modfile78.F90 b/external/llvm-project/flang/test/Semantics/modfile78.F90 index cb3eccd9a410..19b9ac39de93 100644 --- a/external/llvm-project/flang/test/Semantics/modfile78.F90 +++ b/external/llvm-project/flang/test/Semantics/modfile78.F90 @@ -1,4 +1,5 @@ -!RUN: %flang -c -fhermetic-module-files -DWHICH=1 %s && %flang -c -fhermetic-module-files -DWHICH=2 %s && %flang -c -fhermetic-module-files %s && cat modfile78c.mod | FileCheck %s +!RUN: rm -rf %t && mkdir -p %t +!RUN: %flang -c -fhermetic-module-files -DWHICH=1 -J%t %s && %flang -c -fhermetic-module-files -DWHICH=2 -J%t %s && %flang -c -fhermetic-module-files -J%t %s && cat %t/modfile78c.mod | FileCheck %s #if WHICH == 1 module modfile78a diff --git a/external/llvm-project/flang/test/Semantics/modfile79.F90 b/external/llvm-project/flang/test/Semantics/modfile79.F90 new file mode 100644 index 000000000000..ae156527b3bf --- /dev/null +++ b/external/llvm-project/flang/test/Semantics/modfile79.F90 @@ -0,0 +1,34 @@ +!RUN: rm -rf %t && mkdir -p %t +!RUN: %flang -c -DWHICH=1 -J%t %s && FileCheck %s <%t/modfile79a.mod && %flang -c -fhermetic-module-files -DWHICH=2 -J%t %s && %flang -c -J%t %s && FileCheck %s <%t/modfile79a.mod + +!Ensure that writing modfile79c.mod doesn't cause a spurious +!regeneration of modfile79a.mod from its copy in the hermetic +!module file modfile79b.mod. +!CHECK: !mod$ v1 sum:93ec75fe672c5b6c +!CHECK-NEXT: module modfile79a + +#if WHICH == 1 +module modfile79a + interface foo + module procedure foo + end interface + contains + subroutine foo + end +end +#elif WHICH == 2 +module modfile79b + use modfile79a + interface bar + procedure foo + end interface +end +#else +module modfile79c + use modfile79b + contains + subroutine test + call bar + end +end +#endif diff --git a/external/llvm-project/flang/test/Semantics/typeinfo01.f90 b/external/llvm-project/flang/test/Semantics/typeinfo01.f90 index d228cd2a84ca..bb20c546e026 100644 --- a/external/llvm-project/flang/test/Semantics/typeinfo01.f90 +++ b/external/llvm-project/flang/test/Semantics/typeinfo01.f90 @@ -8,7 +8,7 @@ module m01 end type !CHECK: Module scope: m01 !CHECK: .c.t1, SAVE, TARGET (CompilerCreated, ReadOnly): ObjectEntity type: TYPE(component) shape: 0_8:0_8 init:[component::component(name=.n.n,genre=1_1,category=0_1,kind=4_1,rank=0_1,offset=0_8,characterlen=value(genre=1_1,value=0_8),derived=NULL(),lenvalue=NULL(),bounds=NULL(),initialization=NULL())] -!CHECK: .dt.t1, SAVE, TARGET (CompilerCreated, ReadOnly): ObjectEntity type: TYPE(derivedtype) init:derivedtype(binding=NULL(),name=.n.t1,sizeinbytes=4_8,uninstantiated=NULL(),kindparameter=NULL(),lenparameterkind=NULL(),component=.c.t1,procptr=NULL(),special=NULL(),specialbitset=0_4,hasparent=0_1,noinitializationneeded=1_1,nodestructionneeded=1_1,nofinalizationneeded=1_1) +!CHECK: .dt.t1, SAVE, TARGET (CompilerCreated, ReadOnly): ObjectEntity type: TYPE(derivedtype) init:derivedtype(binding=NULL(),name=.n.t1,sizeinbytes=4_8,uninstantiated=NULL(),kindparameter=NULL(),lenparameterkind=NULL(),component=.c.t1,procptr=NULL(),special=NULL(),specialbitset=0_4,hasparent=0_1,noinitializationneeded=1_1,nodestructionneeded=1_1,nofinalizationneeded=1_1,nodefinedassignment=1_1) !CHECK: .n.n, SAVE, TARGET (CompilerCreated, ReadOnly): ObjectEntity type: CHARACTER(1_8,1) init:"n" !CHECK: .n.t1, SAVE, TARGET (CompilerCreated, ReadOnly): ObjectEntity type: CHARACTER(2_8,1) init:"t1" !CHECK: DerivedType scope: t1 @@ -23,8 +23,8 @@ module m02 end type !CHECK: .c.child, SAVE, TARGET (CompilerCreated, ReadOnly): ObjectEntity type: TYPE(component) shape: 0_8:1_8 init:[component::component(name=.n.parent,genre=1_1,category=6_1,kind=0_1,rank=0_1,offset=0_8,characterlen=value(genre=1_1,value=0_8),derived=.dt.parent,lenvalue=NULL(),bounds=NULL(),initialization=NULL()),component(name=.n.cn,genre=1_1,category=0_1,kind=4_1,rank=0_1,offset=4_8,characterlen=value(genre=1_1,value=0_8),derived=NULL(),lenvalue=NULL(),bounds=NULL(),initialization=NULL())] !CHECK: .c.parent, SAVE, TARGET (CompilerCreated, ReadOnly): ObjectEntity type: TYPE(component) shape: 0_8:0_8 init:[component::component(name=.n.pn,genre=1_1,category=0_1,kind=4_1,rank=0_1,offset=0_8,characterlen=value(genre=1_1,value=0_8),derived=NULL(),lenvalue=NULL(),bounds=NULL(),initialization=NULL())] -!CHECK: .dt.child, SAVE, TARGET (CompilerCreated, ReadOnly): ObjectEntity type: TYPE(derivedtype) init:derivedtype(binding=NULL(),name=.n.child,sizeinbytes=8_8,uninstantiated=NULL(),kindparameter=NULL(),lenparameterkind=NULL(),component=.c.child,procptr=NULL(),special=NULL(),specialbitset=0_4,hasparent=1_1,noinitializationneeded=1_1,nodestructionneeded=1_1,nofinalizationneeded=1_1) -!CHECK: .dt.parent, SAVE, TARGET (CompilerCreated, ReadOnly): ObjectEntity type: TYPE(derivedtype) init:derivedtype(binding=NULL(),name=.n.parent,sizeinbytes=4_8,uninstantiated=NULL(),kindparameter=NULL(),lenparameterkind=NULL(),component=.c.parent,procptr=NULL(),special=NULL(),specialbitset=0_4,hasparent=0_1,noinitializationneeded=1_1,nodestructionneeded=1_1,nofinalizationneeded=1_1) +!CHECK: .dt.child, SAVE, TARGET (CompilerCreated, ReadOnly): ObjectEntity type: TYPE(derivedtype) init:derivedtype(binding=NULL(),name=.n.child,sizeinbytes=8_8,uninstantiated=NULL(),kindparameter=NULL(),lenparameterkind=NULL(),component=.c.child,procptr=NULL(),special=NULL(),specialbitset=0_4,hasparent=1_1,noinitializationneeded=1_1,nodestructionneeded=1_1,nofinalizationneeded=1_1,nodefinedassignment=1_1) +!CHECK: .dt.parent, SAVE, TARGET (CompilerCreated, ReadOnly): ObjectEntity type: TYPE(derivedtype) init:derivedtype(binding=NULL(),name=.n.parent,sizeinbytes=4_8,uninstantiated=NULL(),kindparameter=NULL(),lenparameterkind=NULL(),component=.c.parent,procptr=NULL(),special=NULL(),specialbitset=0_4,hasparent=0_1,noinitializationneeded=1_1,nodestructionneeded=1_1,nofinalizationneeded=1_1,nodefinedassignment=1_1) end module module m03 @@ -35,7 +35,7 @@ module m03 type(kpdt(4)) :: x !CHECK: .c.kpdt.4, SAVE, TARGET (CompilerCreated, ReadOnly): ObjectEntity type: TYPE(component) shape: 0_8:0_8 init:[component::component(name=.n.a,genre=1_1,category=2_1,kind=4_1,rank=0_1,offset=0_8,characterlen=value(genre=1_1,value=0_8),derived=NULL(),lenvalue=NULL(),bounds=NULL(),initialization=NULL())] !CHECK: .dt.kpdt, SAVE, TARGET (CompilerCreated, ReadOnly): ObjectEntity type: TYPE(derivedtype) init:derivedtype(name=.n.kpdt,uninstantiated=NULL(),kindparameter=.kp.kpdt,lenparameterkind=NULL()) -!CHECK: .dt.kpdt.4, SAVE, TARGET (CompilerCreated, ReadOnly): ObjectEntity type: TYPE(derivedtype) init:derivedtype(binding=NULL(),name=.n.kpdt,sizeinbytes=4_8,uninstantiated=.dt.kpdt,kindparameter=.kp.kpdt.4,lenparameterkind=NULL(),component=.c.kpdt.4,procptr=NULL(),special=NULL(),specialbitset=0_4,hasparent=0_1,noinitializationneeded=1_1,nodestructionneeded=1_1,nofinalizationneeded=1_1) +!CHECK: .dt.kpdt.4, SAVE, TARGET (CompilerCreated, ReadOnly): ObjectEntity type: TYPE(derivedtype) init:derivedtype(binding=NULL(),name=.n.kpdt,sizeinbytes=4_8,uninstantiated=.dt.kpdt,kindparameter=.kp.kpdt.4,lenparameterkind=NULL(),component=.c.kpdt.4,procptr=NULL(),special=NULL(),specialbitset=0_4,hasparent=0_1,noinitializationneeded=1_1,nodestructionneeded=1_1,nofinalizationneeded=1_1,nodefinedassignment=1_1) !CHECK: .kp.kpdt.4, SAVE, TARGET (CompilerCreated, ReadOnly): ObjectEntity type: INTEGER(8) shape: 0_8:0_8 init:[INTEGER(8)::4_8] end module @@ -49,7 +49,7 @@ module m04 subroutine s1(x) class(tbps), intent(in) :: x end subroutine -!CHECK: .dt.tbps, SAVE, TARGET (CompilerCreated, ReadOnly): ObjectEntity type: TYPE(derivedtype) init:derivedtype(binding=.v.tbps,name=.n.tbps,sizeinbytes=0_8,uninstantiated=NULL(),kindparameter=NULL(),lenparameterkind=NULL(),component=NULL(),procptr=NULL(),special=NULL(),specialbitset=0_4,hasparent=0_1,noinitializationneeded=1_1,nodestructionneeded=1_1,nofinalizationneeded=1_1) +!CHECK: .dt.tbps, SAVE, TARGET (CompilerCreated, ReadOnly): ObjectEntity type: TYPE(derivedtype) init:derivedtype(binding=.v.tbps,name=.n.tbps,sizeinbytes=0_8,uninstantiated=NULL(),kindparameter=NULL(),lenparameterkind=NULL(),component=NULL(),procptr=NULL(),special=NULL(),specialbitset=0_4,hasparent=0_1,noinitializationneeded=1_1,nodestructionneeded=1_1,nofinalizationneeded=1_1,nodefinedassignment=1_1) !CHECK: .v.tbps, SAVE, TARGET (CompilerCreated, ReadOnly): ObjectEntity type: TYPE(binding) shape: 0_8:1_8 init:[binding::binding(proc=s1,name=.n.b1),binding(proc=s1,name=.n.b2)] end module @@ -61,7 +61,7 @@ module m05 subroutine s1(x) class(t), intent(in) :: x end subroutine -!CHECK: .dt.t, SAVE, TARGET (CompilerCreated, ReadOnly): ObjectEntity type: TYPE(derivedtype) init:derivedtype(binding=NULL(),name=.n.t,sizeinbytes=8_8,uninstantiated=NULL(),kindparameter=NULL(),lenparameterkind=NULL(),component=NULL(),procptr=.p.t,special=NULL(),specialbitset=0_4,hasparent=0_1,noinitializationneeded=0_1,nodestructionneeded=1_1,nofinalizationneeded=1_1) +!CHECK: .dt.t, SAVE, TARGET (CompilerCreated, ReadOnly): ObjectEntity type: TYPE(derivedtype) init:derivedtype(binding=NULL(),name=.n.t,sizeinbytes=8_8,uninstantiated=NULL(),kindparameter=NULL(),lenparameterkind=NULL(),component=NULL(),procptr=.p.t,special=NULL(),specialbitset=0_4,hasparent=0_1,noinitializationneeded=0_1,nodestructionneeded=1_1,nofinalizationneeded=1_1,nodefinedassignment=1_1) !CHECK: .p.t, SAVE, TARGET (CompilerCreated, ReadOnly): ObjectEntity type: TYPE(procptrcomponent) shape: 0_8:0_8 init:[procptrcomponent::procptrcomponent(name=.n.p1,offset=0_8,initialization=s1)] end module @@ -85,8 +85,8 @@ subroutine s2(x, y) class(t), intent(in) :: y end subroutine !CHECK: .c.t2, SAVE, TARGET (CompilerCreated, ReadOnly): ObjectEntity type: TYPE(component) shape: 0_8:0_8 init:[component::component(name=.n.t,genre=1_1,category=6_1,kind=0_1,rank=0_1,offset=0_8,characterlen=value(genre=1_1,value=0_8),derived=.dt.t,lenvalue=NULL(),bounds=NULL(),initialization=NULL())] -!CHECK: .dt.t, SAVE, TARGET (CompilerCreated, ReadOnly): ObjectEntity type: TYPE(derivedtype) init:derivedtype(binding=.v.t,name=.n.t,sizeinbytes=0_8,uninstantiated=NULL(),kindparameter=NULL(),lenparameterkind=NULL(),component=NULL(),procptr=NULL(),special=.s.t,specialbitset=2_4,hasparent=0_1,noinitializationneeded=1_1,nodestructionneeded=1_1,nofinalizationneeded=1_1) -!CHECK: .dt.t2, SAVE, TARGET (CompilerCreated, ReadOnly): ObjectEntity type: TYPE(derivedtype) init:derivedtype(binding=.v.t2,name=.n.t2,sizeinbytes=0_8,uninstantiated=NULL(),kindparameter=NULL(),lenparameterkind=NULL(),component=.c.t2,procptr=NULL(),special=.s.t2,specialbitset=2_4,hasparent=1_1,noinitializationneeded=1_1,nodestructionneeded=1_1,nofinalizationneeded=1_1) +!CHECK: .dt.t, SAVE, TARGET (CompilerCreated, ReadOnly): ObjectEntity type: TYPE(derivedtype) init:derivedtype(binding=.v.t,name=.n.t,sizeinbytes=0_8,uninstantiated=NULL(),kindparameter=NULL(),lenparameterkind=NULL(),component=NULL(),procptr=NULL(),special=.s.t,specialbitset=2_4,hasparent=0_1,noinitializationneeded=1_1,nodestructionneeded=1_1,nofinalizationneeded=1_1,nodefinedassignment=0_1) +!CHECK: .dt.t2, SAVE, TARGET (CompilerCreated, ReadOnly): ObjectEntity type: TYPE(derivedtype) init:derivedtype(binding=.v.t2,name=.n.t2,sizeinbytes=0_8,uninstantiated=NULL(),kindparameter=NULL(),lenparameterkind=NULL(),component=.c.t2,procptr=NULL(),special=.s.t2,specialbitset=2_4,hasparent=1_1,noinitializationneeded=1_1,nodestructionneeded=1_1,nofinalizationneeded=1_1,nodefinedassignment=0_1) !CHECK: .s.t, SAVE, TARGET (CompilerCreated, ReadOnly): ObjectEntity type: TYPE(specialbinding) shape: 0_8:0_8 init:[specialbinding::specialbinding(which=1_1,isargdescriptorset=3_1,istypebound=1_1,isargcontiguousset=0_1,proc=s1)] !CHECK: .s.t2, SAVE, TARGET (CompilerCreated, ReadOnly): ObjectEntity type: TYPE(specialbinding) shape: 0_8:0_8 init:[specialbinding::specialbinding(which=1_1,isargdescriptorset=3_1,istypebound=1_1,isargcontiguousset=0_1,proc=s2)] !CHECK: .v.t, SAVE, TARGET (CompilerCreated, ReadOnly): ObjectEntity type: TYPE(binding) shape: 0_8:0_8 init:[binding::binding(proc=s1,name=.n.s1)] @@ -113,8 +113,8 @@ subroutine s2(x, y) class(t2), intent(in) :: y end subroutine !CHECK: .c.t2, SAVE, TARGET (CompilerCreated, ReadOnly): ObjectEntity type: TYPE(component) shape: 0_8:0_8 init:[component::component(name=.n.t,genre=1_1,category=6_1,kind=0_1,rank=0_1,offset=0_8,characterlen=value(genre=1_1,value=0_8),derived=.dt.t,lenvalue=NULL(),bounds=NULL(),initialization=NULL())] -!CHECK: .dt.t, SAVE, TARGET (CompilerCreated, ReadOnly): ObjectEntity type: TYPE(derivedtype) init:derivedtype(binding=.v.t,name=.n.t,sizeinbytes=0_8,uninstantiated=NULL(),kindparameter=NULL(),lenparameterkind=NULL(),component=NULL(),procptr=NULL(),special=.s.t,specialbitset=2_4,hasparent=0_1,noinitializationneeded=1_1,nodestructionneeded=1_1,nofinalizationneeded=1_1) -!CHECK: .dt.t2, SAVE, TARGET (CompilerCreated, ReadOnly): ObjectEntity type: TYPE(derivedtype) init:derivedtype(binding=.v.t2,name=.n.t2,sizeinbytes=0_8,uninstantiated=NULL(),kindparameter=NULL(),lenparameterkind=NULL(),component=.c.t2,procptr=NULL(),special=.s.t2,specialbitset=2_4,hasparent=1_1,noinitializationneeded=1_1,nodestructionneeded=1_1,nofinalizationneeded=1_1) +!CHECK: .dt.t, SAVE, TARGET (CompilerCreated, ReadOnly): ObjectEntity type: TYPE(derivedtype) init:derivedtype(binding=.v.t,name=.n.t,sizeinbytes=0_8,uninstantiated=NULL(),kindparameter=NULL(),lenparameterkind=NULL(),component=NULL(),procptr=NULL(),special=.s.t,specialbitset=2_4,hasparent=0_1,noinitializationneeded=1_1,nodestructionneeded=1_1,nofinalizationneeded=1_1,nodefinedassignment=0_1) +!CHECK: .dt.t2, SAVE, TARGET (CompilerCreated, ReadOnly): ObjectEntity type: TYPE(derivedtype) init:derivedtype(binding=.v.t2,name=.n.t2,sizeinbytes=0_8,uninstantiated=NULL(),kindparameter=NULL(),lenparameterkind=NULL(),component=.c.t2,procptr=NULL(),special=.s.t2,specialbitset=2_4,hasparent=1_1,noinitializationneeded=1_1,nodestructionneeded=1_1,nofinalizationneeded=1_1,nodefinedassignment=0_1) !CHECK: .s.t, SAVE, TARGET (CompilerCreated, ReadOnly): ObjectEntity type: TYPE(specialbinding) shape: 0_8:0_8 init:[specialbinding::specialbinding(which=1_1,isargdescriptorset=3_1,istypebound=1_1,isargcontiguousset=0_1,proc=s1)] !CHECK: .s.t2, SAVE, TARGET (CompilerCreated, ReadOnly): ObjectEntity type: TYPE(specialbinding) shape: 0_8:0_8 init:[specialbinding::specialbinding(which=1_1,isargdescriptorset=3_1,istypebound=1_1,isargcontiguousset=0_1,proc=s2)] !CHECK: .v.t, SAVE, TARGET (CompilerCreated, ReadOnly): ObjectEntity type: TYPE(binding) shape: 0_8:0_8 init:[binding::binding(proc=s1,name=.n.s1)] @@ -132,7 +132,7 @@ impure elemental subroutine s1(x, y) class(t), intent(out) :: x class(t), intent(in) :: y end subroutine -!CHECK: .dt.t, SAVE, TARGET (CompilerCreated, ReadOnly): ObjectEntity type: TYPE(derivedtype) init:derivedtype(binding=.v.t,name=.n.t,sizeinbytes=0_8,uninstantiated=NULL(),kindparameter=NULL(),lenparameterkind=NULL(),component=NULL(),procptr=NULL(),special=.s.t,specialbitset=4_4,hasparent=0_1,noinitializationneeded=1_1,nodestructionneeded=1_1,nofinalizationneeded=1_1) +!CHECK: .dt.t, SAVE, TARGET (CompilerCreated, ReadOnly): ObjectEntity type: TYPE(derivedtype) init:derivedtype(binding=.v.t,name=.n.t,sizeinbytes=0_8,uninstantiated=NULL(),kindparameter=NULL(),lenparameterkind=NULL(),component=NULL(),procptr=NULL(),special=.s.t,specialbitset=4_4,hasparent=0_1,noinitializationneeded=1_1,nodestructionneeded=1_1,nofinalizationneeded=1_1,nodefinedassignment=0_1) !CHECK: .s.t, SAVE, TARGET (CompilerCreated, ReadOnly): ObjectEntity type: TYPE(specialbinding) shape: 0_8:0_8 init:[specialbinding::specialbinding(which=2_1,isargdescriptorset=3_1,istypebound=1_1,isargcontiguousset=0_1,proc=s1)] !CHECK: .v.t, SAVE, TARGET (CompilerCreated, ReadOnly): ObjectEntity type: TYPE(binding) shape: 0_8:0_8 init:[binding::binding(proc=s1,name=.n.s1)] end module @@ -155,8 +155,8 @@ impure elemental subroutine s3(x) subroutine s4(x) type(t), contiguous :: x(:,:,:) end subroutine -!CHECK: .dt.t, SAVE, TARGET (CompilerCreated, ReadOnly): ObjectEntity type: TYPE(derivedtype) init:derivedtype(binding=NULL(),name=.n.t,sizeinbytes=0_8,uninstantiated=NULL(),kindparameter=NULL(),lenparameterkind=NULL(),component=NULL(),procptr=NULL(),special=.s.t,specialbitset=7296_4,hasparent=0_1,noinitializationneeded=1_1,nodestructionneeded=0_1,nofinalizationneeded=0_1) -!CHECK: .s.t, SAVE, TARGET (CompilerCreated, ReadOnly): ObjectEntity type: TYPE(specialbinding) shape: 0_8:3_8 init:[specialbinding::specialbinding(which=7_1,isargdescriptorset=0_1,istypebound=1_1,isargcontiguousset=0_1,proc=s3),specialbinding(which=10_1,isargdescriptorset=1_1,istypebound=1_1,isargcontiguousset=0_1,proc=s1),specialbinding(which=11_1,isargdescriptorset=0_1,istypebound=1_1,isargcontiguousset=1_1,proc=s2),specialbinding(which=12_1,isargdescriptorset=1_1,istypebound=1_1,isargcontiguousset=1_1,proc=s4)] +!CHECK: .dt.t, SAVE, TARGET (CompilerCreated, ReadOnly): ObjectEntity type: TYPE(derivedtype) init:derivedtype(binding=NULL(),name=.n.t,sizeinbytes=0_8,uninstantiated=NULL(),kindparameter=NULL(),lenparameterkind=NULL(),component=NULL(),procptr=NULL(),special=.s.t,specialbitset=7296_4,hasparent=0_1,noinitializationneeded=1_1,nodestructionneeded=0_1,nofinalizationneeded=0_1,nodefinedassignment=1_1) +!CHECK: .s.t, SAVE, TARGET (CompilerCreated, ReadOnly): ObjectEntity type: TYPE(specialbinding) shape: 0_8:3_8 init:[specialbinding::specialbinding(which=7_1,isargdescriptorset=0_1,istypebound=0_1,isargcontiguousset=0_1,proc=s3),specialbinding(which=10_1,isargdescriptorset=1_1,istypebound=0_1,isargcontiguousset=0_1,proc=s1),specialbinding(which=11_1,isargdescriptorset=0_1,istypebound=0_1,isargcontiguousset=1_1,proc=s2),specialbinding(which=12_1,isargdescriptorset=1_1,istypebound=0_1,isargcontiguousset=1_1,proc=s4)] end module module m09 @@ -197,8 +197,8 @@ subroutine wu(x,u,iostat,iomsg) integer, intent(out) :: iostat character(len=*), intent(inout) :: iomsg end subroutine -!CHECK: .dt.t, SAVE, TARGET (CompilerCreated, ReadOnly): ObjectEntity type: TYPE(derivedtype) init:derivedtype(binding=.v.t,name=.n.t,sizeinbytes=0_8,uninstantiated=NULL(),kindparameter=NULL(),lenparameterkind=NULL(),component=NULL(),procptr=NULL(),special=.s.t,specialbitset=120_4,hasparent=0_1,noinitializationneeded=1_1,nodestructionneeded=1_1,nofinalizationneeded=1_1) -!CHECK: .s.t, SAVE, TARGET (CompilerCreated, ReadOnly): ObjectEntity type: TYPE(specialbinding) shape: 0_8:3_8 init:[specialbinding::specialbinding(which=3_1,isargdescriptorset=1_1,istypebound=1_1,isargcontiguousset=0_1,proc=rf),specialbinding(which=4_1,isargdescriptorset=1_1,istypebound=1_1,isargcontiguousset=0_1,proc=ru),specialbinding(which=5_1,isargdescriptorset=1_1,istypebound=1_1,isargcontiguousset=0_1,proc=wf),specialbinding(which=6_1,isargdescriptorset=1_1,istypebound=1_1,isargcontiguousset=0_1,proc=wu)] +!CHECK: .dt.t, SAVE, TARGET (CompilerCreated, ReadOnly): ObjectEntity type: TYPE(derivedtype) init:derivedtype(binding=.v.t,name=.n.t,sizeinbytes=0_8,uninstantiated=NULL(),kindparameter=NULL(),lenparameterkind=NULL(),component=NULL(),procptr=NULL(),special=.s.t,specialbitset=120_4,hasparent=0_1,noinitializationneeded=1_1,nodestructionneeded=1_1,nofinalizationneeded=1_1,nodefinedassignment=1_1) +!CHECK: .s.t, SAVE, TARGET (CompilerCreated, ReadOnly): ObjectEntity type: TYPE(specialbinding) shape: 0_8:3_8 init:[specialbinding::specialbinding(which=3_1,isargdescriptorset=1_1,istypebound=1_1,isargcontiguousset=0_1,proc=rf),specialbinding(which=4_1,isargdescriptorset=1_1,istypebound=2_1,isargcontiguousset=0_1,proc=ru),specialbinding(which=5_1,isargdescriptorset=1_1,istypebound=3_1,isargcontiguousset=0_1,proc=wf),specialbinding(which=6_1,isargdescriptorset=1_1,istypebound=4_1,isargcontiguousset=0_1,proc=wu)] !CHECK: .v.t, SAVE, TARGET (CompilerCreated, ReadOnly): ObjectEntity type: TYPE(binding) shape: 0_8:3_8 init:[binding::binding(proc=rf,name=.n.rf),binding(proc=ru,name=.n.ru),binding(proc=wf,name=.n.wf),binding(proc=wu,name=.n.wu)] end module @@ -246,7 +246,7 @@ subroutine wu(x,u,iostat,iomsg) integer, intent(out) :: iostat character(len=*), intent(inout) :: iomsg end subroutine -!CHECK: .dt.t, SAVE, TARGET (CompilerCreated, ReadOnly): ObjectEntity type: TYPE(derivedtype) init:derivedtype(binding=NULL(),name=.n.t,sizeinbytes=0_8,uninstantiated=NULL(),kindparameter=NULL(),lenparameterkind=NULL(),component=NULL(),procptr=NULL(),special=.s.t,specialbitset=120_4,hasparent=0_1,noinitializationneeded=1_1,nodestructionneeded=1_1,nofinalizationneeded=1_1) +!CHECK: .dt.t, SAVE, TARGET (CompilerCreated, ReadOnly): ObjectEntity type: TYPE(derivedtype) init:derivedtype(binding=NULL(),name=.n.t,sizeinbytes=0_8,uninstantiated=NULL(),kindparameter=NULL(),lenparameterkind=NULL(),component=NULL(),procptr=NULL(),special=.s.t,specialbitset=120_4,hasparent=0_1,noinitializationneeded=1_1,nodestructionneeded=1_1,nofinalizationneeded=1_1,nodefinedassignment=1_1) !CHECK: .s.t, SAVE, TARGET (CompilerCreated, ReadOnly): ObjectEntity type: TYPE(specialbinding) shape: 0_8:3_8 init:[specialbinding::specialbinding(which=3_1,isargdescriptorset=0_1,istypebound=0_1,isargcontiguousset=0_1,proc=rf),specialbinding(which=4_1,isargdescriptorset=0_1,istypebound=0_1,isargcontiguousset=0_1,proc=ru),specialbinding(which=5_1,isargdescriptorset=0_1,istypebound=0_1,isargcontiguousset=0_1,proc=wf),specialbinding(which=6_1,isargdescriptorset=0_1,istypebound=0_1,isargcontiguousset=0_1,proc=wu)] end module @@ -263,7 +263,7 @@ module m11 !CHECK: .c.t, SAVE, TARGET (CompilerCreated, ReadOnly): ObjectEntity type: TYPE(component) shape: 0_8:3_8 init:[component::component(name=.n.allocatable,genre=3_1,category=2_1,kind=4_1,rank=1_1,offset=0_8,characterlen=value(genre=1_1,value=0_8),derived=NULL(),lenvalue=NULL(),bounds=NULL(),initialization=NULL()),component(name=.n.pointer,genre=2_1,category=2_1,kind=4_1,rank=0_1,offset=48_8,characterlen=value(genre=1_1,value=0_8),derived=NULL(),lenvalue=NULL(),bounds=NULL(),initialization=.di.t.pointer),component(name=.n.chauto,genre=4_1,category=4_1,kind=1_1,rank=0_1,offset=72_8,characterlen=value(genre=3_1,value=0_8),derived=NULL(),lenvalue=NULL(),bounds=NULL(),initialization=NULL()),component(name=.n.automatic,genre=4_1,category=2_1,kind=4_1,rank=1_1,offset=96_8,characterlen=value(genre=1_1,value=0_8),derived=NULL(),lenvalue=NULL(),bounds=.b.t.automatic,initialization=NULL())] !CHECK: .di.t.pointer, SAVE, TARGET (CompilerCreated, ReadOnly): ObjectEntity type: TYPE(.dp.t.pointer) init:.dp.t.pointer(pointer=target) !CHECK: .dp.t.pointer (CompilerCreated): DerivedType components: pointer -!CHECK: .dt.t, SAVE, TARGET (CompilerCreated, ReadOnly): ObjectEntity type: TYPE(derivedtype) init:derivedtype(binding=NULL(),name=.n.t,sizeinbytes=144_8,uninstantiated=NULL(),kindparameter=NULL(),lenparameterkind=.lpk.t,component=.c.t,procptr=NULL(),special=NULL(),specialbitset=0_4,hasparent=0_1,noinitializationneeded=0_1,nodestructionneeded=0_1,nofinalizationneeded=1_1) +!CHECK: .dt.t, SAVE, TARGET (CompilerCreated, ReadOnly): ObjectEntity type: TYPE(derivedtype) init:derivedtype(binding=NULL(),name=.n.t,sizeinbytes=144_8,uninstantiated=NULL(),kindparameter=NULL(),lenparameterkind=.lpk.t,component=.c.t,procptr=NULL(),special=NULL(),specialbitset=0_4,hasparent=0_1,noinitializationneeded=0_1,nodestructionneeded=0_1,nofinalizationneeded=1_1,nodefinedassignment=1_1) !CHECK: .lpk.t, SAVE, TARGET (CompilerCreated, ReadOnly): ObjectEntity type: INTEGER(1) shape: 0_8:0_8 init:[INTEGER(1)::8_1] !CHECK: DerivedType scope: .dp.t.pointer size=24 alignment=8 instantiation of .dp.t.pointer !CHECK: pointer, POINTER size=24 offset=0: ObjectEntity type: REAL(4) diff --git a/external/llvm-project/flang/test/Semantics/typeinfo03.f90 b/external/llvm-project/flang/test/Semantics/typeinfo03.f90 index f0c0a817da4a..e2552d0a21d6 100644 --- a/external/llvm-project/flang/test/Semantics/typeinfo03.f90 +++ b/external/llvm-project/flang/test/Semantics/typeinfo03.f90 @@ -6,4 +6,4 @@ module m class(*), pointer :: sp, ap(:) end type end module -!CHECK: .dt.haspointer, SAVE, TARGET (CompilerCreated, ReadOnly): ObjectEntity type: TYPE(derivedtype) init:derivedtype(binding=NULL(),name=.n.haspointer,sizeinbytes=104_8,uninstantiated=NULL(),kindparameter=NULL(),lenparameterkind=NULL(),component=.c.haspointer,procptr=NULL(),special=NULL(),specialbitset=0_4,hasparent=0_1,noinitializationneeded=0_1,nodestructionneeded=1_1,nofinalizationneeded=1_1) +!CHECK: .dt.haspointer, SAVE, TARGET (CompilerCreated, ReadOnly): ObjectEntity type: TYPE(derivedtype) init:derivedtype(binding=NULL(),name=.n.haspointer,sizeinbytes=104_8,uninstantiated=NULL(),kindparameter=NULL(),lenparameterkind=NULL(),component=.c.haspointer,procptr=NULL(),special=NULL(),specialbitset=0_4,hasparent=0_1,noinitializationneeded=0_1,nodestructionneeded=1_1,nofinalizationneeded=1_1,nodefinedassignment=1_1) diff --git a/external/llvm-project/flang/test/Semantics/typeinfo04.f90 b/external/llvm-project/flang/test/Semantics/typeinfo04.f90 index de8464321a40..94dd2199db35 100644 --- a/external/llvm-project/flang/test/Semantics/typeinfo04.f90 +++ b/external/llvm-project/flang/test/Semantics/typeinfo04.f90 @@ -7,18 +7,18 @@ module m contains final :: final end type -!CHECK: .dt.finalizable, SAVE, TARGET (CompilerCreated, ReadOnly): ObjectEntity type: TYPE(derivedtype) init:derivedtype(binding=NULL(),name=.n.finalizable,sizeinbytes=0_8,uninstantiated=NULL(),kindparameter=NULL(),lenparameterkind=NULL(),component=NULL(),procptr=NULL(),special=.s.finalizable,specialbitset=128_4,hasparent=0_1,noinitializationneeded=1_1,nodestructionneeded=0_1,nofinalizationneeded=0_1) +!CHECK: .dt.finalizable, SAVE, TARGET (CompilerCreated, ReadOnly): ObjectEntity type: TYPE(derivedtype) init:derivedtype(binding=NULL(),name=.n.finalizable,sizeinbytes=0_8,uninstantiated=NULL(),kindparameter=NULL(),lenparameterkind=NULL(),component=NULL(),procptr=NULL(),special=.s.finalizable,specialbitset=128_4,hasparent=0_1,noinitializationneeded=1_1,nodestructionneeded=0_1,nofinalizationneeded=0_1,nodefinedassignment=1_1) type, abstract :: t1 end type -!CHECK: .dt.t1, SAVE, TARGET (CompilerCreated, ReadOnly): ObjectEntity type: TYPE(derivedtype) init:derivedtype(name=.n.t1,sizeinbytes=0_8,uninstantiated=NULL(),kindparameter=NULL(),lenparameterkind=NULL(),component=NULL(),procptr=NULL(),specialbitset=0_4,hasparent=0_1,noinitializationneeded=1_1,nodestructionneeded=1_1,nofinalizationneeded=1_1) +!CHECK: .dt.t1, SAVE, TARGET (CompilerCreated, ReadOnly): ObjectEntity type: TYPE(derivedtype) init:derivedtype(name=.n.t1,sizeinbytes=0_8,uninstantiated=NULL(),kindparameter=NULL(),lenparameterkind=NULL(),component=NULL(),procptr=NULL(),specialbitset=0_4,hasparent=0_1,noinitializationneeded=1_1,nodestructionneeded=1_1,nofinalizationneeded=1_1,nodefinedassignment=1_1) type, abstract :: t2 real, allocatable :: a(:) end type -!CHECK: .dt.t2, SAVE, TARGET (CompilerCreated, ReadOnly): ObjectEntity type: TYPE(derivedtype) init:derivedtype(name=.n.t2,sizeinbytes=48_8,uninstantiated=NULL(),kindparameter=NULL(),lenparameterkind=NULL(),component=.c.t2,procptr=NULL(),specialbitset=0_4,hasparent=0_1,noinitializationneeded=0_1,nodestructionneeded=0_1,nofinalizationneeded=1_1) +!CHECK: .dt.t2, SAVE, TARGET (CompilerCreated, ReadOnly): ObjectEntity type: TYPE(derivedtype) init:derivedtype(name=.n.t2,sizeinbytes=48_8,uninstantiated=NULL(),kindparameter=NULL(),lenparameterkind=NULL(),component=.c.t2,procptr=NULL(),specialbitset=0_4,hasparent=0_1,noinitializationneeded=0_1,nodestructionneeded=0_1,nofinalizationneeded=1_1,nodefinedassignment=1_1) type, abstract :: t3 type(finalizable) :: x end type -!CHECK: .dt.t3, SAVE, TARGET (CompilerCreated, ReadOnly): ObjectEntity type: TYPE(derivedtype) init:derivedtype(name=.n.t3,sizeinbytes=0_8,uninstantiated=NULL(),kindparameter=NULL(),lenparameterkind=NULL(),component=.c.t3,procptr=NULL(),specialbitset=0_4,hasparent=0_1,noinitializationneeded=1_1,nodestructionneeded=0_1,nofinalizationneeded=0_1) +!CHECK: .dt.t3, SAVE, TARGET (CompilerCreated, ReadOnly): ObjectEntity type: TYPE(derivedtype) init:derivedtype(name=.n.t3,sizeinbytes=0_8,uninstantiated=NULL(),kindparameter=NULL(),lenparameterkind=NULL(),component=.c.t3,procptr=NULL(),specialbitset=0_4,hasparent=0_1,noinitializationneeded=1_1,nodestructionneeded=0_1,nofinalizationneeded=0_1,nodefinedassignment=1_1) contains impure elemental subroutine final(x) type(finalizable), intent(in out) :: x diff --git a/external/llvm-project/flang/test/Semantics/typeinfo05.f90 b/external/llvm-project/flang/test/Semantics/typeinfo05.f90 index 2a7f12a153eb..df1aecf3821d 100644 --- a/external/llvm-project/flang/test/Semantics/typeinfo05.f90 +++ b/external/llvm-project/flang/test/Semantics/typeinfo05.f90 @@ -7,10 +7,10 @@ program main type t1 type(t2), pointer :: b end type t1 -!CHECK: .dt.t1, SAVE, TARGET (CompilerCreated, ReadOnly): ObjectEntity type: TYPE(derivedtype) init:derivedtype(binding=NULL(),name=.n.t1,sizeinbytes=40_8,uninstantiated=NULL(),kindparameter=NULL(),lenparameterkind=NULL(),component=.c.t1,procptr=NULL(),special=NULL(),specialbitset=0_4,hasparent=0_1,noinitializationneeded=0_1,nodestructionneeded=1_1,nofinalizationneeded=1_1) +!CHECK: .dt.t1, SAVE, TARGET (CompilerCreated, ReadOnly): ObjectEntity type: TYPE(derivedtype) init:derivedtype(binding=NULL(),name=.n.t1,sizeinbytes=40_8,uninstantiated=NULL(),kindparameter=NULL(),lenparameterkind=NULL(),component=.c.t1,procptr=NULL(),special=NULL(),specialbitset=0_4,hasparent=0_1,noinitializationneeded=0_1,nodestructionneeded=1_1,nofinalizationneeded=1_1,nodefinedassignment=1_1) type :: t2 type(t1) :: a end type t2 -! CHECK: .dt.t2, SAVE, TARGET (CompilerCreated, ReadOnly): ObjectEntity type: TYPE(derivedtype) init:derivedtype(binding=NULL(),name=.n.t2,sizeinbytes=40_8,uninstantiated=NULL(),kindparameter=NULL(),lenparameterkind=NULL(),component=.c.t2,procptr=NULL(),special=NULL(),specialbitset=0_4,hasparent=0_1,noinitializationneeded=0_1,nodestructionneeded=1_1,nofinalizationneeded=1_1) +! CHECK: .dt.t2, SAVE, TARGET (CompilerCreated, ReadOnly): ObjectEntity type: TYPE(derivedtype) init:derivedtype(binding=NULL(),name=.n.t2,sizeinbytes=40_8,uninstantiated=NULL(),kindparameter=NULL(),lenparameterkind=NULL(),component=.c.t2,procptr=NULL(),special=NULL(),specialbitset=0_4,hasparent=0_1,noinitializationneeded=0_1,nodestructionneeded=1_1,nofinalizationneeded=1_1,nodefinedassignment=1_1) end program main diff --git a/external/llvm-project/flang/test/Semantics/typeinfo06.f90 b/external/llvm-project/flang/test/Semantics/typeinfo06.f90 index 2385709a8eb4..22f37b1a4369 100644 --- a/external/llvm-project/flang/test/Semantics/typeinfo06.f90 +++ b/external/llvm-project/flang/test/Semantics/typeinfo06.f90 @@ -7,10 +7,10 @@ program main type t1 type(t2), allocatable :: b end type t1 -!CHECK: .dt.t1, SAVE, TARGET (CompilerCreated, ReadOnly): ObjectEntity type: TYPE(derivedtype) init:derivedtype(binding=NULL(),name=.n.t1,sizeinbytes=40_8,uninstantiated=NULL(),kindparameter=NULL(),lenparameterkind=NULL(),component=.c.t1,procptr=NULL(),special=NULL(),specialbitset=0_4,hasparent=0_1,noinitializationneeded=0_1,nodestructionneeded=0_1,nofinalizationneeded=1_1) +!CHECK: .dt.t1, SAVE, TARGET (CompilerCreated, ReadOnly): ObjectEntity type: TYPE(derivedtype) init:derivedtype(binding=NULL(),name=.n.t1,sizeinbytes=40_8,uninstantiated=NULL(),kindparameter=NULL(),lenparameterkind=NULL(),component=.c.t1,procptr=NULL(),special=NULL(),specialbitset=0_4,hasparent=0_1,noinitializationneeded=0_1,nodestructionneeded=0_1,nofinalizationneeded=1_1,nodefinedassignment=1_1) type :: t2 type(t1) :: a end type t2 -! CHECK: .dt.t2, SAVE, TARGET (CompilerCreated, ReadOnly): ObjectEntity type: TYPE(derivedtype) init:derivedtype(binding=NULL(),name=.n.t2,sizeinbytes=40_8,uninstantiated=NULL(),kindparameter=NULL(),lenparameterkind=NULL(),component=.c.t2,procptr=NULL(),special=NULL(),specialbitset=0_4,hasparent=0_1,noinitializationneeded=0_1,nodestructionneeded=0_1,nofinalizationneeded=1_1) +! CHECK: .dt.t2, SAVE, TARGET (CompilerCreated, ReadOnly): ObjectEntity type: TYPE(derivedtype) init:derivedtype(binding=NULL(),name=.n.t2,sizeinbytes=40_8,uninstantiated=NULL(),kindparameter=NULL(),lenparameterkind=NULL(),component=.c.t2,procptr=NULL(),special=NULL(),specialbitset=0_4,hasparent=0_1,noinitializationneeded=0_1,nodestructionneeded=0_1,nofinalizationneeded=1_1,nodefinedassignment=1_1) end program main diff --git a/external/llvm-project/flang/test/Semantics/typeinfo07.f90 b/external/llvm-project/flang/test/Semantics/typeinfo07.f90 index e8766d9811db..ab20d6f60110 100644 --- a/external/llvm-project/flang/test/Semantics/typeinfo07.f90 +++ b/external/llvm-project/flang/test/Semantics/typeinfo07.f90 @@ -16,7 +16,7 @@ type(t_container_extension) :: wrapper end type end -! CHECK: .dt.t_container, SAVE, TARGET (CompilerCreated, ReadOnly): {{.*}}noinitializationneeded=0_1,nodestructionneeded=0_1,nofinalizationneeded=0_1) -! CHECK: .dt.t_container_extension, SAVE, TARGET (CompilerCreated, ReadOnly): {{.*}}noinitializationneeded=0_1,nodestructionneeded=0_1,nofinalizationneeded=0_1) -! CHECK: .dt.t_container_not_polymorphic, SAVE, TARGET (CompilerCreated, ReadOnly): {{.*}}noinitializationneeded=0_1,nodestructionneeded=0_1,nofinalizationneeded=1_1) -! CHECK: .dt.t_container_wrapper, SAVE, TARGET (CompilerCreated, ReadOnly): {{.*}}noinitializationneeded=0_1,nodestructionneeded=0_1,nofinalizationneeded=0_1) +! CHECK: .dt.t_container, SAVE, TARGET (CompilerCreated, ReadOnly): {{.*}}noinitializationneeded=0_1,nodestructionneeded=0_1,nofinalizationneeded=0_1,nodefinedassignment=0_1) +! CHECK: .dt.t_container_extension, SAVE, TARGET (CompilerCreated, ReadOnly): {{.*}}noinitializationneeded=0_1,nodestructionneeded=0_1,nofinalizationneeded=0_1,nodefinedassignment=0_1) +! CHECK: .dt.t_container_not_polymorphic, SAVE, TARGET (CompilerCreated, ReadOnly): {{.*}}noinitializationneeded=0_1,nodestructionneeded=0_1,nofinalizationneeded=1_1,nodefinedassignment=1_1) +! CHECK: .dt.t_container_wrapper, SAVE, TARGET (CompilerCreated, ReadOnly): {{.*}}noinitializationneeded=0_1,nodestructionneeded=0_1,nofinalizationneeded=0_1,nodefinedassignment=0_1) diff --git a/external/llvm-project/flang/test/Semantics/typeinfo08.f90 b/external/llvm-project/flang/test/Semantics/typeinfo08.f90 index 689cf469dee3..391a66f3d666 100644 --- a/external/llvm-project/flang/test/Semantics/typeinfo08.f90 +++ b/external/llvm-project/flang/test/Semantics/typeinfo08.f90 @@ -13,7 +13,7 @@ module m !CHECK: Module scope: m size=0 alignment=1 sourceRange=113 bytes !CHECK: .c.s, SAVE, TARGET (CompilerCreated, ReadOnly): ObjectEntity type: TYPE(component) shape: 0_8:0_8 init:[component::component(name=.n.t1,genre=1_1,category=6_1,kind=0_1,rank=0_1,offset=0_8,characterlen=value(genre=1_1,value=0_8),lenvalue=NULL(),bounds=NULL(),initialization=NULL())] -!CHECK: .dt.s, SAVE, TARGET (CompilerCreated, ReadOnly): ObjectEntity type: TYPE(derivedtype) init:derivedtype(binding=NULL(),name=.n.s,sizeinbytes=0_8,uninstantiated=NULL(),kindparameter=NULL(),lenparameterkind=.lpk.s,component=.c.s,procptr=NULL(),special=NULL(),specialbitset=0_4,hasparent=0_1,noinitializationneeded=1_1,nodestructionneeded=1_1,nofinalizationneeded=1_1) +!CHECK: .dt.s, SAVE, TARGET (CompilerCreated, ReadOnly): ObjectEntity type: TYPE(derivedtype) init:derivedtype(binding=NULL(),name=.n.s,sizeinbytes=0_8,uninstantiated=NULL(),kindparameter=NULL(),lenparameterkind=.lpk.s,component=.c.s,procptr=NULL(),special=NULL(),specialbitset=0_4,hasparent=0_1,noinitializationneeded=1_1,nodestructionneeded=1_1,nofinalizationneeded=1_1,nodefinedassignment=1_1) !CHECK: .lpk.s, SAVE, TARGET (CompilerCreated, ReadOnly): ObjectEntity type: INTEGER(1) shape: 0_8:0_8 init:[INTEGER(1)::4_1] !CHECK: .n.s, SAVE, TARGET (CompilerCreated, ReadOnly): ObjectEntity type: CHARACTER(1_8,1) init:"s" !CHECK: .n.t1, SAVE, TARGET (CompilerCreated, ReadOnly): ObjectEntity type: CHARACTER(2_8,1) init:"t1" diff --git a/external/llvm-project/flang/test/Semantics/typeinfo11.f90 b/external/llvm-project/flang/test/Semantics/typeinfo11.f90 index 92efc8f9ea54..08e0b95abb76 100644 --- a/external/llvm-project/flang/test/Semantics/typeinfo11.f90 +++ b/external/llvm-project/flang/test/Semantics/typeinfo11.f90 @@ -14,4 +14,4 @@ type(t2) x end -!CHECK: .dt.t2, SAVE, TARGET (CompilerCreated, ReadOnly): ObjectEntity type: TYPE(derivedtype) init:derivedtype(binding=NULL(),name=.n.t2,sizeinbytes=40_8,uninstantiated=NULL(),kindparameter=NULL(),lenparameterkind=NULL(),component=.c.t2,procptr=NULL(),special=NULL(),specialbitset=0_4,hasparent=0_1,noinitializationneeded=0_1,nodestructionneeded=0_1,nofinalizationneeded=0_1) +!CHECK: .dt.t2, SAVE, TARGET (CompilerCreated, ReadOnly): ObjectEntity type: TYPE(derivedtype) init:derivedtype(binding=NULL(),name=.n.t2,sizeinbytes=40_8,uninstantiated=NULL(),kindparameter=NULL(),lenparameterkind=NULL(),component=.c.t2,procptr=NULL(),special=NULL(),specialbitset=0_4,hasparent=0_1,noinitializationneeded=0_1,nodestructionneeded=0_1,nofinalizationneeded=0_1,nodefinedassignment=0_1) diff --git a/external/llvm-project/flang/test/Semantics/typeinfo12.f90 b/external/llvm-project/flang/test/Semantics/typeinfo12.f90 new file mode 100644 index 000000000000..6b23b63d28b1 --- /dev/null +++ b/external/llvm-project/flang/test/Semantics/typeinfo12.f90 @@ -0,0 +1,67 @@ +!RUN: bbc --dump-symbols %s | FileCheck %s +!Check "nodefinedassignment" settings. + +module m01 + + type hasAsst1 + contains + procedure asst1 + generic :: assignment(=) => asst1 + end type +!CHECK: .dt.hasasst1, SAVE, TARGET (CompilerCreated, ReadOnly): ObjectEntity type: TYPE(derivedtype) init:derivedtype(binding=.v.hasasst1,name=.n.hasasst1,sizeinbytes=0_8,uninstantiated=NULL(),kindparameter=NULL(),lenparameterkind=NULL(),component=NULL(),procptr=NULL(),special=.s.hasasst1,specialbitset=4_4,hasparent=0_1,noinitializationneeded=1_1,nodestructionneeded=1_1,nofinalizationneeded=1_1,nodefinedassignment=0_1) + + type hasAsst2 ! no defined assignment relevant to the runtime + end type + interface assignment(=) + procedure asst2 + end interface +!CHECK: .dt.hasasst2, SAVE, TARGET (CompilerCreated, ReadOnly): ObjectEntity type: TYPE(derivedtype) init:derivedtype(binding=NULL(),name=.n.hasasst2,sizeinbytes=0_8,uninstantiated=NULL(),kindparameter=NULL(),lenparameterkind=NULL(),component=NULL(),procptr=NULL(),special=NULL(),specialbitset=0_4,hasparent=0_1,noinitializationneeded=1_1,nodestructionneeded=1_1,nofinalizationneeded=1_1,nodefinedassignment=1_1) + + type test1 + type(hasAsst1) c + end type +!CHECK: .dt.test1, SAVE, TARGET (CompilerCreated, ReadOnly): ObjectEntity type: TYPE(derivedtype) init:derivedtype(binding=NULL(),name=.n.test1,sizeinbytes=0_8,uninstantiated=NULL(),kindparameter=NULL(),lenparameterkind=NULL(),component=.c.test1,procptr=NULL(),special=NULL(),specialbitset=0_4,hasparent=0_1,noinitializationneeded=1_1,nodestructionneeded=1_1,nofinalizationneeded=1_1,nodefinedassignment=0_1) + + type test2 + type(hasAsst2) c + end type +!CHECK: .dt.test2, SAVE, TARGET (CompilerCreated, ReadOnly): ObjectEntity type: TYPE(derivedtype) init:derivedtype(binding=NULL(),name=.n.test2,sizeinbytes=0_8,uninstantiated=NULL(),kindparameter=NULL(),lenparameterkind=NULL(),component=.c.test2,procptr=NULL(),special=NULL(),specialbitset=0_4,hasparent=0_1,noinitializationneeded=1_1,nodestructionneeded=1_1,nofinalizationneeded=1_1,nodefinedassignment=1_1) + + type test3 + type(hasAsst1), pointer :: p + end type +!CHECK: .dt.test3, SAVE, TARGET (CompilerCreated, ReadOnly): ObjectEntity type: TYPE(derivedtype) init:derivedtype(binding=NULL(),name=.n.test3,sizeinbytes=40_8,uninstantiated=NULL(),kindparameter=NULL(),lenparameterkind=NULL(),component=.c.test3,procptr=NULL(),special=NULL(),specialbitset=0_4,hasparent=0_1,noinitializationneeded=0_1,nodestructionneeded=1_1,nofinalizationneeded=1_1,nodefinedassignment=1_1) + + type test4 + type(hasAsst2), pointer :: p + end type +!CHECK: .dt.test4, SAVE, TARGET (CompilerCreated, ReadOnly): ObjectEntity type: TYPE(derivedtype) init:derivedtype(binding=NULL(),name=.n.test4,sizeinbytes=40_8,uninstantiated=NULL(),kindparameter=NULL(),lenparameterkind=NULL(),component=.c.test4,procptr=NULL(),special=NULL(),specialbitset=0_4,hasparent=0_1,noinitializationneeded=0_1,nodestructionneeded=1_1,nofinalizationneeded=1_1,nodefinedassignment=1_1) + + type, extends(hasAsst1) :: test5 + end type +!CHECK: .dt.test5, SAVE, TARGET (CompilerCreated, ReadOnly): ObjectEntity type: TYPE(derivedtype) init:derivedtype(binding=.v.test5,name=.n.test5,sizeinbytes=0_8,uninstantiated=NULL(),kindparameter=NULL(),lenparameterkind=NULL(),component=.c.test5,procptr=NULL(),special=.s.test5,specialbitset=4_4,hasparent=1_1,noinitializationneeded=1_1,nodestructionneeded=1_1,nofinalizationneeded=1_1,nodefinedassignment=0_1) + + type, extends(hasAsst2) :: test6 + end type +!CHECK: .dt.test6, SAVE, TARGET (CompilerCreated, ReadOnly): ObjectEntity type: TYPE(derivedtype) init:derivedtype(binding=NULL(),name=.n.test6,sizeinbytes=0_8,uninstantiated=NULL(),kindparameter=NULL(),lenparameterkind=NULL(),component=.c.test6,procptr=NULL(),special=NULL(),specialbitset=0_4,hasparent=1_1,noinitializationneeded=1_1,nodestructionneeded=1_1,nofinalizationneeded=1_1,nodefinedassignment=1_1) + + type test7 + type(test7), allocatable :: c + end type +!CHECK: .dt.test7, SAVE, TARGET (CompilerCreated, ReadOnly): ObjectEntity type: TYPE(derivedtype) init:derivedtype(binding=NULL(),name=.n.test7,sizeinbytes=40_8,uninstantiated=NULL(),kindparameter=NULL(),lenparameterkind=NULL(),component=.c.test7,procptr=NULL(),special=NULL(),specialbitset=0_4,hasparent=0_1,noinitializationneeded=0_1,nodestructionneeded=0_1,nofinalizationneeded=1_1,nodefinedassignment=1_1) + + type test8 + class(test8), allocatable :: c + end type +!CHECK: .dt.test8, SAVE, TARGET (CompilerCreated, ReadOnly): ObjectEntity type: TYPE(derivedtype) init:derivedtype(binding=NULL(),name=.n.test8,sizeinbytes=40_8,uninstantiated=NULL(),kindparameter=NULL(),lenparameterkind=NULL(),component=.c.test8,procptr=NULL(),special=NULL(),specialbitset=0_4,hasparent=0_1,noinitializationneeded=0_1,nodestructionneeded=0_1,nofinalizationneeded=0_1,nodefinedassignment=0_1) + + contains + impure elemental subroutine asst1(left, right) + class(hasAsst1), intent(out) :: left + class(hasAsst1), intent(in) :: right + end + impure elemental subroutine asst2(left, right) + class(hasAsst2), intent(out) :: left + class(hasAsst2), intent(in) :: right + end +end diff --git a/external/llvm-project/flang/test/Semantics/typeinfo13.f90 b/external/llvm-project/flang/test/Semantics/typeinfo13.f90 index cf4abf9e3818..ad824ad3590a 100644 --- a/external/llvm-project/flang/test/Semantics/typeinfo13.f90 +++ b/external/llvm-project/flang/test/Semantics/typeinfo13.f90 @@ -22,5 +22,5 @@ impure elemental subroutine override(to, from) end end -!CHECK: .s.child, SAVE, TARGET (CompilerCreated, ReadOnly): ObjectEntity type: TYPE(specialbinding) shape: 0_8:0_8 init:[specialbinding::specialbinding(which=2_1,isargdescriptorset=1_1,istypebound=1_1,isargcontiguousset=0_1,proc=override)] +!CHECK: .s.child, SAVE, TARGET (CompilerCreated, ReadOnly): ObjectEntity type: TYPE(specialbinding) shape: 0_8:0_8 init:[specialbinding::specialbinding(which=2_1,isargdescriptorset=1_1,istypebound=2_1,isargcontiguousset=0_1,proc=override)] !CHECK: .v.child, SAVE, TARGET (CompilerCreated, ReadOnly): ObjectEntity type: TYPE(binding) shape: 0_8:1_8 init:[binding::binding(proc=baseassign,name=.n.baseassign),binding(proc=override,name=.n.override)] diff --git a/external/llvm-project/flang/test/Transforms/lower-repack-arrays.fir b/external/llvm-project/flang/test/Transforms/lower-repack-arrays.fir index 012e957173ac..458869cce45f 100644 --- a/external/llvm-project/flang/test/Transforms/lower-repack-arrays.fir +++ b/external/llvm-project/flang/test/Transforms/lower-repack-arrays.fir @@ -22,7 +22,7 @@ func.func @_QPtest1(%arg0: !fir.box> {fir.bindc_name = "x"}) // CHECK: %[[VAL_11:.*]] = fir.box_addr %[[VAL_0]] : (!fir.box>) -> !fir.ref>> // CHECK: %[[VAL_12:.*]] = fir.is_present %[[VAL_11]] : (!fir.ref>>) -> i1 // CHECK: %[[VAL_13:.*]] = arith.andi %[[VAL_10]], %[[VAL_12]] : i1 -// CHECK: %[[VAL_14:.*]] = fir.if %[[VAL_13]] -> (!fir.box>) { +// CHECK: %[[VAL_14:.*]] = fir.if %[[VAL_13]] weights([0, 1]) -> (!fir.box>) { // CHECK: %[[VAL_15:.*]]:3 = fir.box_dims %[[VAL_0]], %[[VAL_4]] : (!fir.box>, index) -> (index, index, index) // CHECK: %[[VAL_16:.*]]:3 = fir.box_dims %[[VAL_0]], %[[VAL_3]] : (!fir.box>, index) -> (index, index, index) // CHECK: %[[VAL_17:.*]] = fir.shape %[[VAL_15]]#1, %[[VAL_16]]#1 : (index, index) -> !fir.shape<2> @@ -52,7 +52,7 @@ func.func @_QPtest1(%arg0: !fir.box> {fir.bindc_name = "x"}) // CHECK: %[[VAL_30:.*]] = fir.convert %[[VAL_29]] : (!fir.heap>) -> index // CHECK: %[[VAL_32:.*]] = fir.convert %[[VAL_31]] : (!fir.heap>) -> index // CHECK: %[[VAL_33:.*]] = arith.cmpi ne, %[[VAL_30]], %[[VAL_32]] : index -// CHECK: fir.if %[[VAL_33]] { +// CHECK: fir.if %[[VAL_33]] weights([0, 1]) { // CHECK: %[[VAL_34:.*]] = fir.address_of(@{{_QQcl.*}} // CHECK: %[[VAL_35:.*]] = fir.convert %[[VAL_0]] : (!fir.box>) -> !fir.box // CHECK: %[[VAL_36:.*]] = fir.convert %[[VAL_8]] : (!fir.box>) -> !fir.box @@ -87,7 +87,7 @@ func.func @_QPtest1_whole(%arg0: !fir.box> {fir.bindc_name = // CHECK: %[[VAL_11:.*]] = fir.box_addr %[[VAL_0]] : (!fir.box>) -> !fir.ref>> // CHECK: %[[VAL_12:.*]] = fir.is_present %[[VAL_11]] : (!fir.ref>>) -> i1 // CHECK: %[[VAL_13:.*]] = arith.andi %[[VAL_10]], %[[VAL_12]] : i1 -// CHECK: %[[VAL_14:.*]] = fir.if %[[VAL_13]] -> (!fir.box>) { +// CHECK: %[[VAL_14:.*]] = fir.if %[[VAL_13]] weights([0, 1]) -> (!fir.box>) { // CHECK: %[[VAL_15:.*]]:3 = fir.box_dims %[[VAL_0]], %[[VAL_4]] : (!fir.box>, index) -> (index, index, index) // CHECK: %[[VAL_16:.*]]:3 = fir.box_dims %[[VAL_0]], %[[VAL_3]] : (!fir.box>, index) -> (index, index, index) // CHECK: %[[VAL_17:.*]] = fir.shape %[[VAL_15]]#1, %[[VAL_16]]#1 : (index, index) -> !fir.shape<2> @@ -117,7 +117,7 @@ func.func @_QPtest1_whole(%arg0: !fir.box> {fir.bindc_name = // CHECK: %[[VAL_30:.*]] = fir.convert %[[VAL_29]] : (!fir.heap>) -> index // CHECK: %[[VAL_32:.*]] = fir.convert %[[VAL_31]] : (!fir.heap>) -> index // CHECK: %[[VAL_33:.*]] = arith.cmpi ne, %[[VAL_30]], %[[VAL_32]] : index -// CHECK: fir.if %[[VAL_33]] { +// CHECK: fir.if %[[VAL_33]] weights([0, 1]) { // CHECK: %[[VAL_34:.*]] = fir.address_of(@{{_QQcl.*}} // CHECK: %[[VAL_35:.*]] = fir.convert %[[VAL_0]] : (!fir.box>) -> !fir.box // CHECK: %[[VAL_36:.*]] = fir.convert %[[VAL_8]] : (!fir.box>) -> !fir.box @@ -150,7 +150,7 @@ func.func @_QPtest1_in(%arg0: !fir.box> {fir.bindc_name = "x // CHECK: %[[VAL_10:.*]] = fir.box_addr %[[VAL_0]] : (!fir.box>) -> !fir.ref>> // CHECK: %[[VAL_11:.*]] = fir.is_present %[[VAL_10]] : (!fir.ref>>) -> i1 // CHECK: %[[VAL_12:.*]] = arith.andi %[[VAL_9]], %[[VAL_11]] : i1 -// CHECK: %[[VAL_13:.*]] = fir.if %[[VAL_12]] -> (!fir.box>) { +// CHECK: %[[VAL_13:.*]] = fir.if %[[VAL_12]] weights([0, 1]) -> (!fir.box>) { // CHECK: %[[VAL_14:.*]]:3 = fir.box_dims %[[VAL_0]], %[[VAL_3]] : (!fir.box>, index) -> (index, index, index) // CHECK: %[[VAL_15:.*]]:3 = fir.box_dims %[[VAL_0]], %[[VAL_2]] : (!fir.box>, index) -> (index, index, index) // CHECK: %[[VAL_16:.*]] = fir.shape %[[VAL_14]]#1, %[[VAL_15]]#1 : (index, index) -> !fir.shape<2> @@ -180,7 +180,7 @@ func.func @_QPtest1_in(%arg0: !fir.box> {fir.bindc_name = "x // CHECK: %[[VAL_29:.*]] = fir.convert %[[VAL_28]] : (!fir.heap>) -> index // CHECK: %[[VAL_31:.*]] = fir.convert %[[VAL_30]] : (!fir.heap>) -> index // CHECK: %[[VAL_32:.*]] = arith.cmpi ne, %[[VAL_29]], %[[VAL_31]] : index -// CHECK: fir.if %[[VAL_32]] { +// CHECK: fir.if %[[VAL_32]] weights([0, 1]) { // CHECK: fir.freemem %[[VAL_28]] : !fir.heap> // CHECK: } // CHECK: } @@ -209,7 +209,7 @@ func.func @_QPtest1_out(%arg0: !fir.box> {fir.bindc_name = " // CHECK: %[[VAL_10:.*]] = fir.box_addr %[[VAL_0]] : (!fir.box>) -> !fir.ref>> // CHECK: %[[VAL_11:.*]] = fir.is_present %[[VAL_10]] : (!fir.ref>>) -> i1 // CHECK: %[[VAL_12:.*]] = arith.andi %[[VAL_9]], %[[VAL_11]] : i1 -// CHECK: %[[VAL_13:.*]] = fir.if %[[VAL_12]] -> (!fir.box>) { +// CHECK: %[[VAL_13:.*]] = fir.if %[[VAL_12]] weights([0, 1]) -> (!fir.box>) { // CHECK: %[[VAL_14:.*]]:3 = fir.box_dims %[[VAL_0]], %[[VAL_3]] : (!fir.box>, index) -> (index, index, index) // CHECK: %[[VAL_15:.*]]:3 = fir.box_dims %[[VAL_0]], %[[VAL_2]] : (!fir.box>, index) -> (index, index, index) // CHECK: %[[VAL_16:.*]] = fir.shape %[[VAL_14]]#1, %[[VAL_15]]#1 : (index, index) -> !fir.shape<2> @@ -234,7 +234,7 @@ func.func @_QPtest1_out(%arg0: !fir.box> {fir.bindc_name = " // CHECK: %[[VAL_25:.*]] = fir.convert %[[VAL_24]] : (!fir.heap>) -> index // CHECK: %[[VAL_27:.*]] = fir.convert %[[VAL_26]] : (!fir.heap>) -> index // CHECK: %[[VAL_28:.*]] = arith.cmpi ne, %[[VAL_25]], %[[VAL_27]] : index -// CHECK: fir.if %[[VAL_28]] { +// CHECK: fir.if %[[VAL_28]] weights([0, 1]) { // CHECK: %[[VAL_29:.*]] = fir.address_of(@{{_QQcl.*}} // CHECK: %[[VAL_30:.*]] = fir.convert %[[VAL_0]] : (!fir.box>) -> !fir.box // CHECK: %[[VAL_31:.*]] = fir.convert %[[VAL_7]] : (!fir.box>) -> !fir.box @@ -280,7 +280,7 @@ func.func @_QPtest2(%arg0: !fir.ref {fir.bindc_name = "n"}, %arg1: !fir.box // CHECK: %[[VAL_17:.*]] = fir.box_addr %[[VAL_1]] : (!fir.box>>) -> !fir.ref>>> // CHECK: %[[VAL_18:.*]] = fir.is_present %[[VAL_17]] : (!fir.ref>>>) -> i1 // CHECK: %[[VAL_19:.*]] = arith.andi %[[VAL_16]], %[[VAL_18]] : i1 -// CHECK: %[[VAL_20:.*]] = fir.if %[[VAL_19]] -> (!fir.box>>) { +// CHECK: %[[VAL_20:.*]] = fir.if %[[VAL_19]] weights([0, 1]) -> (!fir.box>>) { // CHECK: %[[VAL_21:.*]]:3 = fir.box_dims %[[VAL_1]], %[[VAL_5]] : (!fir.box>>, index) -> (index, index, index) // CHECK: %[[VAL_22:.*]]:3 = fir.box_dims %[[VAL_1]], %[[VAL_4]] : (!fir.box>>, index) -> (index, index, index) // CHECK: %[[VAL_23:.*]] = fir.shape %[[VAL_21]]#1, %[[VAL_22]]#1 : (index, index) -> !fir.shape<2> @@ -310,7 +310,7 @@ func.func @_QPtest2(%arg0: !fir.ref {fir.bindc_name = "n"}, %arg1: !fir.box // CHECK: %[[VAL_36:.*]] = fir.convert %[[VAL_35]] : (!fir.heap>>) -> index // CHECK: %[[VAL_38:.*]] = fir.convert %[[VAL_37]] : (!fir.heap>>) -> index // CHECK: %[[VAL_39:.*]] = arith.cmpi ne, %[[VAL_36]], %[[VAL_38]] : index -// CHECK: fir.if %[[VAL_39]] { +// CHECK: fir.if %[[VAL_39]] weights([0, 1]) { // CHECK: %[[VAL_40:.*]] = fir.address_of(@{{_QQcl.*}} // CHECK: %[[VAL_41:.*]] = fir.convert %[[VAL_1]] : (!fir.box>>) -> !fir.box // CHECK: %[[VAL_42:.*]] = fir.convert %[[VAL_14]] : (!fir.box>>) -> !fir.box @@ -356,7 +356,7 @@ func.func @_QPtest2_stack(%arg0: !fir.ref {fir.bindc_name = "n"}, %arg1: !f // CHECK: %[[VAL_17:.*]] = fir.box_addr %[[VAL_1]] : (!fir.box>>) -> !fir.ref>>> // CHECK: %[[VAL_18:.*]] = fir.is_present %[[VAL_17]] : (!fir.ref>>>) -> i1 // CHECK: %[[VAL_19:.*]] = arith.andi %[[VAL_16]], %[[VAL_18]] : i1 -// CHECK: %[[VAL_20:.*]] = fir.if %[[VAL_19]] -> (!fir.box>>) { +// CHECK: %[[VAL_20:.*]] = fir.if %[[VAL_19]] weights([0, 1]) -> (!fir.box>>) { // CHECK: %[[VAL_21:.*]]:3 = fir.box_dims %[[VAL_1]], %[[VAL_5]] : (!fir.box>>, index) -> (index, index, index) // CHECK: %[[VAL_22:.*]]:3 = fir.box_dims %[[VAL_1]], %[[VAL_4]] : (!fir.box>>, index) -> (index, index, index) // CHECK: %[[VAL_23:.*]] = fir.shape %[[VAL_21]]#1, %[[VAL_22]]#1 : (index, index) -> !fir.shape<2> @@ -386,7 +386,7 @@ func.func @_QPtest2_stack(%arg0: !fir.ref {fir.bindc_name = "n"}, %arg1: !f // CHECK: %[[VAL_36:.*]] = fir.convert %[[VAL_35]] : (!fir.heap>>) -> index // CHECK: %[[VAL_38:.*]] = fir.convert %[[VAL_37]] : (!fir.heap>>) -> index // CHECK: %[[VAL_39:.*]] = arith.cmpi ne, %[[VAL_36]], %[[VAL_38]] : index -// CHECK: fir.if %[[VAL_39]] { +// CHECK: fir.if %[[VAL_39]] weights([0, 1]) { // CHECK: %[[VAL_40:.*]] = fir.address_of(@{{_QQcl.*}} // CHECK: %[[VAL_41:.*]] = fir.convert %[[VAL_1]] : (!fir.box>>) -> !fir.box // CHECK: %[[VAL_42:.*]] = fir.convert %[[VAL_14]] : (!fir.box>>) -> !fir.box @@ -420,7 +420,7 @@ func.func @_QPtest3(%arg0: !fir.box>> {fir.bindc_n // CHECK: %[[VAL_11:.*]] = fir.box_addr %[[VAL_0]] : (!fir.box>>) -> !fir.ref>>> // CHECK: %[[VAL_12:.*]] = fir.is_present %[[VAL_11]] : (!fir.ref>>>) -> i1 // CHECK: %[[VAL_13:.*]] = arith.andi %[[VAL_10]], %[[VAL_12]] : i1 -// CHECK: %[[VAL_14:.*]] = fir.if %[[VAL_13]] -> (!fir.box>>) { +// CHECK: %[[VAL_14:.*]] = fir.if %[[VAL_13]] weights([0, 1]) -> (!fir.box>>) { // CHECK: %[[VAL_15:.*]]:3 = fir.box_dims %[[VAL_0]], %[[VAL_4]] : (!fir.box>>, index) -> (index, index, index) // CHECK: %[[VAL_16:.*]]:3 = fir.box_dims %[[VAL_0]], %[[VAL_3]] : (!fir.box>>, index) -> (index, index, index) // CHECK: %[[VAL_17:.*]] = fir.box_elesize %[[VAL_0]] : (!fir.box>>) -> index @@ -451,7 +451,7 @@ func.func @_QPtest3(%arg0: !fir.box>> {fir.bindc_n // CHECK: %[[VAL_31:.*]] = fir.convert %[[VAL_30]] : (!fir.heap>>) -> index // CHECK: %[[VAL_33:.*]] = fir.convert %[[VAL_32]] : (!fir.heap>>) -> index // CHECK: %[[VAL_34:.*]] = arith.cmpi ne, %[[VAL_31]], %[[VAL_33]] : index -// CHECK: fir.if %[[VAL_34]] { +// CHECK: fir.if %[[VAL_34]] weights([0, 1]) { // CHECK: %[[VAL_35:.*]] = fir.address_of(@{{_QQcl.*}} // CHECK: %[[VAL_36:.*]] = fir.convert %[[VAL_0]] : (!fir.box>>) -> !fir.box // CHECK: %[[VAL_37:.*]] = fir.convert %[[VAL_8]] : (!fir.box>>) -> !fir.box @@ -486,7 +486,7 @@ func.func @_QPtest3_stack(%arg0: !fir.box>> {fir.b // CHECK: %[[VAL_11:.*]] = fir.box_addr %[[VAL_0]] : (!fir.box>>) -> !fir.ref>>> // CHECK: %[[VAL_12:.*]] = fir.is_present %[[VAL_11]] : (!fir.ref>>>) -> i1 // CHECK: %[[VAL_13:.*]] = arith.andi %[[VAL_10]], %[[VAL_12]] : i1 -// CHECK: %[[VAL_14:.*]] = fir.if %[[VAL_13]] -> (!fir.box>>) { +// CHECK: %[[VAL_14:.*]] = fir.if %[[VAL_13]] weights([0, 1]) -> (!fir.box>>) { // CHECK: %[[VAL_15:.*]]:3 = fir.box_dims %[[VAL_0]], %[[VAL_4]] : (!fir.box>>, index) -> (index, index, index) // CHECK: %[[VAL_16:.*]]:3 = fir.box_dims %[[VAL_0]], %[[VAL_3]] : (!fir.box>>, index) -> (index, index, index) // CHECK: %[[VAL_17:.*]] = fir.box_elesize %[[VAL_0]] : (!fir.box>>) -> index @@ -517,7 +517,7 @@ func.func @_QPtest3_stack(%arg0: !fir.box>> {fir.b // CHECK: %[[VAL_31:.*]] = fir.convert %[[VAL_30]] : (!fir.heap>>) -> index // CHECK: %[[VAL_33:.*]] = fir.convert %[[VAL_32]] : (!fir.heap>>) -> index // CHECK: %[[VAL_34:.*]] = arith.cmpi ne, %[[VAL_31]], %[[VAL_33]] : index -// CHECK: fir.if %[[VAL_34]] { +// CHECK: fir.if %[[VAL_34]] weights([0, 1]) { // CHECK: %[[VAL_35:.*]] = fir.address_of(@{{_QQcl.*}} // CHECK: %[[VAL_36:.*]] = fir.convert %[[VAL_0]] : (!fir.box>>) -> !fir.box // CHECK: %[[VAL_37:.*]] = fir.convert %[[VAL_8]] : (!fir.box>>) -> !fir.box @@ -553,7 +553,7 @@ func.func @_QPtest4(%arg0: !fir.box>> {fir.bindc_ // CHECK: %[[VAL_12:.*]] = fir.box_addr %[[VAL_0]] : (!fir.box>>) -> !fir.ref>>> // CHECK: %[[VAL_13:.*]] = fir.is_present %[[VAL_12]] : (!fir.ref>>>) -> i1 // CHECK: %[[VAL_14:.*]] = arith.andi %[[VAL_11]], %[[VAL_13]] : i1 -// CHECK: %[[VAL_15:.*]] = fir.if %[[VAL_14]] -> (!fir.box>>) { +// CHECK: %[[VAL_15:.*]] = fir.if %[[VAL_14]] weights([0, 1]) -> (!fir.box>>) { // CHECK: %[[VAL_16:.*]]:3 = fir.box_dims %[[VAL_0]], %[[VAL_4]] : (!fir.box>>, index) -> (index, index, index) // CHECK: %[[VAL_17:.*]]:3 = fir.box_dims %[[VAL_0]], %[[VAL_3]] : (!fir.box>>, index) -> (index, index, index) // CHECK: %[[VAL_18:.*]] = fir.shape %[[VAL_16]]#1, %[[VAL_17]]#1 : (index, index) -> !fir.shape<2> @@ -583,7 +583,7 @@ func.func @_QPtest4(%arg0: !fir.box>> {fir.bindc_ // CHECK: %[[VAL_31:.*]] = fir.convert %[[VAL_30]] : (!fir.heap>>) -> index // CHECK: %[[VAL_33:.*]] = fir.convert %[[VAL_32]] : (!fir.heap>>) -> index // CHECK: %[[VAL_34:.*]] = arith.cmpi ne, %[[VAL_31]], %[[VAL_33]] : index -// CHECK: fir.if %[[VAL_34]] { +// CHECK: fir.if %[[VAL_34]] weights([0, 1]) { // CHECK: %[[VAL_35:.*]] = fir.address_of(@{{_QQcl.*}} // CHECK: %[[VAL_36:.*]] = fir.convert %[[VAL_0]] : (!fir.box>>) -> !fir.box // CHECK: %[[VAL_37:.*]] = fir.convert %[[VAL_9]] : (!fir.box>>) -> !fir.box @@ -620,7 +620,7 @@ func.func @_QPtest4_stack(%arg0: !fir.box>> {fir. // CHECK: %[[VAL_12:.*]] = fir.box_addr %[[VAL_0]] : (!fir.box>>) -> !fir.ref>>> // CHECK: %[[VAL_13:.*]] = fir.is_present %[[VAL_12]] : (!fir.ref>>>) -> i1 // CHECK: %[[VAL_14:.*]] = arith.andi %[[VAL_11]], %[[VAL_13]] : i1 -// CHECK: %[[VAL_15:.*]] = fir.if %[[VAL_14]] -> (!fir.box>>) { +// CHECK: %[[VAL_15:.*]] = fir.if %[[VAL_14]] weights([0, 1]) -> (!fir.box>>) { // CHECK: %[[VAL_16:.*]]:3 = fir.box_dims %[[VAL_0]], %[[VAL_4]] : (!fir.box>>, index) -> (index, index, index) // CHECK: %[[VAL_17:.*]]:3 = fir.box_dims %[[VAL_0]], %[[VAL_3]] : (!fir.box>>, index) -> (index, index, index) // CHECK: %[[VAL_18:.*]] = fir.shape %[[VAL_16]]#1, %[[VAL_17]]#1 : (index, index) -> !fir.shape<2> @@ -650,7 +650,7 @@ func.func @_QPtest4_stack(%arg0: !fir.box>> {fir. // CHECK: %[[VAL_31:.*]] = fir.convert %[[VAL_30]] : (!fir.heap>>) -> index // CHECK: %[[VAL_33:.*]] = fir.convert %[[VAL_32]] : (!fir.heap>>) -> index // CHECK: %[[VAL_34:.*]] = arith.cmpi ne, %[[VAL_31]], %[[VAL_33]] : index -// CHECK: fir.if %[[VAL_34]] { +// CHECK: fir.if %[[VAL_34]] weights([0, 1]) { // CHECK: %[[VAL_35:.*]] = fir.address_of(@{{_QQcl.*}} // CHECK: %[[VAL_36:.*]] = fir.convert %[[VAL_0]] : (!fir.box>>) -> !fir.box // CHECK: %[[VAL_37:.*]] = fir.convert %[[VAL_9]] : (!fir.box>>) -> !fir.box @@ -684,7 +684,7 @@ func.func @_QPtest5(%arg0: !fir.box>> {fir.bind // CHECK: %[[VAL_11:.*]] = fir.box_addr %[[VAL_0]] : (!fir.box>>) -> !fir.ref>>> // CHECK: %[[VAL_12:.*]] = fir.is_present %[[VAL_11]] : (!fir.ref>>>) -> i1 // CHECK: %[[VAL_13:.*]] = arith.andi %[[VAL_10]], %[[VAL_12]] : i1 -// CHECK: %[[VAL_14:.*]] = fir.if %[[VAL_13]] -> (!fir.box>>) { +// CHECK: %[[VAL_14:.*]] = fir.if %[[VAL_13]] weights([0, 1]) -> (!fir.box>>) { // CHECK: %[[VAL_15:.*]]:3 = fir.box_dims %[[VAL_0]], %[[VAL_4]] : (!fir.box>>, index) -> (index, index, index) // CHECK: %[[VAL_16:.*]]:3 = fir.box_dims %[[VAL_0]], %[[VAL_3]] : (!fir.box>>, index) -> (index, index, index) // CHECK: %[[VAL_17:.*]] = fir.shape %[[VAL_15]]#1, %[[VAL_16]]#1 : (index, index) -> !fir.shape<2> @@ -714,7 +714,7 @@ func.func @_QPtest5(%arg0: !fir.box>> {fir.bind // CHECK: %[[VAL_30:.*]] = fir.convert %[[VAL_29]] : (!fir.heap>>) -> index // CHECK: %[[VAL_32:.*]] = fir.convert %[[VAL_31]] : (!fir.heap>>) -> index // CHECK: %[[VAL_33:.*]] = arith.cmpi ne, %[[VAL_30]], %[[VAL_32]] : index -// CHECK: fir.if %[[VAL_33]] { +// CHECK: fir.if %[[VAL_33]] weights([0, 1]) { // CHECK: %[[VAL_34:.*]] = fir.address_of(@{{_QQcl.*}} // CHECK: %[[VAL_35:.*]] = fir.convert %[[VAL_0]] : (!fir.box>>) -> !fir.box // CHECK: %[[VAL_36:.*]] = fir.convert %[[VAL_8]] : (!fir.box>>) -> !fir.box @@ -749,7 +749,7 @@ func.func @_QPtest5_stack(%arg0: !fir.box>> {fi // CHECK: %[[VAL_11:.*]] = fir.box_addr %[[VAL_0]] : (!fir.box>>) -> !fir.ref>>> // CHECK: %[[VAL_12:.*]] = fir.is_present %[[VAL_11]] : (!fir.ref>>>) -> i1 // CHECK: %[[VAL_13:.*]] = arith.andi %[[VAL_10]], %[[VAL_12]] : i1 -// CHECK: %[[VAL_14:.*]] = fir.if %[[VAL_13]] -> (!fir.box>>) { +// CHECK: %[[VAL_14:.*]] = fir.if %[[VAL_13]] weights([0, 1]) -> (!fir.box>>) { // CHECK: %[[VAL_15:.*]]:3 = fir.box_dims %[[VAL_0]], %[[VAL_4]] : (!fir.box>>, index) -> (index, index, index) // CHECK: %[[VAL_16:.*]]:3 = fir.box_dims %[[VAL_0]], %[[VAL_3]] : (!fir.box>>, index) -> (index, index, index) // CHECK: %[[VAL_17:.*]] = fir.shape %[[VAL_15]]#1, %[[VAL_16]]#1 : (index, index) -> !fir.shape<2> @@ -779,7 +779,7 @@ func.func @_QPtest5_stack(%arg0: !fir.box>> {fi // CHECK: %[[VAL_30:.*]] = fir.convert %[[VAL_29]] : (!fir.heap>>) -> index // CHECK: %[[VAL_32:.*]] = fir.convert %[[VAL_31]] : (!fir.heap>>) -> index // CHECK: %[[VAL_33:.*]] = arith.cmpi ne, %[[VAL_30]], %[[VAL_32]] : index -// CHECK: fir.if %[[VAL_33]] { +// CHECK: fir.if %[[VAL_33]] weights([0, 1]) { // CHECK: %[[VAL_34:.*]] = fir.address_of(@{{_QQcl.*}} // CHECK: %[[VAL_35:.*]] = fir.convert %[[VAL_0]] : (!fir.box>>) -> !fir.box // CHECK: %[[VAL_36:.*]] = fir.convert %[[VAL_8]] : (!fir.box>>) -> !fir.box @@ -814,7 +814,7 @@ func.func @_QPtest6(%arg0: !fir.class>> {fir.bi // CHECK: %[[VAL_11:.*]] = fir.box_addr %[[ARG0]] : (!fir.class>>) -> !fir.ref>>> // CHECK: %[[VAL_12:.*]] = fir.is_present %[[VAL_11]] : (!fir.ref>>>) -> i1 // CHECK: %[[VAL_13:.*]] = arith.andi %[[VAL_10]], %[[VAL_12]] : i1 -// CHECK: %[[VAL_14:.*]] = fir.if %[[VAL_13]] -> (!fir.class>>) { +// CHECK: %[[VAL_14:.*]] = fir.if %[[VAL_13]] weights([0, 1]) -> (!fir.class>>) { // CHECK: %[[VAL_15:.*]]:3 = fir.box_dims %[[ARG0]], %[[VAL_3]] : (!fir.class>>, index) -> (index, index, index) // CHECK: %[[VAL_16:.*]]:3 = fir.box_dims %[[ARG0]], %[[VAL_2]] : (!fir.class>>, index) -> (index, index, index) // CHECK: %[[VAL_17:.*]] = fir.shape %[[VAL_15]]#1, %[[VAL_16]]#1 : (index, index) -> !fir.shape<2> @@ -853,7 +853,7 @@ func.func @_QPtest6(%arg0: !fir.class>> {fir.bi // CHECK: %[[VAL_39:.*]] = fir.convert %[[VAL_37]] : (!fir.heap>>) -> index // CHECK: %[[VAL_40:.*]] = fir.convert %[[VAL_38]] : (!fir.heap>>) -> index // CHECK: %[[VAL_41:.*]] = arith.cmpi ne, %[[VAL_39]], %[[VAL_40]] : index -// CHECK: fir.if %[[VAL_41]] { +// CHECK: fir.if %[[VAL_41]] weights([0, 1]) { // CHECK: %[[VAL_42:.*]] = fir.address_of(@{{_QQcl.*}}) : !fir.ref> // CHECK: %[[VAL_43:.*]] = fir.convert %[[ARG0]] : (!fir.class>>) -> !fir.box // CHECK: %[[VAL_44:.*]] = fir.convert %[[VAL_8]] : (!fir.class>>) -> !fir.box @@ -890,7 +890,7 @@ func.func @_QPtest6_stack(%arg0: !fir.class>> { // CHECK: %[[VAL_11:.*]] = fir.box_addr %[[ARG0]] : (!fir.class>>) -> !fir.ref>>> // CHECK: %[[VAL_12:.*]] = fir.is_present %[[VAL_11]] : (!fir.ref>>>) -> i1 // CHECK: %[[VAL_13:.*]] = arith.andi %[[VAL_10]], %[[VAL_12]] : i1 -// CHECK: %[[VAL_14:.*]] = fir.if %[[VAL_13]] -> (!fir.class>>) { +// CHECK: %[[VAL_14:.*]] = fir.if %[[VAL_13]] weights([0, 1]) -> (!fir.class>>) { // CHECK: %[[VAL_15:.*]]:3 = fir.box_dims %[[ARG0]], %[[VAL_3]] : (!fir.class>>, index) -> (index, index, index) // CHECK: %[[VAL_16:.*]]:3 = fir.box_dims %[[ARG0]], %[[VAL_2]] : (!fir.class>>, index) -> (index, index, index) // CHECK: %[[VAL_17:.*]] = fir.shape %[[VAL_15]]#1, %[[VAL_16]]#1 : (index, index) -> !fir.shape<2> @@ -929,7 +929,7 @@ func.func @_QPtest6_stack(%arg0: !fir.class>> { // CHECK: %[[VAL_39:.*]] = fir.convert %[[VAL_37]] : (!fir.heap>>) -> index // CHECK: %[[VAL_40:.*]] = fir.convert %[[VAL_38]] : (!fir.heap>>) -> index // CHECK: %[[VAL_41:.*]] = arith.cmpi ne, %[[VAL_39]], %[[VAL_40]] : index -// CHECK: fir.if %[[VAL_41]] { +// CHECK: fir.if %[[VAL_41]] weights([0, 1]) { // CHECK: %[[VAL_42:.*]] = fir.address_of(@{{_QQcl.*}}) : !fir.ref> // CHECK: %[[VAL_43:.*]] = fir.convert %[[ARG0]] : (!fir.class>>) -> !fir.box // CHECK: %[[VAL_44:.*]] = fir.convert %[[VAL_8]] : (!fir.class>>) -> !fir.box @@ -965,7 +965,7 @@ func.func @_QPtest7(%arg0: !fir.class> {fir.bindc_name = "x // CHECK: %[[VAL_11:.*]] = fir.box_addr %[[ARG0]] : (!fir.class>) -> !fir.ref>> // CHECK: %[[VAL_12:.*]] = fir.is_present %[[VAL_11]] : (!fir.ref>>) -> i1 // CHECK: %[[VAL_13:.*]] = arith.andi %[[VAL_10]], %[[VAL_12]] : i1 -// CHECK: %[[VAL_14:.*]] = fir.if %[[VAL_13]] -> (!fir.class>) { +// CHECK: %[[VAL_14:.*]] = fir.if %[[VAL_13]] weights([0, 1]) -> (!fir.class>) { // CHECK: %[[VAL_15:.*]]:3 = fir.box_dims %[[ARG0]], %[[VAL_3]] : (!fir.class>, index) -> (index, index, index) // CHECK: %[[VAL_16:.*]]:3 = fir.box_dims %[[ARG0]], %[[VAL_2]] : (!fir.class>, index) -> (index, index, index) // CHECK: %[[VAL_17:.*]] = fir.shape %[[VAL_15]]#1, %[[VAL_16]]#1 : (index, index) -> !fir.shape<2> @@ -1004,7 +1004,7 @@ func.func @_QPtest7(%arg0: !fir.class> {fir.bindc_name = "x // CHECK: %[[VAL_39:.*]] = fir.convert %[[VAL_37]] : (!fir.heap>) -> index // CHECK: %[[VAL_40:.*]] = fir.convert %[[VAL_38]] : (!fir.heap>) -> index // CHECK: %[[VAL_41:.*]] = arith.cmpi ne, %[[VAL_39]], %[[VAL_40]] : index -// CHECK: fir.if %[[VAL_41]] { +// CHECK: fir.if %[[VAL_41]] weights([0, 1]) { // CHECK: %[[VAL_42:.*]] = fir.address_of(@{{_QQcl.*}}) : !fir.ref> // CHECK: %[[VAL_43:.*]] = fir.convert %[[ARG0]] : (!fir.class>) -> !fir.box // CHECK: %[[VAL_44:.*]] = fir.convert %[[VAL_8]] : (!fir.class>) -> !fir.box @@ -1041,7 +1041,7 @@ func.func @_QPtest7_stack(%arg0: !fir.class> {fir.bindc_nam // CHECK: %[[VAL_11:.*]] = fir.box_addr %[[ARG0]] : (!fir.class>) -> !fir.ref>> // CHECK: %[[VAL_12:.*]] = fir.is_present %[[VAL_11]] : (!fir.ref>>) -> i1 // CHECK: %[[VAL_13:.*]] = arith.andi %[[VAL_10]], %[[VAL_12]] : i1 -// CHECK: %[[VAL_14:.*]] = fir.if %[[VAL_13]] -> (!fir.class>) { +// CHECK: %[[VAL_14:.*]] = fir.if %[[VAL_13]] weights([0, 1]) -> (!fir.class>) { // CHECK: %[[VAL_15:.*]]:3 = fir.box_dims %[[ARG0]], %[[VAL_3]] : (!fir.class>, index) -> (index, index, index) // CHECK: %[[VAL_16:.*]]:3 = fir.box_dims %[[ARG0]], %[[VAL_2]] : (!fir.class>, index) -> (index, index, index) // CHECK: %[[VAL_17:.*]] = fir.shape %[[VAL_15]]#1, %[[VAL_16]]#1 : (index, index) -> !fir.shape<2> @@ -1080,7 +1080,7 @@ func.func @_QPtest7_stack(%arg0: !fir.class> {fir.bindc_nam // CHECK: %[[VAL_39:.*]] = fir.convert %[[VAL_37]] : (!fir.heap>) -> index // CHECK: %[[VAL_40:.*]] = fir.convert %[[VAL_38]] : (!fir.heap>) -> index // CHECK: %[[VAL_41:.*]] = arith.cmpi ne, %[[VAL_39]], %[[VAL_40]] : index -// CHECK: fir.if %[[VAL_41]] { +// CHECK: fir.if %[[VAL_41]] weights([0, 1]) { // CHECK: %[[VAL_42:.*]] = fir.address_of(@{{_QQcl.*}}) : !fir.ref> // CHECK: %[[VAL_43:.*]] = fir.convert %[[ARG0]] : (!fir.class>) -> !fir.box // CHECK: %[[VAL_44:.*]] = fir.convert %[[VAL_8]] : (!fir.class>) -> !fir.box diff --git a/external/llvm-project/libc/CMakeLists.txt b/external/llvm-project/libc/CMakeLists.txt index 9907adfc55a5..507b3aa88bab 100644 --- a/external/llvm-project/libc/CMakeLists.txt +++ b/external/llvm-project/libc/CMakeLists.txt @@ -4,7 +4,7 @@ set(LLVM_SUBPROJECT_TITLE "libc") if(CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR) message(FATAL_ERROR "Builds rooted in the libc directory are not supported. " "Builds should be rooted in the runtimes directory instead. " - "Please see the documentation at https://libc.llvm.org/usage_modes.html for more info.") + "Please see the documentation at https://libc.llvm.org/build_and_test.html for more info.") endif() # Include LLVM's cmake policies. diff --git a/external/llvm-project/libc/cmake/modules/LLVMLibCCompileOptionRules.cmake b/external/llvm-project/libc/cmake/modules/LLVMLibCCompileOptionRules.cmake index a98e7276bef8..82d06e2b9eb5 100644 --- a/external/llvm-project/libc/cmake/modules/LLVMLibCCompileOptionRules.cmake +++ b/external/llvm-project/libc/cmake/modules/LLVMLibCCompileOptionRules.cmake @@ -107,7 +107,7 @@ function(_get_compile_options_from_config output_var) endif() if(LIBC_CONF_ERRNO_MODE) - set(APPEND config_options "-DLIBC_ERRNO_MODE=${LIBC_CONF_ERRNO_MODE}") + list(APPEND config_options "-DLIBC_ERRNO_MODE=${LIBC_CONF_ERRNO_MODE}") endif() set(${output_var} ${config_options} PARENT_SCOPE) diff --git a/external/llvm-project/libc/config/darwin/aarch64/config.json b/external/llvm-project/libc/config/darwin/aarch64/config.json new file mode 100644 index 000000000000..c82f13e5cbf7 --- /dev/null +++ b/external/llvm-project/libc/config/darwin/aarch64/config.json @@ -0,0 +1,8 @@ +{ + "setjmp": { + "LIBC_CONF_SETJMP_AARCH64_RESTORE_PLATFORM_REGISTER": { + "value": false, + "doc": "Avoid setjmp saving the value of x18, and longjmp restoring it. The Apple AArch64 ABI specifies that this register is reserved and should not be used" + } + } +} diff --git a/external/llvm-project/libc/config/darwin/aarch64/entrypoints.txt b/external/llvm-project/libc/config/darwin/aarch64/entrypoints.txt index 308fc49d681d..437eca79a76f 100644 --- a/external/llvm-project/libc/config/darwin/aarch64/entrypoints.txt +++ b/external/llvm-project/libc/config/darwin/aarch64/entrypoints.txt @@ -101,6 +101,17 @@ set(TARGET_LIBC_ENTRYPOINTS libc.src.stdlib.free ) +if(LLVM_LIBC_FULL_BUILD) + list(APPEND TARGET_LIBC_ENTRYPOINTS + # setjmp.h entrypoints + libc.src.setjmp.longjmp + libc.src.setjmp.setjmp + libc.src.setjmp.siglongjmp + libc.src.setjmp.sigsetjmp + ) +endif() + + set(TARGET_LIBM_ENTRYPOINTS # complex.h entrypoints libc.src.complex.creal diff --git a/external/llvm-project/libc/config/darwin/aarch64/headers.txt b/external/llvm-project/libc/config/darwin/aarch64/headers.txt index 86e714597232..8f3d6029c9b6 100644 --- a/external/llvm-project/libc/config/darwin/aarch64/headers.txt +++ b/external/llvm-project/libc/config/darwin/aarch64/headers.txt @@ -7,6 +7,7 @@ set(TARGET_PUBLIC_HEADERS libc.include.inttypes libc.include.limits libc.include.math + libc.include.setjmp libc.include.stdlib libc.include.string libc.include.strings diff --git a/external/llvm-project/libc/config/linux/x86_64/entrypoints.txt b/external/llvm-project/libc/config/linux/x86_64/entrypoints.txt index aa2079faed40..c8a6d6e648af 100644 --- a/external/llvm-project/libc/config/linux/x86_64/entrypoints.txt +++ b/external/llvm-project/libc/config/linux/x86_64/entrypoints.txt @@ -384,6 +384,8 @@ set(TARGET_LIBC_ENTRYPOINTS libc.src.wchar.wcsncat libc.src.wchar.wcscpy libc.src.wchar.wmemchr + libc.src.wchar.wcpcpy + libc.src.wchar.wcpncpy # sys/uio.h entrypoints libc.src.sys.uio.writev @@ -1244,6 +1246,11 @@ if(LLVM_LIBC_FULL_BUILD) libc.src.sys.socket.recv libc.src.sys.socket.recvfrom libc.src.sys.socket.recvmsg + + # wchar.h entrypoints + libc.src.wchar.mbrtowc + libc.src.wchar.mbtowc + libc.src.wchar.wcrtomb ) endif() diff --git a/external/llvm-project/libc/docs/dev/code_style.rst b/external/llvm-project/libc/docs/dev/code_style.rst index 86247966552f..5eafff9ef9b3 100644 --- a/external/llvm-project/libc/docs/dev/code_style.rst +++ b/external/llvm-project/libc/docs/dev/code_style.rst @@ -191,9 +191,10 @@ Header Inclusion Policy ======================= Because llvm-libc supports -`Overlay Mode `__ and -`Fullbuild Mode `__ care must be -taken when ``#include``'ing certain headers. +`Overlay Mode `__, +`Full Host Build Mode `__ and +`Full Cross Build Mode `__ care +must be taken when ``#include``'ing certain headers. The ``include/`` directory contains public facing headers that users must consume for fullbuild mode. As such, types defined here will have ABI diff --git a/external/llvm-project/libc/examples/README.md b/external/llvm-project/libc/examples/README.md index 1bc4a67294f2..2f3e2019e9a6 100644 --- a/external/llvm-project/libc/examples/README.md +++ b/external/llvm-project/libc/examples/README.md @@ -3,7 +3,7 @@ Examples This directory contains a few example programs which illustrate how one can set up their own projects to use LLVM's libc, either as an overlay or as the only libc in their projects. See the -[the usage mode document](https://libc.llvm.org/usage_modes.html) for more +[the usage mode document](https://libc.llvm.org/build_and_test.html) for more information about the different modes in which one can build and use the libc. Building the Examples @@ -19,8 +19,9 @@ cd build ``` Each example can be built to use the libc in either -[the overlay mode](https://libc.llvm.org/overlay_mode.html) or the -[full build mode](https://libc.llvm.org/fullbuild_mode.html). The CMake +[the overlay mode](https://libc.llvm.org/overlay_mode.html), the +[full host build mode](https://libc.llvm.org/full_host_build.html) or the +[full cross build mode](https://libc.llvm.org/full_cross_build.html). The CMake configure step differs slightly depending on the mode you want to use the libc in. @@ -49,7 +50,8 @@ Building against a full libc ---------------------------- Before you can link an example against the full libc, you will have to first -install it. See [the documentation of the full build mode](https://libc.llvm.org/fullbuild_mode.html) +install it. See [documentation for full host build mode](https://libc.llvm.org/full_host_build.html) +or [documentation for full cross build mode](https://libc.llvm.org/full_cross_build.html) to learn how to install a full libc along with the other LLVM toolchain pieces like `clang`, `lld` and `compiler-rt`. The CMake build for the examples will assume that you have all of these components installed in a special sysroot diff --git a/external/llvm-project/libc/hdr/types/CMakeLists.txt b/external/llvm-project/libc/hdr/types/CMakeLists.txt index c88c35700907..e4b3cb0faa82 100644 --- a/external/llvm-project/libc/hdr/types/CMakeLists.txt +++ b/external/llvm-project/libc/hdr/types/CMakeLists.txt @@ -20,6 +20,14 @@ add_proxy_header_library( libc.include.uchar ) +add_proxy_header_library( + mbstate_t + HDRS + mbstate_t.h + DEPENDS + libc.include.llvm-libc-types.mbstate_t +) + add_proxy_header_library( div_t HDRS diff --git a/external/llvm-project/libc/hdr/types/char8_t.h b/external/llvm-project/libc/hdr/types/char8_t.h index 31de764658f9..4d71e3dd8909 100644 --- a/external/llvm-project/libc/hdr/types/char8_t.h +++ b/external/llvm-project/libc/hdr/types/char8_t.h @@ -9,14 +9,6 @@ #ifndef LLVM_LIBC_HDR_TYPES_CHAR8_T_H #define LLVM_LIBC_HDR_TYPES_CHAR8_T_H -#ifdef LIBC_FULL_BUILD - #include "include/llvm-libc-types/char8_t.h" -#else // overlay mode - -#include "hdr/uchar_overlay.h" - -#endif // LLVM_LIBC_FULL_BUILD - #endif // LLVM_LIBC_HDR_TYPES_CHAR8_T_H diff --git a/external/llvm-project/libc/hdr/types/mbstate_t.h b/external/llvm-project/libc/hdr/types/mbstate_t.h new file mode 100644 index 000000000000..d8fadceaaac8 --- /dev/null +++ b/external/llvm-project/libc/hdr/types/mbstate_t.h @@ -0,0 +1,22 @@ +//===-- Definition of macros from mbstate_t.h -----------------------------===// +// +// 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_LIBC_HDR_TYPES_MBSTATE_T_H +#define LLVM_LIBC_HDR_TYPES_MBSTATE_T_H + +#ifdef LIBC_FULL_BUILD + +#include "include/llvm-libc-types/mbstate_t.h" + +#else // Overlay mode + +#error "Cannot overlay mbstate_t" + +#endif // LLVM_LIBC_FULL_BUILD + +#endif // LLVM_LIBC_HDR_TYPES_MBSTATE_T_H diff --git a/external/llvm-project/libc/include/llvm-libc-types/mbstate_t.h b/external/llvm-project/libc/include/llvm-libc-types/mbstate_t.h index 540d50975a26..009fe57da50e 100644 --- a/external/llvm-project/libc/include/llvm-libc-types/mbstate_t.h +++ b/external/llvm-project/libc/include/llvm-libc-types/mbstate_t.h @@ -9,8 +9,12 @@ #ifndef LLVM_LIBC_TYPES_MBSTATE_T_H #define LLVM_LIBC_TYPES_MBSTATE_T_H -// TODO: Complete this once we implement functions that operate on this type. +#include "../llvm-libc-macros/stdint-macros.h" + typedef struct { + uint32_t __field1; + uint8_t __field2; + uint8_t __field3; } mbstate_t; #endif // LLVM_LIBC_TYPES_MBSTATE_T_H diff --git a/external/llvm-project/libc/include/wchar.yaml b/external/llvm-project/libc/include/wchar.yaml index 84db73d8f01e..98cb3bdaf0ac 100644 --- a/external/llvm-project/libc/include/wchar.yaml +++ b/external/llvm-project/libc/include/wchar.yaml @@ -29,6 +29,23 @@ functions: return_type: wint_t arguments: - type: int + - name: mbrtowc + standards: + - stdc + return_type: size_t + arguments: + - type: wchar_t *__restrict + - type: const char *__restrict + - type: size_t + - type: mbstate_t *__restrict + - name: mbtowc + standards: + - stdc + return_type: int + arguments: + - type: wchar_t *__restrict + - type: const char *__restrict + - type: size_t - name: wmemset standards: - stdc @@ -150,6 +167,14 @@ functions: - type: wchar_t *__restrict - type: const wchar_t *__restrict - type: size_t + - name: wcrtomb + standards: + - stdc + return_type: size_t + arguments: + - type: char *__restrict + - type: wchar_t + - type: mbstate_t *__restrict - name: wcscpy standards: - stdc @@ -157,3 +182,18 @@ functions: arguments: - type: wchar_t *__restrict - type: const wchar_t *__restrict + - name: wcpcpy + standards: + - stdc + return_type: wchar_t * + arguments: + - type: wchar_t *__restrict + - type: const wchar_t *__restrict + - name: wcpncpy + standards: + - stdc + return_type: wchar_t * + arguments: + - type: wchar_t *__restrict + - type: const wchar_t *__restrict + - type: size_t diff --git a/external/llvm-project/libc/src/__support/FPUtil/FEnvImpl.h b/external/llvm-project/libc/src/__support/FPUtil/FEnvImpl.h index 50a101f833c5..76910880eb81 100644 --- a/external/llvm-project/libc/src/__support/FPUtil/FEnvImpl.h +++ b/external/llvm-project/libc/src/__support/FPUtil/FEnvImpl.h @@ -15,6 +15,7 @@ #include "src/__support/libc_errno.h" #include "src/__support/macros/attributes.h" // LIBC_INLINE #include "src/__support/macros/config.h" +#include "src/__support/macros/optimization.h" #include "src/__support/macros/properties/architectures.h" #if defined(LIBC_TARGET_ARCH_IS_AARCH64) && defined(__ARM_FP) @@ -71,27 +72,40 @@ LIBC_INLINE int set_env(const fenv_t *) { return 0; } namespace LIBC_NAMESPACE_DECL { namespace fputil { -LIBC_INLINE int clear_except_if_required(int excepts) { +LIBC_INLINE static int clear_except_if_required([[maybe_unused]] int excepts) { +#ifndef LIBC_MATH_HAS_NO_EXCEPT if (math_errhandling & MATH_ERREXCEPT) return clear_except(excepts); +#endif // LIBC_MATH_HAS_NO_EXCEPT return 0; } -LIBC_INLINE int set_except_if_required(int excepts) { +LIBC_INLINE static int set_except_if_required([[maybe_unused]] int excepts) { +#ifndef LIBC_MATH_HAS_NO_EXCEPT if (math_errhandling & MATH_ERREXCEPT) return set_except(excepts); +#endif // LIBC_MATH_HAS_NO_EXCEPT return 0; } -LIBC_INLINE int raise_except_if_required(int excepts) { +LIBC_INLINE static int raise_except_if_required([[maybe_unused]] int excepts) { +#ifndef LIBC_MATH_HAS_NO_EXCEPT if (math_errhandling & MATH_ERREXCEPT) +#ifdef LIBC_TARGET_ARCH_IS_X86_64 + return raise_except(excepts); +#else // !LIBC_TARGET_ARCH_IS_X86 return raise_except(excepts); +#endif // LIBC_TARGET_ARCH_IS_X86 + +#endif // LIBC_MATH_HAS_NO_EXCEPT return 0; } -LIBC_INLINE void set_errno_if_required(int err) { +LIBC_INLINE static void set_errno_if_required([[maybe_unused]] int err) { +#ifndef LIBC_MATH_HAS_NO_ERRNO if (math_errhandling & MATH_ERRNO) libc_errno = err; +#endif // LIBC_MATH_HAS_NO_ERRNO } } // namespace fputil diff --git a/external/llvm-project/libc/src/__support/FPUtil/dyadic_float.h b/external/llvm-project/libc/src/__support/FPUtil/dyadic_float.h index 6c3e1520e5af..4c77d3c541cd 100644 --- a/external/llvm-project/libc/src/__support/FPUtil/dyadic_float.h +++ b/external/llvm-project/libc/src/__support/FPUtil/dyadic_float.h @@ -465,7 +465,10 @@ template struct DyadicFloat { // exponents coming in to this function _shouldn't_ be that large). The // result should always end up as a positive size_t. size_t shift = -static_cast(exponent); - new_mant >>= shift; + if (shift >= Bits) + new_mant = 0; + else + new_mant >>= shift; round_dir = rounding_direction(mantissa, shift, sign); if (round_dir > 0) ++new_mant; diff --git a/external/llvm-project/libc/src/__support/FPUtil/x86_64/FEnvImpl.h b/external/llvm-project/libc/src/__support/FPUtil/x86_64/FEnvImpl.h index b77178ea69ea..560727c22978 100644 --- a/external/llvm-project/libc/src/__support/FPUtil/x86_64/FEnvImpl.h +++ b/external/llvm-project/libc/src/__support/FPUtil/x86_64/FEnvImpl.h @@ -239,7 +239,7 @@ LIBC_INLINE int set_except(int excepts) { return 0; } -LIBC_INLINE int raise_except(int excepts) { +template LIBC_INLINE int raise_except(int excepts) { uint16_t status_value = internal::get_status_value_for_except(excepts); // We set the status flag for exception one at a time and call the @@ -256,13 +256,16 @@ LIBC_INLINE int raise_except(int excepts) { // when raising the next exception. auto raise_helper = [](uint16_t singleExceptFlag) { - internal::X87StateDescriptor state; + if constexpr (!SKIP_X87_FPU) { + internal::X87StateDescriptor state; + internal::get_x87_state_descriptor(state); + state.status_word |= singleExceptFlag; + internal::write_x87_state_descriptor(state); + } + uint32_t mxcsr = 0; - internal::get_x87_state_descriptor(state); mxcsr = internal::get_mxcsr(); - state.status_word |= singleExceptFlag; mxcsr |= singleExceptFlag; - internal::write_x87_state_descriptor(state); internal::write_mxcsr(mxcsr); internal::fwait(); }; diff --git a/external/llvm-project/libc/src/__support/HashTable/CMakeLists.txt b/external/llvm-project/libc/src/__support/HashTable/CMakeLists.txt index 3c487e4f2926..698b8d0dfa68 100644 --- a/external/llvm-project/libc/src/__support/HashTable/CMakeLists.txt +++ b/external/llvm-project/libc/src/__support/HashTable/CMakeLists.txt @@ -15,7 +15,8 @@ if (NOT ${getrandom_index} EQUAL -1) message(STATUS "Using getrandom for hashtable randomness") set(randomness_compile_flags -DLIBC_HASHTABLE_USE_GETRANDOM) set(randomness_extra_depends - libc.src.sys.random.getrandom libc.src.errno.errno) + libc.src.__support.OSUtil.linux.getrandom + libc.hdr.errno_macros) endif() @@ -32,9 +33,8 @@ add_header_library( libc.src.__support.macros.attributes libc.src.__support.macros.optimization libc.src.__support.memory_size - libc.src.string.memset - libc.src.string.strcmp - libc.src.string.strlen + libc.src.string.memory_utils.inline_strcmp + libc.src.string.string_utils ) add_header_library( diff --git a/external/llvm-project/libc/src/__support/HashTable/randomness.h b/external/llvm-project/libc/src/__support/HashTable/randomness.h index 6b58a4125f78..7e54c9aa6ad1 100644 --- a/external/llvm-project/libc/src/__support/HashTable/randomness.h +++ b/external/llvm-project/libc/src/__support/HashTable/randomness.h @@ -14,8 +14,8 @@ #include "src/__support/macros/attributes.h" #include "src/__support/macros/config.h" #if defined(LIBC_HASHTABLE_USE_GETRANDOM) -#include "src/__support/libc_errno.h" -#include "src/sys/random/getrandom.h" +#include "hdr/errno_macros.h" +#include "src/__support/OSUtil/linux/getrandom.h" #endif namespace LIBC_NAMESPACE_DECL { @@ -35,20 +35,18 @@ LIBC_INLINE uint64_t next_random_seed() { entropy[0] = reinterpret_cast(&entropy); entropy[1] = reinterpret_cast(&state); #if defined(LIBC_HASHTABLE_USE_GETRANDOM) - int errno_backup = libc_errno; size_t count = sizeof(entropy); uint8_t *buffer = reinterpret_cast(entropy); while (count > 0) { - ssize_t len = getrandom(buffer, count, 0); - if (len == -1) { - if (libc_errno == ENOSYS) + auto len = internal::getrandom(buffer, count, 0); + if (!len.has_value()) { + if (len.error() == ENOSYS) break; continue; } - count -= len; - buffer += len; + count -= len.value(); + buffer += len.value(); } - libc_errno = errno_backup; #endif state.update(&entropy, sizeof(entropy)); } diff --git a/external/llvm-project/libc/src/__support/HashTable/table.h b/external/llvm-project/libc/src/__support/HashTable/table.h index 13badb90dbfd..10dd9711afbf 100644 --- a/external/llvm-project/libc/src/__support/HashTable/table.h +++ b/external/llvm-project/libc/src/__support/HashTable/table.h @@ -18,9 +18,8 @@ #include "src/__support/macros/config.h" #include "src/__support/macros/optimization.h" #include "src/__support/memory_size.h" -#include "src/string/memset.h" -#include "src/string/strcmp.h" -#include "src/string/strlen.h" +#include "src/string/memory_utils/inline_strcmp.h" +#include "src/string/string_utils.h" #include #include @@ -158,7 +157,9 @@ struct HashTable { for (size_t i : masks) { size_t index = (pos + i) & entries_mask; ENTRY &entry = this->entry(index); - if (LIBC_LIKELY(entry.key != nullptr && strcmp(entry.key, key) == 0)) + auto comp = [](char l, char r) -> int { return l - r; }; + if (LIBC_LIKELY(entry.key != nullptr && + inline_strcmp(entry.key, key, comp) == 0)) return index; } BitMask available = ctrls.mask_available(); @@ -176,7 +177,7 @@ struct HashTable { LIBC_INLINE uint64_t oneshot_hash(const char *key) const { LIBC_NAMESPACE::internal::HashState hasher = state; - hasher.update(key, strlen(key)); + hasher.update(key, internal::string_length(key)); return hasher.finish(); } @@ -282,8 +283,8 @@ struct HashTable { table->entries_mask = entries - 1u; table->available_slots = entries / 8 * 7; table->state = HashState{randomness}; - memset(&table->control(0), 0x80, ctrl_sizes); - memset(mem, 0, table->offset_from_entries()); + __builtin_memset(&table->control(0), 0x80, ctrl_sizes); + __builtin_memset(mem, 0, table->offset_from_entries()); } return table; } diff --git a/external/llvm-project/libc/src/__support/OSUtil/linux/CMakeLists.txt b/external/llvm-project/libc/src/__support/OSUtil/linux/CMakeLists.txt index 4681d8c2bb73..f303e54ce7b3 100644 --- a/external/llvm-project/libc/src/__support/OSUtil/linux/CMakeLists.txt +++ b/external/llvm-project/libc/src/__support/OSUtil/linux/CMakeLists.txt @@ -24,6 +24,19 @@ add_object_library( libc.include.sys_syscall ) +add_header_library( + getrandom + HDRS + getrandom.h + DEPENDS + libc.src.__support.OSUtil.osutil + libc.src.__support.common + libc.src.__support.error_or + libc.src.__support.macros.config + libc.hdr.types.ssize_t + libc.include.sys_syscall +) + add_header_library( vdso_sym HDRS diff --git a/external/llvm-project/libc/src/__support/OSUtil/linux/getrandom.h b/external/llvm-project/libc/src/__support/OSUtil/linux/getrandom.h new file mode 100644 index 000000000000..793639472fee --- /dev/null +++ b/external/llvm-project/libc/src/__support/OSUtil/linux/getrandom.h @@ -0,0 +1,35 @@ +//===------------ Implementation of getrandom function ----------*- 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_LIBC_SRC___SUPPORT_OSUTIL_GETRANDOM_H +#define LLVM_LIBC_SRC___SUPPORT_OSUTIL_GETRANDOM_H + +#include "hdr/types/ssize_t.h" +#include "src/__support/OSUtil/linux/syscall.h" // syscall_impl +#include "src/__support/common.h" +#include "src/__support/error_or.h" +#include "src/__support/macros/config.h" +#include // For syscall numbers + +namespace LIBC_NAMESPACE_DECL { +namespace internal { + +LIBC_INLINE static ErrorOr getrandom(void *buf, size_t buflen, + unsigned int flags) { + ssize_t ret = + LIBC_NAMESPACE::syscall_impl(SYS_getrandom, buf, buflen, flags); + if (ret < 0) { + return Error(-static_cast(ret)); + } + return ret; +} + +} // namespace internal +} // namespace LIBC_NAMESPACE_DECL + +#endif // LLVM_LIBC_SRC___SUPPORT_OSUTIL_GETRANDOM_H diff --git a/external/llvm-project/libc/src/__support/macros/optimization.h b/external/llvm-project/libc/src/__support/macros/optimization.h index 253843e5e37a..db008d323b3a 100644 --- a/external/llvm-project/libc/src/__support/macros/optimization.h +++ b/external/llvm-project/libc/src/__support/macros/optimization.h @@ -63,4 +63,12 @@ LIBC_INLINE constexpr bool expects_bool_condition(T value, T expected) { #define LIBC_MATH_HAS_INTERMEDIATE_COMP_IN_FLOAT #endif +#if (LIBC_MATH & LIBC_MATH_NO_ERRNO) +#define LIBC_MATH_HAS_NO_ERRNO +#endif + +#if (LIBC_MATH & LIBC_MATH_NO_EXCEPT) +#define LIBC_MATH_HAS_NO_EXCEPT +#endif + #endif // LLVM_LIBC_SRC___SUPPORT_MACROS_OPTIMIZATION_H diff --git a/external/llvm-project/libc/src/__support/macros/properties/cpu_features.h b/external/llvm-project/libc/src/__support/macros/properties/cpu_features.h index 3677e1fc3275..457a2b7869d4 100644 --- a/external/llvm-project/libc/src/__support/macros/properties/cpu_features.h +++ b/external/llvm-project/libc/src/__support/macros/properties/cpu_features.h @@ -61,15 +61,15 @@ #if defined(__riscv_flen) // https://github.com/riscv-non-isa/riscv-c-api-doc/blob/main/src/c-api.adoc -#if (__riscv_flen & 0x10) +#if (__riscv_arch_test && __riscv_zfhmin) #define LIBC_TARGET_CPU_HAS_RISCV_FPU_HALF #define LIBC_TARGET_CPU_HAS_FPU_HALF #endif // LIBC_TARGET_CPU_HAS_RISCV_FPU_HALF -#if (__riscv_flen & 0x20) +#if (__riscv_flen >= 32) #define LIBC_TARGET_CPU_HAS_RISCV_FPU_FLOAT #define LIBC_TARGET_CPU_HAS_FPU_FLOAT #endif // LIBC_TARGET_CPU_HAS_RISCV_FPU_FLOAT -#if (__riscv_flen & 0x40) +#if (__riscv_flen >= 64) #define LIBC_TARGET_CPU_HAS_RISCV_FPU_DOUBLE #define LIBC_TARGET_CPU_HAS_FPU_DOUBLE #endif // LIBC_TARGET_CPU_HAS_RISCV_FPU_DOUBLE diff --git a/external/llvm-project/libc/src/__support/wchar/CMakeLists.txt b/external/llvm-project/libc/src/__support/wchar/CMakeLists.txt index 5cca58400ff4..6aade4ccc84a 100644 --- a/external/llvm-project/libc/src/__support/wchar/CMakeLists.txt +++ b/external/llvm-project/libc/src/__support/wchar/CMakeLists.txt @@ -15,12 +15,39 @@ add_object_library( DEPENDS libc.hdr.types.char8_t libc.hdr.types.char32_t + libc.src.__support.error_or + libc.src.__support.math_extras .mbstate - .utf_ret ) -add_header_library( - utf_ret +add_object_library( + wcrtomb HDRS - utf_ret.h + wcrtomb.h + SRCS + wcrtomb.cpp + DEPENDS + libc.hdr.types.char32_t + libc.hdr.types.size_t + libc.hdr.types.wchar_t + libc.src.__support.error_or + libc.src.__support.common + .character_converter + .mbstate +) + +add_object_library( + mbrtowc + HDRS + mbrtowc.h + SRCS + mbrtowc.cpp + DEPENDS + libc.hdr.types.wchar_t + libc.hdr.types.size_t + libc.src.__support.common + libc.src.__support.error_or + libc.src.__support.macros.config + .character_converter + .mbstate ) diff --git a/external/llvm-project/libc/src/__support/wchar/character_converter.cpp b/external/llvm-project/libc/src/__support/wchar/character_converter.cpp index f09c7815a6cc..1f81de4248ff 100644 --- a/external/llvm-project/libc/src/__support/wchar/character_converter.cpp +++ b/external/llvm-project/libc/src/__support/wchar/character_converter.cpp @@ -8,27 +8,143 @@ #include "hdr/types/char32_t.h" #include "hdr/types/char8_t.h" +#include "src/__support/CPP/bit.h" +#include "src/__support/common.h" +#include "src/__support/error_or.h" +#include "src/__support/math_extras.h" #include "src/__support/wchar/mbstate.h" -#include "src/__support/wchar/utf_ret.h" #include "character_converter.h" namespace LIBC_NAMESPACE_DECL { namespace internal { +// This is for utf-8 bytes other than the first byte +constexpr size_t ENCODED_BITS_PER_UTF8 = 6; +// The number of bits per utf-8 byte that actually encode character +// Information not metadata (# of bits excluding the byte headers) +constexpr uint32_t MASK_ENCODED_BITS = + mask_trailing_ones(); + CharacterConverter::CharacterConverter(mbstate *mbstate) { state = mbstate; } -bool CharacterConverter::isComplete() { - return state->bytes_processed == state->total_bytes; +void CharacterConverter::clear() { + state->partial = 0; + state->bytes_stored = 0; + state->total_bytes = 0; +} + +bool CharacterConverter::isFull() { + return state->bytes_stored == state->total_bytes && state->total_bytes != 0; +} + +bool CharacterConverter::isEmpty() { return state->bytes_stored == 0; } + +int CharacterConverter::push(char8_t utf8_byte) { + uint8_t num_ones = static_cast(cpp::countl_one(utf8_byte)); + // Checking the first byte if first push + if (isEmpty()) { + // UTF-8 char has 1 byte total + if (num_ones == 0) { + state->total_bytes = 1; + } + // UTF-8 char has 2 through 4 bytes total + else if (num_ones >= 2 && num_ones <= 4) { + /* Since the format is 110xxxxx, 1110xxxx, and 11110xxx for 2, 3, and 4, + we will make the base mask with 7 ones and right shift it as necessary. */ + constexpr size_t SIGNIFICANT_BITS = 7; + char8_t base_mask = + static_cast(mask_trailing_ones()); + state->total_bytes = num_ones; + utf8_byte &= (base_mask >> num_ones); + } + // Invalid first byte + else { + // bytes_stored and total_bytes will always be 0 here + state->partial = static_cast(0); + return -1; + } + state->partial = static_cast(utf8_byte); + state->bytes_stored++; + return 0; + } + // Any subsequent push + // Adding 6 more bits so need to left shift + if (num_ones == 1 && !isFull()) { + char32_t byte = utf8_byte & MASK_ENCODED_BITS; + state->partial = state->partial << ENCODED_BITS_PER_UTF8; + state->partial |= byte; + state->bytes_stored++; + return 0; + } + // Invalid byte -> reset the state + clear(); + return -1; } -int CharacterConverter::push(char8_t utf8_byte) {} +int CharacterConverter::push(char32_t utf32) { + // we can't be partially through a conversion when pushing a utf32 value + if (!isEmpty()) + return -1; -int CharacterConverter::push(char32_t utf32) {} + state->partial = utf32; -utf_ret CharacterConverter::pop_utf8() {} + // determine number of utf-8 bytes needed to represent this utf32 value + constexpr char32_t MAX_VALUE_PER_UTF8_LEN[] = {0x7f, 0x7ff, 0xffff, 0x10ffff}; + constexpr int NUM_RANGES = 4; + for (uint8_t i = 0; i < NUM_RANGES; i++) { + if (state->partial <= MAX_VALUE_PER_UTF8_LEN[i]) { + state->total_bytes = i + 1; + state->bytes_stored = i + 1; + return 0; + } + } + + // `utf32` contains a value that is too large to actually represent a valid + // unicode character + clear(); + return -1; +} -utf_ret CharacterConverter::pop_utf32() {} +ErrorOr CharacterConverter::pop_utf32() { + // If pop is called too early, do not reset the state, use error to determine + // whether enough bytes have been pushed + if (!isFull()) + return Error(-1); + char32_t utf32 = state->partial; + // reset if successful pop + clear(); + return utf32; +} + +ErrorOr CharacterConverter::pop_utf8() { + if (isEmpty()) + return Error(-1); + + constexpr char8_t FIRST_BYTE_HEADERS[] = {0, 0xC0, 0xE0, 0xF0}; + constexpr char8_t CONTINUING_BYTE_HEADER = 0x80; + + char32_t output; + + // Shift to get the next 6 bits from the utf32 encoding + const size_t shift_amount = (state->bytes_stored - 1) * ENCODED_BITS_PER_UTF8; + if (isFull()) { + /* + Choose the correct set of most significant bits to encode the length + of the utf8 sequence. The remaining bits contain the most significant + bits of the unicode value of the character. + */ + output = FIRST_BYTE_HEADERS[state->total_bytes - 1] | + (state->partial >> shift_amount); + } else { + // Get the next 6 bits and format it like so: 10xxxxxx + output = CONTINUING_BYTE_HEADER | + ((state->partial >> shift_amount) & MASK_ENCODED_BITS); + } + + state->bytes_stored--; + return static_cast(output); +} } // namespace internal } // namespace LIBC_NAMESPACE_DECL diff --git a/external/llvm-project/libc/src/__support/wchar/character_converter.h b/external/llvm-project/libc/src/__support/wchar/character_converter.h index d0602d2defe2..be0e6129df23 100644 --- a/external/llvm-project/libc/src/__support/wchar/character_converter.h +++ b/external/llvm-project/libc/src/__support/wchar/character_converter.h @@ -11,8 +11,9 @@ #include "hdr/types/char32_t.h" #include "hdr/types/char8_t.h" +#include "src/__support/common.h" +#include "src/__support/error_or.h" #include "src/__support/wchar/mbstate.h" -#include "src/__support/wchar/utf_ret.h" namespace LIBC_NAMESPACE_DECL { namespace internal { @@ -24,13 +25,15 @@ class CharacterConverter { public: CharacterConverter(mbstate *mbstate); - bool isComplete(); + void clear(); + bool isFull(); + bool isEmpty(); int push(char8_t utf8_byte); int push(char32_t utf32); - utf_ret pop_utf8(); - utf_ret pop_utf32(); + ErrorOr pop_utf8(); + ErrorOr pop_utf32(); }; } // namespace internal diff --git a/external/llvm-project/libc/src/__support/wchar/mbrtowc.cpp b/external/llvm-project/libc/src/__support/wchar/mbrtowc.cpp new file mode 100644 index 000000000000..954c7458f4df --- /dev/null +++ b/external/llvm-project/libc/src/__support/wchar/mbrtowc.cpp @@ -0,0 +1,49 @@ +//===-- Implementation for mbrtowc function ---------------------*- 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 "src/__support/wchar/mbrtowc.h" +#include "hdr/types/mbstate_t.h" +#include "hdr/types/size_t.h" +#include "hdr/types/wchar_t.h" +#include "src/__support/common.h" +#include "src/__support/error_or.h" +#include "src/__support/macros/config.h" +#include "src/__support/wchar/character_converter.h" +#include "src/__support/wchar/mbstate.h" + +namespace LIBC_NAMESPACE_DECL { +namespace internal { + +ErrorOr mbrtowc(wchar_t *__restrict pwc, const char *__restrict s, + size_t n, mbstate *__restrict ps) { + CharacterConverter char_conv(ps); + if (s == nullptr) + return 0; + size_t i = 0; + // Reading in bytes until we have a complete wc or error + for (; i < n && !char_conv.isFull(); ++i) { + int err = char_conv.push(static_cast(s[i])); + // Encoding error + if (err == -1) + return Error(-1); + } + auto wc = char_conv.pop_utf32(); + if (wc.has_value()) { + *pwc = wc.value(); + // null terminator -> return 0 + if (wc.value() == L'\0') + return 0; + return i; + } + // Incomplete but potentially valid + return -2; +} + +} // namespace internal + +} // namespace LIBC_NAMESPACE_DECL diff --git a/external/llvm-project/libc/src/__support/wchar/mbrtowc.h b/external/llvm-project/libc/src/__support/wchar/mbrtowc.h new file mode 100644 index 000000000000..37329ee61bea --- /dev/null +++ b/external/llvm-project/libc/src/__support/wchar/mbrtowc.h @@ -0,0 +1,29 @@ +//===-- Implementation header for mbrtowc function --------------*- 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_LIBC_SRC___SUPPORT_WCHAR_MBRTOWC +#define LLVM_LIBC_SRC___SUPPORT_WCHAR_MBRTOWC + +#include "hdr/types/size_t.h" +#include "hdr/types/wchar_t.h" +#include "src/__support/common.h" +#include "src/__support/error_or.h" +#include "src/__support/macros/config.h" +#include "src/__support/wchar/mbstate.h" + +namespace LIBC_NAMESPACE_DECL { +namespace internal { + +ErrorOr mbrtowc(wchar_t *__restrict pwc, const char *__restrict s, + size_t n, mbstate *__restrict ps); + +} // namespace internal + +} // namespace LIBC_NAMESPACE_DECL + +#endif // LLVM_LIBC_SRC___SUPPORT_WCHAR_MBRTOWC diff --git a/external/llvm-project/libc/src/__support/wchar/mbstate.h b/external/llvm-project/libc/src/__support/wchar/mbstate.h index d33ee354a544..32304a521524 100644 --- a/external/llvm-project/libc/src/__support/wchar/mbstate.h +++ b/external/llvm-project/libc/src/__support/wchar/mbstate.h @@ -17,9 +17,18 @@ namespace LIBC_NAMESPACE_DECL { namespace internal { struct mbstate { - char32_t partial; - uint8_t bytes_processed; - uint8_t total_bytes; + // store a partial codepoint (in UTF-32) + char32_t partial = 0; + + /* + Progress towards a conversion + Increases with each push(...) until it reaches total_bytes + Decreases with each pop(...) until it reaches 0 + */ + uint8_t bytes_stored = 0; + + // Total number of bytes that will be needed to represent this character + uint8_t total_bytes = 0; }; } // namespace internal diff --git a/external/llvm-project/libc/src/__support/wchar/wcrtomb.cpp b/external/llvm-project/libc/src/__support/wchar/wcrtomb.cpp new file mode 100644 index 000000000000..8ca3d17ad6ce --- /dev/null +++ b/external/llvm-project/libc/src/__support/wchar/wcrtomb.cpp @@ -0,0 +1,49 @@ +//===-- Implementation of wcrtomb -----------------------------------------===// +// +// 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 "src/__support/wchar/wcrtomb.h" +#include "src/__support/error_or.h" +#include "src/__support/wchar/character_converter.h" +#include "src/__support/wchar/mbstate.h" + +#include "hdr/types/char32_t.h" +#include "hdr/types/size_t.h" +#include "hdr/types/wchar_t.h" +#include "src/__support/common.h" +#include "src/__support/libc_assert.h" + +namespace LIBC_NAMESPACE_DECL { +namespace internal { + +ErrorOr wcrtomb(char *__restrict s, wchar_t wc, + mbstate *__restrict ps) { + static_assert(sizeof(wchar_t) == 4); + + CharacterConverter cr(ps); + + if (s == nullptr) + return Error(-1); + + int status = cr.push(static_cast(wc)); + if (status != 0) + return Error(status); + + size_t count = 0; + while (!cr.isEmpty()) { + auto utf8 = cr.pop_utf8(); // can never fail as long as the push succeeded + LIBC_ASSERT(utf8.has_value()); + + *s = utf8.value(); + s++; + count++; + } + return count; +} + +} // namespace internal +} // namespace LIBC_NAMESPACE_DECL diff --git a/external/llvm-project/libc/src/__support/wchar/wcrtomb.h b/external/llvm-project/libc/src/__support/wchar/wcrtomb.h new file mode 100644 index 000000000000..bcd39a92a3b7 --- /dev/null +++ b/external/llvm-project/libc/src/__support/wchar/wcrtomb.h @@ -0,0 +1,26 @@ +//===-- Implementation header for wcrtomb ---------------------------------===// +// +// 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_LIBC_SRC__SUPPORT_WCHAR_WCRTOMB_H +#define LLVM_LIBC_SRC__SUPPORT_WCHAR_WCRTOMB_H + +#include "hdr/types/size_t.h" +#include "hdr/types/wchar_t.h" +#include "src/__support/error_or.h" +#include "src/__support/macros/config.h" +#include "src/__support/wchar/mbstate.h" + +namespace LIBC_NAMESPACE_DECL { +namespace internal { + +ErrorOr wcrtomb(char *__restrict s, wchar_t wc, mbstate *__restrict ps); + +} // namespace internal +} // namespace LIBC_NAMESPACE_DECL + +#endif // LLVM_LIBC_SRC__SUPPORT_WCHAR_WCRTOMB_H diff --git a/external/llvm-project/libc/src/math/generic/log2f.cpp b/external/llvm-project/libc/src/math/generic/log2f.cpp index b25ec41f277b..cff718eec216 100644 --- a/external/llvm-project/libc/src/math/generic/log2f.cpp +++ b/external/llvm-project/libc/src/math/generic/log2f.cpp @@ -79,7 +79,7 @@ LLVM_LIBC_FUNCTION(float, log2f, (float x)) { } if (xbits.is_neg() && !xbits.is_nan()) { fputil::set_errno_if_required(EDOM); - fputil::raise_except(FE_INVALID); + fputil::raise_except_if_required(FE_INVALID); return FPBits::quiet_nan().get_val(); } if (xbits.is_inf_or_nan()) { diff --git a/external/llvm-project/libc/src/setjmp/CMakeLists.txt b/external/llvm-project/libc/src/setjmp/CMakeLists.txt index 239254fa57dc..8b8e74f0955e 100644 --- a/external/llvm-project/libc/src/setjmp/CMakeLists.txt +++ b/external/llvm-project/libc/src/setjmp/CMakeLists.txt @@ -1,3 +1,6 @@ +# Process architecture-specific subdirectory FIRST to avoid missing targets. + +# Then process OS-specific subdirectory if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/${LIBC_TARGET_OS}) add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/${LIBC_TARGET_OS}) add_object_library( diff --git a/external/llvm-project/libc/src/setjmp/darwin/CMakeLists.txt b/external/llvm-project/libc/src/setjmp/darwin/CMakeLists.txt new file mode 100644 index 000000000000..b844c8c5ee55 --- /dev/null +++ b/external/llvm-project/libc/src/setjmp/darwin/CMakeLists.txt @@ -0,0 +1,12 @@ +add_object_library( + sigsetjmp_epilogue + HDRS + ../sigsetjmp_epilogue.h + SRCS + sigsetjmp_epilogue.cpp + DEPENDS + libc.src.__support.common + libc.src.__support.OSUtil.osutil + libc.hdr.types.jmp_buf + libc.hdr.types.sigset_t +) diff --git a/external/llvm-project/libc/src/setjmp/darwin/sigsetjmp_epilogue.cpp b/external/llvm-project/libc/src/setjmp/darwin/sigsetjmp_epilogue.cpp new file mode 100644 index 000000000000..b2ca4d99ed82 --- /dev/null +++ b/external/llvm-project/libc/src/setjmp/darwin/sigsetjmp_epilogue.cpp @@ -0,0 +1,21 @@ +//===-- Implementation of sigsetjmp_epilogue ------------------------------===// +// +// 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 "src/setjmp/sigsetjmp_epilogue.h" +#include "src/__support/OSUtil/syscall.h" +#include "src/__support/common.h" +#include "src/signal/sigprocmask.h" + +namespace LIBC_NAMESPACE_DECL { +[[gnu::returns_twice]] int sigsetjmp_epilogue(jmp_buf buffer, int retval) { + syscall_impl(sigprocmask, SIG_SETMASK, + /* set= */ retval ? &buffer->sigmask : nullptr, + /* old_set= */ retval ? nullptr : &buffer->sigmask); + return retval; +} +} // namespace LIBC_NAMESPACE_DECL diff --git a/external/llvm-project/libc/src/stdio/baremetal/printf.cpp b/external/llvm-project/libc/src/stdio/baremetal/printf.cpp index c94698ec0295..7253c6549a4e 100644 --- a/external/llvm-project/libc/src/stdio/baremetal/printf.cpp +++ b/external/llvm-project/libc/src/stdio/baremetal/printf.cpp @@ -21,8 +21,8 @@ namespace LIBC_NAMESPACE_DECL { namespace { -LIBC_INLINE int raw_write_hook(cpp::string_view new_str, void *) { - write_to_stderr(new_str); +LIBC_INLINE int stdout_write_hook(cpp::string_view new_str, void *) { + write_to_stdout(new_str); return printf_core::WRITE_OK; } @@ -35,11 +35,11 @@ LLVM_LIBC_FUNCTION(int, printf, (const char *__restrict format, ...)) { // and pointer semantics, as well as handling // destruction automatically. va_end(vlist); - constexpr size_t BUFF_SIZE = 1024; + static constexpr size_t BUFF_SIZE = 1024; char buffer[BUFF_SIZE]; printf_core::WriteBuffer wb( - buffer, BUFF_SIZE, &raw_write_hook, nullptr); + buffer, BUFF_SIZE, &stdout_write_hook, nullptr); printf_core::Writer writer(wb); int retval = printf_core::printf_main(&writer, format, args); diff --git a/external/llvm-project/libc/src/stdio/baremetal/putchar.cpp b/external/llvm-project/libc/src/stdio/baremetal/putchar.cpp index 0ba46a5ade6c..ac21e6e783b0 100644 --- a/external/llvm-project/libc/src/stdio/baremetal/putchar.cpp +++ b/external/llvm-project/libc/src/stdio/baremetal/putchar.cpp @@ -16,7 +16,7 @@ namespace LIBC_NAMESPACE_DECL { LLVM_LIBC_FUNCTION(int, putchar, (int c)) { char uc = static_cast(c); - write_to_stderr(cpp::string_view(&uc, 1)); + write_to_stdout(cpp::string_view(&uc, 1)); return 0; } diff --git a/external/llvm-project/libc/src/stdio/baremetal/puts.cpp b/external/llvm-project/libc/src/stdio/baremetal/puts.cpp index 5062efda1c0d..fcd3aa086b2b 100644 --- a/external/llvm-project/libc/src/stdio/baremetal/puts.cpp +++ b/external/llvm-project/libc/src/stdio/baremetal/puts.cpp @@ -17,8 +17,8 @@ LLVM_LIBC_FUNCTION(int, puts, (const char *__restrict str)) { cpp::string_view str_view(str); // TODO: Can we combine these to avoid needing two writes? - write_to_stderr(str_view); - write_to_stderr("\n"); + write_to_stdout(str_view); + write_to_stdout("\n"); return 0; } diff --git a/external/llvm-project/libc/src/stdio/baremetal/vprintf.cpp b/external/llvm-project/libc/src/stdio/baremetal/vprintf.cpp index 3e8631abd90d..ab02533f1491 100644 --- a/external/llvm-project/libc/src/stdio/baremetal/vprintf.cpp +++ b/external/llvm-project/libc/src/stdio/baremetal/vprintf.cpp @@ -21,8 +21,8 @@ namespace LIBC_NAMESPACE_DECL { namespace { -LIBC_INLINE int raw_write_hook(cpp::string_view new_str, void *) { - write_to_stderr(new_str); +LIBC_INLINE int stdout_write_hook(cpp::string_view new_str, void *) { + write_to_stdout(new_str); return printf_core::WRITE_OK; } @@ -33,11 +33,11 @@ LLVM_LIBC_FUNCTION(int, vprintf, internal::ArgList args(vlist); // This holder class allows for easier copying // and pointer semantics, as well as handling // destruction automatically. - constexpr size_t BUFF_SIZE = 1024; + static constexpr size_t BUFF_SIZE = 1024; char buffer[BUFF_SIZE]; printf_core::WriteBuffer wb( - buffer, BUFF_SIZE, &raw_write_hook, nullptr); + buffer, BUFF_SIZE, &stdout_write_hook, nullptr); printf_core::Writer writer(wb); int retval = printf_core::printf_main(&writer, format, args); diff --git a/external/llvm-project/libc/src/sys/random/linux/getrandom.cpp b/external/llvm-project/libc/src/sys/random/linux/getrandom.cpp index 0b8471ed8b37..4a95bddfa428 100644 --- a/external/llvm-project/libc/src/sys/random/linux/getrandom.cpp +++ b/external/llvm-project/libc/src/sys/random/linux/getrandom.cpp @@ -8,24 +8,23 @@ #include "src/sys/random/getrandom.h" +#include "src/__support/OSUtil/linux/getrandom.h" #include "src/__support/OSUtil/syscall.h" // For internal syscall function. #include "src/__support/common.h" - +#include "src/__support/error_or.h" #include "src/__support/libc_errno.h" #include "src/__support/macros/config.h" -#include // For syscall numbers. namespace LIBC_NAMESPACE_DECL { LLVM_LIBC_FUNCTION(ssize_t, getrandom, (void *buf, size_t buflen, unsigned int flags)) { - ssize_t ret = - LIBC_NAMESPACE::syscall_impl(SYS_getrandom, buf, buflen, flags); - if (ret < 0) { - libc_errno = static_cast(-ret); + auto rand = internal::getrandom(buf, buflen, flags); + if (!rand.has_value()) { + libc_errno = static_cast(rand.error()); return -1; } - return ret; + return rand.value(); } } // namespace LIBC_NAMESPACE_DECL diff --git a/external/llvm-project/libc/src/wchar/CMakeLists.txt b/external/llvm-project/libc/src/wchar/CMakeLists.txt index 491dd5b34340..f390785e5817 100644 --- a/external/llvm-project/libc/src/wchar/CMakeLists.txt +++ b/external/llvm-project/libc/src/wchar/CMakeLists.txt @@ -34,6 +34,53 @@ add_entrypoint_object( libc.src.__support.wctype_utils ) +add_entrypoint_object( + wcrtomb + SRCS + wcrtomb.cpp + HDRS + wcrtomb.h + DEPENDS + libc.hdr.types.wchar_t + libc.hdr.types.mbstate_t + libc.src.__support.libc_errno + libc.src.__support.wchar.wcrtomb + libc.src.__support.wchar.mbstate +) + +add_entrypoint_object( + mbrtowc + SRCS + mbrtowc.cpp + HDRS + mbrtowc.h + DEPENDS + libc.hdr.types.size_t + libc.hdr.types.mbstate_t + libc.hdr.types.wchar_t + libc.src.__support.common + libc.src.__support.macros.config + libc.src.__support.wchar.mbrtowc + libc.src.__support.libc_errno + libc.src.__support.wchar.mbstate +) + +add_entrypoint_object( + mbtowc + SRCS + mbtowc.cpp + HDRS + mbtowc.h + DEPENDS + libc.hdr.types.size_t + libc.hdr.types.wchar_t + libc.src.__support.common + libc.src.__support.macros.config + libc.src.__support.libc_errno + libc.src.__support.wchar.mbrtowc + libc.src.__support.wchar.mbstate +) + add_entrypoint_object( wmemset SRCS @@ -45,6 +92,30 @@ add_entrypoint_object( libc.hdr.types.wchar_t ) +add_entrypoint_object( + wcpcpy + SRCS + wcpcpy.cpp + HDRS + wcpcpy.h + DEPENDS + libc.hdr.types.size_t + libc.hdr.wchar_macros + libc.src.string.string_utils +) + +add_entrypoint_object( + wcpncpy + SRCS + wcpncpy.cpp + HDRS + wcpncpy.h + DEPENDS + libc.hdr.types.size_t + libc.hdr.wchar_macros + libc.src.__support.macros.null_check +) + add_entrypoint_object( wcschr SRCS diff --git a/external/llvm-project/libc/src/wchar/mbrtowc.cpp b/external/llvm-project/libc/src/wchar/mbrtowc.cpp new file mode 100644 index 000000000000..cd429ab8d30e --- /dev/null +++ b/external/llvm-project/libc/src/wchar/mbrtowc.cpp @@ -0,0 +1,38 @@ +//===-- Implementation of mbrtowc -----------------------------------------===// +// +// 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 "src/wchar/mbrtowc.h" + +#include "hdr/types/mbstate_t.h" +#include "hdr/types/size_t.h" +#include "hdr/types/wchar_t.h" +#include "src/__support/common.h" +#include "src/__support/libc_errno.h" +#include "src/__support/macros/config.h" +#include "src/__support/wchar/mbrtowc.h" +#include "src/__support/wchar/mbstate.h" + +namespace LIBC_NAMESPACE_DECL { + +LLVM_LIBC_FUNCTION(size_t, mbrtowc, + (wchar_t *__restrict pwc, const char *__restrict s, size_t n, + mbstate_t *__restrict ps)) { + static internal::mbstate internal_mbstate; + auto ret = internal::mbrtowc(pwc, s, n, + ps == nullptr + ? &internal_mbstate + : reinterpret_cast(ps)); + if (!ret.has_value()) { + // Encoding failure + libc_errno = EILSEQ; + return -1; + } + return ret.value(); +} + +} // namespace LIBC_NAMESPACE_DECL diff --git a/external/llvm-project/libc/src/wchar/mbrtowc.h b/external/llvm-project/libc/src/wchar/mbrtowc.h new file mode 100644 index 000000000000..e2e3d3ebd285 --- /dev/null +++ b/external/llvm-project/libc/src/wchar/mbrtowc.h @@ -0,0 +1,24 @@ +//===-- Implementation header for mbrtowc ---------------------------------===// +// +// 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_LIBC_SRC_WCHAR_MBRTOWC_H +#define LLVM_LIBC_SRC_WCHAR_MBRTOWC_H + +#include "hdr/types/mbstate_t.h" +#include "hdr/types/size_t.h" +#include "hdr/types/wchar_t.h" +#include "src/__support/macros/config.h" + +namespace LIBC_NAMESPACE_DECL { + +size_t mbrtowc(wchar_t *__restrict pwc, const char *__restrict s, size_t n, + mbstate_t *__restrict ps); + +} // namespace LIBC_NAMESPACE_DECL + +#endif // LLVM_LIBC_SRC_WCHAR_MBRTOWC_H diff --git a/external/llvm-project/libc/src/wchar/mbtowc.cpp b/external/llvm-project/libc/src/wchar/mbtowc.cpp new file mode 100644 index 000000000000..eae39ba6081f --- /dev/null +++ b/external/llvm-project/libc/src/wchar/mbtowc.cpp @@ -0,0 +1,40 @@ +//===-- Implementation of mbtowc -----------------------------------------===// +// +// 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 "src/wchar/mbtowc.h" + +#include "hdr/types/size_t.h" +#include "hdr/types/wchar_t.h" +#include "src/__support/common.h" +#include "src/__support/libc_errno.h" +#include "src/__support/macros/config.h" +#include "src/__support/wchar/mbrtowc.h" +#include "src/__support/wchar/mbstate.h" + +namespace LIBC_NAMESPACE_DECL { + +LLVM_LIBC_FUNCTION(int, mbtowc, + (wchar_t *__restrict pwc, const char *__restrict s, + size_t n)) { + // returns 0 since UTF-8 encoding is not state-dependent + if (s == nullptr) + return 0; + internal::mbstate internal_mbstate; + // temp ptr to use if pwc is nullptr + wchar_t buf[1]; + auto ret = + internal::mbrtowc(pwc == nullptr ? buf : pwc, s, n, &internal_mbstate); + if (!ret.has_value() || static_cast(ret.value()) == -2) { + // Encoding failure + libc_errno = EILSEQ; + return -1; + } + return static_cast(ret.value()); +} + +} // namespace LIBC_NAMESPACE_DECL diff --git a/external/llvm-project/libc/src/wchar/mbtowc.h b/external/llvm-project/libc/src/wchar/mbtowc.h new file mode 100644 index 000000000000..f974197f81b5 --- /dev/null +++ b/external/llvm-project/libc/src/wchar/mbtowc.h @@ -0,0 +1,22 @@ +//===-- Implementation header for mbtowc ---------------------------------===// +// +// 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_LIBC_SRC_WCHAR_MBTOWC_H +#define LLVM_LIBC_SRC_WCHAR_MBTOWC_H + +#include "hdr/types/size_t.h" +#include "hdr/types/wchar_t.h" +#include "src/__support/macros/config.h" + +namespace LIBC_NAMESPACE_DECL { + +int mbtowc(wchar_t *__restrict pwc, const char *__restrict s, size_t n); + +} // namespace LIBC_NAMESPACE_DECL + +#endif // LLVM_LIBC_SRC_WCHAR_MBTOWC_H diff --git a/external/llvm-project/libc/src/wchar/wcpcpy.cpp b/external/llvm-project/libc/src/wchar/wcpcpy.cpp new file mode 100644 index 000000000000..9e2b12f09eb0 --- /dev/null +++ b/external/llvm-project/libc/src/wchar/wcpcpy.cpp @@ -0,0 +1,27 @@ +//===-- Implementation of wcpcpy ------------------------------------------===// +// +// 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 "src/wchar/wcpcpy.h" + +#include "hdr/types/size_t.h" +#include "hdr/types/wchar_t.h" +#include "src/__support/common.h" +#include "src/__support/macros/config.h" +#include "src/string/string_utils.h" + +namespace LIBC_NAMESPACE_DECL { + +LLVM_LIBC_FUNCTION(wchar_t *, wcpcpy, + (wchar_t *__restrict s1, const wchar_t *__restrict s2)) { + size_t size = internal::string_length(s2); + __builtin_memcpy(s1, s2, (size + 1) * sizeof(wchar_t)); + wchar_t *result = s1 + size; + return result; +} + +} // namespace LIBC_NAMESPACE_DECL diff --git a/external/llvm-project/libc/src/__support/wchar/utf_ret.h b/external/llvm-project/libc/src/wchar/wcpcpy.h similarity index 50% rename from external/llvm-project/libc/src/__support/wchar/utf_ret.h rename to external/llvm-project/libc/src/wchar/wcpcpy.h index fa99b76159bd..333491fc13ab 100644 --- a/external/llvm-project/libc/src/__support/wchar/utf_ret.h +++ b/external/llvm-project/libc/src/wchar/wcpcpy.h @@ -1,4 +1,4 @@ -//===-- Definition of utf_ret ----------------------------------*-- C++ -*-===// +//===-- Implementation header for wcpcpy ----------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -6,19 +6,16 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_LIBC_SRC___SUPPORT_UTF_RET_H -#define LLVM_LIBC_SRC___SUPPORT_UTF_RET_H +#ifndef LLVM_LIBC_SRC_WCHAR_WCPCPY_H +#define LLVM_LIBC_SRC_WCHAR_WCPCPY_H -#include "src/__support/common.h" +#include "hdr/types/wchar_t.h" +#include "src/__support/macros/config.h" namespace LIBC_NAMESPACE_DECL { -namespace internal { -template struct utf_ret { - T out; - int error; -}; -} // namespace internal +wchar_t *wcpcpy(wchar_t *__restrict ws1, const wchar_t *__restrict ws2); + } // namespace LIBC_NAMESPACE_DECL -#endif // LLVM_LIBC_SRC___SUPPORT_UTF_RET_H +#endif // LLVM_LIBC_SRC_WCHAR_WCPCPY_H diff --git a/external/llvm-project/libc/src/wchar/wcpncpy.cpp b/external/llvm-project/libc/src/wchar/wcpncpy.cpp new file mode 100644 index 000000000000..9f451b73f07c --- /dev/null +++ b/external/llvm-project/libc/src/wchar/wcpncpy.cpp @@ -0,0 +1,36 @@ +//===-- Implementation of wcpncpy -----------------------------------------===// +// +// 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 "src/wchar/wcpncpy.h" + +#include "hdr/types/size_t.h" +#include "hdr/types/wchar_t.h" +#include "src/__support/common.h" +#include "src/__support/macros/config.h" +#include "src/__support/macros/null_check.h" + +namespace LIBC_NAMESPACE_DECL { + +LLVM_LIBC_FUNCTION(wchar_t *, wcpncpy, + (wchar_t *__restrict s1, const wchar_t *__restrict s2, + size_t n)) { + if (n) { + LIBC_CRASH_ON_NULLPTR(s1); + LIBC_CRASH_ON_NULLPTR(s2); + } + size_t i; + // Copy up until \0 is found. + for (i = 0; i < n && s2[i] != '\0'; ++i) + s1[i] = s2[i]; + // When n>strlen(src), n-strlen(src) \0 are appended. + for (; i < n; ++i) + s1[i] = L'\0'; + return s1 + i; +} + +} // namespace LIBC_NAMESPACE_DECL diff --git a/external/llvm-project/libc/src/wchar/wcpncpy.h b/external/llvm-project/libc/src/wchar/wcpncpy.h new file mode 100644 index 000000000000..d817239d2d0b --- /dev/null +++ b/external/llvm-project/libc/src/wchar/wcpncpy.h @@ -0,0 +1,23 @@ +//===-- Implementation header for wcpncpy ---------------------------------===// +// +// 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_LIBC_SRC_WCHAR_WCPNCPY_H +#define LLVM_LIBC_SRC_WCHAR_WCPNCPY_H + +#include "hdr/types/size_t.h" +#include "hdr/types/wchar_t.h" +#include "src/__support/macros/config.h" + +namespace LIBC_NAMESPACE_DECL { + +wchar_t *wcpncpy(wchar_t *__restrict ws1, const wchar_t *__restrict ws2, + size_t n); + +} // namespace LIBC_NAMESPACE_DECL + +#endif // LLVM_LIBC_SRC_WCHAR_WCPNsCPY_H diff --git a/external/llvm-project/libc/src/wchar/wcrtomb.cpp b/external/llvm-project/libc/src/wchar/wcrtomb.cpp new file mode 100644 index 000000000000..6d604a00599e --- /dev/null +++ b/external/llvm-project/libc/src/wchar/wcrtomb.cpp @@ -0,0 +1,45 @@ +//===-- Implementation of wcrtomb -----------------------------------------===// +// +// 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 "src/wchar/wcrtomb.h" + +#include "hdr/types/mbstate_t.h" +#include "hdr/types/wchar_t.h" +#include "src/__support/common.h" +#include "src/__support/libc_errno.h" +#include "src/__support/macros/config.h" +#include "src/__support/wchar/mbstate.h" +#include "src/__support/wchar/wcrtomb.h" + +namespace LIBC_NAMESPACE_DECL { + +LLVM_LIBC_FUNCTION(size_t, wcrtomb, + (char *__restrict s, wchar_t wc, mbstate_t *__restrict ps)) { + static internal::mbstate internal_mbstate; + + // when s is nullptr, this is equivalent to wcrtomb(buf, L'\0', ps) + char buf[sizeof(wchar_t) / sizeof(char)]; + if (s == nullptr) { + s = buf; + wc = L'\0'; + } + + auto result = internal::wcrtomb( + s, wc, + ps == nullptr ? &internal_mbstate + : reinterpret_cast(ps)); + + if (!result.has_value()) { + libc_errno = EILSEQ; + return -1; + } + + return result.value(); +} + +} // namespace LIBC_NAMESPACE_DECL diff --git a/external/llvm-project/libc/src/wchar/wcrtomb.h b/external/llvm-project/libc/src/wchar/wcrtomb.h new file mode 100644 index 000000000000..06c42f158122 --- /dev/null +++ b/external/llvm-project/libc/src/wchar/wcrtomb.h @@ -0,0 +1,23 @@ +//===-- Implementation header for wcrtomb -----------------------*- 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_LIBC_SRC_WCHAR_WCRTOMB_H +#define LLVM_LIBC_SRC_WCHAR_WCRTOMB_H + +#include "hdr/types/mbstate_t.h" +#include "hdr/types/size_t.h" +#include "hdr/types/wchar_t.h" +#include "src/__support/macros/config.h" + +namespace LIBC_NAMESPACE_DECL { + +size_t wcrtomb(char *__restrict s, wchar_t wc, mbstate_t *__restrict ps); + +} // namespace LIBC_NAMESPACE_DECL + +#endif // LLVM_LIBC_SRC_WCHAR_WCRTOMB_H diff --git a/external/llvm-project/libc/test/src/CMakeLists.txt b/external/llvm-project/libc/test/src/CMakeLists.txt index b7c145788c0c..6dca47b5343e 100644 --- a/external/llvm-project/libc/test/src/CMakeLists.txt +++ b/external/llvm-project/libc/test/src/CMakeLists.txt @@ -62,6 +62,7 @@ add_subdirectory(errno) add_subdirectory(fenv) add_subdirectory(math) add_subdirectory(search) +add_subdirectory(setjmp) add_subdirectory(stdbit) add_subdirectory(stdfix) add_subdirectory(stdio) @@ -92,7 +93,6 @@ add_subdirectory(assert) add_subdirectory(compiler) add_subdirectory(dirent) add_subdirectory(locale) -add_subdirectory(setjmp) add_subdirectory(signal) add_subdirectory(spawn) diff --git a/external/llvm-project/libc/test/src/__support/CMakeLists.txt b/external/llvm-project/libc/test/src/__support/CMakeLists.txt index 4fb0dae86e5c..9f626ed31cc0 100644 --- a/external/llvm-project/libc/test/src/__support/CMakeLists.txt +++ b/external/llvm-project/libc/test/src/__support/CMakeLists.txt @@ -275,3 +275,8 @@ add_subdirectory(fixed_point) add_subdirectory(HashTable) add_subdirectory(time) add_subdirectory(threads) +# Requires access to uchar header which is not on MacOS +# Cannot currently build this on MacOS in overlay mode +if(NOT(LIBC_TARGET_OS_IS_DARWIN)) + add_subdirectory(wchar) +endif() diff --git a/external/llvm-project/libc/test/src/__support/HashTable/table_test.cpp b/external/llvm-project/libc/test/src/__support/HashTable/table_test.cpp index a579bfabb2d7..ba9849b6b5af 100644 --- a/external/llvm-project/libc/test/src/__support/HashTable/table_test.cpp +++ b/external/llvm-project/libc/test/src/__support/HashTable/table_test.cpp @@ -108,7 +108,9 @@ TEST(LlvmLibcTableTest, Insertion) { static_cast(keys[CAP].bytes)); for (size_t i = 0; i <= CAP; ++i) { - ASSERT_EQ(strcmp(table->find(keys[i].bytes)->key, keys[i].bytes), 0); + auto comp = [](char l, char r) -> int { return l - r; }; + ASSERT_EQ( + inline_strcmp(table->find(keys[i].bytes)->key, keys[i].bytes, comp), 0); } for (size_t i = CAP + 1; i < 256; ++i) { ASSERT_EQ(table->find(keys[i].bytes), static_cast(nullptr)); diff --git a/external/llvm-project/libc/test/src/__support/wchar/CMakeLists.txt b/external/llvm-project/libc/test/src/__support/wchar/CMakeLists.txt new file mode 100644 index 000000000000..5176bfd4b024 --- /dev/null +++ b/external/llvm-project/libc/test/src/__support/wchar/CMakeLists.txt @@ -0,0 +1,21 @@ +add_custom_target(libc-support-wchar-tests) + +add_libc_test( + utf8_to_32_test + SUITE + libc-support-tests + SRCS + utf8_to_32_test.cpp + DEPENDS + libc.src.__support.wchar.character_converter +) + +add_libc_test( + utf32_to_8_test + SUITE + libc-support-tests + SRCS + utf32_to_8_test.cpp + DEPENDS + libc.src.__support.wchar.character_converter +) diff --git a/external/llvm-project/libc/test/src/__support/wchar/utf32_to_8_test.cpp b/external/llvm-project/libc/test/src/__support/wchar/utf32_to_8_test.cpp new file mode 100644 index 000000000000..a6a7bc4aa6f4 --- /dev/null +++ b/external/llvm-project/libc/test/src/__support/wchar/utf32_to_8_test.cpp @@ -0,0 +1,188 @@ +//===-- Unittests for the CharacterConverter class (utf32 -> 8) -----------===// +// +// 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 "src/__support/common.h" +#include "src/__support/wchar/character_converter.h" +#include "src/__support/wchar/mbstate.h" + +#include "test/UnitTest/Test.h" + +TEST(LlvmLibcCharacterConverterUTF32To8Test, OneByte) { + LIBC_NAMESPACE::internal::mbstate state; + LIBC_NAMESPACE::internal::CharacterConverter cr(&state); + cr.clear(); + + // utf8 1-byte encodings are identical to their utf32 representations + char32_t utf32_A = 0x41; // 'A' + cr.push(utf32_A); + ASSERT_TRUE(cr.isFull()); + auto popped = cr.pop_utf8(); + ASSERT_TRUE(popped.has_value()); + ASSERT_EQ(static_cast(popped.value()), 'A'); + ASSERT_TRUE(cr.isEmpty()); + + char32_t utf32_B = 0x42; // 'B' + cr.push(utf32_B); + ASSERT_TRUE(cr.isFull()); + popped = cr.pop_utf8(); + ASSERT_TRUE(popped.has_value()); + ASSERT_EQ(static_cast(popped.value()), 'B'); + ASSERT_TRUE(cr.isEmpty()); + + // should error if we try to pop another utf8 byte out + popped = cr.pop_utf8(); + ASSERT_FALSE(popped.has_value()); +} + +TEST(LlvmLibcCharacterConverterUTF32To8Test, TwoByte) { + LIBC_NAMESPACE::internal::mbstate state; + LIBC_NAMESPACE::internal::CharacterConverter cr(&state); + cr.clear(); + + // testing utf32: 0xff -> utf8: 0xc3 0xbf + char32_t utf32 = 0xff; + cr.push(utf32); + ASSERT_TRUE(cr.isFull()); + auto popped = cr.pop_utf8(); + ASSERT_TRUE(popped.has_value()); + ASSERT_EQ(static_cast(popped.value()), 0xc3); + ASSERT_TRUE(!cr.isEmpty()); + popped = cr.pop_utf8(); + ASSERT_TRUE(popped.has_value()); + ASSERT_EQ(static_cast(popped.value()), 0xbf); + ASSERT_TRUE(cr.isEmpty()); + + // testing utf32: 0x58e -> utf8: 0xd6 0x8e + utf32 = 0x58e; + cr.push(utf32); + ASSERT_TRUE(cr.isFull()); + popped = cr.pop_utf8(); + ASSERT_TRUE(popped.has_value()); + ASSERT_EQ(static_cast(popped.value()), 0xd6); + ASSERT_TRUE(!cr.isEmpty()); + popped = cr.pop_utf8(); + ASSERT_TRUE(popped.has_value()); + ASSERT_EQ(static_cast(popped.value()), 0x8e); + ASSERT_TRUE(cr.isEmpty()); + + // should error if we try to pop another utf8 byte out + popped = cr.pop_utf8(); + ASSERT_FALSE(popped.has_value()); +} + +TEST(LlvmLibcCharacterConverterUTF32To8Test, ThreeByte) { + LIBC_NAMESPACE::internal::mbstate state; + LIBC_NAMESPACE::internal::CharacterConverter cr(&state); + cr.clear(); + + // testing utf32: 0xac15 -> utf8: 0xea 0xb0 0x95 + char32_t utf32 = 0xac15; + cr.push(utf32); + ASSERT_TRUE(cr.isFull()); + auto popped = cr.pop_utf8(); + ASSERT_TRUE(popped.has_value()); + ASSERT_EQ(static_cast(popped.value()), 0xea); + ASSERT_TRUE(!cr.isEmpty()); + popped = cr.pop_utf8(); + ASSERT_TRUE(popped.has_value()); + ASSERT_EQ(static_cast(popped.value()), 0xb0); + ASSERT_TRUE(!cr.isEmpty()); + popped = cr.pop_utf8(); + ASSERT_TRUE(popped.has_value()); + ASSERT_EQ(static_cast(popped.value()), 0x95); + ASSERT_TRUE(cr.isEmpty()); + + // testing utf32: 0x267b -> utf8: 0xe2 0x99 0xbb + utf32 = 0x267b; + cr.push(utf32); + ASSERT_TRUE(cr.isFull()); + popped = cr.pop_utf8(); + ASSERT_TRUE(popped.has_value()); + ASSERT_EQ(static_cast(popped.value()), 0xe2); + ASSERT_TRUE(!cr.isEmpty()); + popped = cr.pop_utf8(); + ASSERT_TRUE(popped.has_value()); + ASSERT_EQ(static_cast(popped.value()), 0x99); + ASSERT_TRUE(!cr.isEmpty()); + popped = cr.pop_utf8(); + ASSERT_TRUE(popped.has_value()); + ASSERT_EQ(static_cast(popped.value()), 0xbb); + ASSERT_TRUE(cr.isEmpty()); + + // should error if we try to pop another utf8 byte out + popped = cr.pop_utf8(); + ASSERT_FALSE(popped.has_value()); +} + +TEST(LlvmLibcCharacterConverterUTF32To8Test, FourByte) { + LIBC_NAMESPACE::internal::mbstate state; + LIBC_NAMESPACE::internal::CharacterConverter cr(&state); + cr.clear(); + + // testing utf32: 0x1f921 -> utf8: 0xf0 0x9f 0xa4 0xa1 + char32_t utf32 = 0x1f921; + cr.push(utf32); + ASSERT_TRUE(cr.isFull()); + auto popped = cr.pop_utf8(); + ASSERT_TRUE(popped.has_value()); + ASSERT_EQ(static_cast(popped.value()), 0xf0); + ASSERT_TRUE(!cr.isEmpty()); + popped = cr.pop_utf8(); + ASSERT_TRUE(popped.has_value()); + ASSERT_EQ(static_cast(popped.value()), 0x9f); + ASSERT_TRUE(!cr.isEmpty()); + popped = cr.pop_utf8(); + ASSERT_TRUE(popped.has_value()); + ASSERT_EQ(static_cast(popped.value()), 0xa4); + ASSERT_TRUE(!cr.isEmpty()); + popped = cr.pop_utf8(); + ASSERT_TRUE(popped.has_value()); + ASSERT_EQ(static_cast(popped.value()), 0xa1); + ASSERT_TRUE(cr.isEmpty()); + + // testing utf32: 0x12121 -> utf8: 0xf0 0x92 0x84 0xa1 + utf32 = 0x12121; + cr.push(utf32); + ASSERT_TRUE(cr.isFull()); + popped = cr.pop_utf8(); + ASSERT_TRUE(popped.has_value()); + ASSERT_EQ(static_cast(popped.value()), 0xf0); + ASSERT_TRUE(!cr.isEmpty()); + popped = cr.pop_utf8(); + ASSERT_TRUE(popped.has_value()); + ASSERT_EQ(static_cast(popped.value()), 0x92); + ASSERT_TRUE(!cr.isEmpty()); + popped = cr.pop_utf8(); + ASSERT_TRUE(popped.has_value()); + ASSERT_EQ(static_cast(popped.value()), 0x84); + ASSERT_TRUE(!cr.isEmpty()); + popped = cr.pop_utf8(); + ASSERT_TRUE(popped.has_value()); + ASSERT_EQ(static_cast(popped.value()), 0xa1); + ASSERT_TRUE(cr.isEmpty()); + + // should error if we try to pop another utf8 byte out + popped = cr.pop_utf8(); + ASSERT_FALSE(popped.has_value()); +} + +TEST(LlvmLibcCharacterConverterUTF32To8Test, CantPushMidConversion) { + LIBC_NAMESPACE::internal::mbstate state; + LIBC_NAMESPACE::internal::CharacterConverter cr(&state); + cr.clear(); + + // testing utf32: 0x12121 -> utf8: 0xf0 0x92 0x84 0xa1 + char32_t utf32 = 0x12121; + ASSERT_EQ(cr.push(utf32), 0); + auto popped = cr.pop_utf8(); + ASSERT_TRUE(popped.has_value()); + + // can't push a utf32 without finishing popping the utf8 bytes out + int err = cr.push(utf32); + ASSERT_EQ(err, -1); +} diff --git a/external/llvm-project/libc/test/src/__support/wchar/utf8_to_32_test.cpp b/external/llvm-project/libc/test/src/__support/wchar/utf8_to_32_test.cpp new file mode 100644 index 000000000000..36ae7d689cc0 --- /dev/null +++ b/external/llvm-project/libc/test/src/__support/wchar/utf8_to_32_test.cpp @@ -0,0 +1,196 @@ +//===-- Unittests for character_converter utf8->utf32 ---------------------===// +// +// 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 "src/__support/error_or.h" +#include "src/__support/wchar/character_converter.h" +#include "src/__support/wchar/mbstate.h" +#include "test/UnitTest/Test.h" + +TEST(LlvmLibcCharacterConverterUTF8To32Test, OneByte) { + LIBC_NAMESPACE::internal::mbstate state; + state.bytes_stored = 0; + state.total_bytes = 0; + char ch = 'A'; + + LIBC_NAMESPACE::internal::CharacterConverter char_conv(&state); + int err = char_conv.push(static_cast(ch)); + auto wch = char_conv.pop_utf32(); + + ASSERT_EQ(err, 0); + ASSERT_TRUE(wch.has_value()); + ASSERT_EQ(static_cast(wch.value()), 65); +} + +TEST(LlvmLibcCharacterConverterUTF8To32Test, TwoBytes) { + LIBC_NAMESPACE::internal::mbstate state; + state.bytes_stored = 0; + state.total_bytes = 0; + const char ch[2] = {static_cast(0xC2), + static_cast(0x8E)}; // Ž car symbol + + LIBC_NAMESPACE::internal::CharacterConverter char_conv(&state); + char_conv.push(static_cast(ch[0])); + char_conv.push(static_cast(ch[1])); + auto wch = char_conv.pop_utf32(); + + ASSERT_TRUE(wch.has_value()); + ASSERT_EQ(static_cast(wch.value()), 142); +} + +TEST(LlvmLibcCharacterConverterUTF8To32Test, ThreeBytes) { + LIBC_NAMESPACE::internal::mbstate state; + state.bytes_stored = 0; + state.total_bytes = 0; + const char ch[3] = {static_cast(0xE2), static_cast(0x88), + static_cast(0x91)}; // ∑ sigma symbol + + LIBC_NAMESPACE::internal::CharacterConverter char_conv(&state); + char_conv.push(static_cast(ch[0])); + char_conv.push(static_cast(ch[1])); + char_conv.push(static_cast(ch[2])); + auto wch = char_conv.pop_utf32(); + + ASSERT_TRUE(wch.has_value()); + ASSERT_EQ(static_cast(wch.value()), 8721); +} + +TEST(LlvmLibcCharacterConverterUTF8To32Test, FourBytes) { + LIBC_NAMESPACE::internal::mbstate state; + state.bytes_stored = 0; + state.total_bytes = 0; + const char ch[4] = {static_cast(0xF0), static_cast(0x9F), + static_cast(0xA4), + static_cast(0xA1)}; // 🤡 clown emoji + + LIBC_NAMESPACE::internal::CharacterConverter char_conv(&state); + char_conv.push(static_cast(ch[0])); + char_conv.push(static_cast(ch[1])); + char_conv.push(static_cast(ch[2])); + char_conv.push(static_cast(ch[3])); + auto wch = char_conv.pop_utf32(); + + ASSERT_TRUE(wch.has_value()); + ASSERT_EQ(static_cast(wch.value()), 129313); +} + +TEST(LlvmLibcCharacterConverterUTF8To32Test, InvalidByte) { + LIBC_NAMESPACE::internal::mbstate state; + state.bytes_stored = 0; + state.total_bytes = 0; + const char ch = static_cast(0x80); // invalid starting bit sequence + + LIBC_NAMESPACE::internal::CharacterConverter char_conv(&state); + int err = char_conv.push(static_cast(ch)); + + ASSERT_EQ(err, -1); +} + +TEST(LlvmLibcCharacterConverterUTF8To32Test, InvalidMultiByte) { + LIBC_NAMESPACE::internal::mbstate state; + state.bytes_stored = 0; + state.total_bytes = 0; + const char ch[4] = { + static_cast(0x80), static_cast(0x00), static_cast(0x80), + static_cast(0x00)}; // first and third bytes are invalid + + LIBC_NAMESPACE::internal::CharacterConverter char_conv(&state); + int err = char_conv.push(static_cast(ch[0])); + ASSERT_EQ(err, -1); + err = char_conv.push(static_cast(ch[1])); + ASSERT_EQ(err, 0); + // Prev byte was single byte so trying to push another should error. + err = char_conv.push(static_cast(ch[2])); + ASSERT_EQ(err, -1); + err = char_conv.push(static_cast(ch[3])); + ASSERT_EQ(err, 0); +} + +TEST(LlvmLibcCharacterConverterUTF8To32Test, InvalidLastByte) { + LIBC_NAMESPACE::internal::mbstate state; + state.bytes_stored = 0; + state.total_bytes = 0; + // Last byte is invalid since it does not have correct starting sequence. + // 0xC0 --> 11000000 starting sequence should be 10xxxxxx + const char ch[4] = {static_cast(0xF1), static_cast(0x80), + static_cast(0x80), static_cast(0xC0)}; + + LIBC_NAMESPACE::internal::CharacterConverter char_conv(&state); + int err = char_conv.push(static_cast(ch[0])); + ASSERT_EQ(err, 0); + err = char_conv.push(static_cast(ch[1])); + ASSERT_EQ(err, 0); + err = char_conv.push(static_cast(ch[2])); + ASSERT_EQ(err, 0); + err = char_conv.push(static_cast(ch[3])); + ASSERT_EQ(err, -1); +} + +TEST(LlvmLibcCharacterConverterUTF8To32Test, ValidTwoByteWithExtraRead) { + LIBC_NAMESPACE::internal::mbstate state; + state.bytes_stored = 0; + state.total_bytes = 0; + const char ch[3] = {static_cast(0xC2), static_cast(0x8E), + static_cast(0x80)}; + + LIBC_NAMESPACE::internal::CharacterConverter char_conv(&state); + int err = char_conv.push(static_cast(ch[0])); + ASSERT_EQ(err, 0); + err = char_conv.push(static_cast(ch[1])); + ASSERT_EQ(err, 0); + // Should produce an error on 3rd byte + err = char_conv.push(static_cast(ch[2])); + ASSERT_EQ(err, -1); + + // Should produce an error since mbstate was reset + auto wch = char_conv.pop_utf32(); + ASSERT_FALSE(wch.has_value()); +} + +TEST(LlvmLibcCharacterConverterUTF8To32Test, TwoValidTwoBytes) { + LIBC_NAMESPACE::internal::mbstate state; + state.bytes_stored = 0; + state.total_bytes = 0; + const char ch[4] = {static_cast(0xC2), static_cast(0x8E), + static_cast(0xC7), static_cast(0x8C)}; + + LIBC_NAMESPACE::internal::CharacterConverter char_conv(&state); + int err = char_conv.push(static_cast(ch[0])); + ASSERT_EQ(err, 0); + err = char_conv.push(static_cast(ch[1])); + ASSERT_EQ(err, 0); + auto wch = char_conv.pop_utf32(); + ASSERT_TRUE(wch.has_value()); + ASSERT_EQ(static_cast(wch.value()), 142); + + // Second two byte character + err = char_conv.push(static_cast(ch[2])); + ASSERT_EQ(err, 0); + err = char_conv.push(static_cast(ch[3])); + ASSERT_EQ(err, 0); + wch = char_conv.pop_utf32(); + ASSERT_TRUE(wch.has_value()); + ASSERT_EQ(static_cast(wch.value()), 460); +} + +TEST(LlvmLibcCharacterConverterUTF8To32Test, InvalidPop) { + LIBC_NAMESPACE::internal::mbstate state; + state.bytes_stored = 0; + state.total_bytes = 0; + LIBC_NAMESPACE::internal::CharacterConverter char_conv(&state); + const char ch[2] = {static_cast(0xC2), static_cast(0x8E)}; + int err = char_conv.push(static_cast(ch[0])); + ASSERT_EQ(err, 0); + auto wch = char_conv.pop_utf32(); + ASSERT_FALSE( + wch.has_value()); // Should fail since we have not read enough bytes + err = char_conv.push(static_cast(ch[1])); + ASSERT_EQ(err, 0); + wch = char_conv.pop_utf32(); + ASSERT_TRUE(wch.has_value()); + ASSERT_EQ(static_cast(wch.value()), 142); +} diff --git a/external/llvm-project/libc/test/src/stdio/CMakeLists.txt b/external/llvm-project/libc/test/src/stdio/CMakeLists.txt index ce2171f19597..4aa8b9588001 100644 --- a/external/llvm-project/libc/test/src/stdio/CMakeLists.txt +++ b/external/llvm-project/libc/test/src/stdio/CMakeLists.txt @@ -20,6 +20,7 @@ add_libc_test( libc.src.stdio.fread libc.src.stdio.fseek libc.src.stdio.fwrite + libc.test.UnitTest.ErrnoCheckingTest ) add_libc_test( @@ -68,6 +69,7 @@ add_libc_test( libc.src.stdio.fread libc.src.stdio.fwrite libc.src.stdio.setvbuf + libc.test.UnitTest.ErrnoCheckingTest ) add_libc_test( @@ -88,6 +90,7 @@ add_libc_test( libc.src.stdio.fread_unlocked libc.src.stdio.funlockfile libc.src.stdio.fwrite_unlocked + libc.test.UnitTest.ErrnoCheckingTest ) add_libc_test( @@ -109,6 +112,7 @@ add_libc_test( libc.src.stdio.fread libc.src.stdio.fseek libc.src.stdio.fwrite + libc.test.UnitTest.ErrnoCheckingTest LINK_LIBRARIES LibcMemoryHelpers ) @@ -438,6 +442,7 @@ if(${LIBC_TARGET_OS} STREQUAL "linux") libc.src.sys.stat.mkdirat libc.src.unistd.access libc.src.unistd.close + libc.test.UnitTest.ErrnoCheckingTest ) add_libc_test( @@ -452,6 +457,7 @@ if(${LIBC_TARGET_OS} STREQUAL "linux") libc.src.stdio.rename libc.src.unistd.access libc.src.unistd.close + libc.test.UnitTest.ErrnoCheckingTest libc.test.UnitTest.ErrnoSetterMatcher ) @@ -468,6 +474,7 @@ if(${LIBC_TARGET_OS} STREQUAL "linux") libc.src.stdio.fgets libc.src.stdio.fputs libc.src.unistd.close + libc.test.UnitTest.ErrnoCheckingTest libc.test.UnitTest.ErrnoSetterMatcher ) endif() @@ -488,6 +495,8 @@ add_libc_test( libc.src.stdio.fopen libc.src.stdio.fwrite libc.src.stdio.getc + libc.test.UnitTest.ErrnoCheckingTest + libc.test.UnitTest.ErrnoSetterMatcher ) add_libc_test( @@ -510,6 +519,8 @@ add_libc_test( libc.src.stdio.funlockfile libc.src.stdio.fwrite libc.src.stdio.getc_unlocked + libc.test.UnitTest.ErrnoCheckingTest + libc.test.UnitTest.ErrnoSetterMatcher ) add_libc_test( @@ -527,6 +538,8 @@ add_libc_test( libc.src.stdio.fgets libc.src.stdio.fopen libc.src.stdio.fwrite + libc.test.UnitTest.ErrnoCheckingTest + libc.test.UnitTest.ErrnoSetterMatcher ) add_libc_test( diff --git a/external/llvm-project/libc/test/src/stdio/fdopen_test.cpp b/external/llvm-project/libc/test/src/stdio/fdopen_test.cpp index 104fc478b100..b53184c30be3 100644 --- a/external/llvm-project/libc/test/src/stdio/fdopen_test.cpp +++ b/external/llvm-project/libc/test/src/stdio/fdopen_test.cpp @@ -9,20 +9,21 @@ #include "src/stdio/fdopen.h" #include "hdr/fcntl_macros.h" -#include "src/__support/libc_errno.h" #include "src/fcntl/open.h" #include "src/stdio/fclose.h" #include "src/stdio/fgets.h" #include "src/stdio/fputs.h" #include "src/unistd/close.h" +#include "test/UnitTest/ErrnoCheckingTest.h" #include "test/UnitTest/ErrnoSetterMatcher.h" #include "test/UnitTest/Test.h" #include // For S_IRWXU -TEST(LlvmLibcStdioFdopenTest, WriteAppendRead) { +using LlvmLibcStdioFdopenTest = LIBC_NAMESPACE::testing::ErrnoCheckingTest; + +TEST_F(LlvmLibcStdioFdopenTest, WriteAppendRead) { using LIBC_NAMESPACE::testing::ErrnoSetterMatcher::Succeeds; - libc_errno = 0; constexpr const char *TEST_FILE_NAME = "testdata/write_read_append.test"; auto TEST_FILE = libc_make_test_file_path(TEST_FILE_NAME); int fd = LIBC_NAMESPACE::open(TEST_FILE, O_CREAT | O_TRUNC | O_RDWR, S_IRWXU); @@ -52,8 +53,7 @@ TEST(LlvmLibcStdioFdopenTest, WriteAppendRead) { ASSERT_ERRNO_SUCCESS(); } -TEST(LlvmLibcStdioFdopenTest, InvalidFd) { - libc_errno = 0; +TEST_F(LlvmLibcStdioFdopenTest, InvalidFd) { constexpr const char *TEST_FILE_NAME = "testdata/invalid_fd.test"; auto TEST_FILE = libc_make_test_file_path(TEST_FILE_NAME); int fd = LIBC_NAMESPACE::open(TEST_FILE, O_CREAT | O_TRUNC); @@ -64,8 +64,7 @@ TEST(LlvmLibcStdioFdopenTest, InvalidFd) { ASSERT_TRUE(nullptr == fp); } -TEST(LlvmLibcStdioFdopenTest, InvalidMode) { - libc_errno = 0; +TEST_F(LlvmLibcStdioFdopenTest, InvalidMode) { constexpr const char *TEST_FILE_NAME = "testdata/invalid_mode.test"; auto TEST_FILE = libc_make_test_file_path(TEST_FILE_NAME); int fd = LIBC_NAMESPACE::open(TEST_FILE, O_CREAT | O_RDONLY, S_IRWXU); @@ -83,7 +82,6 @@ TEST(LlvmLibcStdioFdopenTest, InvalidMode) { auto *fp2 = LIBC_NAMESPACE::fdopen(fd, "w"); ASSERT_ERRNO_EQ(EINVAL); ASSERT_TRUE(nullptr == fp2); - libc_errno = 0; LIBC_NAMESPACE::close(fd); ASSERT_ERRNO_SUCCESS(); } diff --git a/external/llvm-project/libc/test/src/stdio/fgetc_test.cpp b/external/llvm-project/libc/test/src/stdio/fgetc_test.cpp index 56bde5f0099a..be2e50271b51 100644 --- a/external/llvm-project/libc/test/src/stdio/fgetc_test.cpp +++ b/external/llvm-project/libc/test/src/stdio/fgetc_test.cpp @@ -14,12 +14,15 @@ #include "src/stdio/fopen.h" #include "src/stdio/fwrite.h" #include "src/stdio/getc.h" +#include "test/UnitTest/ErrnoCheckingTest.h" +#include "test/UnitTest/ErrnoSetterMatcher.h" #include "test/UnitTest/Test.h" #include "hdr/stdio_macros.h" -#include "src/__support/libc_errno.h" -class LlvmLibcGetcTest : public LIBC_NAMESPACE::testing::Test { +using namespace LIBC_NAMESPACE::testing::ErrnoSetterMatcher; + +class LlvmLibcGetcTest : public LIBC_NAMESPACE::testing::ErrnoCheckingTest { public: using GetcFunc = int(FILE *); void test_with_func(GetcFunc *func, const char *filename) { @@ -27,29 +30,28 @@ class LlvmLibcGetcTest : public LIBC_NAMESPACE::testing::Test { ASSERT_FALSE(file == nullptr); constexpr char CONTENT[] = "123456789"; constexpr size_t WRITE_SIZE = sizeof(CONTENT) - 1; - ASSERT_EQ(WRITE_SIZE, LIBC_NAMESPACE::fwrite(CONTENT, 1, WRITE_SIZE, file)); + ASSERT_THAT(LIBC_NAMESPACE::fwrite(CONTENT, 1, WRITE_SIZE, file), + Succeeds(WRITE_SIZE)); // This is a write-only file so reads should fail. - ASSERT_EQ(func(file), EOF); + ASSERT_THAT(func(file), Fails(EBADF, EOF)); // This is an error and not a real EOF. ASSERT_EQ(LIBC_NAMESPACE::feof(file), 0); ASSERT_NE(LIBC_NAMESPACE::ferror(file), 0); - libc_errno = 0; - ASSERT_EQ(0, LIBC_NAMESPACE::fclose(file)); + ASSERT_THAT(LIBC_NAMESPACE::fclose(file), Succeeds()); file = LIBC_NAMESPACE::fopen(filename, "r"); ASSERT_FALSE(file == nullptr); for (size_t i = 0; i < WRITE_SIZE; ++i) { - int c = func(file); - ASSERT_EQ(c, int('1' + i)); + ASSERT_THAT(func(file), Succeeds(int('1' + i))); } // Reading more should return EOF but not set error. - ASSERT_EQ(func(file), EOF); + ASSERT_THAT(func(file), Succeeds(EOF)); ASSERT_NE(LIBC_NAMESPACE::feof(file), 0); ASSERT_EQ(LIBC_NAMESPACE::ferror(file), 0); - ASSERT_EQ(0, LIBC_NAMESPACE::fclose(file)); + ASSERT_THAT(LIBC_NAMESPACE::fclose(file), Succeeds()); } }; diff --git a/external/llvm-project/libc/test/src/stdio/fgetc_unlocked_test.cpp b/external/llvm-project/libc/test/src/stdio/fgetc_unlocked_test.cpp index 90429ecf4e82..bef9dafd3d87 100644 --- a/external/llvm-project/libc/test/src/stdio/fgetc_unlocked_test.cpp +++ b/external/llvm-project/libc/test/src/stdio/fgetc_unlocked_test.cpp @@ -17,12 +17,15 @@ #include "src/stdio/funlockfile.h" #include "src/stdio/fwrite.h" #include "src/stdio/getc_unlocked.h" +#include "test/UnitTest/ErrnoCheckingTest.h" +#include "test/UnitTest/ErrnoSetterMatcher.h" #include "test/UnitTest/Test.h" #include "hdr/stdio_macros.h" -#include "src/__support/libc_errno.h" -class LlvmLibcGetcTest : public LIBC_NAMESPACE::testing::Test { +using namespace LIBC_NAMESPACE::testing::ErrnoSetterMatcher; + +class LlvmLibcGetcTest : public LIBC_NAMESPACE::testing::ErrnoCheckingTest { public: using GetcFunc = int(FILE *); void test_with_func(GetcFunc *func, const char *filename) { @@ -30,31 +33,30 @@ class LlvmLibcGetcTest : public LIBC_NAMESPACE::testing::Test { ASSERT_FALSE(file == nullptr); constexpr char CONTENT[] = "123456789"; constexpr size_t WRITE_SIZE = sizeof(CONTENT) - 1; - ASSERT_EQ(WRITE_SIZE, LIBC_NAMESPACE::fwrite(CONTENT, 1, WRITE_SIZE, file)); + ASSERT_THAT(LIBC_NAMESPACE::fwrite(CONTENT, 1, WRITE_SIZE, file), + Succeeds(WRITE_SIZE)); // This is a write-only file so reads should fail. - ASSERT_EQ(func(file), EOF); + ASSERT_THAT(func(file), Fails(EBADF, EOF)); // This is an error and not a real EOF. ASSERT_EQ(LIBC_NAMESPACE::feof(file), 0); ASSERT_NE(LIBC_NAMESPACE::ferror(file), 0); - libc_errno = 0; - ASSERT_EQ(0, LIBC_NAMESPACE::fclose(file)); + ASSERT_THAT(LIBC_NAMESPACE::fclose(file), Succeeds()); file = LIBC_NAMESPACE::fopen(filename, "r"); ASSERT_FALSE(file == nullptr); LIBC_NAMESPACE::flockfile(file); for (size_t i = 0; i < WRITE_SIZE; ++i) { - int c = func(file); - ASSERT_EQ(c, int('1' + i)); + ASSERT_THAT(func(file), Succeeds(int('1' + i))); } // Reading more should return EOF but not set error. - ASSERT_EQ(func(file), EOF); + ASSERT_THAT(func(file), Succeeds(EOF)); ASSERT_NE(LIBC_NAMESPACE::feof_unlocked(file), 0); ASSERT_EQ(LIBC_NAMESPACE::ferror_unlocked(file), 0); LIBC_NAMESPACE::funlockfile(file); - ASSERT_EQ(0, LIBC_NAMESPACE::fclose(file)); + ASSERT_THAT(LIBC_NAMESPACE::fclose(file), Succeeds()); } }; diff --git a/external/llvm-project/libc/test/src/stdio/fgets_test.cpp b/external/llvm-project/libc/test/src/stdio/fgets_test.cpp index abed3d405293..8fc38b065918 100644 --- a/external/llvm-project/libc/test/src/stdio/fgets_test.cpp +++ b/external/llvm-project/libc/test/src/stdio/fgets_test.cpp @@ -12,11 +12,14 @@ #include "src/stdio/fgets.h" #include "src/stdio/fopen.h" #include "src/stdio/fwrite.h" +#include "test/UnitTest/ErrnoCheckingTest.h" +#include "test/UnitTest/ErrnoSetterMatcher.h" #include "test/UnitTest/Test.h" -#include "src/__support/libc_errno.h" +using LlvmLibcFgetsTest = LIBC_NAMESPACE::testing::ErrnoCheckingTest; +using namespace LIBC_NAMESPACE::testing::ErrnoSetterMatcher; -TEST(LlvmLibcFgetsTest, WriteAndReadCharacters) { +TEST_F(LlvmLibcFgetsTest, WriteAndReadCharacters) { constexpr char FILENAME[] = "testdata/fgets.test"; ::FILE *file = LIBC_NAMESPACE::fopen(FILENAME, "w"); ASSERT_FALSE(file == nullptr); @@ -29,15 +32,16 @@ TEST(LlvmLibcFgetsTest, WriteAndReadCharacters) { char buff[8]; char *output; - ASSERT_EQ(WRITE_SIZE, LIBC_NAMESPACE::fwrite(CONTENT, 1, WRITE_SIZE, file)); + ASSERT_THAT(LIBC_NAMESPACE::fwrite(CONTENT, 1, WRITE_SIZE, file), + Succeeds(WRITE_SIZE)); // This is a write-only file so reads should fail. - ASSERT_TRUE(LIBC_NAMESPACE::fgets(buff, 8, file) == nullptr); + ASSERT_THAT(LIBC_NAMESPACE::fgets(buff, 8, file), + Fails(EBADF, static_cast(nullptr))); // This is an error and not a real EOF. ASSERT_EQ(LIBC_NAMESPACE::feof(file), 0); ASSERT_NE(LIBC_NAMESPACE::ferror(file), 0); - libc_errno = 0; - ASSERT_EQ(0, LIBC_NAMESPACE::fclose(file)); + ASSERT_THAT(LIBC_NAMESPACE::fclose(file), Succeeds()); file = LIBC_NAMESPACE::fopen(FILENAME, "r"); ASSERT_FALSE(file == nullptr); @@ -55,6 +59,7 @@ TEST(LlvmLibcFgetsTest, WriteAndReadCharacters) { // This is also implementation defined. output = LIBC_NAMESPACE::fgets(buff, 0, file); ASSERT_TRUE(output == nullptr); + ASSERT_ERRNO_SUCCESS(); #endif const char *output_arr[] = { @@ -86,5 +91,5 @@ TEST(LlvmLibcFgetsTest, WriteAndReadCharacters) { ASSERT_NE(LIBC_NAMESPACE::feof(file), 0); ASSERT_ERRNO_SUCCESS(); - ASSERT_EQ(0, LIBC_NAMESPACE::fclose(file)); + ASSERT_THAT(LIBC_NAMESPACE::fclose(file), Succeeds()); } diff --git a/external/llvm-project/libc/test/src/stdio/fileop_test.cpp b/external/llvm-project/libc/test/src/stdio/fileop_test.cpp index e624181c795b..e097785832d5 100644 --- a/external/llvm-project/libc/test/src/stdio/fileop_test.cpp +++ b/external/llvm-project/libc/test/src/stdio/fileop_test.cpp @@ -17,17 +17,18 @@ #include "src/stdio/fread.h" #include "src/stdio/fseek.h" #include "src/stdio/fwrite.h" +#include "test/UnitTest/ErrnoCheckingTest.h" #include "test/UnitTest/ErrnoSetterMatcher.h" #include "test/UnitTest/Test.h" #include "hdr/stdio_macros.h" -#include "src/__support/libc_errno.h" +using LlvmLibcFILETest = LIBC_NAMESPACE::testing::ErrnoCheckingTest; using LIBC_NAMESPACE::testing::ErrnoSetterMatcher::EQ; using LIBC_NAMESPACE::testing::ErrnoSetterMatcher::NE; using LIBC_NAMESPACE::testing::ErrnoSetterMatcher::returns; -TEST(LlvmLibcFILETest, SimpleFileOperations) { +TEST_F(LlvmLibcFILETest, SimpleFileOperations) { constexpr char FILENAME[] = "testdata/simple_operations.test"; ::FILE *file = LIBC_NAMESPACE::fopen(FILENAME, "w"); ASSERT_FALSE(file == nullptr); @@ -41,7 +42,6 @@ TEST(LlvmLibcFILETest, SimpleFileOperations) { ASSERT_THAT(LIBC_NAMESPACE::fread(read_data, 1, sizeof(CONTENT), file), returns(EQ(size_t(0))).with_errno(NE(0))); ASSERT_NE(LIBC_NAMESPACE::ferror(file), 0); - libc_errno = 0; LIBC_NAMESPACE::clearerr(file); ASSERT_EQ(LIBC_NAMESPACE::ferror(file), 0); @@ -72,7 +72,6 @@ TEST(LlvmLibcFILETest, SimpleFileOperations) { ASSERT_THAT(LIBC_NAMESPACE::fwrite(CONTENT, 1, sizeof(CONTENT), file), returns(EQ(size_t(0))).with_errno(NE(0))); ASSERT_NE(LIBC_NAMESPACE::ferror(file), 0); - libc_errno = 0; LIBC_NAMESPACE::clearerr(file); @@ -80,15 +79,12 @@ TEST(LlvmLibcFILETest, SimpleFileOperations) { ASSERT_THAT(LIBC_NAMESPACE::fputs(CONTENT, file), returns(EQ(EOF)).with_errno(NE(0))); ASSERT_NE(LIBC_NAMESPACE::ferror(file), 0); - libc_errno = 0; LIBC_NAMESPACE::clearerr(file); ASSERT_EQ(LIBC_NAMESPACE::ferror(file), 0); - libc_errno = 0; ASSERT_THAT(LIBC_NAMESPACE::fwrite("nothing", 1, 1, file), returns(EQ(size_t(0))).with_errno(NE(0))); - libc_errno = 0; ASSERT_EQ(LIBC_NAMESPACE::fclose(file), 0); @@ -103,10 +99,8 @@ TEST(LlvmLibcFILETest, SimpleFileOperations) { ASSERT_EQ(LIBC_NAMESPACE::ferror(file), 0); // This is not a readable file. - libc_errno = 0; ASSERT_THAT(LIBC_NAMESPACE::fread(data, 1, 1, file), returns(EQ(0)).with_errno(NE(0))); - libc_errno = 0; ASSERT_EQ(0, LIBC_NAMESPACE::fclose(file)); @@ -121,21 +115,18 @@ TEST(LlvmLibcFILETest, SimpleFileOperations) { // Check that the other functions correctly set libc_errno. - // libc_errno = 0; // ASSERT_NE(LIBC_NAMESPACE::fseek(file, 0, SEEK_SET), 0); // ASSERT_ERRNO_FAILURE(); - // libc_errno = 0; // ASSERT_NE(LIBC_NAMESPACE::fclose(file), 0); // ASSERT_ERRNO_FAILURE(); - // libc_errno = 0; // ASSERT_EQ(LIBC_NAMESPACE::fopen("INVALID FILE NAME", "r"), // static_cast(nullptr)); // ASSERT_ERRNO_FAILURE(); } -TEST(LlvmLibcFILETest, FFlush) { +TEST_F(LlvmLibcFILETest, FFlush) { constexpr char FILENAME[] = "testdata/fflush.test"; ::FILE *file = LIBC_NAMESPACE::fopen(FILENAME, "w+"); ASSERT_FALSE(file == nullptr); @@ -156,7 +147,7 @@ TEST(LlvmLibcFILETest, FFlush) { ASSERT_EQ(LIBC_NAMESPACE::fclose(file), 0); } -TEST(LlvmLibcFILETest, FOpenFWriteSizeGreaterThanOne) { +TEST_F(LlvmLibcFILETest, FOpenFWriteSizeGreaterThanOne) { using MyStruct = struct { char c; unsigned long long i; @@ -165,7 +156,6 @@ TEST(LlvmLibcFILETest, FOpenFWriteSizeGreaterThanOne) { constexpr size_t WRITE_NMEMB = sizeof(WRITE_DATA) / sizeof(MyStruct); constexpr char FILENAME[] = "testdata/fread_fwrite.test"; - libc_errno = 0; FILE *file = LIBC_NAMESPACE::fopen(FILENAME, "w"); ASSERT_FALSE(file == nullptr); ASSERT_EQ(size_t(0), LIBC_NAMESPACE::fwrite(WRITE_DATA, 0, 1, file)); diff --git a/external/llvm-project/libc/test/src/stdio/fopencookie_test.cpp b/external/llvm-project/libc/test/src/stdio/fopencookie_test.cpp index 03e1ac286b64..bcf5e674141a 100644 --- a/external/llvm-project/libc/test/src/stdio/fopencookie_test.cpp +++ b/external/llvm-project/libc/test/src/stdio/fopencookie_test.cpp @@ -15,6 +15,7 @@ #include "src/stdio/fread.h" #include "src/stdio/fseek.h" #include "src/stdio/fwrite.h" +#include "test/UnitTest/ErrnoCheckingTest.h" #include "test/UnitTest/MemoryMatcher.h" #include "test/UnitTest/Test.h" @@ -22,6 +23,7 @@ #include "hdr/types/size_t.h" #include "src/__support/libc_errno.h" +using LlvmLibcFOpenCookieTest = LIBC_NAMESPACE::testing::ErrnoCheckingTest; using MemoryView = LIBC_NAMESPACE::testing::MemoryView; struct StringStream { @@ -88,7 +90,7 @@ int close_ss(void *cookie) { constexpr cookie_io_functions_t STRING_STREAM_FUNCS = {&read_ss, &write_ss, &seek_ss, &close_ss}; -TEST(LlvmLibcFOpenCookie, ReadOnlyCookieTest) { +TEST_F(LlvmLibcFOpenCookieTest, ReadOnlyCookieTest) { constexpr char CONTENT[] = "Hello,readonly!"; auto *ss = reinterpret_cast(malloc(sizeof(StringStream))); ss->buf = reinterpret_cast(malloc(sizeof(CONTENT))); @@ -115,7 +117,6 @@ TEST(LlvmLibcFOpenCookie, ReadOnlyCookieTest) { ASSERT_EQ(size_t(0), LIBC_NAMESPACE::fwrite(CONTENT, 1, sizeof(CONTENT), f)); ASSERT_NE(LIBC_NAMESPACE::ferror(f), 0); ASSERT_ERRNO_FAILURE(); - libc_errno = 0; LIBC_NAMESPACE::clearerr(f); ASSERT_EQ(LIBC_NAMESPACE::ferror(f), 0); @@ -124,7 +125,7 @@ TEST(LlvmLibcFOpenCookie, ReadOnlyCookieTest) { free(ss); } -TEST(LlvmLibcFOpenCookie, WriteOnlyCookieTest) { +TEST_F(LlvmLibcFOpenCookieTest, WriteOnlyCookieTest) { size_t INIT_BUFSIZE = 32; auto *ss = reinterpret_cast(malloc(sizeof(StringStream))); ss->buf = reinterpret_cast(malloc(INIT_BUFSIZE)); @@ -149,7 +150,6 @@ TEST(LlvmLibcFOpenCookie, WriteOnlyCookieTest) { LIBC_NAMESPACE::fread(read_data, 1, sizeof(WRITE_DATA), f)); ASSERT_NE(LIBC_NAMESPACE::ferror(f), 0); ASSERT_ERRNO_EQ(EBADF); - libc_errno = 0; LIBC_NAMESPACE::clearerr(f); ASSERT_EQ(LIBC_NAMESPACE::ferror(f), 0); @@ -158,7 +158,7 @@ TEST(LlvmLibcFOpenCookie, WriteOnlyCookieTest) { free(ss); } -TEST(LlvmLibcFOpenCookie, AppendOnlyCookieTest) { +TEST_F(LlvmLibcFOpenCookieTest, AppendOnlyCookieTest) { constexpr char INITIAL_CONTENT[] = "1234567890987654321"; constexpr char WRITE_DATA[] = "append"; auto *ss = reinterpret_cast(malloc(sizeof(StringStream))); @@ -178,7 +178,6 @@ TEST(LlvmLibcFOpenCookie, AppendOnlyCookieTest) { ASSERT_EQ(LIBC_NAMESPACE::fread(read_data, 1, READ_SIZE, f), size_t(0)); ASSERT_NE(LIBC_NAMESPACE::ferror(f), 0); ASSERT_ERRNO_FAILURE(); - libc_errno = 0; LIBC_NAMESPACE::clearerr(f); ASSERT_EQ(LIBC_NAMESPACE::ferror(f), 0); @@ -192,7 +191,7 @@ TEST(LlvmLibcFOpenCookie, AppendOnlyCookieTest) { free(ss); } -TEST(LlvmLibcFOpenCookie, ReadUpdateCookieTest) { +TEST_F(LlvmLibcFOpenCookieTest, ReadUpdateCookieTest) { const char INITIAL_CONTENT[] = "1234567890987654321"; auto *ss = reinterpret_cast(malloc(sizeof(StringStream))); ss->buf = reinterpret_cast(malloc(sizeof(INITIAL_CONTENT))); @@ -223,7 +222,7 @@ TEST(LlvmLibcFOpenCookie, ReadUpdateCookieTest) { free(ss); } -TEST(LlvmLibcFOpenCookie, WriteUpdateCookieTest) { +TEST_F(LlvmLibcFOpenCookieTest, WriteUpdateCookieTest) { constexpr char WRITE_DATA[] = "hello, file"; auto *ss = reinterpret_cast(malloc(sizeof(StringStream))); ss->buf = reinterpret_cast(malloc(sizeof(WRITE_DATA))); diff --git a/external/llvm-project/libc/test/src/stdio/remove_test.cpp b/external/llvm-project/libc/test/src/stdio/remove_test.cpp index 84984e26398c..296bff1f5dc1 100644 --- a/external/llvm-project/libc/test/src/stdio/remove_test.cpp +++ b/external/llvm-project/libc/test/src/stdio/remove_test.cpp @@ -11,16 +11,17 @@ #include "src/sys/stat/mkdirat.h" #include "src/unistd/access.h" #include "src/unistd/close.h" +#include "test/UnitTest/ErrnoCheckingTest.h" #include "test/UnitTest/ErrnoSetterMatcher.h" #include "test/UnitTest/Test.h" -#include "src/__support/libc_errno.h" #include -TEST(LlvmLibcRemoveTest, CreateAndRemoveFile) { +using LlvmLibcRemoveTest = LIBC_NAMESPACE::testing::ErrnoCheckingTest; + +TEST_F(LlvmLibcRemoveTest, CreateAndRemoveFile) { // The test strategy is to create a file and remove it, and also verify that // it was removed. - libc_errno = 0; using LIBC_NAMESPACE::testing::ErrnoSetterMatcher::Fails; using LIBC_NAMESPACE::testing::ErrnoSetterMatcher::Succeeds; @@ -36,10 +37,9 @@ TEST(LlvmLibcRemoveTest, CreateAndRemoveFile) { ASSERT_THAT(LIBC_NAMESPACE::access(TEST_FILE, F_OK), Fails(ENOENT)); } -TEST(LlvmLibcRemoveTest, CreateAndRemoveDir) { +TEST_F(LlvmLibcRemoveTest, CreateAndRemoveDir) { // The test strategy is to create a dir and remove it, and also verify that // it was removed. - libc_errno = 0; using LIBC_NAMESPACE::testing::ErrnoSetterMatcher::Fails; using LIBC_NAMESPACE::testing::ErrnoSetterMatcher::Succeeds; constexpr const char *FILENAME = "remove.test.dir"; diff --git a/external/llvm-project/libc/test/src/stdio/rename_test.cpp b/external/llvm-project/libc/test/src/stdio/rename_test.cpp index ac494a4ecaf8..135fb98c07fb 100644 --- a/external/llvm-project/libc/test/src/stdio/rename_test.cpp +++ b/external/llvm-project/libc/test/src/stdio/rename_test.cpp @@ -8,18 +8,19 @@ #include "include/llvm-libc-macros/linux/sys-stat-macros.h" #include "include/llvm-libc-macros/linux/unistd-macros.h" -#include "src/__support/libc_errno.h" #include "src/fcntl/open.h" #include "src/stdio/rename.h" #include "src/unistd/access.h" #include "src/unistd/close.h" +#include "test/UnitTest/ErrnoCheckingTest.h" #include "test/UnitTest/ErrnoSetterMatcher.h" #include "test/UnitTest/Test.h" -TEST(LlvmLibcRenameTest, CreateAndRenameFile) { +using LlvmLibcRenameTest = LIBC_NAMESPACE::testing::ErrnoCheckingTest; + +TEST_F(LlvmLibcRenameTest, CreateAndRenameFile) { // The test strategy is to create a file and rename it, and also verify that // it was renamed. - libc_errno = 0; using LIBC_NAMESPACE::testing::ErrnoSetterMatcher::Fails; using LIBC_NAMESPACE::testing::ErrnoSetterMatcher::Succeeds; @@ -40,7 +41,7 @@ TEST(LlvmLibcRenameTest, CreateAndRenameFile) { ASSERT_THAT(LIBC_NAMESPACE::access(TEST_FILEPATH0, F_OK), Fails(ENOENT)); } -TEST(LlvmLibcRenameTest, RenameNonExistent) { +TEST_F(LlvmLibcRenameTest, RenameNonExistent) { using LIBC_NAMESPACE::testing::ErrnoSetterMatcher::Fails; constexpr const char *FILENAME1 = "rename.test.file1"; diff --git a/external/llvm-project/libc/test/src/stdio/setvbuf_test.cpp b/external/llvm-project/libc/test/src/stdio/setvbuf_test.cpp index 5872943c1bb4..a0936ba79ef7 100644 --- a/external/llvm-project/libc/test/src/stdio/setvbuf_test.cpp +++ b/external/llvm-project/libc/test/src/stdio/setvbuf_test.cpp @@ -11,12 +11,14 @@ #include "src/stdio/fread.h" #include "src/stdio/fwrite.h" #include "src/stdio/setvbuf.h" +#include "test/UnitTest/ErrnoCheckingTest.h" #include "test/UnitTest/Test.h" #include "hdr/stdio_macros.h" -#include "src/__support/libc_errno.h" -TEST(LlvmLibcSetvbufTest, SetNBFBuffer) { +using LlvmLibcSetvbufTest = LIBC_NAMESPACE::testing::ErrnoCheckingTest; + +TEST_F(LlvmLibcSetvbufTest, SetNBFBuffer) { // The idea in this test is that we open a file for writing and reading, and // then set a NBF buffer to the write handle. Since it is NBF, the data // written using the write handle should be immediately readable by the read @@ -52,7 +54,7 @@ TEST(LlvmLibcSetvbufTest, SetNBFBuffer) { ASSERT_EQ(0, LIBC_NAMESPACE::fclose(fr)); } -TEST(LlvmLibcSetvbufTest, SetLBFBuffer) { +TEST_F(LlvmLibcSetvbufTest, SetLBFBuffer) { // The idea in this test is that we open a file for writing and reading, and // then set a LBF buffer to the write handle. Since it is LBF, the data // written using the write handle should be available right after a '\n' is @@ -102,6 +104,5 @@ TEST(LlvmLibcSetbufTest, InvalidBufferMode) { 0); ASSERT_ERRNO_EQ(EINVAL); - libc_errno = 0; ASSERT_EQ(0, LIBC_NAMESPACE::fclose(f)); } diff --git a/external/llvm-project/libc/test/src/stdio/unlocked_fileop_test.cpp b/external/llvm-project/libc/test/src/stdio/unlocked_fileop_test.cpp index 5d482b70064b..e99b382d1211 100644 --- a/external/llvm-project/libc/test/src/stdio/unlocked_fileop_test.cpp +++ b/external/llvm-project/libc/test/src/stdio/unlocked_fileop_test.cpp @@ -15,11 +15,12 @@ #include "src/stdio/fread_unlocked.h" #include "src/stdio/funlockfile.h" #include "src/stdio/fwrite_unlocked.h" +#include "test/UnitTest/ErrnoCheckingTest.h" #include "test/UnitTest/Test.h" -#include "src/__support/libc_errno.h" +using LlvmLibcFILETest = LIBC_NAMESPACE::testing::ErrnoCheckingTest; -TEST(LlvmLibcFILETest, UnlockedReadAndWrite) { +TEST_F(LlvmLibcFILETest, UnlockedReadAndWrite) { constexpr char fNAME[] = "testdata/unlocked_read_and_write.test"; ::FILE *f = LIBC_NAMESPACE::fopen(fNAME, "w"); ASSERT_FALSE(f == nullptr); @@ -36,7 +37,6 @@ TEST(LlvmLibcFILETest, UnlockedReadAndWrite) { LIBC_NAMESPACE::fread_unlocked(data, 1, sizeof(READ_SIZE), f)); ASSERT_NE(LIBC_NAMESPACE::ferror_unlocked(f), 0); ASSERT_ERRNO_FAILURE(); - libc_errno = 0; LIBC_NAMESPACE::clearerr_unlocked(f); ASSERT_EQ(LIBC_NAMESPACE::ferror_unlocked(f), 0); @@ -57,7 +57,6 @@ TEST(LlvmLibcFILETest, UnlockedReadAndWrite) { LIBC_NAMESPACE::fwrite_unlocked(CONTENT, 1, sizeof(CONTENT), f)); ASSERT_NE(LIBC_NAMESPACE::ferror_unlocked(f), 0); ASSERT_ERRNO_FAILURE(); - libc_errno = 0; LIBC_NAMESPACE::clearerr_unlocked(f); ASSERT_EQ(LIBC_NAMESPACE::ferror_unlocked(f), 0); diff --git a/external/llvm-project/libc/test/src/stdlib/StrtolTest.h b/external/llvm-project/libc/test/src/stdlib/StrtolTest.h index 3eeccc5727e7..03f0a6539c78 100644 --- a/external/llvm-project/libc/test/src/stdlib/StrtolTest.h +++ b/external/llvm-project/libc/test/src/stdlib/StrtolTest.h @@ -9,7 +9,6 @@ #include "src/__support/CPP/limits.h" #include "src/__support/CPP/type_traits.h" #include "src/__support/ctype_utils.h" -#include "src/__support/libc_errno.h" #include "src/__support/macros/properties/architectures.h" #include "test/UnitTest/ErrnoCheckingTest.h" #include "test/UnitTest/Test.h" diff --git a/external/llvm-project/libc/test/src/stdlib/strtold_test.cpp b/external/llvm-project/libc/test/src/stdlib/strtold_test.cpp index c2f2b9c9a11c..eb4056dc7ba6 100644 --- a/external/llvm-project/libc/test/src/stdlib/strtold_test.cpp +++ b/external/llvm-project/libc/test/src/stdlib/strtold_test.cpp @@ -7,7 +7,6 @@ //===----------------------------------------------------------------------===// #include "src/__support/FPUtil/FPBits.h" -#include "src/__support/libc_errno.h" #include "src/__support/uint128.h" #include "src/stdlib/strtold.h" diff --git a/external/llvm-project/libc/test/src/wchar/CMakeLists.txt b/external/llvm-project/libc/test/src/wchar/CMakeLists.txt index 4990b6953348..48688b3bdd1f 100644 --- a/external/llvm-project/libc/test/src/wchar/CMakeLists.txt +++ b/external/llvm-project/libc/test/src/wchar/CMakeLists.txt @@ -23,6 +23,33 @@ add_libc_test( libc.src.wchar.btowc ) +add_libc_test( + mbrtowc_test + SUITE + libc_wchar_unittests + SRCS + mbrtowc_test.cpp + DEPENDS + libc.src.__support.libc_errno + libc.src.string.memset + libc.src.wchar.mbrtowc + libc.hdr.types.mbstate_t + libc.hdr.types.wchar_t +) + +add_libc_test( + mbtowc_test + SUITE + libc_wchar_unittests + SRCS + mbtowc_test.cpp + DEPENDS + libc.src.__support.libc_errno + libc.src.wchar.mbtowc + libc.hdr.types.wchar_t + libc.test.UnitTest.ErrnoCheckingTest +) + add_libc_test( wctob_test SUITE @@ -33,6 +60,20 @@ add_libc_test( libc.src.wchar.wctob ) +add_libc_test( + wcrtomb_test + SUITE + libc_wchar_unittests + SRCS + wcrtomb_test.cpp + DEPENDS + libc.src.wchar.wcrtomb + libc.src.string.memset + libc.hdr.types.wchar_t + libc.hdr.types.mbstate_t + libc.src.__support.libc_errno +) + add_libc_test( wmemset_test SUITE @@ -204,3 +245,23 @@ add_libc_test( DEPENDS libc.src.wchar.wcscpy ) + +add_libc_test( + wcpcpy_test + SUITE + libc_wchar_unittests + SRCS + wcpcpy_test.cpp + DEPENDS + libc.src.wchar.wcpcpy +) + +add_libc_test( + wcpncpy_test + SUITE + libc_wchar_unittests + SRCS + wcpncpy_test.cpp + DEPENDS + libc.src.wchar.wcpncpy +) diff --git a/external/llvm-project/libc/test/src/wchar/mbrtowc_test.cpp b/external/llvm-project/libc/test/src/wchar/mbrtowc_test.cpp new file mode 100644 index 000000000000..69dcf00fde20 --- /dev/null +++ b/external/llvm-project/libc/test/src/wchar/mbrtowc_test.cpp @@ -0,0 +1,172 @@ +//===-- Unittests for mbrtowc ---------------------------------------------===// +// +// 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 "hdr/types/mbstate_t.h" +#include "hdr/types/wchar_t.h" +#include "src/__support/libc_errno.h" +#include "src/string/memset.h" +#include "src/wchar/mbrtowc.h" +#include "test/UnitTest/Test.h" + +TEST(LlvmLibcMBRToWC, OneByte) { + const char *ch = "A"; + wchar_t dest[2]; + // Testing if it works with nullptr mbstate_t + mbstate_t *mb = nullptr; + size_t n = LIBC_NAMESPACE::mbrtowc(dest, ch, 1, mb); + ASSERT_EQ(static_cast(*dest), 'A'); + ASSERT_EQ(static_cast(n), 1); + + // Should fail since we have not read enough + n = LIBC_NAMESPACE::mbrtowc(dest, ch, 0, mb); + ASSERT_EQ(static_cast(n), -2); +} + +TEST(LlvmLibcMBRToWC, TwoByte) { + const char ch[2] = {static_cast(0xC2), + static_cast(0x8E)}; // Ž car symbol + wchar_t dest[2]; + mbstate_t *mb; + LIBC_NAMESPACE::memset(&mb, 0, sizeof(mbstate_t)); + size_t n = LIBC_NAMESPACE::mbrtowc(dest, ch, 2, mb); + ASSERT_EQ(static_cast(*dest), 142); + ASSERT_EQ(static_cast(n), 2); + + // Should fail since we have not read enough + n = LIBC_NAMESPACE::mbrtowc(dest, ch, 1, mb); + ASSERT_EQ(static_cast(n), -2); + // Should pass after reading one more byte + n = LIBC_NAMESPACE::mbrtowc(dest, ch + 1, 1, mb); + ASSERT_EQ(static_cast(n), 1); + ASSERT_EQ(static_cast(*dest), 142); +} + +TEST(LlvmLibcMBRToWC, ThreeByte) { + const char ch[3] = {static_cast(0xE2), static_cast(0x88), + static_cast(0x91)}; // ∑ sigma symbol + wchar_t dest[2]; + mbstate_t *mb; + LIBC_NAMESPACE::memset(&mb, 0, sizeof(mbstate_t)); + size_t n = LIBC_NAMESPACE::mbrtowc(dest, ch, 3, mb); + ASSERT_EQ(static_cast(*dest), 8721); + ASSERT_EQ(static_cast(n), 3); + + // Should fail since we have not read enough + n = LIBC_NAMESPACE::mbrtowc(dest, ch, 1, mb); + ASSERT_EQ(static_cast(n), -2); + // Should pass after reading two more bytes + n = LIBC_NAMESPACE::mbrtowc(dest, ch + 1, 2, mb); + ASSERT_EQ(static_cast(n), 2); + ASSERT_EQ(static_cast(*dest), 8721); +} + +TEST(LlvmLibcMBRToWC, FourByte) { + const char ch[4] = {static_cast(0xF0), static_cast(0x9F), + static_cast(0xA4), + static_cast(0xA1)}; // 🤡 clown emoji + wchar_t dest[2]; + mbstate_t *mb; + LIBC_NAMESPACE::memset(&mb, 0, sizeof(mbstate_t)); + size_t n = LIBC_NAMESPACE::mbrtowc(dest, ch, 4, mb); + ASSERT_EQ(static_cast(*dest), 129313); + ASSERT_EQ(static_cast(n), 4); + + // Should fail since we have not read enough + n = LIBC_NAMESPACE::mbrtowc(dest, ch, 2, mb); + ASSERT_EQ(static_cast(n), -2); + // Should pass after reading two more bytes + n = LIBC_NAMESPACE::mbrtowc(dest, ch + 2, 2, mb); + ASSERT_EQ(static_cast(n), 2); + ASSERT_EQ(static_cast(*dest), 129313); +} + +TEST(LlvmLibcMBRToWC, InvalidByte) { + const char ch[1] = {static_cast(0x80)}; + wchar_t dest[2]; + mbstate_t *mb; + LIBC_NAMESPACE::memset(&mb, 0, sizeof(mbstate_t)); + size_t n = LIBC_NAMESPACE::mbrtowc(dest, ch, 1, mb); + ASSERT_EQ(static_cast(n), -1); + ASSERT_EQ(static_cast(libc_errno), EILSEQ); +} + +TEST(LlvmLibcMBRToWC, InvalidMultiByte) { + const char ch[4] = {static_cast(0x80), static_cast(0x00), + static_cast(0x80), + static_cast(0x00)}; // invalid sequence of bytes + wchar_t dest[2]; + mbstate_t *mb; + LIBC_NAMESPACE::memset(&mb, 0, sizeof(mbstate_t)); + // Trying to push all 4 should error + size_t n = LIBC_NAMESPACE::mbrtowc(dest, ch, 4, mb); + ASSERT_EQ(static_cast(n), -1); + ASSERT_EQ(static_cast(libc_errno), EILSEQ); + // Trying to push just the first one should error + n = LIBC_NAMESPACE::mbrtowc(dest, ch, 1, mb); + ASSERT_EQ(static_cast(n), -1); + ASSERT_EQ(static_cast(libc_errno), EILSEQ); + // Trying to push the second and third should correspond to null wc + n = LIBC_NAMESPACE::mbrtowc(dest, ch + 1, 2, mb); + ASSERT_EQ(static_cast(n), 0); + ASSERT_TRUE(*dest == L'\0'); +} + +TEST(LlvmLibcMBRToWC, InvalidLastByte) { + // Last byte is invalid since it does not have correct starting sequence. + // 0xC0 --> 11000000 starting sequence should be 10xxxxxx + const char ch[4] = {static_cast(0xF1), static_cast(0x80), + static_cast(0x80), static_cast(0xC0)}; + wchar_t dest[2]; + mbstate_t *mb; + LIBC_NAMESPACE::memset(&mb, 0, sizeof(mbstate_t)); + // Trying to push all 4 should error + size_t n = LIBC_NAMESPACE::mbrtowc(dest, ch, 4, mb); + ASSERT_EQ(static_cast(n), -1); + ASSERT_EQ(static_cast(libc_errno), EILSEQ); +} + +TEST(LlvmLibcMBRToWC, ValidTwoByteWithExtraRead) { + const char ch[3] = {static_cast(0xC2), static_cast(0x8E), + static_cast(0x80)}; + wchar_t dest[2]; + mbstate_t *mb; + LIBC_NAMESPACE::memset(&mb, 0, sizeof(mbstate_t)); + // Trying to push all 3 should return valid 2 byte + size_t n = LIBC_NAMESPACE::mbrtowc(dest, ch, 3, mb); + ASSERT_EQ(static_cast(n), 2); + ASSERT_EQ(static_cast(*dest), 142); +} + +TEST(LlvmLibcMBRToWC, TwoValidTwoBytes) { + const char ch[4] = {static_cast(0xC2), static_cast(0x8E), + static_cast(0xC7), static_cast(0x8C)}; + wchar_t dest[2]; + mbstate_t *mb; + LIBC_NAMESPACE::memset(&mb, 0, sizeof(mbstate_t)); + // mbstate should reset after reading first one + size_t n = LIBC_NAMESPACE::mbrtowc(dest, ch, 2, mb); + ASSERT_EQ(static_cast(n), 2); + ASSERT_EQ(static_cast(*dest), 142); + n = LIBC_NAMESPACE::mbrtowc(dest + 1, ch + 2, 2, mb); + ASSERT_EQ(static_cast(n), 2); + ASSERT_EQ(static_cast(*(dest + 1)), 460); +} + +TEST(LlvmLibcMBRToWC, NullString) { + wchar_t dest[2] = {L'O', L'K'}; + mbstate_t *mb; + LIBC_NAMESPACE::memset(&mb, 0, sizeof(mbstate_t)); + // reading on nullptr should return 0 + size_t n = LIBC_NAMESPACE::mbrtowc(dest, nullptr, 2, mb); + ASSERT_EQ(static_cast(n), 0); + ASSERT_TRUE(dest[0] == L'O'); + // reading a null terminator should return 0 + const char *ch = "\0"; + n = LIBC_NAMESPACE::mbrtowc(dest, ch, 1, mb); + ASSERT_EQ(static_cast(n), 0); +} diff --git a/external/llvm-project/libc/test/src/wchar/mbtowc_test.cpp b/external/llvm-project/libc/test/src/wchar/mbtowc_test.cpp new file mode 100644 index 000000000000..b27b05cbd899 --- /dev/null +++ b/external/llvm-project/libc/test/src/wchar/mbtowc_test.cpp @@ -0,0 +1,154 @@ +//===-- Unittests for mbtowc ---------------------------------------------===// +// +// 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 "hdr/types/wchar_t.h" +#include "src/__support/libc_errno.h" +#include "src/wchar/mbtowc.h" +#include "test/UnitTest/ErrnoCheckingTest.h" +#include "test/UnitTest/Test.h" + +using LlvmLibcMBToWCTest = LIBC_NAMESPACE::testing::ErrnoCheckingTest; + +TEST_F(LlvmLibcMBToWCTest, OneByte) { + const char *ch = "A"; + wchar_t dest[2]; + int n = LIBC_NAMESPACE::mbtowc(dest, ch, 1); + ASSERT_EQ(static_cast(*dest), 'A'); + ASSERT_EQ(n, 1); + + // Should fail since we have not read enough + n = LIBC_NAMESPACE::mbtowc(dest, ch, 0); + ASSERT_EQ(n, -1); + ASSERT_ERRNO_EQ(EILSEQ); +} + +TEST_F(LlvmLibcMBToWCTest, TwoByte) { + const char ch[2] = {static_cast(0xC2), + static_cast(0x8E)}; // Ž car symbol + wchar_t dest[2]; + int n = LIBC_NAMESPACE::mbtowc(dest, ch, 2); + ASSERT_EQ(static_cast(*dest), 142); + ASSERT_EQ(n, 2); + + // Should fail since we have not read enough + n = LIBC_NAMESPACE::mbtowc(dest, ch, 1); + ASSERT_EQ(n, -1); + // Should fail after trying to read next byte too + n = LIBC_NAMESPACE::mbtowc(dest, ch + 1, 1); + ASSERT_EQ(n, -1); + ASSERT_ERRNO_EQ(EILSEQ); +} + +TEST_F(LlvmLibcMBToWCTest, ThreeByte) { + const char ch[3] = {static_cast(0xE2), static_cast(0x88), + static_cast(0x91)}; // ∑ sigma symbol + wchar_t dest[2]; + int n = LIBC_NAMESPACE::mbtowc(dest, ch, 3); + ASSERT_EQ(static_cast(*dest), 8721); + ASSERT_EQ(n, 3); + + // Should fail since we have not read enough + n = LIBC_NAMESPACE::mbtowc(dest, ch, 2); + ASSERT_EQ(n, -1); + ASSERT_ERRNO_EQ(EILSEQ); +} + +TEST_F(LlvmLibcMBToWCTest, FourByte) { + const char ch[4] = {static_cast(0xF0), static_cast(0x9F), + static_cast(0xA4), + static_cast(0xA1)}; // 🤡 clown emoji + wchar_t dest[2]; + int n = LIBC_NAMESPACE::mbtowc(dest, ch, 4); + ASSERT_EQ(static_cast(*dest), 129313); + ASSERT_EQ(n, 4); + + // Should fail since we have not read enough + n = LIBC_NAMESPACE::mbtowc(dest, ch, 2); + ASSERT_EQ(n, -1); + ASSERT_ERRNO_EQ(EILSEQ); +} + +TEST_F(LlvmLibcMBToWCTest, InvalidByte) { + const char ch[1] = {static_cast(0x80)}; + wchar_t dest[2]; + int n = LIBC_NAMESPACE::mbtowc(dest, ch, 1); + ASSERT_EQ(n, -1); + ASSERT_ERRNO_EQ(EILSEQ); +} + +TEST_F(LlvmLibcMBToWCTest, InvalidMultiByte) { + const char ch[4] = {static_cast(0x80), static_cast(0x00), + static_cast(0x80), + static_cast(0x00)}; // invalid sequence of bytes + wchar_t dest[2]; + // Trying to push all 4 should error + int n = LIBC_NAMESPACE::mbtowc(dest, ch, 4); + ASSERT_EQ(n, -1); + ASSERT_ERRNO_EQ(EILSEQ); + + // Trying to push the second and third should correspond to null wc + n = LIBC_NAMESPACE::mbtowc(dest, ch + 1, 2); + ASSERT_EQ(n, 0); + ASSERT_TRUE(*dest == L'\0'); +} + +TEST_F(LlvmLibcMBToWCTest, InvalidLastByte) { + // Last byte is invalid since it does not have correct starting sequence. + // 0xC0 --> 11000000 starting sequence should be 10xxxxxx + const char ch[4] = {static_cast(0xF1), static_cast(0x80), + static_cast(0x80), static_cast(0xC0)}; + wchar_t dest[2]; + // Trying to push all 4 should error + int n = LIBC_NAMESPACE::mbtowc(dest, ch, 4); + ASSERT_EQ(n, -1); + ASSERT_ERRNO_EQ(EILSEQ); +} + +TEST_F(LlvmLibcMBToWCTest, ValidTwoByteWithExtraRead) { + const char ch[3] = {static_cast(0xC2), static_cast(0x8E), + static_cast(0x80)}; + wchar_t dest[2]; + // Trying to push all 3 should return valid 2 byte + int n = LIBC_NAMESPACE::mbtowc(dest, ch, 3); + ASSERT_EQ(n, 2); + ASSERT_EQ(static_cast(*dest), 142); +} + +TEST_F(LlvmLibcMBToWCTest, TwoValidTwoBytes) { + const char ch[4] = {static_cast(0xC2), static_cast(0x8E), + static_cast(0xC7), static_cast(0x8C)}; + wchar_t dest[2]; + int n = LIBC_NAMESPACE::mbtowc(dest, ch, 2); + ASSERT_EQ(n, 2); + ASSERT_EQ(static_cast(*dest), 142); + n = LIBC_NAMESPACE::mbtowc(dest + 1, ch + 2, 2); + ASSERT_EQ(n, 2); + ASSERT_EQ(static_cast(*(dest + 1)), 460); +} + +TEST_F(LlvmLibcMBToWCTest, NullString) { + wchar_t dest[2] = {L'O', L'K'}; + // reading on nullptr should return 0 + int n = LIBC_NAMESPACE::mbtowc(dest, nullptr, 2); + ASSERT_EQ(n, 0); + ASSERT_TRUE(dest[0] == L'O'); + // reading a null terminator should return 0 + const char *ch = "\0"; + n = LIBC_NAMESPACE::mbtowc(dest, ch, 1); + ASSERT_EQ(n, 0); +} + +TEST_F(LlvmLibcMBToWCTest, NullWCPtr) { + const char ch[2] = { + static_cast(0xC2), + static_cast(0x8E), + }; + // a null destination should still return the number of read bytes + int n = LIBC_NAMESPACE::mbtowc(nullptr, ch, 2); + ASSERT_EQ(n, 2); +} diff --git a/external/llvm-project/libc/test/src/wchar/wcpcpy_test.cpp b/external/llvm-project/libc/test/src/wchar/wcpcpy_test.cpp new file mode 100644 index 000000000000..c59b61fb131b --- /dev/null +++ b/external/llvm-project/libc/test/src/wchar/wcpcpy_test.cpp @@ -0,0 +1,50 @@ +//===-- Unittests for wcpcpy ---------------------------------------------===// +// +// 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 "hdr/types/wchar_t.h" +#include "src/wchar/wcpcpy.h" +#include "test/UnitTest/Test.h" + +TEST(LlvmLibcWCPCpyTest, EmptySrc) { + // Empty src should lead to empty destination. + wchar_t dest[4] = {L'a', L'b', L'c', L'\0'}; + const wchar_t *src = L""; + LIBC_NAMESPACE::wcpcpy(dest, src); + ASSERT_TRUE(dest[0] == src[0]); + ASSERT_TRUE(dest[0] == L'\0'); +} + +TEST(LlvmLibcWCPCpyTest, EmptyDest) { + // Empty dest should result in src + const wchar_t *src = L"abc"; + wchar_t dest[4]; + wchar_t *result = LIBC_NAMESPACE::wcpcpy(dest, src); + ASSERT_EQ(dest + 3, result); + ASSERT_TRUE(result[0] == L'\0'); + ASSERT_TRUE(dest[0] == L'a'); + ASSERT_TRUE(dest[1] == L'b'); + ASSERT_TRUE(dest[2] == L'c'); +} + +TEST(LlvmLibcWCPCpyTest, OffsetDest) { + // Offsetting should result in a concatenation. + const wchar_t *src = L"abc"; + wchar_t dest[7]; + dest[0] = L'x'; + dest[1] = L'y'; + dest[2] = L'z'; + wchar_t *result = LIBC_NAMESPACE::wcpcpy(dest + 3, src); + ASSERT_TRUE(dest[0] == L'x'); + ASSERT_TRUE(dest[1] == L'y'); + ASSERT_TRUE(dest[2] == L'z'); + ASSERT_TRUE(dest[3] == src[0]); + ASSERT_TRUE(dest[4] == src[1]); + ASSERT_TRUE(dest[5] == src[2]); + ASSERT_TRUE(result[0] == L'\0'); + ASSERT_EQ(dest + 6, result); +} diff --git a/external/llvm-project/libc/test/src/wchar/wcpncpy_test.cpp b/external/llvm-project/libc/test/src/wchar/wcpncpy_test.cpp new file mode 100644 index 000000000000..98738e230e32 --- /dev/null +++ b/external/llvm-project/libc/test/src/wchar/wcpncpy_test.cpp @@ -0,0 +1,84 @@ +//===-- Unittests for wcpncpy --------------------------------------------===// +// +// 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 "hdr/types/wchar_t.h" +#include "src/wchar/wcpncpy.h" +#include "test/UnitTest/Test.h" + +TEST(LlvmLibcWCPNCpyTest, EmptySrc) { + // Empty src should lead to empty destination. + wchar_t dest[4] = {L'a', L'b', L'c', L'\0'}; + const wchar_t *src = L""; + LIBC_NAMESPACE::wcpncpy(dest, src, 3); + ASSERT_TRUE(dest[0] == src[0]); + ASSERT_TRUE(dest[0] == L'\0'); + // Rest should also be padded with L'\0' + ASSERT_TRUE(dest[1] == L'\0'); + ASSERT_TRUE(dest[2] == L'\0'); +} + +TEST(LlvmLibcWCPNCpyTest, Untouched) { + wchar_t dest[] = {L'a', L'b'}; + const wchar_t src[] = {L'x', L'\0'}; + LIBC_NAMESPACE::wcpncpy(dest, src, 0); + ASSERT_TRUE(dest[0] == L'a'); + ASSERT_TRUE(dest[1] == L'b'); +} + +TEST(LlvmLibcWCPNCpyTest, CopyOne) { + wchar_t dest[] = {L'a', L'b'}; + const wchar_t src[] = {L'x', L'y'}; + wchar_t *res = LIBC_NAMESPACE::wcpncpy(dest, src, 1); + ASSERT_TRUE(dest[0] == L'x'); + ASSERT_TRUE(dest[1] == L'b'); + ASSERT_EQ(dest + 1, res); +} + +TEST(LlvmLibcWCPNCpyTest, CopyNull) { + wchar_t dest[] = {L'a', L'b'}; + const wchar_t src[] = {L'\0', L'y'}; + wchar_t *res = LIBC_NAMESPACE::wcpncpy(dest, src, 1); + ASSERT_TRUE(dest[0] == L'\0'); + ASSERT_TRUE(dest[1] == L'b'); + ASSERT_EQ(dest + 1, res); +} + +TEST(LlvmLibcWCPNCpyTest, CopyPastSrc) { + wchar_t dest[] = {L'a', L'b'}; + const wchar_t src[] = {L'\0', L'y'}; + wchar_t *res = LIBC_NAMESPACE::wcpncpy(dest, src, 2); + ASSERT_TRUE(dest[0] == L'\0'); + ASSERT_TRUE(dest[1] == L'\0'); + ASSERT_EQ(dest + 2, res); +} + +TEST(LlvmLibcWCPNCpyTest, CopyTwoNoNull) { + wchar_t dest[] = {L'a', L'b'}; + const wchar_t src[] = {L'x', L'y'}; + wchar_t *res = LIBC_NAMESPACE::wcpncpy(dest, src, 2); + ASSERT_TRUE(dest[0] == L'x'); + ASSERT_TRUE(dest[1] == L'y'); + ASSERT_EQ(dest + 2, res); +} + +TEST(LlvmLibcWCPNCpyTest, CopyTwoWithNull) { + wchar_t dest[] = {L'a', L'b'}; + const wchar_t src[] = {L'x', L'\0'}; + wchar_t *res = LIBC_NAMESPACE::wcpncpy(dest, src, 2); + ASSERT_TRUE(dest[0] == L'x'); + ASSERT_TRUE(dest[1] == L'\0'); + ASSERT_EQ(dest + 2, res); +} + +#if defined(LIBC_ADD_NULL_CHECKS) && !defined(LIBC_HAS_SANITIZER) +TEST(LlvmLibcWCPNCpyTest, NullptrCrash) { + // Passing in a nullptr should crash the program. + EXPECT_DEATH([] { LIBC_NAMESPACE::wcpncpy(nullptr, nullptr, 1); }, + WITH_SIGNAL(-1)); +} +#endif // LIBC_HAS_ADDRESS_SANITIZER diff --git a/external/llvm-project/libc/test/src/wchar/wcrtomb_test.cpp b/external/llvm-project/libc/test/src/wchar/wcrtomb_test.cpp new file mode 100644 index 000000000000..c06b39ae0143 --- /dev/null +++ b/external/llvm-project/libc/test/src/wchar/wcrtomb_test.cpp @@ -0,0 +1,93 @@ +//===-- Unittests for wcrtomb --------------------------------------------===// +// +// 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 "hdr/types/mbstate_t.h" +#include "hdr/types/wchar_t.h" +#include "src/__support/libc_errno.h" +#include "src/string/memset.h" +#include "src/wchar/wcrtomb.h" +#include "test/UnitTest/Test.h" + +TEST(LlvmLibcWCRToMBTest, OneByte) { + mbstate_t state; + LIBC_NAMESPACE::memset(&state, 0, sizeof(mbstate_t)); + wchar_t wc = L'U'; + char mb[4]; + size_t cnt = LIBC_NAMESPACE::wcrtomb(mb, wc, &state); + ASSERT_EQ(cnt, static_cast(1)); + ASSERT_EQ(mb[0], 'U'); +} + +TEST(LlvmLibcWCRToMBTest, TwoByte) { + mbstate_t state; + LIBC_NAMESPACE::memset(&state, 0, sizeof(mbstate_t)); + // testing utf32: 0xff -> utf8: 0xc3 0xbf + wchar_t wc = 0xff; + char mb[4]; + size_t cnt = LIBC_NAMESPACE::wcrtomb(mb, wc, &state); + ASSERT_EQ(cnt, static_cast(2)); + ASSERT_EQ(mb[0], static_cast(0xc3)); + ASSERT_EQ(mb[1], static_cast(0xbf)); +} + +TEST(LlvmLibcWCRToMBTest, ThreeByte) { + mbstate_t state; + LIBC_NAMESPACE::memset(&state, 0, sizeof(mbstate_t)); + // testing utf32: 0xac15 -> utf8: 0xea 0xb0 0x95 + wchar_t wc = 0xac15; + char mb[4]; + size_t cnt = LIBC_NAMESPACE::wcrtomb(mb, wc, &state); + ASSERT_EQ(cnt, static_cast(3)); + ASSERT_EQ(mb[0], static_cast(0xea)); + ASSERT_EQ(mb[1], static_cast(0xb0)); + ASSERT_EQ(mb[2], static_cast(0x95)); +} + +TEST(LlvmLibcWCRToMBTest, FourByte) { + mbstate_t state; + LIBC_NAMESPACE::memset(&state, 0, sizeof(mbstate_t)); + // testing utf32: 0x1f921 -> utf8: 0xf0 0x9f 0xa4 0xa1 + wchar_t wc = 0x1f921; + char mb[4]; + size_t cnt = LIBC_NAMESPACE::wcrtomb(mb, wc, &state); + ASSERT_EQ(cnt, static_cast(4)); + ASSERT_EQ(mb[0], static_cast(0xf0)); + ASSERT_EQ(mb[1], static_cast(0x9f)); + ASSERT_EQ(mb[2], static_cast(0xa4)); + ASSERT_EQ(mb[3], static_cast(0xa1)); +} + +TEST(LlvmLibcWCRToMBTest, NullString) { + mbstate_t state; + LIBC_NAMESPACE::memset(&state, 0, sizeof(mbstate_t)); + wchar_t wc = L'A'; + char mb[4]; + + // should be equivalent to the call wcrtomb(buf, L'\0', state) + size_t cnt1 = LIBC_NAMESPACE::wcrtomb(nullptr, wc, &state); + size_t cnt2 = LIBC_NAMESPACE::wcrtomb(mb, L'\0', &state); + + ASSERT_EQ(cnt1, cnt2); +} + +TEST(LlvmLibcWCRToMBTest, NullState) { + wchar_t wc = L'A'; + char mb[4]; + size_t cnt = LIBC_NAMESPACE::wcrtomb(mb, wc, nullptr); + ASSERT_EQ(cnt, static_cast(1)); +} + +TEST(LlvmLibcWCRToMBTest, InvalidWchar) { + mbstate_t state; + LIBC_NAMESPACE::memset(&state, 0, sizeof(mbstate_t)); + wchar_t wc = 0x12ffff; + char mb[4]; + size_t cnt = LIBC_NAMESPACE::wcrtomb(mb, wc, &state); + ASSERT_EQ(cnt, static_cast(-1)); + ASSERT_EQ(static_cast(libc_errno), EILSEQ); +} diff --git a/external/llvm-project/libcxx/docs/ABIGuarantees.rst b/external/llvm-project/libcxx/docs/ABIGuarantees.rst index e6ac4f2b5b23..c7d5afe1080b 100644 --- a/external/llvm-project/libcxx/docs/ABIGuarantees.rst +++ b/external/llvm-project/libcxx/docs/ABIGuarantees.rst @@ -92,7 +92,7 @@ Linking TUs which have been compiled with different flags affecting code gen There are a lot of compiler (and library) flags which change the code generated for functions. This includes flags like ``-O1``, which are guaranteed by the compiler to not change the observable behaviour of a correct program, as well as flags like ``-fexceptions``, which **do** change the observable behaviour. libc++ allows linking of TUs which have been -compiled whith specific flags only and makes no guarantees for any of the flags not listed below. +compiled with specific flags only and makes no guarantees for any of the flags not listed below. The flags allowed (in any combination) are: - ``-f[no-]exceptions`` diff --git a/external/llvm-project/libcxx/docs/FeatureTestMacroTable.rst b/external/llvm-project/libcxx/docs/FeatureTestMacroTable.rst index 3e6fd643f620..3c635e5e46bb 100644 --- a/external/llvm-project/libcxx/docs/FeatureTestMacroTable.rst +++ b/external/llvm-project/libcxx/docs/FeatureTestMacroTable.rst @@ -376,7 +376,7 @@ Status ---------------------------------------------------------- ----------------- ``__cpp_lib_ranges_iota`` ``202202L`` ---------------------------------------------------------- ----------------- - ``__cpp_lib_ranges_join_with`` *unimplemented* + ``__cpp_lib_ranges_join_with`` ``202202L`` ---------------------------------------------------------- ----------------- ``__cpp_lib_ranges_repeat`` ``202207L`` ---------------------------------------------------------- ----------------- @@ -422,6 +422,8 @@ Status ---------------------------------------------------------- ----------------- ``__cpp_lib_constexpr_forward_list`` ``202502L`` ---------------------------------------------------------- ----------------- + ``__cpp_lib_constexpr_list`` ``202502L`` + ---------------------------------------------------------- ----------------- ``__cpp_lib_constexpr_new`` ``202406L`` ---------------------------------------------------------- ----------------- ``__cpp_lib_constexpr_queue`` ``202502L`` diff --git a/external/llvm-project/libcxx/docs/ReleaseNotes/21.rst b/external/llvm-project/libcxx/docs/ReleaseNotes/21.rst index 2a5b90750eaf..c52bc54f412b 100644 --- a/external/llvm-project/libcxx/docs/ReleaseNotes/21.rst +++ b/external/llvm-project/libcxx/docs/ReleaseNotes/21.rst @@ -47,6 +47,10 @@ Implemented Papers - P1222R4: A Standard ``flat_set`` (`Github `__) - P2897R7: ``aligned_accessor``: An mdspan accessor expressing pointer over-alignment (`Github `__) - P3247R2: Deprecate the notion of trivial types (`Github `__) +- P3372R3: ``constexpr`` containers and adaptors (`Github `__) (Only ``constexpr flat_map`` is implemented) +- P2441R2: ``views::join_with`` (`Github `__) +- P2711R1: Making multi-param constructors of ``views`` ``explicit`` (`Github `__) +- P2770R0: Stashing stashing ``iterators`` for proper flattening (`Github `__) Improvements and New Features ----------------------------- @@ -70,8 +74,9 @@ Improvements and New Features - The segmented iterator optimization for ``std::for_each`` has been backported to C++11. Previously it was only available in C++23 and later. -- The ``std::for_each_n`` algorithm has been optimized for segmented iterators, resulting in a performance improvement of - up to 17.7x for ``std::deque`` iterators, and up to 13.9x for ``std::join_view>>`` iterators. +- The ``std::for_each_n``, ``std::ranges::for_each`` and ``std::ranges::for_each_n`` algorithms have been optimized for + segmented iterators, resulting in a performance improvement of up to 17.7x for ``std::deque`` iterators, and up + to 13.9x for ``std::join_view>>`` iterators. - The ``bitset::to_string`` function has been optimized, resulting in a performance improvement of up to 8.3x for bitsets with uniformly distributed zeros and ones, and up to 13.5x and 16.1x for sparse and dense bitsets, respectively. diff --git a/external/llvm-project/libcxx/docs/Status/Cxx23Papers.csv b/external/llvm-project/libcxx/docs/Status/Cxx23Papers.csv index c26363bcda79..574675175a4c 100644 --- a/external/llvm-project/libcxx/docs/Status/Cxx23Papers.csv +++ b/external/llvm-project/libcxx/docs/Status/Cxx23Papers.csv @@ -47,7 +47,7 @@ "`P2273R3 `__","Making ``std::unique_ptr`` constexpr","2022-02 (Virtual)","|Complete|","16","" "`P2387R3 `__","Pipe support for user-defined range adaptors","2022-02 (Virtual)","|Complete|","19","" "`P2440R1 `__","``ranges::iota``, ``ranges::shift_left`` and ``ranges::shift_right``","2022-02 (Virtual)","|Partial|","","Only ``ranges::iota`` is implemented." -"`P2441R2 `__","``views::join_with``","2022-02 (Virtual)","|In Progress|","","" +"`P2441R2 `__","``views::join_with``","2022-02 (Virtual)","|Complete|","21","" "`P2442R1 `__","Windowing range adaptors: ``views::chunk`` and ``views::slide``","2022-02 (Virtual)","","","" "`P2443R1 `__","``views::chunk_by``","2022-02 (Virtual)","|Complete|","18","" "","","","","","" @@ -103,9 +103,9 @@ "`P2708R1 `__","No Further Fundamentals TSes","2022-11 (Kona)","|Nothing To Do|","","" "","","","","","" "`P0290R4 `__","``apply()`` for ``synchronized_value``","2023-02 (Issaquah)","","","" -"`P2770R0 `__","Stashing stashing ``iterators`` for proper flattening","2023-02 (Issaquah)","|Partial|","","``join_with_view`` hasn't been done yet since this type isn't implemented yet" +"`P2770R0 `__","Stashing stashing ``iterators`` for proper flattening","2023-02 (Issaquah)","|Complete|","21","" "`P2164R9 `__","``views::enumerate``","2023-02 (Issaquah)","","","" -"`P2711R1 `__","Making multi-param constructors of ``views`` ``explicit``","2023-02 (Issaquah)","|In Progress|","","``join_with_view`` hasn't been done yet since this type isn't implemented yet" +"`P2711R1 `__","Making multi-param constructors of ``views`` ``explicit``","2023-02 (Issaquah)","|Complete|","21","" "`P2609R3 `__","Relaxing Ranges Just A Smidge","2023-02 (Issaquah)","|Complete|","20","Implemented as a DR in C++20. Other implementations will do the same." "`P2713R1 `__","Escaping improvements in ``std::format``","2023-02 (Issaquah)","|Complete|","19","" "`P2675R1 `__","``format``'s width estimation is too approximate and not forward compatible","2023-02 (Issaquah)","|Complete|","17","" diff --git a/external/llvm-project/libcxx/docs/Status/Cxx2cIssues.csv b/external/llvm-project/libcxx/docs/Status/Cxx2cIssues.csv index fdf381862d87..d3feecf6513e 100644 --- a/external/llvm-project/libcxx/docs/Status/Cxx2cIssues.csv +++ b/external/llvm-project/libcxx/docs/Status/Cxx2cIssues.csv @@ -66,7 +66,7 @@ "`LWG4060 `__","``submdspan`` preconditions do not forbid creating invalid pointer","2024-06 (St. Louis)","","","" "`LWG4061 `__","Should ``std::basic_format_context`` be default-constructible/copyable/movable?","2024-06 (St. Louis)","|Complete|","19","" "`LWG4071 `__","``reference_wrapper`` comparisons are not SFINAE-friendly","2024-06 (St. Louis)","|Complete|","19","" -"`LWG4074 `__","``compatible-joinable-ranges`` is underconstrained","2024-06 (St. Louis)","","","" +"`LWG4074 `__","``compatible-joinable-ranges`` is underconstrained","2024-06 (St. Louis)","|Complete|","21","" "`LWG4076 `__","``concat_view`` should be freestanding","2024-06 (St. Louis)","","","" "`LWG4079 `__","Missing Preconditions in ``concat_view::iterator``\`s conversion constructor","2024-06 (St. Louis)","","","" "`LWG4082 `__","``views::concat(r)`` is well-formed when ``r`` is an ``output_range``","2024-06 (St. Louis)","","","" diff --git a/external/llvm-project/libcxx/docs/Status/Cxx2cPapers.csv b/external/llvm-project/libcxx/docs/Status/Cxx2cPapers.csv index 8a0417e120d7..2eb192106977 100644 --- a/external/llvm-project/libcxx/docs/Status/Cxx2cPapers.csv +++ b/external/llvm-project/libcxx/docs/Status/Cxx2cPapers.csv @@ -104,7 +104,7 @@ "`P3137R3 `__","``views::to_input``","2025-02 (Hagenberg)","","","" "`P0472R3 `__","Put ``std::monostate`` in ````","2025-02 (Hagenberg)","|Complete|","21","" "`P3349R1 `__","Converting contiguous iterators to pointers","2025-02 (Hagenberg)","","","" -"`P3372R3 `__","constexpr containers and adaptors","2025-02 (Hagenberg)","","","" +"`P3372R3 `__","constexpr containers and adaptors","2025-02 (Hagenberg)","|In Progress|","","" "`P3378R2 `__","constexpr exception types","2025-02 (Hagenberg)","","","" "`P3441R2 `__","Rename ``simd_split`` to ``simd_chunk``","2025-02 (Hagenberg)","","","" "`P3287R3 `__","Exploration of namespaces for ``std::simd``","2025-02 (Hagenberg)","","","" diff --git a/external/llvm-project/libcxx/include/CMakeLists.txt b/external/llvm-project/libcxx/include/CMakeLists.txt index 8931a1b35f6d..e386f31386b6 100644 --- a/external/llvm-project/libcxx/include/CMakeLists.txt +++ b/external/llvm-project/libcxx/include/CMakeLists.txt @@ -706,6 +706,7 @@ set(files __ranges/iota_view.h __ranges/istream_view.h __ranges/join_view.h + __ranges/join_with_view.h __ranges/lazy_split_view.h __ranges/movable_box.h __ranges/non_propagating_cache.h diff --git a/external/llvm-project/libcxx/include/__algorithm/for_each.h b/external/llvm-project/libcxx/include/__algorithm/for_each.h index b6c2c7c056ed..4167eec3506e 100644 --- a/external/llvm-project/libcxx/include/__algorithm/for_each.h +++ b/external/llvm-project/libcxx/include/__algorithm/for_each.h @@ -12,41 +12,54 @@ #include <__algorithm/for_each_segment.h> #include <__config> +#include <__functional/identity.h> #include <__iterator/segmented_iterator.h> #include <__type_traits/enable_if.h> +#include <__type_traits/invoke.h> +#include <__utility/move.h> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) # pragma GCC system_header #endif +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + _LIBCPP_BEGIN_NAMESPACE_STD -template -_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void __for_each(_InputIterator __first, _Sent __last, _Func& __f) { +template +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _InputIterator +__for_each(_InputIterator __first, _Sent __last, _Func& __f, _Proj& __proj) { for (; __first != __last; ++__first) - __f(*__first); + std::__invoke(__f, std::__invoke(__proj, *__first)); + return __first; } #ifndef _LIBCPP_CXX03_LANG template ::value, int> = 0> -_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void -__for_each(_SegmentedIterator __first, _SegmentedIterator __last, _Function& __func) { +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _SegmentedIterator +__for_each(_SegmentedIterator __first, _SegmentedIterator __last, _Func& __func, _Proj& __proj) { using __local_iterator_t = typename __segmented_iterator_traits<_SegmentedIterator>::__local_iterator; std::__for_each_segment(__first, __last, [&](__local_iterator_t __lfirst, __local_iterator_t __llast) { - std::__for_each(__lfirst, __llast, __func); + std::__for_each(__lfirst, __llast, __func, __proj); }); + return __last; } #endif // !_LIBCPP_CXX03_LANG -template -_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _Function -for_each(_InputIterator __first, _InputIterator __last, _Function __f) { - std::__for_each(__first, __last, __f); +template +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _Func +for_each(_InputIterator __first, _InputIterator __last, _Func __f) { + __identity __proj; + std::__for_each(__first, __last, __f, __proj); return __f; } _LIBCPP_END_NAMESPACE_STD +_LIBCPP_POP_MACROS + #endif // _LIBCPP___ALGORITHM_FOR_EACH_H diff --git a/external/llvm-project/libcxx/include/__algorithm/for_each_n.h b/external/llvm-project/libcxx/include/__algorithm/for_each_n.h index 29351ec39f4e..9a6c6bb5175d 100644 --- a/external/llvm-project/libcxx/include/__algorithm/for_each_n.h +++ b/external/llvm-project/libcxx/include/__algorithm/for_each_n.h @@ -13,10 +13,12 @@ #include <__algorithm/for_each.h> #include <__algorithm/for_each_n_segment.h> #include <__config> +#include <__functional/identity.h> #include <__iterator/iterator_traits.h> #include <__iterator/segmented_iterator.h> #include <__type_traits/disjunction.h> #include <__type_traits/enable_if.h> +#include <__type_traits/invoke.h> #include <__type_traits/negation.h> #include <__utility/convert_to_integral.h> #include <__utility/move.h> @@ -33,16 +35,17 @@ _LIBCPP_BEGIN_NAMESPACE_STD template ::value && _Or< _Not<__is_segmented_iterator<_InputIterator> >, _Not<__has_random_access_local_iterator<_InputIterator> > >::value, int> = 0> _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _InputIterator -__for_each_n(_InputIterator __first, _Size __orig_n, _Func& __f) { +__for_each_n(_InputIterator __first, _Size __orig_n, _Func& __f, _Proj& __proj) { typedef decltype(std::__convert_to_integral(__orig_n)) _IntegralSize; _IntegralSize __n = __orig_n; while (__n > 0) { - __f(*__first); + std::__invoke(__f, std::__invoke(__proj, *__first)); ++__first; --__n; } @@ -52,39 +55,42 @@ __for_each_n(_InputIterator __first, _Size __orig_n, _Func& __f) { template ::value, int> = 0> _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _RandIter -__for_each_n(_RandIter __first, _Size __orig_n, _Func& __f) { +__for_each_n(_RandIter __first, _Size __orig_n, _Func& __f, _Proj& __proj) { typename std::iterator_traits<_RandIter>::difference_type __n = __orig_n; auto __last = __first + __n; - std::__for_each(__first, __last, __f); - return std::move(__last); + std::__for_each(__first, __last, __f, __proj); + return __last; } #ifndef _LIBCPP_CXX03_LANG template ::value && __is_segmented_iterator<_SegmentedIterator>::value && __has_random_access_iterator_category< typename __segmented_iterator_traits<_SegmentedIterator>::__local_iterator>::value, int> = 0> _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _SegmentedIterator -__for_each_n(_SegmentedIterator __first, _Size __orig_n, _Func& __f) { +__for_each_n(_SegmentedIterator __first, _Size __orig_n, _Func& __f, _Proj& __proj) { using __local_iterator_t = typename __segmented_iterator_traits<_SegmentedIterator>::__local_iterator; return std::__for_each_n_segment(__first, __orig_n, [&](__local_iterator_t __lfirst, __local_iterator_t __llast) { - std::__for_each(__lfirst, __llast, __f); + std::__for_each(__lfirst, __llast, __f, __proj); }); } #endif // !_LIBCPP_CXX03_LANG #if _LIBCPP_STD_VER >= 17 -template +template inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _InputIterator -for_each_n(_InputIterator __first, _Size __orig_n, _Function __f) { - return std::__for_each_n(__first, __orig_n, __f); +for_each_n(_InputIterator __first, _Size __orig_n, _Func __f) { + __identity __proj; + return std::__for_each_n(__first, __orig_n, __f, __proj); } #endif // _LIBCPP_STD_VER >= 17 diff --git a/external/llvm-project/libcxx/include/__algorithm/ranges_for_each.h b/external/llvm-project/libcxx/include/__algorithm/ranges_for_each.h index de39bc552275..e9c84e8583f8 100644 --- a/external/llvm-project/libcxx/include/__algorithm/ranges_for_each.h +++ b/external/llvm-project/libcxx/include/__algorithm/ranges_for_each.h @@ -9,10 +9,12 @@ #ifndef _LIBCPP___ALGORITHM_RANGES_FOR_EACH_H #define _LIBCPP___ALGORITHM_RANGES_FOR_EACH_H +#include <__algorithm/for_each.h> +#include <__algorithm/for_each_n.h> #include <__algorithm/in_fun_result.h> +#include <__concepts/assignable.h> #include <__config> #include <__functional/identity.h> -#include <__functional/invoke.h> #include <__iterator/concepts.h> #include <__iterator/projected.h> #include <__ranges/access.h> @@ -41,9 +43,17 @@ struct __for_each { template _LIBCPP_HIDE_FROM_ABI constexpr static for_each_result<_Iter, _Func> __for_each_impl(_Iter __first, _Sent __last, _Func& __func, _Proj& __proj) { - for (; __first != __last; ++__first) - std::invoke(__func, std::invoke(__proj, *__first)); - return {std::move(__first), std::move(__func)}; + // In the case where we have different iterator and sentinel types, the segmented iterator optimization + // in std::for_each will not kick in. Therefore, we prefer std::for_each_n in that case (whenever we can + // obtain the `n`). + if constexpr (!std::assignable_from<_Iter&, _Sent> && std::sized_sentinel_for<_Sent, _Iter>) { + auto __n = __last - __first; + auto __end = std::__for_each_n(std::move(__first), __n, __func, __proj); + return {std::move(__end), std::move(__func)}; + } else { + auto __end = std::__for_each(std::move(__first), std::move(__last), __func, __proj); + return {std::move(__end), std::move(__func)}; + } } public: diff --git a/external/llvm-project/libcxx/include/__algorithm/ranges_for_each_n.h b/external/llvm-project/libcxx/include/__algorithm/ranges_for_each_n.h index 603cb723233c..3aab1b79c10a 100644 --- a/external/llvm-project/libcxx/include/__algorithm/ranges_for_each_n.h +++ b/external/llvm-project/libcxx/include/__algorithm/ranges_for_each_n.h @@ -9,10 +9,10 @@ #ifndef _LIBCPP___ALGORITHM_RANGES_FOR_EACH_N_H #define _LIBCPP___ALGORITHM_RANGES_FOR_EACH_N_H +#include <__algorithm/for_each_n.h> #include <__algorithm/in_fun_result.h> #include <__config> #include <__functional/identity.h> -#include <__functional/invoke.h> #include <__iterator/concepts.h> #include <__iterator/incrementable_traits.h> #include <__iterator/iterator_traits.h> @@ -40,11 +40,8 @@ struct __for_each_n { template > _Func> _LIBCPP_HIDE_FROM_ABI constexpr for_each_n_result<_Iter, _Func> operator()(_Iter __first, iter_difference_t<_Iter> __count, _Func __func, _Proj __proj = {}) const { - while (__count-- > 0) { - std::invoke(__func, std::invoke(__proj, *__first)); - ++__first; - } - return {std::move(__first), std::move(__func)}; + auto __last = std::__for_each_n(std::move(__first), __count, __func, __proj); + return {std::move(__last), std::move(__func)}; } }; diff --git a/external/llvm-project/libcxx/include/__flat_map/flat_map.h b/external/llvm-project/libcxx/include/__flat_map/flat_map.h index 8f01882934b7..bf193f6d3c62 100644 --- a/external/llvm-project/libcxx/include/__flat_map/flat_map.h +++ b/external/llvm-project/libcxx/include/__flat_map/flat_map.h @@ -114,11 +114,12 @@ class flat_map { class value_compare { private: _LIBCPP_NO_UNIQUE_ADDRESS key_compare __comp_; - _LIBCPP_HIDE_FROM_ABI value_compare(key_compare __c) : __comp_(__c) {} + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 value_compare(key_compare __c) : __comp_(__c) {} friend flat_map; public: - _LIBCPP_HIDE_FROM_ABI bool operator()(const_reference __x, const_reference __y) const { + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 bool + operator()(const_reference __x, const_reference __y) const { return __comp_(__x.first, __y.first); } }; @@ -137,14 +138,14 @@ class flat_map { public: // [flat.map.cons], construct/copy/destroy - _LIBCPP_HIDE_FROM_ABI flat_map() noexcept( + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 flat_map() noexcept( is_nothrow_default_constructible_v<_KeyContainer> && is_nothrow_default_constructible_v<_MappedContainer> && is_nothrow_default_constructible_v<_Compare>) : __containers_(), __compare_() {} _LIBCPP_HIDE_FROM_ABI flat_map(const flat_map&) = default; - _LIBCPP_HIDE_FROM_ABI flat_map(flat_map&& __other) noexcept( + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 flat_map(flat_map&& __other) noexcept( is_nothrow_move_constructible_v<_KeyContainer> && is_nothrow_move_constructible_v<_MappedContainer> && is_nothrow_move_constructible_v<_Compare>) # if _LIBCPP_HAS_EXCEPTIONS @@ -165,7 +166,7 @@ class flat_map { template requires __allocator_ctor_constraint<_Allocator> - _LIBCPP_HIDE_FROM_ABI flat_map(const flat_map& __other, const _Allocator& __alloc) + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 flat_map(const flat_map& __other, const _Allocator& __alloc) : flat_map(__ctor_uses_allocator_tag{}, __alloc, __other.__containers_.keys, @@ -174,7 +175,7 @@ class flat_map { template requires __allocator_ctor_constraint<_Allocator> - _LIBCPP_HIDE_FROM_ABI flat_map(flat_map&& __other, const _Allocator& __alloc) + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 flat_map(flat_map&& __other, const _Allocator& __alloc) # if _LIBCPP_HAS_EXCEPTIONS try # endif // _LIBCPP_HAS_EXCEPTIONS @@ -191,7 +192,7 @@ class flat_map { # endif // _LIBCPP_HAS_EXCEPTIONS } - _LIBCPP_HIDE_FROM_ABI flat_map( + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 flat_map( key_container_type __key_cont, mapped_container_type __mapped_cont, const key_compare& __comp = key_compare()) : __containers_{.keys = std::move(__key_cont), .values = std::move(__mapped_cont)}, __compare_(__comp) { _LIBCPP_ASSERT_VALID_INPUT_RANGE(__containers_.keys.size() == __containers_.values.size(), @@ -201,7 +202,7 @@ class flat_map { template requires __allocator_ctor_constraint<_Allocator> - _LIBCPP_HIDE_FROM_ABI + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 flat_map(const key_container_type& __key_cont, const mapped_container_type& __mapped_cont, const _Allocator& __alloc) : flat_map(__ctor_uses_allocator_tag{}, __alloc, __key_cont, __mapped_cont) { _LIBCPP_ASSERT_VALID_INPUT_RANGE(__containers_.keys.size() == __containers_.values.size(), @@ -211,7 +212,7 @@ class flat_map { template requires __allocator_ctor_constraint<_Allocator> - _LIBCPP_HIDE_FROM_ABI + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 flat_map(const key_container_type& __key_cont, const mapped_container_type& __mapped_cont, const key_compare& __comp, @@ -222,7 +223,7 @@ class flat_map { __sort_and_unique(); } - _LIBCPP_HIDE_FROM_ABI + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 flat_map(sorted_unique_t, key_container_type __key_cont, mapped_container_type __mapped_cont, @@ -236,7 +237,7 @@ class flat_map { template requires __allocator_ctor_constraint<_Allocator> - _LIBCPP_HIDE_FROM_ABI + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 flat_map(sorted_unique_t, const key_container_type& __key_cont, const mapped_container_type& __mapped_cont, @@ -250,12 +251,12 @@ class flat_map { template requires __allocator_ctor_constraint<_Allocator> - _LIBCPP_HIDE_FROM_ABI - flat_map(sorted_unique_t, - const key_container_type& __key_cont, - const mapped_container_type& __mapped_cont, - const key_compare& __comp, - const _Allocator& __alloc) + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 flat_map( + sorted_unique_t, + const key_container_type& __key_cont, + const mapped_container_type& __mapped_cont, + const key_compare& __comp, + const _Allocator& __alloc) : flat_map(__ctor_uses_allocator_tag{}, __alloc, __key_cont, __mapped_cont, __comp) { _LIBCPP_ASSERT_VALID_INPUT_RANGE(__containers_.keys.size() == __containers_.values.size(), "flat_map keys and mapped containers have different size"); @@ -263,21 +264,22 @@ class flat_map { __is_sorted_and_unique(__containers_.keys), "Either the key container is not sorted or it contains duplicates"); } - _LIBCPP_HIDE_FROM_ABI explicit flat_map(const key_compare& __comp) : __containers_(), __compare_(__comp) {} + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 explicit flat_map(const key_compare& __comp) + : __containers_(), __compare_(__comp) {} template requires __allocator_ctor_constraint<_Allocator> - _LIBCPP_HIDE_FROM_ABI flat_map(const key_compare& __comp, const _Allocator& __alloc) + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 flat_map(const key_compare& __comp, const _Allocator& __alloc) : flat_map(__ctor_uses_allocator_empty_tag{}, __alloc, __comp) {} template requires __allocator_ctor_constraint<_Allocator> - _LIBCPP_HIDE_FROM_ABI explicit flat_map(const _Allocator& __alloc) + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 explicit flat_map(const _Allocator& __alloc) : flat_map(__ctor_uses_allocator_empty_tag{}, __alloc) {} template requires __has_input_iterator_category<_InputIterator>::value - _LIBCPP_HIDE_FROM_ABI + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 flat_map(_InputIterator __first, _InputIterator __last, const key_compare& __comp = key_compare()) : __containers_(), __compare_(__comp) { insert(__first, __last); @@ -285,7 +287,7 @@ class flat_map { template requires(__has_input_iterator_category<_InputIterator>::value && __allocator_ctor_constraint<_Allocator>) - _LIBCPP_HIDE_FROM_ABI + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 flat_map(_InputIterator __first, _InputIterator __last, const key_compare& __comp, const _Allocator& __alloc) : flat_map(__ctor_uses_allocator_empty_tag{}, __alloc, __comp) { insert(__first, __last); @@ -293,99 +295,105 @@ class flat_map { template requires(__has_input_iterator_category<_InputIterator>::value && __allocator_ctor_constraint<_Allocator>) - _LIBCPP_HIDE_FROM_ABI flat_map(_InputIterator __first, _InputIterator __last, const _Allocator& __alloc) + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 + flat_map(_InputIterator __first, _InputIterator __last, const _Allocator& __alloc) : flat_map(__ctor_uses_allocator_empty_tag{}, __alloc) { insert(__first, __last); } template <_ContainerCompatibleRange _Range> - _LIBCPP_HIDE_FROM_ABI flat_map(from_range_t __fr, _Range&& __rg) + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 flat_map(from_range_t __fr, _Range&& __rg) : flat_map(__fr, std::forward<_Range>(__rg), key_compare()) {} template <_ContainerCompatibleRange _Range, class _Allocator> requires __allocator_ctor_constraint<_Allocator> - _LIBCPP_HIDE_FROM_ABI flat_map(from_range_t, _Range&& __rg, const _Allocator& __alloc) + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 flat_map(from_range_t, _Range&& __rg, const _Allocator& __alloc) : flat_map(__ctor_uses_allocator_empty_tag{}, __alloc) { insert_range(std::forward<_Range>(__rg)); } template <_ContainerCompatibleRange _Range> - _LIBCPP_HIDE_FROM_ABI flat_map(from_range_t, _Range&& __rg, const key_compare& __comp) : flat_map(__comp) { + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 flat_map(from_range_t, _Range&& __rg, const key_compare& __comp) + : flat_map(__comp) { insert_range(std::forward<_Range>(__rg)); } template <_ContainerCompatibleRange _Range, class _Allocator> requires __allocator_ctor_constraint<_Allocator> - _LIBCPP_HIDE_FROM_ABI flat_map(from_range_t, _Range&& __rg, const key_compare& __comp, const _Allocator& __alloc) + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 + flat_map(from_range_t, _Range&& __rg, const key_compare& __comp, const _Allocator& __alloc) : flat_map(__ctor_uses_allocator_empty_tag{}, __alloc, __comp) { insert_range(std::forward<_Range>(__rg)); } template requires __has_input_iterator_category<_InputIterator>::value - _LIBCPP_HIDE_FROM_ABI + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 flat_map(sorted_unique_t, _InputIterator __first, _InputIterator __last, const key_compare& __comp = key_compare()) : __containers_(), __compare_(__comp) { insert(sorted_unique, __first, __last); } template requires(__has_input_iterator_category<_InputIterator>::value && __allocator_ctor_constraint<_Allocator>) - _LIBCPP_HIDE_FROM_ABI - flat_map(sorted_unique_t, - _InputIterator __first, - _InputIterator __last, - const key_compare& __comp, - const _Allocator& __alloc) + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 flat_map( + sorted_unique_t, + _InputIterator __first, + _InputIterator __last, + const key_compare& __comp, + const _Allocator& __alloc) : flat_map(__ctor_uses_allocator_empty_tag{}, __alloc, __comp) { insert(sorted_unique, __first, __last); } template requires(__has_input_iterator_category<_InputIterator>::value && __allocator_ctor_constraint<_Allocator>) - _LIBCPP_HIDE_FROM_ABI + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 flat_map(sorted_unique_t, _InputIterator __first, _InputIterator __last, const _Allocator& __alloc) : flat_map(__ctor_uses_allocator_empty_tag{}, __alloc) { insert(sorted_unique, __first, __last); } - _LIBCPP_HIDE_FROM_ABI flat_map(initializer_list __il, const key_compare& __comp = key_compare()) + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 + flat_map(initializer_list __il, const key_compare& __comp = key_compare()) : flat_map(__il.begin(), __il.end(), __comp) {} template requires __allocator_ctor_constraint<_Allocator> - _LIBCPP_HIDE_FROM_ABI + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 flat_map(initializer_list __il, const key_compare& __comp, const _Allocator& __alloc) : flat_map(__il.begin(), __il.end(), __comp, __alloc) {} template requires __allocator_ctor_constraint<_Allocator> - _LIBCPP_HIDE_FROM_ABI flat_map(initializer_list __il, const _Allocator& __alloc) + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 + flat_map(initializer_list __il, const _Allocator& __alloc) : flat_map(__il.begin(), __il.end(), __alloc) {} - _LIBCPP_HIDE_FROM_ABI + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 flat_map(sorted_unique_t, initializer_list __il, const key_compare& __comp = key_compare()) : flat_map(sorted_unique, __il.begin(), __il.end(), __comp) {} template requires __allocator_ctor_constraint<_Allocator> - _LIBCPP_HIDE_FROM_ABI + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 flat_map(sorted_unique_t, initializer_list __il, const key_compare& __comp, const _Allocator& __alloc) : flat_map(sorted_unique, __il.begin(), __il.end(), __comp, __alloc) {} template requires __allocator_ctor_constraint<_Allocator> - _LIBCPP_HIDE_FROM_ABI flat_map(sorted_unique_t, initializer_list __il, const _Allocator& __alloc) + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 + flat_map(sorted_unique_t, initializer_list __il, const _Allocator& __alloc) : flat_map(sorted_unique, __il.begin(), __il.end(), __alloc) {} - _LIBCPP_HIDE_FROM_ABI flat_map& operator=(initializer_list __il) { + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 flat_map& operator=(initializer_list __il) { clear(); insert(__il); return *this; } - _LIBCPP_HIDE_FROM_ABI flat_map& operator=(const flat_map&) = default; + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 flat_map& operator=(const flat_map&) = default; - _LIBCPP_HIDE_FROM_ABI flat_map& operator=(flat_map&& __other) noexcept( + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 flat_map& operator=(flat_map&& __other) noexcept( is_nothrow_move_assignable_v<_KeyContainer> && is_nothrow_move_assignable_v<_MappedContainer> && is_nothrow_move_assignable_v<_Compare>) { // No matter what happens, we always want to clear the other container before returning @@ -402,49 +410,65 @@ class flat_map { } // iterators - _LIBCPP_HIDE_FROM_ABI iterator begin() noexcept { + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator begin() noexcept { return iterator(__containers_.keys.begin(), __containers_.values.begin()); } - _LIBCPP_HIDE_FROM_ABI const_iterator begin() const noexcept { + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_iterator begin() const noexcept { return const_iterator(__containers_.keys.begin(), __containers_.values.begin()); } - _LIBCPP_HIDE_FROM_ABI iterator end() noexcept { + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator end() noexcept { return iterator(__containers_.keys.end(), __containers_.values.end()); } - _LIBCPP_HIDE_FROM_ABI const_iterator end() const noexcept { + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_iterator end() const noexcept { return const_iterator(__containers_.keys.end(), __containers_.values.end()); } - _LIBCPP_HIDE_FROM_ABI reverse_iterator rbegin() noexcept { return reverse_iterator(end()); } - _LIBCPP_HIDE_FROM_ABI const_reverse_iterator rbegin() const noexcept { return const_reverse_iterator(end()); } - _LIBCPP_HIDE_FROM_ABI reverse_iterator rend() noexcept { return reverse_iterator(begin()); } - _LIBCPP_HIDE_FROM_ABI const_reverse_iterator rend() const noexcept { return const_reverse_iterator(begin()); } + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 reverse_iterator rbegin() noexcept { + return reverse_iterator(end()); + } + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_reverse_iterator rbegin() const noexcept { + return const_reverse_iterator(end()); + } + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 reverse_iterator rend() noexcept { + return reverse_iterator(begin()); + } + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_reverse_iterator rend() const noexcept { + return const_reverse_iterator(begin()); + } - _LIBCPP_HIDE_FROM_ABI const_iterator cbegin() const noexcept { return begin(); } - _LIBCPP_HIDE_FROM_ABI const_iterator cend() const noexcept { return end(); } - _LIBCPP_HIDE_FROM_ABI const_reverse_iterator crbegin() const noexcept { return const_reverse_iterator(end()); } - _LIBCPP_HIDE_FROM_ABI const_reverse_iterator crend() const noexcept { return const_reverse_iterator(begin()); } + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_iterator cbegin() const noexcept { return begin(); } + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_iterator cend() const noexcept { return end(); } + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_reverse_iterator crbegin() const noexcept { + return const_reverse_iterator(end()); + } + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_reverse_iterator crend() const noexcept { + return const_reverse_iterator(begin()); + } // [flat.map.capacity], capacity - [[nodiscard]] _LIBCPP_HIDE_FROM_ABI bool empty() const noexcept { return __containers_.keys.empty(); } + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 bool empty() const noexcept { + return __containers_.keys.empty(); + } - _LIBCPP_HIDE_FROM_ABI size_type size() const noexcept { return __containers_.keys.size(); } + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 size_type size() const noexcept { + return __containers_.keys.size(); + } - _LIBCPP_HIDE_FROM_ABI size_type max_size() const noexcept { + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 size_type max_size() const noexcept { return std::min(__containers_.keys.max_size(), __containers_.values.max_size()); } // [flat.map.access], element access - _LIBCPP_HIDE_FROM_ABI mapped_type& operator[](const key_type& __x) + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 mapped_type& operator[](const key_type& __x) requires is_constructible_v { return try_emplace(__x).first->second; } - _LIBCPP_HIDE_FROM_ABI mapped_type& operator[](key_type&& __x) + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 mapped_type& operator[](key_type&& __x) requires is_constructible_v { return try_emplace(std::move(__x)).first->second; @@ -453,11 +477,11 @@ class flat_map { template requires(__is_compare_transparent && is_constructible_v && is_constructible_v && !is_convertible_v<_Kp &&, const_iterator> && !is_convertible_v<_Kp &&, iterator>) - _LIBCPP_HIDE_FROM_ABI mapped_type& operator[](_Kp&& __x) { + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 mapped_type& operator[](_Kp&& __x) { return try_emplace(std::forward<_Kp>(__x)).first->second; } - _LIBCPP_HIDE_FROM_ABI mapped_type& at(const key_type& __x) { + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 mapped_type& at(const key_type& __x) { auto __it = find(__x); if (__it == end()) { std::__throw_out_of_range("flat_map::at(const key_type&): Key does not exist"); @@ -465,7 +489,7 @@ class flat_map { return __it->second; } - _LIBCPP_HIDE_FROM_ABI const mapped_type& at(const key_type& __x) const { + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const mapped_type& at(const key_type& __x) const { auto __it = find(__x); if (__it == end()) { std::__throw_out_of_range("flat_map::at(const key_type&) const: Key does not exist"); @@ -475,7 +499,7 @@ class flat_map { template requires __is_compare_transparent - _LIBCPP_HIDE_FROM_ABI mapped_type& at(const _Kp& __x) { + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 mapped_type& at(const _Kp& __x) { auto __it = find(__x); if (__it == end()) { std::__throw_out_of_range("flat_map::at(const K&): Key does not exist"); @@ -485,7 +509,7 @@ class flat_map { template requires __is_compare_transparent - _LIBCPP_HIDE_FROM_ABI const mapped_type& at(const _Kp& __x) const { + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const mapped_type& at(const _Kp& __x) const { auto __it = find(__x); if (__it == end()) { std::__throw_out_of_range("flat_map::at(const K&) const: Key does not exist"); @@ -496,45 +520,49 @@ class flat_map { // [flat.map.modifiers], modifiers template requires is_constructible_v, _Args...> - _LIBCPP_HIDE_FROM_ABI pair emplace(_Args&&... __args) { + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 pair emplace(_Args&&... __args) { std::pair __pair(std::forward<_Args>(__args)...); return __try_emplace(std::move(__pair.first), std::move(__pair.second)); } template requires is_constructible_v, _Args...> - _LIBCPP_HIDE_FROM_ABI iterator emplace_hint(const_iterator __hint, _Args&&... __args) { + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator emplace_hint(const_iterator __hint, _Args&&... __args) { std::pair __pair(std::forward<_Args>(__args)...); return __try_emplace_hint(__hint, std::move(__pair.first), std::move(__pair.second)).first; } - _LIBCPP_HIDE_FROM_ABI pair insert(const value_type& __x) { return emplace(__x); } + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 pair insert(const value_type& __x) { + return emplace(__x); + } - _LIBCPP_HIDE_FROM_ABI pair insert(value_type&& __x) { return emplace(std::move(__x)); } + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 pair insert(value_type&& __x) { + return emplace(std::move(__x)); + } - _LIBCPP_HIDE_FROM_ABI iterator insert(const_iterator __hint, const value_type& __x) { + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator insert(const_iterator __hint, const value_type& __x) { return emplace_hint(__hint, __x); } - _LIBCPP_HIDE_FROM_ABI iterator insert(const_iterator __hint, value_type&& __x) { + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator insert(const_iterator __hint, value_type&& __x) { return emplace_hint(__hint, std::move(__x)); } template requires is_constructible_v, _PairLike> - _LIBCPP_HIDE_FROM_ABI pair insert(_PairLike&& __x) { + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 pair insert(_PairLike&& __x) { return emplace(std::forward<_PairLike>(__x)); } template requires is_constructible_v, _PairLike> - _LIBCPP_HIDE_FROM_ABI iterator insert(const_iterator __hint, _PairLike&& __x) { + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator insert(const_iterator __hint, _PairLike&& __x) { return emplace_hint(__hint, std::forward<_PairLike>(__x)); } template requires __has_input_iterator_category<_InputIterator>::value - _LIBCPP_HIDE_FROM_ABI void insert(_InputIterator __first, _InputIterator __last) { + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 void insert(_InputIterator __first, _InputIterator __last) { if constexpr (sized_sentinel_for<_InputIterator, _InputIterator>) { __reserve(__last - __first); } @@ -543,7 +571,8 @@ class flat_map { template requires __has_input_iterator_category<_InputIterator>::value - _LIBCPP_HIDE_FROM_ABI void insert(sorted_unique_t, _InputIterator __first, _InputIterator __last) { + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 void + insert(sorted_unique_t, _InputIterator __first, _InputIterator __last) { if constexpr (sized_sentinel_for<_InputIterator, _InputIterator>) { __reserve(__last - __first); } @@ -552,7 +581,7 @@ class flat_map { } template <_ContainerCompatibleRange _Range> - _LIBCPP_HIDE_FROM_ABI void insert_range(_Range&& __range) { + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 void insert_range(_Range&& __range) { if constexpr (ranges::sized_range<_Range>) { __reserve(ranges::size(__range)); } @@ -560,19 +589,22 @@ class flat_map { __append_sort_merge_unique(ranges::begin(__range), ranges::end(__range)); } - _LIBCPP_HIDE_FROM_ABI void insert(initializer_list __il) { insert(__il.begin(), __il.end()); } + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 void insert(initializer_list __il) { + insert(__il.begin(), __il.end()); + } - _LIBCPP_HIDE_FROM_ABI void insert(sorted_unique_t, initializer_list __il) { + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 void insert(sorted_unique_t, initializer_list __il) { insert(sorted_unique, __il.begin(), __il.end()); } - _LIBCPP_HIDE_FROM_ABI containers extract() && { + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 containers extract() && { auto __guard = std::__make_scope_guard([&]() noexcept { clear() /* noexcept */; }); auto __ret = std::move(__containers_); return __ret; } - _LIBCPP_HIDE_FROM_ABI void replace(key_container_type&& __key_cont, mapped_container_type&& __mapped_cont) { + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 void + replace(key_container_type&& __key_cont, mapped_container_type&& __mapped_cont) { _LIBCPP_ASSERT_VALID_INPUT_RANGE( __key_cont.size() == __mapped_cont.size(), "flat_map keys and mapped containers have different size"); @@ -586,13 +618,15 @@ class flat_map { template requires is_constructible_v - _LIBCPP_HIDE_FROM_ABI pair try_emplace(const key_type& __key, _Args&&... __args) { + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 pair + try_emplace(const key_type& __key, _Args&&... __args) { return __try_emplace(__key, std::forward<_Args>(__args)...); } template requires is_constructible_v - _LIBCPP_HIDE_FROM_ABI pair try_emplace(key_type&& __key, _Args&&... __args) { + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 pair + try_emplace(key_type&& __key, _Args&&... __args) { return __try_emplace(std::move(__key), std::forward<_Args>(__args)...); } @@ -600,75 +634,84 @@ class flat_map { requires(__is_compare_transparent && is_constructible_v && is_constructible_v && !is_convertible_v<_Kp &&, const_iterator> && !is_convertible_v<_Kp &&, iterator>) - _LIBCPP_HIDE_FROM_ABI pair try_emplace(_Kp&& __key, _Args&&... __args) { + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 pair try_emplace(_Kp&& __key, _Args&&... __args) { return __try_emplace(std::forward<_Kp>(__key), std::forward<_Args>(__args)...); } template requires is_constructible_v - _LIBCPP_HIDE_FROM_ABI iterator try_emplace(const_iterator __hint, const key_type& __key, _Args&&... __args) { + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator + try_emplace(const_iterator __hint, const key_type& __key, _Args&&... __args) { return __try_emplace_hint(__hint, __key, std::forward<_Args>(__args)...).first; } template requires is_constructible_v - _LIBCPP_HIDE_FROM_ABI iterator try_emplace(const_iterator __hint, key_type&& __key, _Args&&... __args) { + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator + try_emplace(const_iterator __hint, key_type&& __key, _Args&&... __args) { return __try_emplace_hint(__hint, std::move(__key), std::forward<_Args>(__args)...).first; } template requires __is_compare_transparent && is_constructible_v && is_constructible_v - _LIBCPP_HIDE_FROM_ABI iterator try_emplace(const_iterator __hint, _Kp&& __key, _Args&&... __args) { + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator + try_emplace(const_iterator __hint, _Kp&& __key, _Args&&... __args) { return __try_emplace_hint(__hint, std::forward<_Kp>(__key), std::forward<_Args>(__args)...).first; } template requires is_assignable_v && is_constructible_v - _LIBCPP_HIDE_FROM_ABI pair insert_or_assign(const key_type& __key, _Mapped&& __obj) { + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 pair + insert_or_assign(const key_type& __key, _Mapped&& __obj) { return __insert_or_assign(__key, std::forward<_Mapped>(__obj)); } template requires is_assignable_v && is_constructible_v - _LIBCPP_HIDE_FROM_ABI pair insert_or_assign(key_type&& __key, _Mapped&& __obj) { + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 pair + insert_or_assign(key_type&& __key, _Mapped&& __obj) { return __insert_or_assign(std::move(__key), std::forward<_Mapped>(__obj)); } template requires __is_compare_transparent && is_constructible_v && is_assignable_v && is_constructible_v - _LIBCPP_HIDE_FROM_ABI pair insert_or_assign(_Kp&& __key, _Mapped&& __obj) { + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 pair + insert_or_assign(_Kp&& __key, _Mapped&& __obj) { return __insert_or_assign(std::forward<_Kp>(__key), std::forward<_Mapped>(__obj)); } template requires is_assignable_v && is_constructible_v - _LIBCPP_HIDE_FROM_ABI iterator insert_or_assign(const_iterator __hint, const key_type& __key, _Mapped&& __obj) { + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator + insert_or_assign(const_iterator __hint, const key_type& __key, _Mapped&& __obj) { return __insert_or_assign(__hint, __key, std::forward<_Mapped>(__obj)); } template requires is_assignable_v && is_constructible_v - _LIBCPP_HIDE_FROM_ABI iterator insert_or_assign(const_iterator __hint, key_type&& __key, _Mapped&& __obj) { + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator + insert_or_assign(const_iterator __hint, key_type&& __key, _Mapped&& __obj) { return __insert_or_assign(__hint, std::move(__key), std::forward<_Mapped>(__obj)); } template requires __is_compare_transparent && is_constructible_v && is_assignable_v && is_constructible_v - _LIBCPP_HIDE_FROM_ABI iterator insert_or_assign(const_iterator __hint, _Kp&& __key, _Mapped&& __obj) { + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator + insert_or_assign(const_iterator __hint, _Kp&& __key, _Mapped&& __obj) { return __insert_or_assign(__hint, std::forward<_Kp>(__key), std::forward<_Mapped>(__obj)); } - _LIBCPP_HIDE_FROM_ABI iterator erase(iterator __position) { + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator erase(iterator __position) { return __erase(__position.__key_iter_, __position.__mapped_iter_); } - _LIBCPP_HIDE_FROM_ABI iterator erase(const_iterator __position) { + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator erase(const_iterator __position) { return __erase(__position.__key_iter_, __position.__mapped_iter_); } - _LIBCPP_HIDE_FROM_ABI size_type erase(const key_type& __x) { + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 size_type erase(const key_type& __x) { auto __iter = find(__x); if (__iter != end()) { erase(__iter); @@ -680,14 +723,14 @@ class flat_map { template requires(__is_compare_transparent && !is_convertible_v<_Kp &&, iterator> && !is_convertible_v<_Kp &&, const_iterator>) - _LIBCPP_HIDE_FROM_ABI size_type erase(_Kp&& __x) { + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 size_type erase(_Kp&& __x) { auto [__first, __last] = equal_range(__x); auto __res = __last - __first; erase(__first, __last); return __res; } - _LIBCPP_HIDE_FROM_ABI iterator erase(const_iterator __first, const_iterator __last) { + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator erase(const_iterator __first, const_iterator __last) { auto __on_failure = std::__make_exception_guard([&]() noexcept { clear() /* noexcept */; }); auto __key_it = __containers_.keys.erase(__first.__key_iter_, __last.__key_iter_); auto __mapped_it = __containers_.values.erase(__first.__mapped_iter_, __last.__mapped_iter_); @@ -695,7 +738,7 @@ class flat_map { return iterator(std::move(__key_it), std::move(__mapped_it)); } - _LIBCPP_HIDE_FROM_ABI void swap(flat_map& __y) noexcept { + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 void swap(flat_map& __y) noexcept { // warning: The spec has unconditional noexcept, which means that // if any of the following functions throw an exception, // std::terminate will be called. @@ -705,133 +748,156 @@ class flat_map { ranges::swap(__containers_.values, __y.__containers_.values); } - _LIBCPP_HIDE_FROM_ABI void clear() noexcept { + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 void clear() noexcept { __containers_.keys.clear(); __containers_.values.clear(); } // observers - _LIBCPP_HIDE_FROM_ABI key_compare key_comp() const { return __compare_; } - _LIBCPP_HIDE_FROM_ABI value_compare value_comp() const { return value_compare(__compare_); } + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 key_compare key_comp() const { return __compare_; } + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 value_compare value_comp() const { + return value_compare(__compare_); + } - _LIBCPP_HIDE_FROM_ABI const key_container_type& keys() const noexcept { return __containers_.keys; } - _LIBCPP_HIDE_FROM_ABI const mapped_container_type& values() const noexcept { return __containers_.values; } + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const key_container_type& keys() const noexcept { + return __containers_.keys; + } + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const mapped_container_type& values() const noexcept { + return __containers_.values; + } // map operations - _LIBCPP_HIDE_FROM_ABI iterator find(const key_type& __x) { return __find_impl(*this, __x); } + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator find(const key_type& __x) { + return __find_impl(*this, __x); + } - _LIBCPP_HIDE_FROM_ABI const_iterator find(const key_type& __x) const { return __find_impl(*this, __x); } + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_iterator find(const key_type& __x) const { + return __find_impl(*this, __x); + } template requires __is_compare_transparent - _LIBCPP_HIDE_FROM_ABI iterator find(const _Kp& __x) { + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator find(const _Kp& __x) { return __find_impl(*this, __x); } template requires __is_compare_transparent - _LIBCPP_HIDE_FROM_ABI const_iterator find(const _Kp& __x) const { + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_iterator find(const _Kp& __x) const { return __find_impl(*this, __x); } - _LIBCPP_HIDE_FROM_ABI size_type count(const key_type& __x) const { return contains(__x) ? 1 : 0; } + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 size_type count(const key_type& __x) const { + return contains(__x) ? 1 : 0; + } template requires __is_compare_transparent - _LIBCPP_HIDE_FROM_ABI size_type count(const _Kp& __x) const { + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 size_type count(const _Kp& __x) const { return contains(__x) ? 1 : 0; } - _LIBCPP_HIDE_FROM_ABI bool contains(const key_type& __x) const { return find(__x) != end(); } + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 bool contains(const key_type& __x) const { + return find(__x) != end(); + } template requires __is_compare_transparent - _LIBCPP_HIDE_FROM_ABI bool contains(const _Kp& __x) const { + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 bool contains(const _Kp& __x) const { return find(__x) != end(); } - _LIBCPP_HIDE_FROM_ABI iterator lower_bound(const key_type& __x) { return __lower_bound(*this, __x); } + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator lower_bound(const key_type& __x) { + return __lower_bound(*this, __x); + } - _LIBCPP_HIDE_FROM_ABI const_iterator lower_bound(const key_type& __x) const { + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_iterator lower_bound(const key_type& __x) const { return __lower_bound(*this, __x); } template requires __is_compare_transparent - _LIBCPP_HIDE_FROM_ABI iterator lower_bound(const _Kp& __x) { + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator lower_bound(const _Kp& __x) { return __lower_bound(*this, __x); } template requires __is_compare_transparent - _LIBCPP_HIDE_FROM_ABI const_iterator lower_bound(const _Kp& __x) const { + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_iterator lower_bound(const _Kp& __x) const { return __lower_bound(*this, __x); } - _LIBCPP_HIDE_FROM_ABI iterator upper_bound(const key_type& __x) { return __upper_bound(*this, __x); } + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator upper_bound(const key_type& __x) { + return __upper_bound(*this, __x); + } - _LIBCPP_HIDE_FROM_ABI const_iterator upper_bound(const key_type& __x) const { + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_iterator upper_bound(const key_type& __x) const { return __upper_bound(*this, __x); } template requires __is_compare_transparent - _LIBCPP_HIDE_FROM_ABI iterator upper_bound(const _Kp& __x) { + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator upper_bound(const _Kp& __x) { return __upper_bound(*this, __x); } template requires __is_compare_transparent - _LIBCPP_HIDE_FROM_ABI const_iterator upper_bound(const _Kp& __x) const { + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_iterator upper_bound(const _Kp& __x) const { return __upper_bound(*this, __x); } - _LIBCPP_HIDE_FROM_ABI pair equal_range(const key_type& __x) { + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 pair equal_range(const key_type& __x) { return __equal_range_impl(*this, __x); } - _LIBCPP_HIDE_FROM_ABI pair equal_range(const key_type& __x) const { + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 pair + equal_range(const key_type& __x) const { return __equal_range_impl(*this, __x); } template requires __is_compare_transparent - _LIBCPP_HIDE_FROM_ABI pair equal_range(const _Kp& __x) { + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 pair equal_range(const _Kp& __x) { return __equal_range_impl(*this, __x); } template requires __is_compare_transparent - _LIBCPP_HIDE_FROM_ABI pair equal_range(const _Kp& __x) const { + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 pair + equal_range(const _Kp& __x) const { return __equal_range_impl(*this, __x); } - friend _LIBCPP_HIDE_FROM_ABI bool operator==(const flat_map& __x, const flat_map& __y) { + friend _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 bool operator==(const flat_map& __x, const flat_map& __y) { return ranges::equal(__x, __y); } - friend _LIBCPP_HIDE_FROM_ABI auto operator<=>(const flat_map& __x, const flat_map& __y) { + friend _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 auto + operator<=>(const flat_map& __x, const flat_map& __y) { return std::lexicographical_compare_three_way( __x.begin(), __x.end(), __y.begin(), __y.end(), std::__synth_three_way); } - friend _LIBCPP_HIDE_FROM_ABI void swap(flat_map& __x, flat_map& __y) noexcept { __x.swap(__y); } + friend _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 void swap(flat_map& __x, flat_map& __y) noexcept { + __x.swap(__y); + } private: struct __ctor_uses_allocator_tag { - explicit _LIBCPP_HIDE_FROM_ABI __ctor_uses_allocator_tag() = default; + explicit _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 __ctor_uses_allocator_tag() = default; }; struct __ctor_uses_allocator_empty_tag { - explicit _LIBCPP_HIDE_FROM_ABI __ctor_uses_allocator_empty_tag() = default; + explicit _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 __ctor_uses_allocator_empty_tag() = default; }; template requires __allocator_ctor_constraint<_Allocator> - _LIBCPP_HIDE_FROM_ABI - flat_map(__ctor_uses_allocator_tag, - const _Allocator& __alloc, - _KeyCont&& __key_cont, - _MappedCont&& __mapped_cont, - _CompArg&&... __comp) + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 flat_map( + __ctor_uses_allocator_tag, + const _Allocator& __alloc, + _KeyCont&& __key_cont, + _MappedCont&& __mapped_cont, + _CompArg&&... __comp) : __containers_{.keys = std::make_obj_using_allocator( __alloc, std::forward<_KeyCont>(__key_cont)), .values = std::make_obj_using_allocator( @@ -840,12 +906,13 @@ class flat_map { template requires __allocator_ctor_constraint<_Allocator> - _LIBCPP_HIDE_FROM_ABI flat_map(__ctor_uses_allocator_empty_tag, const _Allocator& __alloc, _CompArg&&... __comp) + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 + flat_map(__ctor_uses_allocator_empty_tag, const _Allocator& __alloc, _CompArg&&... __comp) : __containers_{.keys = std::make_obj_using_allocator(__alloc), .values = std::make_obj_using_allocator(__alloc)}, __compare_(std::forward<_CompArg>(__comp)...) {} - _LIBCPP_HIDE_FROM_ABI bool __is_sorted_and_unique(auto&& __key_container) const { + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 bool __is_sorted_and_unique(auto&& __key_container) const { auto __greater_or_equal_to = [this](const auto& __x, const auto& __y) { return !__compare_(__x, __y); }; return ranges::adjacent_find(__key_container, __greater_or_equal_to) == ranges::end(__key_container); } @@ -853,7 +920,7 @@ class flat_map { // This function is only used in constructors. So there is not exception handling in this function. // If the function exits via an exception, there will be no flat_map object constructed, thus, there // is no invariant state to preserve - _LIBCPP_HIDE_FROM_ABI void __sort_and_unique() { + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 void __sort_and_unique() { auto __zv = ranges::views::zip(__containers_.keys, __containers_.values); ranges::sort(__zv, __compare_, [](const auto& __p) -> decltype(auto) { return std::get<0>(__p); }); auto __dup_start = ranges::unique(__zv, __key_equiv(__compare_)).begin(); @@ -863,14 +930,16 @@ class flat_map { } template - _LIBCPP_HIDE_FROM_ABI static auto __corresponding_mapped_it(_Self&& __self, _KeyIter&& __key_iter) { + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 static auto + __corresponding_mapped_it(_Self&& __self, _KeyIter&& __key_iter) { return __self.__containers_.values.begin() + static_cast>( ranges::distance(__self.__containers_.keys.begin(), __key_iter)); } template - _LIBCPP_HIDE_FROM_ABI void __append_sort_merge_unique(_InputIterator __first, _Sentinel __last) { + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 void + __append_sort_merge_unique(_InputIterator __first, _Sentinel __last) { auto __on_failure = std::__make_exception_guard([&]() noexcept { clear() /* noexcept */; }); size_t __num_of_appended = __flat_map_utils::__append(*this, std::move(__first), std::move(__last)); if (__num_of_appended != 0) { @@ -898,7 +967,7 @@ class flat_map { } template - _LIBCPP_HIDE_FROM_ABI static auto __find_impl(_Self&& __self, const _Kp& __key) { + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 static auto __find_impl(_Self&& __self, const _Kp& __key) { auto __it = __self.lower_bound(__key); auto __last = __self.end(); if (__it == __last || __self.__compare_(__key, __it->first)) { @@ -908,7 +977,7 @@ class flat_map { } template - _LIBCPP_HIDE_FROM_ABI static auto __key_equal_range(_Self&& __self, const _Kp& __key) { + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 static auto __key_equal_range(_Self&& __self, const _Kp& __key) { auto __it = std::lower_bound(__self.__containers_.keys.begin(), __self.__containers_.keys.end(), __key, __self.__compare_); auto __last = __self.__containers_.keys.end(); @@ -919,7 +988,7 @@ class flat_map { } template - _LIBCPP_HIDE_FROM_ABI static auto __equal_range_impl(_Self&& __self, const _Kp& __key) { + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 static auto __equal_range_impl(_Self&& __self, const _Kp& __key) { auto [__key_first, __key_last] = __key_equal_range(__self, __key); using __iterator_type = ranges::iterator_t; return std::make_pair(__iterator_type(__key_first, __corresponding_mapped_it(__self, __key_first)), @@ -927,7 +996,7 @@ class flat_map { } template - _LIBCPP_HIDE_FROM_ABI static _Res __lower_bound(_Self&& __self, _Kp& __x) { + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 static _Res __lower_bound(_Self&& __self, _Kp& __x) { auto __key_iter = std::lower_bound(__self.__containers_.keys.begin(), __self.__containers_.keys.end(), __x, __self.__compare_); auto __mapped_iter = __corresponding_mapped_it(__self, __key_iter); @@ -935,7 +1004,7 @@ class flat_map { } template - _LIBCPP_HIDE_FROM_ABI static _Res __upper_bound(_Self&& __self, _Kp& __x) { + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 static _Res __upper_bound(_Self&& __self, _Kp& __x) { auto __key_iter = std::upper_bound(__self.__containers_.keys.begin(), __self.__containers_.keys.end(), __x, __self.__compare_); auto __mapped_iter = __corresponding_mapped_it(__self, __key_iter); @@ -943,7 +1012,8 @@ class flat_map { } template - _LIBCPP_HIDE_FROM_ABI pair __try_emplace(_KeyArg&& __key, _MArgs&&... __mapped_args) { + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 pair + __try_emplace(_KeyArg&& __key, _MArgs&&... __mapped_args) { auto __key_it = std::lower_bound(__containers_.keys.begin(), __containers_.keys.end(), __key, __compare_); auto __mapped_it = __containers_.values.begin() + ranges::distance(__containers_.keys.begin(), __key_it); @@ -962,7 +1032,7 @@ class flat_map { } template - _LIBCPP_HIDE_FROM_ABI bool __is_hint_correct(const_iterator __hint, _Kp&& __key) { + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 bool __is_hint_correct(const_iterator __hint, _Kp&& __key) { if (__hint != cbegin() && !__compare_((__hint - 1)->first, __key)) { return false; } @@ -973,7 +1043,8 @@ class flat_map { } template - _LIBCPP_HIDE_FROM_ABI pair __try_emplace_hint(const_iterator __hint, _Kp&& __key, _Args&&... __args) { + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 pair + __try_emplace_hint(const_iterator __hint, _Kp&& __key, _Args&&... __args) { if (__is_hint_correct(__hint, __key)) { if (__hint == cend() || __compare_(__key, __hint->first)) { return {__flat_map_utils::__emplace_exact_pos( @@ -994,7 +1065,8 @@ class flat_map { } template - _LIBCPP_HIDE_FROM_ABI pair __insert_or_assign(_Kp&& __key, _Mapped&& __mapped) { + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 pair + __insert_or_assign(_Kp&& __key, _Mapped&& __mapped) { auto __r = try_emplace(std::forward<_Kp>(__key), std::forward<_Mapped>(__mapped)); if (!__r.second) { __r.first->second = std::forward<_Mapped>(__mapped); @@ -1003,7 +1075,8 @@ class flat_map { } template - _LIBCPP_HIDE_FROM_ABI iterator __insert_or_assign(const_iterator __hint, _Kp&& __key, _Mapped&& __mapped) { + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator + __insert_or_assign(const_iterator __hint, _Kp&& __key, _Mapped&& __mapped) { auto __r = __try_emplace_hint(__hint, std::forward<_Kp>(__key), std::forward<_Mapped>(__mapped)); if (!__r.second) { __r.first->second = std::forward<_Mapped>(__mapped); @@ -1011,7 +1084,7 @@ class flat_map { return __r.first; } - _LIBCPP_HIDE_FROM_ABI void __reserve(size_t __size) { + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 void __reserve(size_t __size) { if constexpr (__container_traits<_KeyContainer>::__reservable) { __containers_.keys.reserve(__size); } @@ -1022,7 +1095,8 @@ class flat_map { } template - _LIBCPP_HIDE_FROM_ABI iterator __erase(_KIter __key_iter_to_remove, _MIter __mapped_iter_to_remove) { + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator + __erase(_KIter __key_iter_to_remove, _MIter __mapped_iter_to_remove) { auto __on_failure = std::__make_exception_guard([&]() noexcept { clear() /* noexcept */; }); auto __key_iter = __containers_.keys.erase(__key_iter_to_remove); auto __mapped_iter = __containers_.values.erase(__mapped_iter_to_remove); @@ -1032,7 +1106,8 @@ class flat_map { template friend typename flat_map<_Key2, _Tp2, _Compare2, _KeyContainer2, _MappedContainer2>::size_type - erase_if(flat_map<_Key2, _Tp2, _Compare2, _KeyContainer2, _MappedContainer2>&, _Predicate); + _LIBCPP_CONSTEXPR_SINCE_CXX26 + erase_if(flat_map<_Key2, _Tp2, _Compare2, _KeyContainer2, _MappedContainer2>&, _Predicate); friend __flat_map_utils; @@ -1040,8 +1115,9 @@ class flat_map { _LIBCPP_NO_UNIQUE_ADDRESS key_compare __compare_; struct __key_equiv { - _LIBCPP_HIDE_FROM_ABI __key_equiv(key_compare __c) : __comp_(__c) {} - _LIBCPP_HIDE_FROM_ABI bool operator()(const_reference __x, const_reference __y) const { + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 __key_equiv(key_compare __c) : __comp_(__c) {} + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 bool + operator()(const_reference __x, const_reference __y) const { return !__comp_(std::get<0>(__x), std::get<0>(__y)) && !__comp_(std::get<0>(__y), std::get<0>(__x)); } key_compare __comp_; @@ -1164,8 +1240,9 @@ struct uses_allocator && uses_allocator_v<_MappedContainer, _Allocator>> {}; template -_LIBCPP_HIDE_FROM_ABI typename flat_map<_Key, _Tp, _Compare, _KeyContainer, _MappedContainer>::size_type -erase_if(flat_map<_Key, _Tp, _Compare, _KeyContainer, _MappedContainer>& __flat_map, _Predicate __pred) { +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 + typename flat_map<_Key, _Tp, _Compare, _KeyContainer, _MappedContainer>::size_type + erase_if(flat_map<_Key, _Tp, _Compare, _KeyContainer, _MappedContainer>& __flat_map, _Predicate __pred) { auto __zv = ranges::views::zip(__flat_map.__containers_.keys, __flat_map.__containers_.values); auto __first = __zv.begin(); auto __last = __zv.end(); diff --git a/external/llvm-project/libcxx/include/__flat_map/key_value_iterator.h b/external/llvm-project/libcxx/include/__flat_map/key_value_iterator.h index 3ebb653deb19..f163dfc28706 100644 --- a/external/llvm-project/libcxx/include/__flat_map/key_value_iterator.h +++ b/external/llvm-project/libcxx/include/__flat_map/key_value_iterator.h @@ -46,7 +46,7 @@ struct __key_value_iterator { struct __arrow_proxy { __reference __ref_; - _LIBCPP_HIDE_FROM_ABI __reference* operator->() { return std::addressof(__ref_); } + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 __reference* operator->() { return std::addressof(__ref_); } }; __key_iterator __key_iter_; @@ -69,99 +69,113 @@ struct __key_value_iterator { _LIBCPP_HIDE_FROM_ABI __key_value_iterator() = default; - _LIBCPP_HIDE_FROM_ABI __key_value_iterator(__key_value_iterator<_Owner, _KeyContainer, _MappedContainer, !_Const> __i) + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 + __key_value_iterator(__key_value_iterator<_Owner, _KeyContainer, _MappedContainer, !_Const> __i) requires _Const && convertible_to && convertible_to : __key_iter_(std::move(__i.__key_iter_)), __mapped_iter_(std::move(__i.__mapped_iter_)) {} - _LIBCPP_HIDE_FROM_ABI __key_value_iterator(__key_iterator __key_iter, __mapped_iterator __mapped_iter) + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 + __key_value_iterator(__key_iterator __key_iter, __mapped_iterator __mapped_iter) : __key_iter_(std::move(__key_iter)), __mapped_iter_(std::move(__mapped_iter)) {} - _LIBCPP_HIDE_FROM_ABI __reference operator*() const { return __reference(*__key_iter_, *__mapped_iter_); } - _LIBCPP_HIDE_FROM_ABI __arrow_proxy operator->() const { return __arrow_proxy{**this}; } + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 __reference operator*() const { + return __reference(*__key_iter_, *__mapped_iter_); + } + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 __arrow_proxy operator->() const { return __arrow_proxy{**this}; } - _LIBCPP_HIDE_FROM_ABI __key_value_iterator& operator++() { + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 __key_value_iterator& operator++() { ++__key_iter_; ++__mapped_iter_; return *this; } - _LIBCPP_HIDE_FROM_ABI __key_value_iterator operator++(int) { + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 __key_value_iterator operator++(int) { __key_value_iterator __tmp(*this); ++*this; return __tmp; } - _LIBCPP_HIDE_FROM_ABI __key_value_iterator& operator--() { + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 __key_value_iterator& operator--() { --__key_iter_; --__mapped_iter_; return *this; } - _LIBCPP_HIDE_FROM_ABI __key_value_iterator operator--(int) { + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 __key_value_iterator operator--(int) { __key_value_iterator __tmp(*this); --*this; return __tmp; } - _LIBCPP_HIDE_FROM_ABI __key_value_iterator& operator+=(difference_type __x) { + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 __key_value_iterator& operator+=(difference_type __x) { __key_iter_ += __x; __mapped_iter_ += __x; return *this; } - _LIBCPP_HIDE_FROM_ABI __key_value_iterator& operator-=(difference_type __x) { + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 __key_value_iterator& operator-=(difference_type __x) { __key_iter_ -= __x; __mapped_iter_ -= __x; return *this; } - _LIBCPP_HIDE_FROM_ABI __reference operator[](difference_type __n) const { return *(*this + __n); } + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 __reference operator[](difference_type __n) const { + return *(*this + __n); + } - _LIBCPP_HIDE_FROM_ABI friend constexpr bool + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 friend bool operator==(const __key_value_iterator& __x, const __key_value_iterator& __y) { return __x.__key_iter_ == __y.__key_iter_; } - _LIBCPP_HIDE_FROM_ABI friend bool operator<(const __key_value_iterator& __x, const __key_value_iterator& __y) { + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 friend bool + operator<(const __key_value_iterator& __x, const __key_value_iterator& __y) { return __x.__key_iter_ < __y.__key_iter_; } - _LIBCPP_HIDE_FROM_ABI friend bool operator>(const __key_value_iterator& __x, const __key_value_iterator& __y) { + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 friend bool + operator>(const __key_value_iterator& __x, const __key_value_iterator& __y) { return __y < __x; } - _LIBCPP_HIDE_FROM_ABI friend bool operator<=(const __key_value_iterator& __x, const __key_value_iterator& __y) { + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 friend bool + operator<=(const __key_value_iterator& __x, const __key_value_iterator& __y) { return !(__y < __x); } - _LIBCPP_HIDE_FROM_ABI friend bool operator>=(const __key_value_iterator& __x, const __key_value_iterator& __y) { + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 friend bool + operator>=(const __key_value_iterator& __x, const __key_value_iterator& __y) { return !(__x < __y); } - _LIBCPP_HIDE_FROM_ABI friend auto operator<=>(const __key_value_iterator& __x, const __key_value_iterator& __y) + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 friend auto + operator<=>(const __key_value_iterator& __x, const __key_value_iterator& __y) requires three_way_comparable<__key_iterator> { return __x.__key_iter_ <=> __y.__key_iter_; } - _LIBCPP_HIDE_FROM_ABI friend __key_value_iterator operator+(const __key_value_iterator& __i, difference_type __n) { + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 friend __key_value_iterator + operator+(const __key_value_iterator& __i, difference_type __n) { auto __tmp = __i; __tmp += __n; return __tmp; } - _LIBCPP_HIDE_FROM_ABI friend __key_value_iterator operator+(difference_type __n, const __key_value_iterator& __i) { + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 friend __key_value_iterator + operator+(difference_type __n, const __key_value_iterator& __i) { return __i + __n; } - _LIBCPP_HIDE_FROM_ABI friend __key_value_iterator operator-(const __key_value_iterator& __i, difference_type __n) { + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 friend __key_value_iterator + operator-(const __key_value_iterator& __i, difference_type __n) { auto __tmp = __i; __tmp -= __n; return __tmp; } - _LIBCPP_HIDE_FROM_ABI friend difference_type + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 friend difference_type operator-(const __key_value_iterator& __x, const __key_value_iterator& __y) { return difference_type(__x.__key_iter_ - __y.__key_iter_); } diff --git a/external/llvm-project/libcxx/include/__flat_map/utils.h b/external/llvm-project/libcxx/include/__flat_map/utils.h index acb7dca7ffe9..27687ae8de3b 100644 --- a/external/llvm-project/libcxx/include/__flat_map/utils.h +++ b/external/llvm-project/libcxx/include/__flat_map/utils.h @@ -35,7 +35,7 @@ struct __flat_map_utils { // roll back the changes it made to the map. If it cannot roll back the changes, it will // clear the map. template - _LIBCPP_HIDE_FROM_ABI static typename _Map::iterator __emplace_exact_pos( + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 static typename _Map::iterator __emplace_exact_pos( _Map& __map, _IterK&& __it_key, _IterM&& __it_mapped, _KeyArg&& __key, _MArgs&&... __mapped_args) { auto __on_key_failed = std::__make_exception_guard([&]() noexcept { using _KeyContainer = typename _Map::key_container_type; @@ -82,7 +82,7 @@ struct __flat_map_utils { // TODO: We could optimize this, see // https://github.com/llvm/llvm-project/issues/108624 template - _LIBCPP_HIDE_FROM_ABI static typename _Map::size_type + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 static typename _Map::size_type __append(_Map& __map, _InputIterator __first, _Sentinel __last) { typename _Map::size_type __num_appended = 0; for (; __first != __last; ++__first) { diff --git a/external/llvm-project/libcxx/include/__functional/function.h b/external/llvm-project/libcxx/include/__functional/function.h index e71c778386fd..dc112ebfd0fa 100644 --- a/external/llvm-project/libcxx/include/__functional/function.h +++ b/external/llvm-project/libcxx/include/__functional/function.h @@ -125,31 +125,6 @@ _LIBCPP_HIDE_FROM_ABI bool __not_null(_Rp (^__p)(_Args...)) { namespace __function { -template -class __default_alloc_func; - -template -class __default_alloc_func<_Fp, _Rp(_ArgTypes...)> { - _Fp __f_; - -public: - using _Target _LIBCPP_NODEBUG = _Fp; - - _LIBCPP_HIDE_FROM_ABI const _Target& __target() const { return __f_; } - - _LIBCPP_HIDE_FROM_ABI explicit __default_alloc_func(_Target&& __f) : __f_(std::move(__f)) {} - - _LIBCPP_HIDE_FROM_ABI explicit __default_alloc_func(const _Target& __f) : __f_(__f) {} - - _LIBCPP_HIDE_FROM_ABI _Rp operator()(_ArgTypes&&... __arg) { - return std::__invoke_r<_Rp>(__f_, std::forward<_ArgTypes>(__arg)...); - } - - _LIBCPP_HIDE_FROM_ABI __default_alloc_func* __clone() const { return new __default_alloc_func(__f_); } - - _LIBCPP_HIDE_FROM_ABI void destroy() _NOEXCEPT { __f_.~_Target(); } -}; - // __base provides an abstract interface for copyable functors. template @@ -402,7 +377,7 @@ struct __policy { template _LIBCPP_HIDE_FROM_ABI static void* __large_clone(const void* __s) { const _Fun* __f = static_cast(__s); - return __f->__clone(); + return new _Fun(*__f); } template @@ -417,7 +392,7 @@ struct __policy { std::addressof(__large_destroy<_Fun>), false, # if _LIBCPP_HAS_RTTI - &typeid(typename _Fun::_Target) + &typeid(_Fun) # else nullptr # endif @@ -432,7 +407,7 @@ struct __policy { nullptr, false, # if _LIBCPP_HAS_RTTI - &typeid(typename _Fun::_Target) + &typeid(_Fun) # else nullptr # endif @@ -446,42 +421,7 @@ struct __policy { template using __fast_forward _LIBCPP_NODEBUG = __conditional_t::value, _Tp, _Tp&&>; -// __policy_invoker calls an instance of __default_alloc_func held in __policy_storage. - -template -struct __policy_invoker; - -template -struct __policy_invoker<_Rp(_ArgTypes...)> { - typedef _Rp (*__Call)(const __policy_storage*, __fast_forward<_ArgTypes>...); - - __Call __call_; - - // Creates an invoker that throws bad_function_call. - _LIBCPP_HIDE_FROM_ABI __policy_invoker() : __call_(&__call_empty) {} - - // Creates an invoker that calls the given instance of __func. - template - _LIBCPP_HIDE_FROM_ABI static __policy_invoker __create() { - return __policy_invoker(std::addressof(__call_impl<_Fun>)); - } - -private: - _LIBCPP_HIDE_FROM_ABI explicit __policy_invoker(__Call __c) : __call_(__c) {} - - _LIBCPP_HIDE_FROM_ABI static _Rp __call_empty(const __policy_storage*, __fast_forward<_ArgTypes>...) { - std::__throw_bad_function_call(); - } - - template - _LIBCPP_HIDE_FROM_ABI static _Rp __call_impl(const __policy_storage* __buf, __fast_forward<_ArgTypes>... __args) { - _Fun* __f = reinterpret_cast<_Fun*>(__use_small_storage<_Fun>::value ? &__buf->__small : __buf->__large); - return (*__f)(std::forward<_ArgTypes>(__args)...); - } -}; - -// __policy_func uses a __policy and __policy_invoker to create a type-erased, -// copyable functor. +// __policy_func uses a __policy to create a type-erased, copyable functor. template class __policy_func; @@ -491,45 +431,52 @@ class __policy_func<_Rp(_ArgTypes...)> { // Inline storage for small objects. __policy_storage __buf_; - // Calls the value stored in __buf_. This could technically be part of - // policy, but storing it here eliminates a level of indirection inside - // operator(). - typedef __function::__policy_invoker<_Rp(_ArgTypes...)> __invoker; - __invoker __invoker_; + using _ErasedFunc _LIBCPP_NODEBUG = _Rp(const __policy_storage*, __fast_forward<_ArgTypes>...); + + _ErasedFunc* __func_; // The policy that describes how to move / copy / destroy __buf_. Never // null, even if the function is empty. const __policy* __policy_; + _LIBCPP_HIDE_FROM_ABI static _Rp __empty_func(const __policy_storage*, __fast_forward<_ArgTypes>...) { + std::__throw_bad_function_call(); + } + + template + _LIBCPP_HIDE_FROM_ABI static _Rp __call_func(const __policy_storage* __buf, __fast_forward<_ArgTypes>... __args) { + _Fun* __func = reinterpret_cast<_Fun*>(__use_small_storage<_Fun>::value ? &__buf->__small : __buf->__large); + + return std::__invoke_r<_Rp>(*__func, std::forward<_ArgTypes>(__args)...); + } + public: - _LIBCPP_HIDE_FROM_ABI __policy_func() : __policy_(__policy::__create_empty()) {} + _LIBCPP_HIDE_FROM_ABI __policy_func() : __func_(__empty_func), __policy_(__policy::__create_empty()) {} template , __policy_func>::value, int> = 0> _LIBCPP_HIDE_FROM_ABI explicit __policy_func(_Fp&& __f) : __policy_(__policy::__create_empty()) { - typedef __default_alloc_func<_Fp, _Rp(_ArgTypes...)> _Fun; - if (__function::__not_null(__f)) { - __invoker_ = __invoker::template __create<_Fun>(); - __policy_ = __policy::__create<_Fun>(); - if (__use_small_storage<_Fun>()) { - ::new ((void*)&__buf_.__small) _Fun(std::move(__f)); + __func_ = __call_func<_Fp>; + __policy_ = __policy::__create<_Fp>(); + if (__use_small_storage<_Fp>()) { + ::new ((void*)&__buf_.__small) _Fp(std::move(__f)); } else { - __buf_.__large = ::new _Fun(std::move(__f)); + __buf_.__large = ::new _Fp(std::move(__f)); } } } _LIBCPP_HIDE_FROM_ABI __policy_func(const __policy_func& __f) - : __buf_(__f.__buf_), __invoker_(__f.__invoker_), __policy_(__f.__policy_) { + : __buf_(__f.__buf_), __func_(__f.__func_), __policy_(__f.__policy_) { if (__policy_->__clone) __buf_.__large = __policy_->__clone(__f.__buf_.__large); } _LIBCPP_HIDE_FROM_ABI __policy_func(__policy_func&& __f) - : __buf_(__f.__buf_), __invoker_(__f.__invoker_), __policy_(__f.__policy_) { + : __buf_(__f.__buf_), __func_(__f.__func_), __policy_(__f.__policy_) { if (__policy_->__destroy) { - __f.__policy_ = __policy::__create_empty(); - __f.__invoker_ = __invoker(); + __f.__policy_ = __policy::__create_empty(); + __f.__func_ = {}; } } @@ -539,30 +486,30 @@ class __policy_func<_Rp(_ArgTypes...)> { } _LIBCPP_HIDE_FROM_ABI __policy_func& operator=(__policy_func&& __f) { - *this = nullptr; - __buf_ = __f.__buf_; - __invoker_ = __f.__invoker_; - __policy_ = __f.__policy_; - __f.__policy_ = __policy::__create_empty(); - __f.__invoker_ = __invoker(); + *this = nullptr; + __buf_ = __f.__buf_; + __func_ = __f.__func_; + __policy_ = __f.__policy_; + __f.__policy_ = __policy::__create_empty(); + __f.__func_ = {}; return *this; } _LIBCPP_HIDE_FROM_ABI __policy_func& operator=(nullptr_t) { const __policy* __p = __policy_; __policy_ = __policy::__create_empty(); - __invoker_ = __invoker(); + __func_ = {}; if (__p->__destroy) __p->__destroy(__buf_.__large); return *this; } _LIBCPP_HIDE_FROM_ABI _Rp operator()(_ArgTypes&&... __args) const { - return __invoker_.__call_(std::addressof(__buf_), std::forward<_ArgTypes>(__args)...); + return __func_(std::addressof(__buf_), std::forward<_ArgTypes>(__args)...); } _LIBCPP_HIDE_FROM_ABI void swap(__policy_func& __f) { - std::swap(__invoker_, __f.__invoker_); + std::swap(__func_, __f.__func_); std::swap(__policy_, __f.__policy_); std::swap(__buf_, __f.__buf_); } diff --git a/external/llvm-project/libcxx/include/__iterator/iterator_traits.h b/external/llvm-project/libcxx/include/__iterator/iterator_traits.h index 221d36614db0..f727e8ff36df 100644 --- a/external/llvm-project/libcxx/include/__iterator/iterator_traits.h +++ b/external/llvm-project/libcxx/include/__iterator/iterator_traits.h @@ -71,23 +71,6 @@ struct random_access_iterator_tag : public bidirectional_iterator_tag {}; struct contiguous_iterator_tag : public random_access_iterator_tag {}; #endif -template -struct __has_iterator_typedefs { -private: - template - static false_type __test(...); - template - static true_type - __test(__void_t* = nullptr, - __void_t* = nullptr, - __void_t* = nullptr, - __void_t* = nullptr, - __void_t* = nullptr); - -public: - static const bool value = decltype(__test<_Tp>(nullptr, nullptr, nullptr, nullptr, nullptr))::value; -}; - #if _LIBCPP_STD_VER >= 20 // The `cpp17-*-iterator` exposition-only concepts have very similar names to the `Cpp17*Iterator` named requirements @@ -322,6 +305,23 @@ struct __iterator_traits<_Iter, true> is_convertible::value || is_convertible::value > {}; +template +struct __has_iterator_typedefs { +private: + template + static false_type __test(...); + template + static true_type + __test(__void_t* = nullptr, + __void_t* = nullptr, + __void_t* = nullptr, + __void_t* = nullptr, + __void_t* = nullptr); + +public: + static const bool value = decltype(__test<_Tp>(nullptr, nullptr, nullptr, nullptr, nullptr))::value; +}; + // iterator_traits will only have the nested types if Iterator::iterator_category // exists. Else iterator_traits will be an empty class. This is a // conforming extension which allows some programs to compile and behave as diff --git a/external/llvm-project/libcxx/include/__math/abs.h b/external/llvm-project/libcxx/include/__math/abs.h index fc3bf3a2c7c3..b780159f11eb 100644 --- a/external/llvm-project/libcxx/include/__math/abs.h +++ b/external/llvm-project/libcxx/include/__math/abs.h @@ -39,6 +39,30 @@ template ::value, int> = 0> return __builtin_fabs((double)__x); } +// abs + +[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI inline float abs(float __x) _NOEXCEPT { return __builtin_fabsf(__x); } +[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI inline double abs(double __x) _NOEXCEPT { return __builtin_fabs(__x); } + +[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI inline long double abs(long double __x) _NOEXCEPT { + return __builtin_fabsl(__x); +} + +template +[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI inline int abs(int __x) _NOEXCEPT { + return __builtin_abs(__x); +} + +template +[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI inline long abs(long __x) _NOEXCEPT { + return __builtin_labs(__x); +} + +template +[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI inline long long abs(long long __x) _NOEXCEPT { + return __builtin_llabs(__x); +} + } // namespace __math _LIBCPP_END_NAMESPACE_STD diff --git a/external/llvm-project/libcxx/include/__memory/pointer_traits.h b/external/llvm-project/libcxx/include/__memory/pointer_traits.h index 879b387b9ad1..8c7f8dff1b76 100644 --- a/external/llvm-project/libcxx/include/__memory/pointer_traits.h +++ b/external/llvm-project/libcxx/include/__memory/pointer_traits.h @@ -16,11 +16,13 @@ #include <__type_traits/conditional.h> #include <__type_traits/conjunction.h> #include <__type_traits/decay.h> +#include <__type_traits/detected_or.h> #include <__type_traits/enable_if.h> #include <__type_traits/integral_constant.h> #include <__type_traits/is_class.h> #include <__type_traits/is_function.h> #include <__type_traits/is_void.h> +#include <__type_traits/nat.h> #include <__type_traits/void_t.h> #include <__utility/declval.h> #include <__utility/forward.h> @@ -34,67 +36,37 @@ _LIBCPP_PUSH_MACROS _LIBCPP_BEGIN_NAMESPACE_STD -// clang-format off -#define _LIBCPP_CLASS_TRAITS_HAS_XXX(NAME, PROPERTY) \ - template \ - struct NAME : false_type {}; \ - template \ - struct NAME<_Tp, __void_t > : true_type {} -// clang-format on - -_LIBCPP_CLASS_TRAITS_HAS_XXX(__has_pointer, pointer); -_LIBCPP_CLASS_TRAITS_HAS_XXX(__has_element_type, element_type); - -template ::value> -struct __pointer_traits_element_type {}; - template -struct __pointer_traits_element_type<_Ptr, true> { - using type _LIBCPP_NODEBUG = typename _Ptr::element_type; -}; +struct __pointer_traits_element_type_impl {}; template